Коллекция Magento Catch-22 - PullRequest
       1

Коллекция Magento Catch-22

2 голосов
/ 11 июня 2011

Я не очень понимаю, как работают коллекции Magento, так что, надеюсь, это простой вопрос ...

Как гласит старая поговорка, вы не можете наблюдать эксперимент безкак-то изменив это.Это, кажется, справедливо для коллекций Magento.У меня есть модуль Featured Products , который я написал, который работает довольно хорошо.Недавно мы добавили Отзывы клиентов в наш магазин.При просмотре страницы категории отображается случайный обзор продуктов этой категории.Это также прекрасно работает.Я добавил блок обзора на свою страницу Featured Products , что было легко сделать, но поскольку эти продукты не относятся к определенной категории, он просто выбирает случайный, обычно не связанный, обзор.Чтобы исправить это, я изменил свою функцию getProductCollection в своем модуле Featured и добавил в конец после создания / сохранения коллекции следующее:

$_product = $this->_productCollection->getFirstItem();
$_catIDs = $_product->getCategoryIds();

if(count($_catIDs) > 0)
{
    $_cat = Mage::getModel('catalog/category')->load($_catIDs[0]); 
    Mage::register('current_category', $_cat);
}
* 1017К сожалению, простое действие поиска первого элемента в коллекции ломает пейджер на панели инструментов.Независимо от того, какой из вариантов подкачки я выберу, он всегда показывает все пунктов, когда приведенный выше код на месте.Если я закомментирую этот раздел, он будет работать нормально.

Поэтому у меня такой вопрос: Как я могу получить любую информацию о продуктах в коллекции, не изменяя коллекцию и не нарушая разбиение на страницы?

Добавление моего кода, чтобы помочь объяснить проблему подробнее:

class VPS_Featured_Block_List extends Amasty_Sorting_Block_Catalog_Product_List//Mage_Catalog_Block_Product_List
{
    protected function _getProductCollection()
    {
        if (is_null($this->_productCollection))
        {
            $_attributeNames = 'featured';
            if($this->getAttributeName() != '')
            $_attributeNames = $this->getAttributeName();

            $_attrArray = explode(',', $_attributeNames);

            $this->_productCollection = Mage::getModel('catalog/product')->getCollection();

            $this->_productCollection->addAttributeToSelect('*');

            $_filters = array();

            foreach($_attrArray as $_attr)
            $_filters[] = array('attribute' => $_attr, 'eq' => true);

            $this->_productCollection->addFieldToFilter($_filters);
            //$this->_productCollection->addFieldToFilter(array(array('attribute' => $_attr, 'eq' => true),));

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

            //Get category of first product in collection (used for featured review)
            $_catIDs = array();

            $_product = $this->_productCollection->getFirstItem();
            $_catIDs = $_product->getCategoryIds();

            if(count($_catIDs) > 0)
            {
                $_cat = Mage::getModel('catalog/category')->load($_catIDs[0]);
                Mage::register('current_category', $_cat);
            }
        }
        return $this->_productCollection;
    }
}

Ответы [ 2 ]

4 голосов
/ 16 июня 2011

Спасибо @clockworkgeek за этот ответ, который он опубликовал в моем последующем вопросе :

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

$secondCollection = clone $firstCollection;
$secondCollection->clear();
$_foo123 = $secondCollection->getFirstItem();

Метод clear() выгружает данные для этой коллекции, заставляя их снова обратиться к базе данных в следующий раз

1 голос
/ 11 июня 2011

Трудно сказать, что происходит без какого-либо контекста (версия magento, в каком классе вы находитесь и т. Д.), НО, я думаю (60% уверенности), что это происходит, когда вы получаете ссылку на коллекцию продуктов до его фильтры были добавлены. Ленивая загрузка коллекций Magento, что означает, что запросы к базе данных не выполняются, пока вы явно не вызовете load или , пытаясь получить доступ к элементу. Я предполагаю (опять же, предположение), что при доступе к элементу выше, коллекция загружается (без фильтра). Затем другие части системы добавляют фильтр , но они игнорируются, поскольку коллекция уже загружена .

Ответ на ваш большой вопрос невозможен без дополнительного контекста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...