0

In our Magento project we have around 200 thousand skus and many of them are with incomplete information. So we made a filter to prevent products without images from appearing on the category pages.

<catalog_product_collection_load_before>
    <observers>
        <mymodel_catalog_product_collection_load_before_clean_images>
            <type>singleton</type>
            <class>mymodel/observer</class>
            <method>filterProductsWithoutImages</method>
        </mymodel_catalog_product_collection_load_before_clean_images>
    </observers>
</catalog_product_collection_load_before>

...

public function filterProductsWithoutImages($observer) {
    if (isset($observer['collection'])) {
        $collection = $observer['collection'];
        $collection->addAttributeToFilter('small_image', array('neq' => "no_selection"));

        return $this;
    }
}

Products without images are removed from the collection. The problem occurs with pagination. The filtered products generate "holes" in the product listing. Example:

Category Accessories: 100 SKUS active.

Page 1: 36 products. Only 20 products are displayed, because 16 are without images.

Page 2: 36 products. Only 9 products are displayed, because 27 are without images.

Page 3: 28 products. The 28 products are displayed because they all have images.

So the problem is that after changing the collection, either through events catalog_product_collection_load_before or catalog_product_collection_load_after, the collection's pagination is not updated and the indices of the filtered products remain.

My questions:

  1. In my understanding, the page was built after the load of the collection (so I was using the catalog_product_collection_load_before event). But because of this situation, it does not seem to be that way. How does it actually work?

  2. Considering that if I edit the collection and load it again it can generate an infinite loop, how can I update the collection so as not to generate these "holes"?

1 Answer 1

0

Try controlling the collection filtering via extending the Block_Product_List_Toolbar, this has worked for me on similar scenario to you. Here's some code to get you started;

config.xml (in <global> scope):

<blocks>
  <catalog>
      <rewrite>
          <product_list_toolbar>YourCompany_YourModule_Block_Product_List_Toolbar</product_list_toolbar>
      </rewrite>
  </catalog>
</blocks>

YourModule/Block/Product/List/Toolbar.php:

<?php
class YourCompany_YourModule_Block_Product_List_Toolbar extends Mage_Catalog_Block_Product_List_Toolbar
{

    public function setCollection($collection)
    {
       parent::setCollection($collection);

       $this->getCollection()->addAttributeToFilter('small_image', array('neq' => "no_selection"));

       return $this;
    }

}
3
  • I tried to remove the event I created and use your solution, but the effect was the same. The products were removed but the "holes" continued. Feb 6, 2018 at 15:03
  • Try echo $this->getCollection()->getSelect(); before the return $this; - it will show the SQL query. is this as expected? Is it possible you've got a 3rd-party module overriding Catalog_Block_Product_List_Toolbar? Feb 6, 2018 at 15:07
  • There isn't 3rd-party extension overring Catalog_Block_Product_List_Toolbar, but there is a 3rd-party extension overring the Layer Model. I'll look it. Feb 6, 2018 at 15:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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