magento ограничение количества возвращаемых элементов в вызове коллекции продуктов - PullRequest
11 голосов
/ 18 мая 2010

Я пытаюсь ограничить количество возвращаемых результатов вручную в копии шаблона list.phtml, но это оказалось намного сложнее, чем я ожидал.

Я пытался вручную установить размер коллекции, но у вас снова ничего не получалось.Может кто-нибудь показать мне, как это сделать?Было бы очень признательно!

Ответы [ 6 ]

21 голосов
/ 17 марта 2011

Быстрый способ с этим методом Я недавно обнаружил . Вы даже можете использовать его прямо в шаблоне.

$_productCollection = clone $this->getLoadedProductCollection();
$_productCollection->clear()
                   ->setPageSize(3)
                   ->load();
7 голосов
/ 19 апреля 2011

Подобный подход к @joseph заключается в переопределении Mage_Catalog_Block_Product_List, но вставьте следующий код в ваш новый класс:

const PAGE_SIZE = 3;

protected function _getProductCollection(){
    $collection = parent::_getProductCollection();
    $yourCustomBoolean = someFunctionThatDetectsYourCustomPage();
    if($yourCustomBoolean) {
        $collection->setPageSize(self::PAGE_SIZE);
    }
    return $collection;
}

таким образом, вы будете наследовать любые будущие изменения в коде Mage_Catalog от родительского блока, но все равно будете устанавливать ограничения для вашей страницы.

В идеале вы должны использовать узел system.xml для создания поля, которое может быть отредактировано администратором без жесткого определения размера страницы. XML будет выглядеть примерно так:

<config>
<sections>
    <catalog>
        <groups>
            <frontend>
                <fields>
                    <custom_page_size translate="label">
                        <label>Page Size for Custom Page Type</label>
                        <frontend_type>text</frontend_type>
                        <sort_order>9999</sort_order>
                        <show_in_default>1</show_in_default>
                        <show_in_website>1</show_in_website>
                        <show_in_store>1</show_in_store>
                    </custom_page_size>
                </fields>
            </frontend>
        </groups>
    </catalog>
</sections>
</config>

Затем получите это значение в вашем коде с помощью:

$page_size = Mage::getStoreConfig('catalog/frontend/custom_page_size');

НТН,
JD

5 голосов
/ 17 марта 2011

к сожалению, это не работает, потому что в методе _getProductCollection() коллекция уже инициализирована с размером страницы.

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

Ниже приведен пример (при условии, что расширение yourmodule записано в yourpackage):

ШАГ 1: Определите своего наблюдателя в config.xml

в разделе global вашего файла расширения config.xml вставьте что-то вроде:

<events>
  <catalog_product_collection_load_before>
    <observers>
      <yourpackage_yourmodule_catalog_observer>
        <type>singleton</type>
        <class>yourpackage_yourmodule/catalog_observer</class>
        <method>limitPageSize</method>
      </yourpackage_yourmodule_catalog_observer>
    </observers>
  </catalog_product_collection_load_before>
</events>    

ШАГ 2: Определите свой класс Observer в папке Model\Catalog:

<?php
class Yourpackage_Yourmodule_Model_Catalog_Observer
{
  public function limitPageSize($observer)
  {
    #TODO: Insert the logic you need to differentiate when to apply the following
    $event = $observer->getEvent();
    $collection = $event->getCollection();
    $collection->setPageSize(3);
    return $this;
  }
}

Надеюсь, это поможет. С уважением, Алессандро Рончи

3 голосов
/ 13 апреля 2012

Я получил код пользователя: clockworkgeek, но здесь есть некоторые проблемы, и правильный код следующий: он работает и спасибо clockworkgeek.

$_productCollection = $this->getLoadedProductCollection();
$_productCollection->clear();
$_productCollection->setPageSize(3)
$_productCollection->load();

Вы также пишете enter code here или решите эту проблему, изменив значение

$this->getLoadedProductCollection()->clear();
$_productCollection = $this->getLoadedProductCollection();

Спасибо, Если это поможет вам, то прокомментируйте.

2 голосов
/ 18 мая 2010

Похоже, что для коллекции, возвращенной в list.phtml, уже была вызвана load (), что означает, что к тому времени, когда мы дойдем до шаблона, мы потеряли возможность устанавливать размер страницы. Итак, это будет немного грязно!

Блок, который генерирует эту коллекцию, - Mage_Catalog_Block_Product_List, который мы можем одновременно расширить с помощью нашего собственного класса и переопределить. Создайте новый блок, который расширяет Mage_Catalog_Block_Product_List и переопределите метод _getProductCollection следующим образом:

/**
 * Retrieve loaded category collection
 *
 * @return Mage_Eav_Model_Entity_Collection_Abstract
 */
protected function _getProductCollection()
{
    if (is_null($this->_productCollection)) {
        $layer = Mage::getSingleton('catalog/layer');
        /* @var $layer Mage_Catalog_Model_Layer */
        if ($this->getShowRootCategory()) {
            $this->setCategoryId(Mage::app()->getStore()->getRootCategoryId());
        }

        // if this is a product view page
        if (Mage::registry('product')) {
            // get collection of categories this product is associated with
            $categories = Mage::registry('product')->getCategoryCollection()
                ->setPage(1, 1)
                ->load();
            // if the product is associated with any category
            if ($categories->count()) {
                // show products from this category
                $this->setCategoryId(current($categories->getIterator()));
            }
        }

        $origCategory = null;
        if ($this->getCategoryId()) {
            $category = Mage::getModel('catalog/category')->load($this->getCategoryId());
            if ($category->getId()) {
                $origCategory = $layer->getCurrentCategory();
                $layer->setCurrentCategory($category);
            }
        }
        $this->_productCollection = $layer->getProductCollection();

        $this->prepareSortableFieldsByCategory($layer->getCurrentCategory());

        // OUR CODE MODIFICATION ////////////////////
        $yourCustomPage = someFunctionThatDetectsYourCustomPage();
        if($yourCustomPage) {
            $this->_productCollection->setPageSize(1);
            $this->_productCollection->setCurPage(3);
            $this->_productCollection->load();
        }
        /////////////////////////////////////////////

        if ($origCategory) {
            $layer->setCurrentCategory($origCategory);
        }
    }
    return $this->_productCollection;
}

Важной частью является поиск способа определения, используете ли вы пользовательскую страницу list.phtml или нет. Затем вам нужно будет переопределить ссылки на <block type='catalog/product_list' /> в макетах вашего класса, и вы должны быть настроены на переход.

Надеюсь, это поможет!

Спасибо, Джо

0 голосов
/ 10 апреля 2014

Как уже упоминалось, productCollection уже имеет установленный размер страницы. Есть и другой способ получить коллекцию; через catalog/product модель:

$productCollection = Mage::getModel('catalog/product')
    ->getCollection()
    ->addAttributeToSelect(
        array('name', 'image', 'price')
    )
    ->addIdFilter( 
        array('1', '2')
    )
    ->setPageSize( 2 )
    ->load();
;

return $productCollection->getSelect()->__toString();

Полученный запрос (и в конечном итоге объект ) содержит синтаксис LIMIT:

SELECT `e`.* ... WHERE (`e`.`entity_id` IN('1', '2')) LIMIT 2;

Это то, что вы спрашивали?

...