Magento фильтрует коллекцию товаров по нескольким категориям - PullRequest
6 голосов
/ 27 февраля 2012

Существует ли простой способ фильтрации коллекции товаров по нескольким категориям? Чтобы получить все предметы в любой из перечисленных категорий? addCategoryFilter не разрешает массив.

Является ли единственный способ получить коллекции для каждой интересующей категории отдельно, а затем объединить их?

Я понимаю, что раньше это было возможно с чем-то вроде

addAttributeToFilter('category_ids',array('finset'=>array('1','2')))

или аналогичный, но это невозможно с версии 1.4.

Примечание: я использую 1.6, и в случае его использования я использую что-то вроде этого:

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

Ответы [ 6 ]

9 голосов
/ 08 ноября 2012

Вот метод, который не требует модификации ядра.Он взят из этого поста с добавлением предложения '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');
4 голосов
/ 28 февраля 2012

Теперь Magento работает, чтобы получить Магазин, и в магазине вы можете получить категории из коллекции магазина, такие как $ 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;
    }

Затем вызывается так:

$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.

НТН

3 голосов
/ 16 октября 2013

Если вы хотите выполнить фильтрацию по нескольким категориям, используя AND (поэтому для показа товар должен быть в категориях A, B и C, вам необходимо иметь несколько объединений:

$products = Mage::getModel('catalog/product')->getCollection()
    ->joinField('category_id_1', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left')
    ->joinField('category_id_2', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left')
    ->addAttributeToFilter('category_id_1', array('eq' => 358))
    ->addAttributeToFilter('category_id_2', array('eq' => 252))
// etc...
;
2 голосов
/ 15 февраля 2017

Мне удалось решить эту проблему (после долгих проб и ошибок) с помощью следующего кода:

$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('status', 1);
$collection->addAttributeToSelect(array('name','sku','price','small_image'));

// Filter by multiple categories
$collection->joinField('category_id','catalog/category_product','category_id','product_id=entity_id',null,'left');
$data_cats = $this->getRequest()->getParam('categories');
// Or $data_cats = array(85,86,87,88);

      $filter_cats = array();
      foreach ($data_cats as $value_cats) {
         $filter_cats[] = array(
         'attribute' => 'category_id',
         'finset'    => $value_cats
      );
}

$collection->addAttributeToFilter($filter_cats);

Надеюсь, это кому-нибудь поможет;)

0 голосов
/ 30 августа 2016

Фильтр коллекции продуктов с использованием нескольких идентификаторов категорий

$all_categories = array('3','13','113');   
$productCollection = Mage::getModel('catalog/product')->getCollection();
$productCollection->joinField('category_id', 'catalog/category_product', 'category_id', 
                    'product_id = entity_id', null, 'left')
                  ->addAttributeToSelect('*')
                  ->addAttributeToFilter('type_id', array('eq' => 'simple'))
                  ->addAttributeToFilter('category_id', array($all_categories));
foreach($productCollection as $product)
{
    echo $product->getId() .$product->getName() . "<br/>";
}

Вы можете удалить условие для типа продукта, т.е. type_id или изменить его согласно требованию.

0 голосов
/ 19 марта 2014
  • Magento 1.8.0.0;
  • Плоский каталог включен в админке;
  • Убедитесь, что вы кэшировали блок, в который вы поместите это;
  • Не добавляйте это в платные темы ..
  • Внутреннее соединение, жестко запрограммированное здесь, воспроизводит это:

    $ галерею-> setVisibility (Mage :: getSingleton ( 'Каталог / product_visibility') -> getVisibleInCatalogIds ());

    без 'cat_index.category_id = 2'

$category = Mage::getModel('catalog/category')->load(100);
$allChildsIds = $category->getAllChildren($category);

$visibility = Mage::getModel('catalog/product_visibility');

$collection = Mage::getResourceModel('catalog/product_collection');
$collection = $this->_addProductAttributesAndPrices($collection)
  ->addStoreFilter()
  ->setFlag('do_not_use_category_id', true)
  ->setFlag('disable_root_category_filter', true)
  ->addAttributeToSort('created_at', 'desc');

$whereCategoryCondition = $collection->getConnection()
  ->quoteInto('cat_index.category_id IN(?) ', $allChildsIds);
$collection->getSelect()->where($whereCategoryCondition);

$conditions = array();
$conditions[] = "cat_index.product_id = e.entity_id";
$conditions[] = $collection->getConnection()
  ->quoteInto('cat_index.store_id = ? ', Mage::app()->getStore()->getStoreId());
$conditions[] = $collection->getConnection()
  ->quoteInto('cat_index.visibility IN(?) ', $visibility->getVisibleInCatalogIds());

$collection->getSelect()->join(
  array('cat_index' => $collection->getTable('catalog/category_product_index')),
  join(' AND ', $conditions),
  array()
);

$collection
  ->setPageSize(3)
  ->setCurPage(1);

$collection->load();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...