Magento按多个类别过滤产品

Ale*_*ley 6 collections magento

是否有一种简单的方法来按多个类别过滤产品集合?获取任何列出的类别中的所有项目?addCategoryFilter似乎不允许数组.

是分别获取每个感兴趣类别的集合然后合并它们的唯一方法吗?

据我所知,曾经有过这样的事情

addAttributeToFilter('category_ids',array('finset'=>array('1','2')))
Run Code Online (Sandbox Code Playgroud)

或类似的,但自1.4以来不再可能.

注意:我使用1.6,如果有任何用处,我使用的是这样的:

$product = Mage::getModel('catalog/product');
$_productCollection = $product->getCollection()
  ->addAttributeToSelect('*')
  ->addAttributeToFilter('status',1)
  ->addStoreFilter();
Run Code Online (Sandbox Code Playgroud)

Lai*_*zer 9

这是一种不需要修改核心的方法.它是从这篇文章中添加了"group"子句来处理重复的产品记录.

$categories = array(7,45,233);

        $collection = Mage::getModel('catalog/product')->getCollection()
            ->addAttributeToSelect('*')
            ->joinField('category_id',
                'catalog/category_product',
                'category_id',
                'product_id=entity_id',
                null,
                'left')
            ->addAttributeToFilter('category_id', array('in' => $categories));
        $collection->getSelect()->group('e.entity_id');
Run Code Online (Sandbox Code Playgroud)

  • 我一直在逐步完成代码,当Magento的平面目录关闭时,这个解决方案就可以运行了.启用平面目录时,会发生以下情况.addAttributeToFilter方法识别category_id字段不在SELECT列表中,并调用addAttributeToSelect来添加它.然后addAttributeToSelect方法失败,因为category_id不是产品属性,并且没有向集合添加过滤器. (6认同)

Sha*_*lly 4

Magento 现在的工作方式是获取 Store,在 store 上,您可以从 storecollection 中获取类别,例如 $oStoreCollection->addCategoryFilter(array('1','2'));

我发现了一个可能对您有帮助的解决方案,可以在以下位置找到:

http://www.magentocommerce.com/boards/&/viewthread/201114/#t329230

他们使用的代码如下所示:覆盖Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Collection,并添加以下方法:

public function addCategoriesFilter($categories)
    {
        $this->_productLimitationFilters['category_ids'] = $categories;

        if ($this->getStoreId() == Mage_Core_Model_App::ADMIN_STORE_ID) {
            $this->_applyZeroStoreProductLimitations();
        } else {
            $this->_applyProductLimitations();
        }

        return $this;
    }

    protected function _applyProductLimitations()
    {
        $this->_prepareProductLimitationFilters();
        $this->_productLimitationJoinWebsite();
        $this->_productLimitationJoinPrice();
        $filters = $this->_productLimitationFilters;

        // Addition: support for filtering multiple categories.
        if (!isset($filters['category_id']) && !isset($filters['category_ids']) && !isset($filters['visibility'])) {
            return $this;
        }

        $conditions = array(
            'cat_index.product_id=e.entity_id',
            $this->getConnection()->quoteInto('cat_index.store_id=?', $filters['store_id'])
        );
        if (isset($filters['visibility']) && !isset($filters['store_table'])) {
            $conditions[] = $this->getConnection()
                ->quoteInto('cat_index.visibility IN(?)', $filters['visibility']);
        }

        // Addition: support for filtering multiple categories.
        if (!isset($filters['category_ids'])) {
             $conditions[] = $this->getConnection()
                ->quoteInto('cat_index.category_id=?', $filters['category_id']);
            if (isset($filters['category_is_anchor'])) {
                $conditions[] = $this->getConnection()
                    ->quoteInto('cat_index.is_parent=?', $filters['category_is_anchor']);
            }
        } else {
            $conditions[] = $this->getConnection()->quoteInto('cat_index.category_id IN(' . implode(',', $filters['category_ids']) . ')', "");
        }

        $joinCond = join(' AND ', $conditions);
        $fromPart = $this->getSelect()->getPart(Zend_Db_Select::FROM);
        if (isset($fromPart['cat_index'])) {
            $fromPart['cat_index']['joinCondition'] = $joinCond;
            $this->getSelect()->setPart(Zend_Db_Select::FROM, $fromPart);
        }
        else {
            $this->getSelect()->join(
                array('cat_index' => $this->getTable('catalog/category_product_index')),
                $joinCond,
                array('cat_index_position' => 'position')
            );
        }

        $this->_productLimitationJoinStore();

        Mage::dispatchEvent('catalog_product_collection_apply_limitations_after', array(
            'collection'    => $this
        ));

        return $this;
    }

    protected function _applyZeroStoreProductLimitations()
    {
        $filters = $this->_productLimitationFilters;

        // Addition: supprot for filtering multiple categories.
        $categoryCondition = null;
        if (!isset($filters['category_ids'])) {
            $categoryCondition = $this->getConnection()->quoteInto('cat_pro.category_id=?', $filters['category_id']);
        } else {
            $categoryCondition = $this->getConnection()->quoteInto('cat_pro.category_id IN(' . implode(',', $filters['category_ids']) . ')', "");
        }

        $conditions = array(
            'cat_pro.product_id=e.entity_id',
            $categoryCondition
        );
        $joinCond = join(' AND ', $conditions);

        $fromPart = $this->getSelect()->getPart(Zend_Db_Select::FROM);
        if (isset($fromPart['cat_pro'])) {
            $fromPart['cat_pro']['joinCondition'] = $joinCond;
            $this->getSelect()->setPart(Zend_Db_Select::FROM, $fromPart);
        }
        else {
            $this->getSelect()->join(
                array('cat_pro' => $this->getTable('catalog/category_product')),
                $joinCond,
                array('cat_index_position' => 'position')
            );
        }

        return $this;
    }
Run Code Online (Sandbox Code Playgroud)

然后它会被这样调用:

$collection = Mage::getModel('catalog/product')->getCollection()
                        ->addAttributeToSelect('*')
                        ->distinct(true) // THIS IS WHAT YOU NEED TO ADD
                        ->addCategoriesFilter($category->getAllChildren(true)); // Make sure you don't forget to retrieve your category here.
Run Code Online (Sandbox Code Playgroud)

华泰