2011-05-16 102 views
1

我一直在嘗試數月,以便通過它的存儲根類別來篩選產品集合。我嘗試了許多不同的方式(Magento - addStoreFilter not working?,Magento ->addCategoryFilter - filtering product collection by root category,Magento - Loading root collection loads all products),但仍未找到任何可行的方法。Magento - joinField()查詢將store_id添加到集合中的產品

所以我想嘗試將store_id添加到集合中的產品中。我可以使用下面的調用集合,但我需要加入一些字段,以添加STORE_ID:

$_testproductCollection = Mage::getResourceModel('catalog/product_collection'); 
$_testproductCollection->getSelect()->distinct(true); 
$_testproductCollection->addAttributeToSelect('*')->load(); 

的joinField我需要的是類似以下(這是在上面鏈接後給出),但store_id = 1零件將每個產品store_id更改爲1,我不想要,我只是想要一種方式來添加它的指定商店,以便我可以通過它進行過濾。

$_testproductCollection->joinField('store_id', 'catalog_category_product_index', 'store_id', 'product_id=entity_id', '{{table}}.store_id = 1', 'left'); 

任何人都可以指向正確的方向嗎?乾杯!

回答

0

好的,我認爲這個工程,沒有太多測試,但似乎已經做到了。你需要先得到你的商店根類別ID,然後加入一些字段,以便您可以訪問產品「CATEGORY_ID」,然後篩選使用:

$_rootcatID = Mage::app()->getStore()->getRootCategoryId(); 

$_testproductCollection = Mage::getResourceModel('catalog/product_collection') 
->joinField('category_id','catalog/category_product','category_id','product_id=entity_id',null,'left') 
->addAttributeToFilter('category_id', array('in' => $_rootcatID)) 
->addAttributeToSelect('*'); 
$_testproductCollection->load(); 

foreach($_testproductCollection as $_testproduct){ 
    echo $this->htmlEscape($_testproduct->getName())."<br/>"; 
}; 
0

搜索的核心代碼:

grep '>addStoreFilter' app/code -rsn 

,觀察現有代碼的用途:

Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect('*')->addStoreFilter(Mage::app()->getStore()->getId()); 
+0

過濾通過商店無法正常工作(見我的帖子鏈接在原來的問題)。 – 2011-05-16 14:02:02

+0

那麼你只需要在你的問題中定義「正確」,或者你需要在代碼級別或SQL級別中過濾這些內容 – 2011-05-16 14:49:23

+0

我發佈的鏈接全部說明,沒有意義重複一切。基本上我在phtml模板中調用集合,並且我想爲上面的集合調用添加一個商店過濾器,但首先我需要加入這些字段,以便可以訪問每個產品的store_id。 – 2011-05-16 15:22:16

2

我能想到的與子查詢的方式。以下摘錄摘自我正在研究的圖書館。它們被放置在lib/目錄中,因此自動裝載機可以訪問它們。我還沒有分析性能,但我的直覺告訴我,MySQL會分開緩存子查詢,所以當重用時它們的結果很好而且很快。如果性能不太好,我可能不得不將這些視爲數據庫視圖。

這種技術的關鍵是理解Zend的選擇可以直接用作SELECT,FROM或WHERE子句並自動成爲子查詢。

// A shortened example, not tested directly 
class Example_Product_List extends Varien_Db_Select { 

    protected $_resource; 

    public function __construct($storeId) { 
     // Since this isn't a collection we need to get the resource ourselves 
     $this->_resource = Mage::getSingleton('core/resource'); 
     $adapter = $this->_resource->getConnection('core_read'); 
     parent::__construct($adapter); 

     $this->from(
      array('catprod'=>$this->getTable('catalog/category_product')), 
      'product_id' 
     ); 
     $this->joinInner(
      array('catprodin'=>$this->getTable('catalog/category_product_index'), 
      '(catprodin.category_id=catprod.category_id) AND (catprodin.product_id=catprod.product_id)', 
      'store_id' 
     ); 
     $this->where('store_id = ?', $storeId); 
     $this->group('product_id'); 
    } 

    public function getTable($modelEntity) 
    { 
     return $this->_resource->getTableName($modelEntity); 
    } 

} 

// Using it in a collection 
class Example_Module_Model_Resource_Product_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4 { 

    protected function setStoreId($store) { 
     $this->getSelect()->where(array(
      'attribute'=>'product_id', 
      'in'=>new Example_Product_list($store->getId()) 
     ); 
     return parent::setStoreId($store); 
    } 
} 

// Putting it to use, '1' can be any store ID. 
$_testproductCollection = Mage::getResourceModel('examplemodule/product_collection'); 
$_testproductCollection->addStoreFilter(1); 
$_testproductCollection->addAttributeToSelect('*')->load(); 

靠近我用的是繼承addStoreFilter()因爲我想不僅包含了正確的產品,但也使用店內的相應值結束。如果您的商店翻譯了產品名稱,則會採用正確的名稱。

基本上整個事情是構建商店的所有產品列表(相當大,這就是爲什麼我希望它緩存),然後有效地執行「WHERE product_id IN(list_of_product_ids)」。

+0

自寫這個答案我已經使用了這個技術來製作[查詢模式](https://github.com/Knectar/Magento-Query-Patterns),一個子查詢庫 - 包括[映射商店到產品](https:// github。COM/Knectar/Magento的查詢,模式/ BLOB /主/ Knectar /選擇/存儲/分類/ Product.php)。 – clockworkgeek 2011-12-12 21:47:49