0

Following code fetch the products based on search keyword but the issue is filtering showing all instead of the search result page.

I want filters should be shown only related to the search result page only.

   //Code for fetch products based on search term.    
    $this->_storeManager->setCurrentStore($storeid);
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $filterBuilder = $objectManager->get('Magento\Framework\Api\FilterBuilder');
    $searchCriteriaBuilder = $objectManager->get('Magento\Framework\Api\Search\SearchCriteriaBuilder');
    $searchInterface = $objectManager->get('Magento\Search\Api\SearchInterface');
    $filterGroupBuilder = $objectManager->get('Magento\Framework\Api\Search\FilterGroupBuilder');

    $search_criteria = $searchCriteriaBuilder->create();
    $search_criteria->setRequestName("quick_search_container");
    $filter = $filterBuilder->setField('search_term')
    ->setValue($q)
    ->setConditionType("like")
    ->create();
    $filterGroup = $filterGroupBuilder->addFilter($filter)->create();
    $search_criteria->setFilterGroups([$filterGroup]);
    $resultx = $searchInterface->search($search_criteria);
    //var_dump($resultx); exit;

    $totalSearchResults = $resultx->getTotalCount();
    
    $products = $resultx->getItems();        

    if(count($products) == 0)
    {
      echo json_encode(array('status' => false,'message' => 'No data found'));exit;            
    }
    
    $product_data = array();
    foreach ($products as $pro) {
        //echo $product->getId(); exit;
        $product = $this->_productRepositoryFactory->create()->getById($pro->getId(),false,$storeid);                                                          
        $product_data[] = array(
        'product_id' => $product->getData('entity_id'),
        'sku' => $product->getData('sku'),
        'currency' => $this->_storeManager->getStore()->getCurrentCurrencyCode(),
        'type' => $product->getData('type_id'),
        'visibility' => $product->getData('visibility'),
        'status' => $product->getData('status'),
        'url_key' => $product->getData('url_key'),
        'url_path' => $product->getData('url_path'),
        'image' => $this->imageHelper->init($product, 'product_page_image_medium')->getUrl(),
        'is_in_stock' => $this->getStockStatus($pro->getId()),
        'price' => $product->getData('price'),
        'special_price' => $product->getData('special_price')

        );
        
    }

    //Code for filter.
    $rootCategoryId = $this->_storeManager->getStore()->getRootCategoryId();
    $category = $this->_categoryFactory->create()->setStoreId($storeid)->load($rootCategoryId);
    $filterableAttributes = $objectManager->get(\Magento\Catalog\Model\Layer\Category\FilterableAttributeList::class);
    $layerResolver = $objectManager->get(\Magento\Catalog\Model\Layer\Resolver::class);
    $layer = $layerResolver->get();
    $layer->setCurrentCategory($category);
    $filterList = $objectManager->create(
        \Magento\Catalog\Model\Layer\FilterList::class,
        [
            'filterableAttributes' => $filterableAttributes
        ]
    );
    $collection = $layer->getProductCollection();
    $allFilters = $filterList->getFilters($layer);
    $activeFilters = $this->_appApiHelperData->getFilters($allFilters,$storeid);

    $returnArray['total_count'] = count(array_unique($product_data,SORT_REGULAR));
    $returnArray['product_data'] = $product_data;
    $returnArray['filters'] = $activeFilters;
0

In Magento 2.4.1, I have implemented the below code for fetching products based on search terms and filters based on search results.

<?php
namespace YourModule\Appapi\Model\Search;

use YourModule\Appapi\Api\Search\SearchResultInterface; 
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\CatalogInventory\Api\Data\StockItemInterface;
use Magento\Catalog\Helper\Image;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\Search\SearchCriteriaBuilder;
use Magento\Search\Api\SearchInterface;
use Magento\Framework\Api\Search\FilterGroupBuilder;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;

class SearchResult implements SearchResultInterface
{

    /**
     * @var \Magento\Catalog\Api\ProductRepositoryInterface
     */
    protected $productRepository;
    protected $imageHelper;
    protected $_storeManager;
    protected $_appApiHelperData;
    protected $_stockItemRepository;
    protected $_stockRegistryInterface;
    protected $filterBuilder;
    protected $searchCriteriaBuilder;
    protected $filterGroupBuilder;
    protected $searchInterface;

    public function __construct(
        ProductRepositoryInterface $productRepository,
        Image $imageHelper,
        StoreManagerInterface $storeManager,
        StockRegistryInterface $stockRegistryInterface,
        ScopeConfigInterface $scopeConfig,
        \Magento\Framework\Pricing\Helper\Data $pricingHelper,
        \YourModule\Appapi\Helper\Data $appApiHelperData,
        FilterBuilder $filterBuilder,
        SearchCriteriaBuilder $searchCriteriaBuilder,
        FilterGroupBuilder $filterGroupBuilder,
        SearchInterface $searchInterface        
    )
    {
        $this->productRepository = $productRepository;
        $this->imageHelper = $imageHelper;
        $this->_storeManager = $storeManager;
        $this->_appApiHelperData = $appApiHelperData;
        $this->_stockRegistryInterface = $stockRegistryInterface;;
        $this->scopeConfig = $scopeConfig;
        $this->filterBuilder = $filterBuilder;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
        $this->filterGroupBuilder = $filterGroupBuilder;
        $this->searchInterface = $searchInterface;        

    }

    public function getSearchResult($q,$storeid)
    {   
        try{
            //Code for validations.
            if($storeid == '')
            {
                echo json_encode(array('code' => 200, 'status' => false, 'message' => 'Store id parameter should not be empty.'));
                exit;
            }
            if(!is_numeric($storeid))
            {
                echo json_encode(array('code' => 200, 'status' => false, 'message' => 'Store id parameter accept only numbers.'));
                exit;            
            }            
            if($q == '' || strpos($q, '@') !== false || strpos($q, '.com') !== false){
                $response = [
                    'status' => (bool)false,
                    'code' => 404,
                    'message' => __('Please enter a valid search keyword.')
                ];          
                echo json_encode($response);
                exit;
            }

        //Code for fetch products based on search term.    
        $this->_storeManager->setCurrentStore($storeid);
        $search_criteria = $this->searchCriteriaBuilder->create();
        $search_criteria->setRequestName("quick_search_container");
        $filter = $this->filterBuilder->setField('search_term')
        ->setValue($q)
        ->setConditionType("like")
        ->create();
        $filterGroup = $this->filterGroupBuilder->addFilter($filter)->create();
        $search_criteria->setFilterGroups([$filterGroup]);
        $search_result = $this->searchInterface->search($search_criteria);
        $totalSearchResults = $search_result->getTotalCount();        
        $products = $search_result->getItems();        
        if(count($products) == 0)
        {
          echo json_encode(array('status' => false,'message' => 'No data found'));exit;            
        }
        $product_data = array();
        foreach ($products as $pro)
        {
            $product = $this->productRepository->getById($pro->getId(),false,$storeid);
            $product_data[] = array(
            'product_id' => $product->getData('entity_id'),
            'sku' => $product->getData('sku'),
            'currency' => $this->_storeManager->getStore()->getCurrentCurrencyCode(),
            'type' => $product->getData('type_id'),
            'visibility' => $product->getData('visibility'),
            'status' => $product->getData('status'),
            'url_key' => $product->getData('url_key'),
            'url_path' => $product->getData('url_path'),
            'image' => $this->imageHelper->init($product, 'product_page_image_medium')->getUrl(),
            'is_in_stock' => $this->getStockStatus($pro->getId()),
            'price' => $product->getData('price'),
            'special_price' => $product->getData('special_price')
            );            
        }

        //Code for filter.
        $allAggregations = $search_result->getAggregations();
        $buckets = $allAggregations->getBuckets();        
        $activeFilters = $this->getFilters($buckets,$storeid);

        $returnArray['total_count'] = count(array_unique($product_data,SORT_REGULAR));
        $returnArray['product_data'] = $product_data;
        $returnArray['filters'] = $activeFilters;

        if(empty($product_data)){              
            echo json_encode(array('status' => false,'message' => 'No data found'));
            exit;
        }else{                
            $response = [
                'status' => (bool)true,
                'code' => 200,
                'message' => 'Success',
                'data' => $returnArray
            ];          
            echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            exit;             
        }       


        } catch (Exception $e) {
            echo json_encode(array('status' => (bool)false, 'message' => $e->getMessage()));
            exit;
        }
    }

     /**
     * get stock status
     *
     * @param int $productId
     * @return bool 
     */
    public function getStockStatus($productId)
    {
        /** @var StockItemInterface $stockItem */
        $stockItem = $this->_stockRegistryInterface->getStockItem($productId);
        $isInStock = $stockItem ? $stockItem->getIsInStock() : false;
        return $isInStock;
    }     
}

Fetch Filters based on the search results page.

<?php
namespace YourModule\Appapi\Helper;
use Magento\Eav\Model\Config;

class Data extends AbstractHelper
{
    protected $eavConfig;
    
    public function __construct(
        Config $eavConfig
        ){
        $this->eavConfig                = $eavConfig;
    }
    
    /*
     * Function: getFilters
     * Author: Jitendra Patel
     * Request Params: $filters,$storeid
     * Response Params: All Filters array or error message.
     */
    public function getFilters($buckets,$storeid)
    {
        $finalFilters = array();
        foreach($buckets as $bucket)
        {
            if($bucket->getName() == 'category_bucket')
            {
                continue;
            }
            $attribute_code = '';             
            $filters = array();
            $attribute_code = str_replace('_bucket','', $bucket->getName());
            foreach($bucket->getValues() as $value)
            {
             //code for fetch the attribute option value by option id.
             $metrics = $value->getMetrics();
             if(!empty($metrics['value']))
             {
                $option_id = $metrics['value'];             
                $attribute = $this->eavConfig->getAttribute('catalog_product', $attribute_code);
                $optionlabel =  $attribute->getSource()->getOptionText($option_id);
                $filters['code']  = $attribute_code;
                $filters['name']  = $optionlabel;
                $filters['value'] = $metrics['value'];
                $filters['count'] = $metrics['count'];
             }
             $finalFilters[$attribute_code][] =     $filters;
            }            
        }
        if(empty($finalFilters))
        {
          $message = "Data not found";
          return $message;
        }
        else
        {
          return $finalFilters;
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.