1

I have a Magento site where I need to remove some products from certain customer groups due to them having a zero price on the products.

I have tried catalog_product_collection_load_after event and have successfully managed to remove the products that I want. This however causes a gap on the catagory pages where the products would be. Would there be any way to go about remove products from a collection either before the pagination is set on the collection or to "remake" the collection once you've removed the products.

The code I've tried so far:

 /* Remove all products from the category list where the (group) price is zero */
public function removeZeroPriceProducts($observer) {

    if (! Mage::app()->getStore()->isAdmin())
    {
        $collection = $observer->getEvent()->getCollection();
        //Loop through all products in the collection
        foreach ($collection as $product)
        {

            $origProduct = $product;

            //If it is a configurable we need to get the childrens prices.
            // Since if the customer isn't allowed to see the product all prices on all children will be zero we only need to get any of the children
            if($this->getTypeId() == "configurable") {
                $product = $product->getTypeInstance()->getUsedProductCollection()->addAttributeToSelect('price')->addPriceData()->setPageSize(1)->getFirstItem();
            }

            //Check if the price is zero. If so remove the product from the collection. Note that this --will-- cause a gap in the end of the page before the pagination.
            if($origProduct->getFinalPrice() === 0 || $product->getFinalPrice() === 0)
                $observer->getEvent()->getCollection()->removeItemByKey($origProduct->getId());
        }
    }
}

Edit: I've tried added it to _getProductCollection in List.php as suggested by Mohit. This removes the product as expected but unfortunately still leaves a gap. I'll leave the code for that here as well.

protected function _getProductCollection()
{
    if (is_null($this->_productCollection)) {
        $layer = $this->getLayer();
        /* @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());

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

    //Try and remove a specific ID from the collection
    $collection = $this->_productCollection;
    $collection->removeItemByKey(4146);
    return $collection;
}

2 Answers 2

0

To modify product collection before rendering category page follow these steps:

  1. Override Magento\Catalog\Block\Product\ListProduct
  2. In function _getProductCollection after if statement insert your code:
$collection = $this->_productCollection;
foreach ($collection as $k => $product){
 // Here goes your code to modify product
 // For example:

$collection->removeItemByKey($k);// Remove original item from collection 
}
$collection->setOrder('position','ASC');// Reorder collection as you want
return $collection;
6
  • Thanks, I'll give it a try. Commented Mar 25, 2019 at 12:25
  • By ListProduct I'm guessning you meant List.php? I tried moving my code there but I still get a gap at the end of the page. Where in the function would I be adding the code? I tried a few different places with the same result Commented Mar 25, 2019 at 12:33
  • There is no file called ListProduct.php in Magento 1.7. I've overridden the code, that's not the issue. The issue is that I'm still getting the gap which is what I'm trying to prevent :) Commented Mar 25, 2019 at 12:37
  • Yes in Magento 1.7 there is List.php where you need to add this code. but am not getting what gap you are talking about ? Commented Mar 25, 2019 at 12:43
  • Can you show me your code in _getProductCollection function ? Commented Mar 25, 2019 at 12:44
0

I found a solution that seems to work. On the customer_login event I loop through all the products and add all the products that the customer are not allowed to see into an array that I then save in a customer session variable.

I then create a function called removeZeroPriceProducts that catches onto the catalog_product_collection_load_before event. In this function I've excluded the products by doing the following:

/* Remove all products from the category list where the (group) price is zero */
public function removeZeroPriceProducts($observer) {

    if (! Mage::app()->getStore()->isAdmin())
    {
        //Get all disallowed products for the user
        if($disallowed = Mage::getSingleton('checkout/session')->getDisallowedProducts()){
            //Add a filter for the product collection that removes all the disallowed products
            $observer->getEvent()->getCollection()->addFieldToFilter('entity_id', array('nin' => $disallowed));
        }
    }
}

Instead of using removeItemByKey which removed the product but left a gap I now instead add a filter which removes all products that can be found in my session variable.

Note. I first tried to loop through all the products in the removeZeroPriceProducts fonction. This however broke the page which is why I instead added all the products to a session variable when the customer logs in

Your Answer

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

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