Question

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;
}

No correct solution

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top