0

I have the following code where i want product collection filtered with custom attribute.

typeid = $data['categoryId'];
    $pagesize = $data['limit'];
    $pageno = $data['page'];
    Mage::app()->setCurrentStore(1);
    Mage::app('default');
    Mage::getSingleton("core/session", array("name" => "frontend"));


        $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()

When i apply addAttributeToFilter();

$products->addAttributeToFilter(
                'flavour_weight',array('eq' => '23')
            );

It returns 0 products. I am very new to magento. I have searched the internet and found a solution.

$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()
)->distinct(true);

Applying filter by using above solution works. My question is why first approach not worked? Why second worked? Any help will be appreciated.

My Complete code for applying filter to category products:

    public function _create($data)
      {
        $typeid = $data['categoryId'];
        $pagesize = $data['limit'];
        $pageno = $data['page'];
        Mage::app()->setCurrentStore(1);
        $show_out_of_stock=Mage::getStoreConfig('cataloginventory/options/show_out_of_stock');
    $is_in_stock_option = $show_out_of_stock ? 0 : 1;

    try {
        $layer = Mage::getModel("catalog/layer");
        $category = Mage::getModel('catalog/category')->load($typeid);
        $layer->setCurrentCategory($category);
        $products = $layer->getProductCollection()->joinField(
            'is_in_stock',
            'cataloginventory/stock_item',
            'is_in_stock',
            'product_id=entity_id',
            '{{table}}.stock_id=1',
            'left')
            ->addStoreFilter(1)
            ->addAttributeToFilter('type_id', array('in' => array(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE, Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE, Mage_Catalog_Model_Product_Type::TYPE_GROUPED)))
            ->addAttributeToSelect('*')
            ->addAttributeToFilter('visibility', 4)
            ->addAttributeToFilter('is_in_stock', array('in' => array($is_in_stock_option, 1)))
            ->addAttributeToFilter('status', 1);

        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();
            $i = 0;
            foreach ($attributes as $attribute) {
                if ($attribute->getAttributeCode() == 'price') {
                    $filterBlockName = 'catalog/layer_filter_attribute';
                } else if ($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(',', ((array)$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()
                    )->distinct(true);

                }
            }


            $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) {
        print_r($e);
        $result = array();
        $result['status'] = 2;
        $result['message'] = "Product Listing failed";
    }
    return $result;
}
  • Used in product listing => Yes then Reindex all and try again – PЯINCƏ Feb 12 at 9:17
0

Most likely you have enabled "Use Flat Catalog Product" and your attribute flavour_weight has set "Used in product listing" to "No".

In this case the attribute is not in the flat category product table and therefore not in the product collection you are trying to filter. Setting "Used in product listing" to "Yes" should make your first approach working.

In the second case you explicitely are joining the eav attribute table and get the value from there bypassing the flat table (where your attribute isn't stored at the moment because of the above mentioned setting).

Hope that helps you understanding the difference.

  • Hi @HelgeB thanks for your answer. I just checked that i have already set "Used in product listing" to "Yes". and still it is not working. – Bharat Singh Feb 11 at 12:32
  • Assuming you are in store 1, please do the following SQL queries: select * from catalog_product_flat_1 where flavour_weight = 23;. If that doesn't return anything, please check what the values of flavour_weight are in the table, e.g. select distinct(flavour_weight) from catalog_product_flat_1; – HelgeB Feb 11 at 12:42
  • I ran your queries @HelgeB it was giving me error that column does not exist. Than i checked that i have not enabled "Use Flat Catalog Product" option in magento panel. – Bharat Singh Feb 12 at 5:51
  • OK, then your first statement should run correctly if you have products in the loaded category. Please update your question with the complete code. Anyway you have also an error with a missing $, but I guess that's just a copy error: typeid = $data['categoryId']; instead of $typeid = $data['categoryId']; With that line you can't get products :-) Please also dump the select to log and add the output to your question: Mage::log($products->getSelect()->__toString()); – HelgeB Feb 12 at 8:53
  • I have edited my question and posted complete code. Thanks for your help. – Bharat Singh Feb 12 at 9:02

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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