PHP Magento Tips

Add Search By Category Search option in Advanced Search Form in Magento.

Rate this posting:
{[['']]}

In the advanced search form, “search by category” is not provided by Magento by default. It helps to users to search products according to their needs and improves user interface with your website.

To add this feature, you will need to edit the following files:

       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


Before changing first two files (Magento Core files), i personally recommended you to create Mage/CatalogSearch folder inside app/code/local and then copy files in it as per path above.

if you are using rwd theme then template/catalogsearch/advanced/form.phtml is already there. if its not then put this file in your template folder.

Step 1:

At the very end of app/code/local/Mage/CatalogSearch/Block/Advanced/Form.php (before the closing brace), add:

/**
     * Build date element html string for attribute
     *
     * @param Mage_Eav_Model_Entity_Attribute_Abstract $attribute
     * @param string $part
     * @return string
     */
    public function getDateInput($attribute, $part = 'from')
    {
        $name = $attribute->getAttributeCode() . '[' . $part . ']';
        $value = $this->getAttributeValue($attribute, $part);

        return $this->_getDateBlock()
            ->setName($name)
            ->setId($attribute->getAttributeCode() . ($part == 'from' ? '' : '_' . $part))
            ->setTitle($this->getAttributeLabel($attribute))
            ->setValue($value)
            ->setImage($this->getSkinUrl('images/calendar.gif'))
            ->setFormat('%m/%d/%y')
            ->setClass('input-text')
            ->getHtml();
    }
    // Add New Code here
    public function getStoreCategories()
    {
        $helper = Mage::helper('catalog/category');
        return $helper->getStoreCategories();
    }
}
 
Step: 2

In app/code/local/Mage/CatalogSearch/Model/Advanced.php, replace the getSearchCriterias() function (line 157) with the code below:

    public function getSearchCriterias()
    {
        $search = $this->_searchCriterias;
        /* display category filtering criteria */
        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;
    } 

replace the next function, getProductCollection(), with:

      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);
            /* include category filtering */
            if(isset($_GET['category']) && is_numeric($_GET['category'])) $this->_productCollection->addCategoryFilter(Mage::getModel('catalog/category')->load($_GET['category']),true);
        }
  
        return $this->_productCollection;
    } 

Step 3:

In app/design/frontend/yourdesign/yourdesign/template/catalogsearch/advanced/form.phtml, add new <li> after line no. 83

        <ul class="form-list" 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 class="input-range">
                        <input type="text" pattern="\d*" 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)) ?>" class="input-text validate-number" maxlength="<?php echo $maxQueryLength;?>" />
                        <span class="separator">-</span>
                        <input type="text" pattern="\d*" 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)) ?>" class="input-text validate-number" maxlength="<?php echo $maxQueryLength;?>" />
                    </div>
                    <?php break;
                    case 'price': ?>
                    <div class="input-range">
                        <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)) ?>"  class="input-text validate-number" type="text" pattern="\d*" maxlength="<?php echo $maxQueryLength;?>" />
                        <span class="separator">-</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)) ?>"  class="input-text validate-number" type="text" pattern="\d*" maxlength="<?php echo $maxQueryLength;?>" />
                        <small>(<?php echo $this->getCurrency($_attribute); ?>)</small>
                    </div>
                    <?php break;
                    case 'select': ?>
                        <div class="input-box">
                            <?php echo $this->getAttributeSelectElement($_attribute) ?>
                        </div>
                    <?php break;
                    case 'yesno': ?>
                        <?php echo $this->getAttributeYesNoElement($_attribute) ?>
                    <?php break;
                    case 'date': ?>
                    <div class="input-range">
                        <?php echo $this->getDateInput($_attribute, 'from') ?>
                        <span class="separator">-</span>
                        <?php echo $this->getDateInput($_attribute, 'to') ?>
                    </div>
                    <?php break;
                    default: ?>
                    <div class="input-box">
                        <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)) ?>"  class="input-text <?php echo $this->getAttributeValidationClass($_attribute) ?>" maxlength="<?php echo $maxQueryLength;?>" />
                    </div>
                <?php endswitch; ?>
            </li> 
            <?php endforeach; ?>
            <!-- Add New Code start -->
            <li>
            <label for="category_search_field">Search by Category:</label>
            <select name="category" id="category_search_field">
                <option value="">-- Any Category --</option>
                <?php foreach ($this->getStoreCategories() as $_category): ?>
                <?php if($_category->hasChildren()): ?>
                <option class="parent-cat" 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>
            <!-- Add New Code Ends -->
         </ul> 

Step 4:

Now, If you are going to search only by Category then you will face an error message like “You have to specify at least one search term”. To solve it you need to modify following file:

app/code/local/Mage/CatalogSearch/Model/Advanced.php

Open the file and search this function addFilters. Now at the line no. 211 modify that code with below code:

    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 you won’t face any problem in advanced search only by Category or any single attribute search.

Finally, you will get below form in Advance search page with "Search by Category" option included:

 
Tag : Magento
2 Comments On "Add Search By Category Search option in Advanced Search Form in Magento."

Back To Top