Fixing Invalid Results In Magento Search

 

I spent several hours earlier today (5+) dealing with an issue where Magento was returning all types of products, but not returning what we wanted or expected. In some cases searching for a SKU wouldn’t even find the product. In addition, it was returning too many products.┬áThe advanced search worked fine. Just the quick search was not working.

Now, I realize that Magento’s search engine is often considered screwy, but in my experience it had always worked well enough. That is why this issue confused me so greatly. After stepping through the code line-by-line, I realized that what was going on was that the search query wasn’t actually running.

Further digging finally led me to what was going on. In a nutshell, the issue was related to the layout in that we had changed from a two column layout to a one column layout. Normally, you would think this wouldn’t effect the system, but this is one of those Magento cases that it does, but thankfully it is an easy enough fix and simple to understand why it’s happening.

To start explaining this issue, lets take a quick look at the Magento catalogsearch.xml Layout file (Located in ./app/design/frontend/default/default/layout/catalogsearch.xml).

[code]

<catalogsearch_result_index translate=”label”>
<label>Quick Search Form</label>
<reference name=”root”>
<action method=”setTemplate”><template>page/3columns.phtml</template></action>
</reference>
<reference name=”left”>
<block type=”catalogsearch/layer” name=”catalogsearch.leftnav” after=”currency” template=”catalog/layer/view.phtml”/>
</reference>
<reference name=”content”>
<block type=”catalogsearch/result” name=”search.result” template=”catalogsearch/result.phtml”>
<block type=”catalog/product_list” name=”search_result_list” template=”catalog/product/list.phtml”>
<block type=”catalog/product_list_toolbar” name=”product_list_toolbar” template=”catalog/product/list/toolbar.phtml”>
<block type=”page/html_pager” name=”product_list_toolbar_pager”/>
</block>
<action method=”addColumnCountLayoutDepend”><layout>empty</layout><count>6</count></action>
<action method=”addColumnCountLayoutDepend”><layout>one_column</layout><count>5</count></action>
<action method=”addColumnCountLayoutDepend”><layout>two_columns_left</layout><count>4</count></action>
<action method=”addColumnCountLayoutDepend”><layout>two_columns_right</layout><count>4</count></action>
<action method=”addColumnCountLayoutDepend”><layout>three_columns</layout><count>3</count></action>
<action method=”setToolbarBlockName”><name>product_list_toolbar</name></action>
</block>
<action method=”setListOrders”/>
<action method=”setListModes”/>
<action method=”setListCollection”/>
</block>
</reference>
</catalogsearch_result_index>

[/code]

Notice that there are 5 blocks within this layout. We’re going to ignore product_list_toolbar and product_list_toolbar_pager, as they don’t effect us. Our base search page content is in the search.result block. The list of products is built by it’s sub block, search_result_list, an instance of catalog/product_list. What actually loads our collection of products though is the block listed above these two, catalogsearch.leftnav.

Magento uses a ‘Layer’ block between the search and the search list. Such block are also used in regular listings. When magento tries to get the list of products, it first checks to see if the registry key for this layer is set. If it is, then magento retrieves the list of products from the layer. Otherwise it falls back to the root category of the current store.

What makes the catalog search unique is that it does not actually register it’s layer outside the layer block. Instead, the layer is registered in the construction of the layer block itself. This creates an bit of a snag in that if the block isn’t loaded, the query search results aren’t loaded, and magento falls back to the root category and the search seemingly returns the mess of products you see in the list.

For performance reasons, among others, blocks in magento are not loaded until they are actually requested via $this->getChild() in a phtml file, or one of the similar methods. When we changed the site to a one column layout, the left column never got processed. As a result, the layer was never loaded.

Fortunatly it’s really easy to fix and we don’t have to go far out of the way. We make two changes to our template to fix it. The first is to our local.xml Layout XML file:

[code]

<catalogsearch_result_index>
<reference name=”root”>
<action method=”setTemplate”><template>page/1column.phtml</template></action>
</reference>
<reference name=”search.result”>
<block type=”catalogsearch/layer” name=”catalogsearch” after=”currency” template=”catalog/layer/view.phtml”/>
</reference>
</catalogsearch_result_index>

[/code]

There already exists the line that sets the template to one column. We copy the layer block XML into our local, referencing the search.result block. We could put it other places as well, but the key is to put it somewhere it will load. In the case of search.result, we have to make one more change to ensure the block is loaded. This is in the search.result phtml file:

[code]$this->getChild(‘catalogsearch’);[/code]

We add this line at the beginning of the file so it is ran first. We have to do it first as the first line on the file is using the getResultCount method, which is the line that ultimately results in the collection getting loaded.

Once the block is loading correctly, your search results should return properly.

 


If you found this article useful, please consider donating to show your support. Need help with something? Feel free to Drop-A-Line and we will try to assist where we can.

 
This entry was posted in Creations, Magento, Random, Vents. Bookmark the permalink.