【问题标题】:How to get all product from a category including its subcategories in Magento?如何从一个类别中获取所有产品,包括 Magento 中的子类别?
【发布时间】:2011-06-23 11:46:34
【问题描述】:

我正在寻找一种方法来从一个类别(包括其子类别)中检索所有产品并返回一个产品集合。

我知道我可以遍历类别以获取产品 id 并将它们加载到视图中,但我希望获得一个产品集合,因为它目前在大多数类别/视图中都已完成。

有什么想法吗?

【问题讨论】:

    标签: magento


    【解决方案1】:

    我已经通过在产品集合模型中实现 addCategoriesFilter 解决了这个问题,这里是补丁。将修改后的代码复制到local 池以允许更新到较新的版本。

    @@ -103,6 +103,7 @@
          * Allowed filters
          *  store_id                int;
          *  category_id             int;
    +     *  category_ids            array;
          *  category_is_anchor      int;
          *  visibility              array|int;
          *  website_ids             array|int;
    @@ -567,6 +568,21 @@
         }
    
         /**
    +     * Specify categories filter for product collection
    +     *
    +     * @param array $categories
    +     * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
    +     */
    +    public function addCategoriesFilter(array $categories)
    +    {
    +        $this->_productLimitationFilters['category_ids'] = $categories;
    +
    +        ($this->getStoreId() == 0)? $this->_applyZeroStoreProductLimitations() : $this->_applyProductLimitations();
    +
    +        return $this;
    +    }
    +
    +    /**
          * Join minimal price attribute to result
          *
          * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
    @@ -1592,7 +1608,7 @@
             $this->_productLimitationJoinPrice();
             $filters = $this->_productLimitationFilters;
    
    -        if (!isset($filters['category_id']) && !isset($filters['visibility'])) {
    +        if (!isset($filters['category_id']) && !isset($filters['category_ids']) && !isset($filters['visibility'])) {
                 return $this;
             }
    
    @@ -1604,11 +1620,16 @@
                 $conditions[] = $this->getConnection()
                     ->quoteInto('cat_index.visibility IN(?)', $filters['visibility']);
             }
    -        $conditions[] = $this->getConnection()
    -            ->quoteInto('cat_index.category_id=?', $filters['category_id']);
    -        if (isset($filters['category_is_anchor'])) {
    +
    +        if (!isset($filters['category_ids'])) {
                 $conditions[] = $this->getConnection()
    -                ->quoteInto('cat_index.is_parent=?', $filters['category_is_anchor']);
    +                ->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);
    

    用法:

    $category = $layer->getCurrentCategory();
    $categories = $category->getAllChildren(true);
    
    $collection = Mage::getResourceModel('catalog/product_collection');
    $collection->addCategoriesFilter($categories);
    

    【讨论】:

    • 我实际上做了类似的事情并覆盖了我模块中的资源来添加这样的方法,谢谢。
    • is_anchor 属性还不够吗?
    【解决方案2】:

    您必须在后端将该类别设置为 Anchor = Yes。这样一来,您的收藏将包含他子类别中的所有产品。

    【讨论】:

      【解决方案3】:

      如果您想显示分配到商店根类别下的某个类别的所有产品,您可以执行以下操作(或将根类别替换为您想要的类别):

      $root_category = Mage::getModel('catalog/category')->load(Mage::app()->getStore()->getRootCategoryId());
      $all_cat_ids = explode(",", $root_category->getAllChildren());
      $collection->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left');
      $collection->addAttributeToFilter('category_id', array('in' => $all_cat_ids));
      

      希望这会有所帮助。

      【讨论】:

      • 这几乎可以工作,如果产品同时存在于当前类别和子类别中,它会中断,因为它会尝试将项目添加到集合中两次。
      【解决方案4】:

      与 Matt 的回答类似,但没有“XXX 已存在”错误。

      ini_set('display_errors', 1);
      ini_set('display_startup_errors', 1);
      error_reporting(E_ALL);
      require_once 'app/Mage.php';
      umask(0);
      $app = Mage::app('admin');
      
      $rootCategory = Mage::getModel('catalog/category')->load(17);
      $collection = Mage::getResourceModel('catalog/product_collection');
      $allCatIds = explode(",", $rootCategory->getAllChildren());
      $collection
          ->getSelect()
          ->group('entity_id');
      $collection
          ->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left')
          ->addAttributeToFilter('category_id', array('in' => $allCatIds));
      
      echo $collection->count();
      

      【讨论】:

      • 我们需要在哪里添加这个!
      • @RajMohan 这是一个独立的脚本,所以在网络根目录中
      • 我可以知道文件路径和文件名。
      【解决方案5】:

      抱歉,答案不完整,但一种可行的方法是查看父级 (1/2/3) 的类别路径并使用查询(在类别集合上?)获取该类别的所有后代(路径比如1/2/3%)。然后,您可以使用它来过滤产品集合。也许其他人可以充实这些细节并更好地回答:)

      【讨论】:

      • 嗨,谢谢,这实际上是我可以从网络上获得的第一个“智能”答案。我对使用 Magento 和集合有点陌生,所以我可以请你告诉我更多关于如何自定义集合查询以添加这样的位置吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-27
      • 1970-01-01
      相关资源
      最近更新 更多