5

I have someone issue in api magento 2. I need get layer navigation data available in product collection ( current category , search product ) but I don't know magento 2 api available it or not . I have create new custom api using Magento\Catalog\Model\Layer\Resolver but it not work . Any one can help me ?

i need get this data in rest api

thanks guys

  • @Nguyen Can we add additional filter in it for example : if someone clicked on a particular brand then other brand should be remove from layer navigation? – Kanika Mar 5 at 13:27
8

There are 2 methods to achieve this

First one

Filter.php (api model)

    public function __construct(\Magento\Framework\Webapi\Rest\Request 
        $request){

                $this->_request         = $request;
        }


/**
     * Retrieve filterlist
     *
     * @api
     * @return array
     */
    public function retrieve(){     

        $category = $this->_request->getParam('categoryId');

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();

        $filterableAttributes = $objectManager->getInstance()->get(\Magento\Catalog\Model\Layer\Category\FilterableAttributeList::class);

        $appState = $objectManager->getInstance()->get(\Magento\Framework\App\State::class);
        $layerResolver = $objectManager->getInstance()->get(\Magento\Catalog\Model\Layer\Resolver::class);
        $filterList = $objectManager->getInstance()->create(
            \Magento\Catalog\Model\Layer\FilterList::class,
                [
                    'filterableAttributes' => $filterableAttributes
                ]
            );      

            $layer = $layerResolver->get();
            $layer->setCurrentCategory($category);
            $filters = $filterList->getFilters($layer);
            $maxPrice = $layer->getProductCollection()->getMaxPrice();
            $minPrice = $layer->getProductCollection()->getMinPrice();  

        $i = 0;
       foreach($filters as $filter)
       {
           //$availablefilter = $filter->getRequestVar(); //Gives the request param name such as 'cat' for Category, 'price' for Price
           $availablefilter = (string)$filter->getName(); //Gives Display Name of the filter such as Category,Price etc.
           $items = $filter->getItems(); //Gives all available filter options in that particular filter
           $filterValues = array();
           $j = 0;
           foreach($items as $item)
           {


               $filterValues[$j]['display'] = strip_tags($item->getLabel());
               $filterValues[$j]['value']   = $item->getValue();
               $filterValues[$j]['count']   = $item->getCount(); //Gives no. of products in each filter options
               $j++;
           }
           if(!empty($filterValues) && count($filterValues)>1)
           {
               $filterArray['availablefilter'][$availablefilter] =  $filterValues;
           }
           $i++;
       }  


        echo json_encode($filterArray);
        exit;

    }

Sample out put of this code will be:

{
    "availablefilter": {
        "Climate": [
            {
                "display": "All-Weather",
                "value": "202",
                "count": "1"
            },
            {
                "display": "Cool",
                "value": "204",
                "count": "1"
            }
        ],
        "Manufacturer": [
            {
                "display": "Azzedine Alaïa",
                "value": "216",
                "count": "1"
            },
            {
                "display": "Balenciaga",
                "value": "217",
                "count": "1"
            }
        ],
        "Material": [
            {
                "display": "Cotton",
                "value": "33",
                "count": "1"
            },
            {
                "display": "Nylon",
                "value": "37",
                "count": "1"
            }
        ],

Second method

public function __construct(
        \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $productAttributeCollectionFactory
    ) {
        $this->productAttributeCollectionFactory = $productAttributeCollectionFactory;
    }

    public function getFilterableAttributes()
    {
        /** @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection $productAttributes */
        $productAttributes = $this->productAttributeCollectionFactory->create();
        $productAttributes->addFieldToFilter(
            ['is_filterable', 'is_filterable_in_search'],
            [[1, 2], 1]
        );

        return $productAttributes;
    }
| improve this answer | |
  • Can you explain the 2nd method? How can it filter product within CategoryId. – Nam Trung May 22 '19 at 5:45
  • 1
    @NamTrung You can get all the filterable attribute list by Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory class. The result will be all those attributes which have, Use in Layered Navigation status are Filterable (with results) or Filterable (no results). You need to create __construct( ) function for define dependency of Class. – NID May 22 '19 at 7:16
  • Now call a function in template file by iterating over a loop to fetch each attribute code, $getAttributes = $block->getFilterableAttributes(); foreach ($getAttributes as $attribute) { echo $attribute->getAttributeCode();echo "<br>"; } – NID May 22 '19 at 7:16
  • Result would be something like this: manufacturer color activity style_bags material strap_bags features_bags gender category_gear size eco_collection performance_fabric erin_recommends new sale format style_bottom style_general sleeve collar pattern climate – NID May 22 '19 at 7:16
  • 1
    if you are writing a api i would suggest you to go with first method. I have been following frst method for a while and its working. I haven't tried second method with api. – NID May 22 '19 at 7:33
1

Get request value in json format like below

{
        "category_id":"36" //pass category which you want
}

below is the Filterattributes.php (api model)

class FilterAttributes extends \Magento\Framework\Model\AbstractModel implements FilterAttributesInterface
{



    public function __construct(

    ){

    }

    /**
     * Returns greeting message to user
     *
     * @api
     * @param string $name Users name.
     * @return string Greeting message with users name.
     */
    public function filterAttributes() {

        $json = file_get_contents('php://input');
        $post = json_decode($json);

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();

        $filterableAttributes = $objectManager->getInstance()->get(\Magento\Catalog\Model\Layer\Category\FilterableAttributeList::class);

        $appState = $objectManager->getInstance()->get(\Magento\Framework\App\State::class);
        $layerResolver = $objectManager->getInstance()->get(\Magento\Catalog\Model\Layer\Resolver::class);
        $filterList = $objectManager->getInstance()->create(
            \Magento\Catalog\Model\Layer\FilterList::class,
                [
                    'filterableAttributes' => $filterableAttributes
                ]
            );      

            $layer = $layerResolver->get();
            $layer->setCurrentCategory($post->category_id);
            $filters = $filterList->getFilters($layer);
            $maxPrice = $layer->getProductCollection()->getMaxPrice();
            $minPrice = $layer->getProductCollection()->getMinPrice();  

        $i = 0;
        $filterAttrs = [];
       foreach($filters as $filter)
       {
            $values = [];
            $attr_code = (string)$filter->getRequestVar();
            $attr_label = (string)$filter->getName();
            $items = $filter->getItems(); //Gives all available filter options in that particular filter
           foreach($items as $item)
           {

                $values[] = array("display"=>strip_tags($item->getLabel()),
                                    "value"=>$item->getValue(),
                                    "count"=>$item->getCount());
           }
           if(!empty($values) && count($values)>1)
           {
               $filterAttrs[]=array("attr_code"=>$attr_code,
                                "attr_label"=>$attr_label,
                                "values"=>$values);
           }

       }  


       if(count($filters)>0){
        $data['status'] = "true";
        $data['filters'] = $filterAttrs;
       }else{
        $data['status'] = "false";
        $data['msg'] = "No Filters Found";
       }



         echo json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT );// str_replace('\/','/',json_encode($data)); 
        exit();
    }



}
| improve this answer | |
  • Can we add additional filter in it for example : if someone clicked on a particular brand then other brand should be remove from layer navigation? – Kanika Mar 5 at 13:26

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.