如何在Magento中获取所有属性(在前端可见)及其相应的产品集合选项?

时间:2016-02-21 11:02:42

标签: magento

让我们说,这些是颜色和大小的属性。颜色有以下选项红色,绿色和蓝色,尺寸有以下选项小,中,大。现在,假设产品系列中有两种产品,一种产品是红色,尺寸小,另一种是绿色,大小适中。所以,我想要输出如下

  • 颜色:红色,绿色
  • 尺寸:小,中等

我不想先获取属性列表集合,然后迭代并匹配集合中每个产品的属性,因为这将非常慢并且消耗内存。

1 个答案:

答案 0 :(得分:0)

我调试了分层导航在Magento中的工作方式,并基于我提出的下述解决方案。

try{
        //Get product collection and apply filter to it if any. Here I am applying dummy color filter
        $prodCollection = Mage::getModel('catalog/product')->getCollection()
                        ->addAttributeToFilter('color',array('in' => array(3,4))); //change this filter ad per your need

        $prodCollection
            ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
            ->addMinimalPrice()
            ->addFinalPrice()
            ->addTaxPercents()
            ->addUrlRewrite(Mage::getModel('catalog/layer')->getCurrentCategory()->getId());

        Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($prodCollection);
        Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($prodCollection); 

        $setId = 4; //default attribute set id. change this as pre your need. You can also make this an array

        //Get catalog attribute collection of some attribute sets.
        $attrCollection = Mage::getResourceModel('catalog/product_attribute_collection');
        $attrCollection
            ->setItemObjectClass('catalog/resource_eav_attribute')
            ->setAttributeSetFilter($setId)
            ->addStoreLabel(Mage::app()->getStore()->getId())
            ->setOrder('position', 'ASC');

        $attrCollection->addIsFilterableFilter(); //Check if attributes are filterable or not

        $attrCollection->load();

        $connection = Mage::getSingleton('core/resource')->getConnection('core_read');
        $filterResourceModel = Mage::getResourceModel('catalog/layer_filter_attribute');

        //Apply filter to product collection, if any
        if(1){ //Check if any filters are applied on product collection from query string (?color=4&size=8)
            foreach($attrCollection as $attribute){

                //For now just for testing purpose, I have hardcoded it to work only for single attribute i.e. color
                if($attribute->getAttributeCode() != 'color'){
                    continue;
                }

                //I am assuming color filter is applied twice 
                $filterName = 'color';
                $filterId = 92;
                $filterVal = array(3,4);      

                $tableAlias = $attribute->getAttributeCode() . '_fa';

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

                $prodCollection->getSelect()->join(
                    array($tableAlias => $filterResourceModel->getMainTable()),
                    implode(' AND ', $conditions),
                    array()
                );

            }
        }


        //Iterate each attribute one by one. For now just for testing purpose, I have hardcoded it to work only for single attribute i.e. color
        foreach($attrCollection as $attribute){
            if($attribute->getAttributeCode() != 'color'){
                continue;
            }

            //find attributes options
            $options = $attribute->getFrontend()->getSelectOptions();

            // clone select from collection with filters
            $select = clone $prodCollection->getSelect();
            // reset columns, order and limitation conditions
            $select->reset(Zend_Db_Select::COLUMNS);
            $select->reset(Zend_Db_Select::ORDER);
            $select->reset(Zend_Db_Select::LIMIT_COUNT);
            $select->reset(Zend_Db_Select::LIMIT_OFFSET);

            $tableAlias = sprintf('%s_idx', $attribute->getAttributeCode());
            $conditions = array(
                "{$tableAlias}.entity_id = e.entity_id",
                $connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()),
                $connection->quoteInto("{$tableAlias}.store_id = ?", Mage::app()->getStore()->getId()),  //$filter->getStoreId()
            );

            $select
                ->join(
                    array($tableAlias => $filterResourceModel->getMainTable()),
                    join(' AND ', $conditions),
                    array('value', 'count' => new Zend_Db_Expr("COUNT({$tableAlias}.entity_id)")))
                ->group("{$tableAlias}.value");


            $optionsCount = $connection->fetchPairs($select);


            $data = array();
            foreach ($options as $option) {
                if (is_array($option['value'])) {
                    continue;
                }
                if (Mage::helper('core/string')->strlen($option['value'])) {
                    $data[] = array(
                            'label' => $option['label'],
                            'value' => $option['value'],
                            'count' => isset($optionsCount[$option['value']]) ? $optionsCount[$option['value']] : 0,
                        );
                }

            }  
            echo '<pre>'; print_r($data); die('<><>');
          }        
    }catch(Exception $e){

    }