4

I am building mobile apps integrated with Magento via REST APIs. I have completed the app and created a lot of custom APIs for this purpose. I am now stuck in fetching filterable attributes and associated options for a category listing.

I am aware Magento uses the catalog/layer model for this purpose in the frontend. Most of it is done using blocks. I am not sure how to use this from API since there is no concept of layout here. Correct me if I am wrong.

The app's requirement is this.

  • There are categories listed in the app.
  • Clicking on a category will list all the products in that category.
  • There is a filter button which when clicked should show all available filters for that particular products listed (results).
  • Further, clicking on each filter should fetch the relevant products and the filters will get changed based on whether there are products for a particular attribute's option.

I am able to do this by calling the Magento functions directly. But it is very heavy. Taking forever to load. This is what I am doing.

  • Get all categories using the id.
  • Get all filterable attributes in Magento
  • Get all options for each attribute
  • Load the product collection for each option to determine whether this option has any products in it and to get the count of products.
  • Return the products
  • Return all attributes and options with count.

I cannot do this way obviously because it is too heavy and taking 1 minute to repond for for 5k products and many attributes. In fact there are 3 for loops.

Does anyone know the right way?

1 Answer 1

2

Hi I Know it is a late reply but it may help some other magento api developers.

protected function _create($data){
    $typeid = $data['categoryId'];
    $userid = $data['userId'];
    $pagesize = $data['limit'];
    $pageno = $data['page'];
    Mage::app()->setCurrentStore(1);
    Mage::app('default');
    Mage::getSingleton("core/session", array("name" => "frontend"));
    $websiteId = Mage::app()->getWebsite()->getId();
    $store = Mage::app()->getStore();



    try
    {


            $layer = Mage::getModel("catalog/layer");
            $category = Mage::getModel('catalog/category')->load($typeid);
            Mage::register('current_category', $category);
            Mage::register('current_entity_key', $category->getPath());
            $layer->setCurrentCategory($category);
            $products = $layer->getProductCollection()->addAttributeToSelect('*');

            if($pageno==1){
                $filter=array();
                $attributes = $layer->getFilterableAttributes();
                $min_price = $layer->getProductCollection()->getMinPrice();
                $max_price = $layer->getProductCollection()->getMaxPrice();
                $price['minPrice']=$min_price;
                $price['maxPrice']=$max_price;
                $json['priceRange']=$price;
                $json['priceRangeApplied']=$price;
                $json['attributes'] = array();
                foreach ($attributes as $attribute) {
                    if ($attribute->getAttributeCode() == 'price') {
                        $filterBlockName = 'catalog/layer_filter_attribute';
                    } elseif ($attribute->getBackendType() == 'decimal') {
                        $filterBlockName = 'catalog/layer_filter_decimal';
                    } else {
                        $filterBlockName = 'catalog/layer_filter_attribute';
                    }

                    $result = Mage::app()->getLayout()->createBlock($filterBlockName)->setLayer($layer)->setAttributeModel($attribute)->init();

                    if(array_key_exists($attribute->getAttributeCode(),$data['filters'])){
                    foreach($result->getItems() as $option) {
                        if(in_array($option->getValue(),explode(',',$data['filters'][$attribute->getAttributeCode()]))){
                            $count[] = array('optionId' => $option->getValue(), 'optionLabel' => $option->getLabel(),'selected'=>true);
                        }else {
                            $count[] = array('optionId' => $option->getValue(), 'optionLabel' => $option->getLabel(),'selected'=>false);
                        }
                    }
                    }else{
                        foreach($result->getItems() as $option) {
                            $count[] = array('optionId' => $option->getValue(),'optionLabel' => $option->getLabel(),'selected'=>false);
                        }
                    }
                    if(count($count)>=1){
                        $json['attributes'][] = array('attributeCode'=>$attribute->getAttributeCode(),'attributeLabel'=>ucfirst($attribute->getFrontend_label()),'attributeValues'=>$count);
                    }
                    unset($count);
                }
            }
            $minprice=0;
            $maxprice=0;
            if(array_key_exists('filters',$data)){
                foreach ($data['filters'] as $key=>$item) {
                    $itemss=array();
                    if($key=='price'){
                        $priceRanges =explode(',',$item);
                        foreach($priceRanges as $priceRange) {
                            $pricelimit = explode('-',$priceRange);
                            $minprice = $pricelimit[0];
                            $maxprice = $pricelimit[1];

                        }

                    }
                    else{
                        $itemss=explode(',',$item);
                        $attribute = Mage::getModel('eav/entity_attribute')->loadByCode('catalog_product', $key);
                        $connection = Mage::getSingleton('core/resource')->getConnection('core_read');
                        $tableAlias = $attribute->getAttributeCode() . '_idx';

                        $conditions = array(
                            "{$tableAlias}.entity_id = e.entity_id",
                            $connection->quoteInto("{$tableAlias}.attribute_id = ?",
                                $attribute->getAttributeId()),
                            $connection->quoteInto("{$tableAlias}.store_id = ?", 1),
                            $connection->quoteInto("{$tableAlias}.value IN (?)", $itemss)
                        );

                        $products->getSelect()->join(
                            array($tableAlias =>  Mage::getResourceModel('catalog/layer_filter_attribute')->getMainTable()),
                            implode(' AND ', $conditions),
                            array()
                        );
                    }

                }
                $products->addFinalPrice();
                if($minprice!=0&&$maxprice!=0) {
                    $products->getSelect()
                        ->where('price_index.final_price <= ' . $maxprice)->where('price_index.final_price >= ' . $minprice);
                    $price['minPrice']=(int)$minprice;
                    $price['maxPrice']=(int)$maxprice;
                    $json['priceRangeApplied']=$price;
                }
            }
            $totalproducts=$products->getSize();
            if($pagesize&&$pageno){
                $products->setPageSize($pagesize)
                    ->setCurPage($pageno);
            }
            $i=0;
            $flag=0;
            $response = array();

            foreach($products as $result3){
                $response[$i] = array('productId'=>$result3->getId(),'productName'=>$result3->getName(),'productPrice'=>$result3->getPrice());//give what ever values you need.
                $i++;
            }

            $bestprodts = $response;
            $noofpages = $totalproducts/$pagesize;



        $result                              =   array();
        $result['status']                    =   1;
        if(!$totalproducts){
            if($min_price==0&&$max_price==0){
                $result['message']='No products available in this category.';
            }else{
                $result['message']='No products found. Please check the filter.';
            }

        }else{
        $result['message']='Success';
        }
        $result['noofpages']=ceil($noofpages);
        $result['totalProducts']=$totalproducts;
        $result['data']['productList']=$bestprodts;
        if($pageno==1){
            $result['data']['filters']=$json;
        }
    }
    catch(Exception $e)
    {
        $result           =   array();
        $result['status'] = 2;
        $result['message'] = "Product Listing failed";
    }

    echo json_encode($result);
    return json_encode($result);
}

Request Format { "categoryId":"", "limit":"", "page":"", "filters":{ "price":"from-to", "attribute_code":"values " } }

4
  • It's never too late to do right ;-) Thanks Athul! I will check this and add comments here.
    – Hashid
    Jun 28, 2017 at 11:16
  • It is working exactly but one small issue when we select filter option getting product data and attribute data getting wrong what we got at first time same filters attributes got every time can you give me how to resolve that for example filter at first time size, brand and material i selected size and brand in website result is like 10 products. comming filters resize need to remove from filter right but it is still showing May 25, 2018 at 7:49
  • What about search page, it isn't based on the category?
    – Duke
    Aug 2, 2018 at 11:17
  • @RintoGeorge Create a different question for that and give link. i post that also. Aug 3, 2018 at 13:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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