2011-05-16 122 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

相关问题