Add Search By Category In Advanced Search In Magento



Magento has its very powerful search functionality, you can includes all the filters (Attributes) in it from the admin panel or can remove the unused attributes through the admin panel. But in Magento the advanced search page, "search by category" is not an by default option. Suppose you wants to add the "Search By Category" options in Magento Advance search, by using the given below tutorial its very easy to implement it.

Step 1. Required files in which we have to edit the code

app/code/core/Mage/CatalogSearch/Block/Advanced/Form.php
app/code/core/Mage/CatalogSearch/Model/Advanced.php
app/design/yourdesign/yourdesign/template/catalogsearch/advanced/form.phtml

Step 2. Navigate to the app/code/core/Mage/CatalogSearch/Block/Advanced/Form.php and open the file in the editor of your choice and add the below code very end of the file before closing the brace.

public function getStoreCategories()
{
$helper = Mage::helper('catalog/category');
return $helper->getStoreCategories();
}

Step 3.  Now navigate to the app/code/core/Mage/CatalogSearch/Model/Advanced.php, open the file in the editor of your choice and search for the getSearchCriterias() function and replace the getSearchCriterias() with the code below.

public function getSearchCriterias()
{
$search = $this->_searchCriterias;
/* for displaying the category filter */
if(isset($_GET['category']) && is_numeric($_GET['category'])) {
$category = Mage::getModel('catalog/category')->load($_GET['category']);
$search[] = array('name'=>'Category','value'=>$category->getName());
}
return $search;
}

and search for the getProductCollection(); function in the same file and replace the getProductCollection(); function with the code below.


public function getProductCollection(){
if (is_null($this->_productCollection)) {
$this->_productCollection = Mage::getResourceModel('catalogsearch/advanced_collection')
->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
->addMinimalPrice()
->addStoreFilter();
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($this->_productCollection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($this->_productCollection);
/* adding category filter */
if(isset($_GET['category']) && is_numeric($_GET['category'])) $this->_productCollection->addCategoryFilter(Mage::getModel('catalog/category')->load($_GET['category']),true);
}

return $this->_productCollection;
}

Step 3. Adding the Category dropdown for the frontend.

Now we have to display all the categories into the Advance Search from there user can select the Categories. For this navigate to the file app/design/frontend/default/your_custom_theme/template/catalogsearch/advanced/form.phtml or you can find this file app/design/frontend/base/default/template/catalogsearch/advanced/form.phtml search for the below code.

<ul id="advanced-search-list">
<?php foreach ($this->getSearchableAttributes() as $_attribute): ?>
<?php $_code = $_attribute->getAttributeCode() ?>
<li>
<label for="<?php echo $_code ?>"><?php echo $this->getAttributeLabel($_attribute) ?></label>
<?php switch($this->getAttributeInputType($_attribute)):
case 'number': ?>
<div>
<input name="<?php echo $_code ?>[from]" value="<?php echo $this->htmlEscape($this->getAttributeValue($_attribute, 'from')) ?>" id="<?php echo $_code ?>" title="<?php echo $this->htmlEscape($this->getAttributeLabel($_attribute)) ?>"  type="text" />
<input name="<?php echo $_code ?>[to]" value="<?php echo $this->htmlEscape($this->getAttributeValue($_attribute, 'to')) ?>" id="<?php echo $_code ?>_to" title="<?php echo $this->htmlEscape($this->getAttributeLabel($_attribute)) ?>"  type="text"/>
</div>
<?php break;
case 'select': ?>
<?php echo $this->getAttributeSelectElement($_attribute) ?>
<?php break;
case 'yesno': ?>
<?php echo $this->getAttributeYesNoElement($_attribute) ?>
<?php break;
case 'date': ?>
<?php echo $this->getDateInput($_attribute, 'from') ?>
-
<?php echo $this->getDateInput($_attribute, 'to') ?>
<?php break;
default: ?>
<input name="<?php echo $_code ?>" id="<?php echo $_code ?>" value="<?php echo $this->htmlEscape($this->getAttributeValue($_attribute)) ?>" title="<?php echo $this->htmlEscape($this->getAttributeLabel($_attribute)) ?>"  type="text" />
<?php endswitch; ?>
</li>
<?php endforeach; ?>
</ul>

and Add this code below the above code but remember that it should be under the </ul> tag.

<li>
<label for="category_search_field">Search by Category:</label>
<select name="category" id="category_search_field">
<option value="">-- Select Category --</option>
<?php foreach ($this->getStoreCategories() as $_category): ?>
<?php if($_category->hasChildren()): ?>
<option value="<?php echo $_category->getId(); ?>"><?php echo $_category->getName();?></option>
<?php foreach ($_category->getChildren() as $subcategory):
if($subcategory->getIsActive()) : ?>
<option value="<?php echo $subcategory->getId(); ?>"<?php echo ($this->getRequest()->getQuery('category') == $subcategory->getId() ? ' selected="selected"': "") ?>><?php echo $subcategory->getName(); ?></option>
<?php endif; endforeach; ?>
<?php elseif($_category->getIsActive()): ?>
<option value="<?php echo $_category->getId(); ?>"><?php echo $_category->getName();?></option>
<?php endif; ?>
<?php endforeach ?>

</select>
</li>

Then the code will look like as the below.

<ul id="advanced-search-list">
<?php foreach ($this->getSearchableAttributes() as $_attribute): ?>
<?php $_code = $_attribute->getAttributeCode() ?>
<li>
<label for="<?php echo $_code ?>"><?php echo $this->getAttributeLabel($_attribute) ?></label>
<?php switch($this->getAttributeInputType($_attribute)):
case 'number': ?>
<div>
<input type="text" name="<?php echo $_code ?>[from]" value="<?php echo $this->escapeHtml($this->getAttributeValue($_attribute, 'from')) ?>" id="<?php echo $_code ?>" title="<?php echo $this->escapeHtml($this->getAttributeLabel($_attribute)) ?>" maxlength="<?php echo $maxQueryLength;?>" />
<span>-</span>
<input type="text" name="<?php echo $_code ?>[to]" value="<?php echo $this->escapeHtml($this->getAttributeValue($_attribute, 'to')) ?>" id="<?php echo $_code ?>_to" title="<?php echo $this->escapeHtml($this->getAttributeLabel($_attribute)) ?>" maxlength="<?php echo $maxQueryLength;?>" />
</div>
<?php break;
case 'price': ?>
<div>
<input name="<?php echo $_code ?>[from]" value="<?php echo $this->escapeHtml($this->getAttributeValue($_attribute, 'from')) ?>" id="<?php echo $_code ?>" title="<?php echo $this->escapeHtml($this->getAttributeLabel($_attribute)) ?>"  type="text" maxlength="<?php echo $maxQueryLength;?>" />
<span>-</span>
<input name="<?php echo $_code ?>[to]" value="<?php echo $this->escapeHtml($this->getAttributeValue($_attribute, 'to')) ?>" id="<?php echo $_code ?>_to" title="<?php echo $this->escapeHtml($this->getAttributeLabel($_attribute)) ?>"  type="text" maxlength="<?php echo $maxQueryLength;?>" />
<small>(<?php echo $this->getCurrency($_attribute); ?>)</small>
</div>
<?php break;
case 'select': ?>
<div>
<?php echo $this->getAttributeSelectElement($_attribute) ?>
</div>
<?php break;
case 'yesno': ?>
<?php echo $this->getAttributeYesNoElement($_attribute) ?>
<?php break;
case 'date': ?>
<div>
<?php echo $this->getDateInput($_attribute, 'from') ?>
<span>-</span>
<?php echo $this->getDateInput($_attribute, 'to') ?>
</div>
<?php break;
default: ?>
<div>
<input type="text" name="<?php echo $_code ?>" id="<?php echo $_code ?>" value="<?php echo $this->escapeHtml($this->getAttributeValue($_attribute)) ?>" title="<?php echo $this->escapeHtml($this->getAttributeLabel($_attribute)) ?>"  maxlength="<?php echo $maxQueryLength;?>" />
</div>
<?php endswitch; ?>
</li>
<?php endforeach; ?>

<!---Category Code Starts Here------>

<li>
<label for="category_search_field">Search by Category:</label>
<select name="category" id="category_search_field">
<option value="">-- Select Category --</option>
<?php foreach ($this->getStoreCategories() as $_category): ?>
<?php if($_category->hasChildren()): ?>
<option value="<?php echo $_category->getId(); ?>"><?php echo $_category->getName();?></option>
<?php foreach ($_category->getChildren() as $subcategory):
if($subcategory->getIsActive()) : ?>
<option value="<?php echo $subcategory->getId(); ?>"<?php echo ($this->getRequest()->getQuery('category') == $subcategory->getId() ? ' selected="selected"': "") ?>><?php echo $subcategory->getName(); ?></option>
<?php endif; endforeach; ?>
<?php elseif($_category->getIsActive()): ?>
<option value="<?php echo $_category->getId(); ?>"><?php echo $_category->getName();?></option>
<?php endif; ?>
<?php endforeach ?>

</select>
</li>

<!---Category Code Ends------------->

</ul>

Step 4. Now Navigate to the app/code/core/Mage/CatalogSearch/Model/Advanced.php and open the file in the editor of your choice and search for the addFilters() function and you will see the following codes, replace this one

if ($allConditions) {
$this->getProductCollection()->addFieldsToFilter($allConditions);
} else if (!count($filteredAttributes)) {
Mage::throwException(Mage::helper('catalogsearch')->__('You have to specify at least one search term'));
}

with the below codes.

if (($allConditions) || (isset($values['category']) && is_numeric($values['category']))) {
$this->getProductCollection()->addFieldsToFilter($allConditions);
} else if (!count($filteredAttributes)) {
Mage::throwException(Mage::helper('catalogsearch')->__('You have to specify at least one search term'));
}

Now it is done and it will look like as the image below.