2016-02-21 26 views
0

可以說,這些是屬性的顏色和大小。顏色有以下選項紅色,綠色和藍色,大小有以下選項小,中,大。現在,假設產品集合中有兩種產品,一種產品是紅色的,尺寸小,另一種是綠色的,尺寸中等。所以,我要像下面如何在Magento中獲取所有屬性(在前端可見)及其相應的產品集合選項?

  • 顏色輸出:紅,綠
  • 尺寸:小型,中型

我不希望獲取第一屬性列表集合,然後遍歷和與它的每個產品的屬性相匹配,因爲這會非常緩慢且耗費內存。

+0

假設你已經有產品集合已經,可以遍歷每個產品的配置屬性,並將它們添加到陣列來輸出作爲例如 –

+0

@Robbie Averill的 - 如果有什麼產品集合了數千種產品。然後它會花費很多時間。不能使用單個SQL查詢來完成。在分層導航中,只有那些屬於正在使用的產品集合的屬性和選項才能實現。 –

+0

嗨Vineet,是的這是一個很好的問題,但你必須總是考慮加載時間處理這麼多的實體。你需要做什麼?它會多久運行一次?你可以用SQL來做到這一點,但它會涉及許多表連接 –

回答

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){ 

    } 
相關問題