2

When user is on products list page and there is ?sale=1 parameter to URL, I want Magento to display only products that are on sale.

I already found how to filter collection, so it contains only items on sale - https://stackoverflow.com/questions/11292208/or-and-and-statement-addattributetofilter-magento

I'm trying to modify the collection in catalog_block_product_list_collection event, but no matter what changes I apply to it - old products are displayed in catalog.

<catalog_block_product_list_collection>
    <observers>
        <my_custom_observer>
            <class>Some_Module_Model_Observer</class>
            <method>catalog_block_product_list_collection</method>
        </my_custom_observer>
    </observers>
</catalog_block_product_list_collection>

-

public function catalog_block_product_list_collection(Varien_Event_Observer $observer) {

        $params = Mage::app()->getRequest()->getParams();

        if( isset($params['sale']) && (int)$params['sale'] === 1  ) {

            // this part works and test text prints at the beginning of catalog
            echo "test text";


            $collection = $observer->getCollection();
            // this part doesn't work - old collection is displayed in catalog
            $collection->getSelect()->limit(5); // even simple limit doesn't work

        }

}

Should I be using some other event? Please recommend what's the best way to modify product collection output for catalog pages.

Thank you.

EDIT: Started digging in Magento code to find out why the collection isn't modified and found that the problem is caused by default Magento Review observer that uses same event, added in app/code/core/Mage/Review/etc/config.xml:

        <catalog_block_product_list_collection>
            <observers>
                <review>
                    <type>model</type>
                    <class>review/observer</class>
                    <method>catalogBlockProductCollectionBeforeToHtml</method>
                </review>
            </observers>
        </catalog_block_product_list_collection>

And the function which it refers to:

 public function catalogBlockProductCollectionBeforeToHtml(Varien_Event_Observer $observer)
{
    $productCollection = $observer->getEvent()->getCollection();
    if ($productCollection instanceof Varien_Data_Collection) {

        $productCollection->load();
        Mage::getModel('review/review')->appendSummary($productCollection);
    }

    return $this;
}

If I comment line $productCollection->load(); - everything starts working correctly and my initial filter works. Anyone has any idea how to fix this without editing core file?

  • What do you mean by old products? What do you want to show? – Fabian Blechschmidt Mar 11 '14 at 13:50
  • Edited, please check again. By "old products" I mean default order of catalog. – Marvin3 Mar 11 '14 at 14:11
  • Good catch! Edited my answer. – Fabian Blechschmidt Mar 11 '14 at 14:16
3

You have to add a filter to your collection. And the event is great, best choice.

if(Mage::app()->getRequest()->getParam('sale')) {
    $collection = $observer->getCollection();
    $collection->setPageSize(5);
}

Good catch this observer.

To define the "order" of the observer (which shouldn't be relied on) you can just add a <depends> in your Module.xml in app/etc/modules/Company_Module.xml:

<config>
    <modules>
        <Mage_Eav>
            <active>true</active>
            <codePool>core</codePool>
            <depends>
                <Mage_Core/>
            </depends>
        </Mage_Eav>
    </modules>
</config>

And what you want your Module to depend on is Mage_Review

  • Ty. But not sure if I understand how adding addAttributeToFilter('sale', 1) will help. For example, how do I limit the product collection so it contains only 5 products? – Marvin3 Mar 11 '14 at 12:14
  • I read nothing about limit the collection :-) updated. – Fabian Blechschmidt Mar 11 '14 at 12:18
  • I don't have "sale" attribute on products. I just want to filter to product list (e.g. by limiting it to 5 products) when I have "sale=1" in my URL. – Marvin3 Mar 11 '14 at 12:23
  • ah ok, then just remove the addAttributeToFilter – Fabian Blechschmidt Mar 11 '14 at 12:24
  • That's the problem. When I use this code - nothing changes in product collection - old products are displayed, but I don't understand why. – Marvin3 Mar 11 '14 at 12:25
2

Add this in your own app/etc/modules/NAMESPACE_MODULE.xml:

<Mage_Review>
    <depends>
        <Timonline_CatalogSorting />
    </depends>
</Mage_Review>

So in my case it becomes:

<?xml version="1.0"?>
<config>
    <modules>
        <Timonline_CatalogSorting>
            <active>true</active>
            <codePool>local</codePool>
        </Timonline_CatalogSorting>
        <Mage_Review>
            <depends>
                <Timonline_CatalogSorting />
            </depends>
        </Mage_Review>
    </modules>
</config>

This forces the order of the events hooking into catalog_block_product_list_collection.

0

The problem is the order in which the observers are executed, as you noticed.

You can that with dependencies (as also described here: Magento Observer Events - order of operations), but adding a dependency from a core module to yours seems hacky and might cause other problems.

In your case, you have another possibility. Observers, registered in <global> are executed before the area specific observers in <frontend> and <adminhtml>. Fortunately the observer from Mage_Review has been registered in the frontend area. As soon as you register yours globally, it will be executed first, thus before the collection is loaded:

<global>

    <events>

        <catalog_block_product_list_collection>
            <observers>
                <my_custom_observer>
                    <class>Some_Module_Model_Observer</class>
                    <method>catalog_block_product_list_collection</method>
                </my_custom_observer>
            </observers>
        </catalog_block_product_list_collection>

    </events>

</global>

The event is not used anywhere in the admin panel, so there are no other side effects to expect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.