Magento, использующий addVisibleInCatalogFilterToCollection, ничего не возвращает, когда не должен - PullRequest
4 голосов
/ 29 февраля 2012

В Magento я использую следующий код для сбора данных о бестселлерах:

Модель Функция:

  public function bestSellers($limit = 12){

    $storeId    = Mage::app()->getStore()->getId();
    $_productCollection = Mage::getResourceModel('reports/product_collection')
        ->addOrderedQty()
        ->addAttributeToSelect('id')
        ->setStoreId($storeId)
        ->addStoreFilter($storeId)
        ->setOrder('ordered_qty', 'desc') //best sellers on top
        ->setPageSize($limit); 

    Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($_productCollection);
    Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($_productCollection);

    return $_productCollection; 

}

Блок вывода:

<code><?php $products = Mage::getModel('tabs/collections')->bestSellers($limit); ?>
<pre>
    <?php print_r($productCollection->getData()); ?>

Однако он ничего не возвращает, когда в функции модели используется строка addVisibleInCatalogFilterToCollection, но если я удаляю строку addVisibleInCatalogFilterToCollection, то она возвращает массив ожидаемых данных бестселлера о продукте (включая те, которые не должны быть видны в каталоге) .

Как я могу вернуть свой массив данных с фильтром видимости, работающим как надо? Вместо того, чтобы ничего не возвращать. Очень смущенный. Заранее спасибо!

Вот getSelect:

   SELECT SUM(order_items.qty_ordered) AS `ordered_qty`, `order_items`.`name` AS `order_items_name`, `order_items`.`product_id` AS `entity_id`, `e`.`entity_type_id`, `e`.`attribute_set_id`, `e`.`type_id`, `e`.`sku`, `e`.`has_options`, `e`.`required_options`, `e`.`created_at`, `e`.`updated_at`, `cat_index`.`position` AS `cat_index_position` FROM `sales_flat_order_item` AS `order_items`
  INNER JOIN `sales_flat_order` AS `order` ON `order`.entity_id = order_items.order_id AND `order`.state <> 'canceled'
  LEFT JOIN `catalog_product_entity` AS `e` ON (e.type_id NOT IN ('grouped', 'configurable', 'bundle')) AND e.entity_id = order_items.product_id AND e.entity_type_id = 4
  INNER JOIN `catalog_category_product_index` AS `cat_index` ON cat_index.product_id=e.entity_id AND cat_index.store_id='1' AND cat_index.visibility IN(2, 4) AND cat_index.category_id='2' WHERE (parent_item_id IS NULL) GROUP BY `order_items`.`product_id` HAVING (SUM(order_items.qty_ordered) > 0) ORDER BY `ordered_qty` desc

Ответы [ 3 ]

2 голосов
/ 29 февраля 2012

Я думаю, это происходит потому, что addVisibleInCatalogFilterToCollection() делает больше, чем вы можете себе представить.Давайте посмотрим на его код (app\code\core\Mage\Catalog\Model\Product\Visibility.php, line 66):

public function addVisibleInCatalogFilterToCollection(Mage_Eav_Model_Entity_Collection_Abstract $collection)
{
    $collection->setVisibility($this->getVisibleInCatalogIds());

// $ collection-> addAttributeToFilter ('visibility', array ('in' => $ this-> getVisibleInCatalogIds ()));вернуть $ this;}

Теперь давайте внимательно посмотрим на $collection->setVisibility($this->getVisibleInCatalogIds()).Давайте перейдем к \app\code\core\Mage\Catalog\Model\Resource\Product\Collection.php:

public function setVisibility($visibility)
{
    $this->_productLimitationFilters['visibility'] = $visibility;
    $this->_applyProductLimitations();

    return $this;
}

/**
 * Apply limitation filters to collection
 * Method allows using one time category product index table (or product website table)
 * for different combinations of store_id/category_id/visibility filter states
 * Method supports multiple changes in one collection object for this parameters
 *
 * @return Mage_Catalog_Model_Resource_Product_Collection
 */
protected function _applyProductLimitations()
{
    $this->_prepareProductLimitationFilters();
    $this->_productLimitationJoinWebsite();
    $this->_productLimitationJoinPrice();
    $filters = $this->_productLimitationFilters;

    if (!isset($filters['category_id']) && !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']);
    }
    $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']);
    }

    $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;
}

Итак, как вы можете видеть, продукт должен быть присвоен текущему веб-сайту и должен быть добавлен в некоторую категорию с текущего веб-сайта, чтобы появиться в коллекции продуктов.Также, как вы можете видеть, здесь есть и другие требования.

0 голосов
/ 29 декабря 2013

Только для дальнейшего использования.

У меня была очень похожая проблема.

Один из виджетов не отображал случайные продукты.

Из-за

Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($collection);

Товар должен быть установлен видимым для каталога (продукт -> видимость -> каталог, поиск).

0 голосов
/ 13 марта 2012

Вот мой Блок, который я использую для получения бестселлеров.Это также делает простые продукты, которые являются вариантами родительских конфигурируемых продуктов, для конфигурируемых продуктов (работает правильно, только если один простой продукт назначен макс. 1 конфигурируемому продукту): http://devblog.fishol.pl/bestselling-products-in-magento/

...