Question

I have created an observer listening to the catalog_block_product_list_collection event.

What I am trying to do is limit the products being listed by customer group and whether a customer has a custom price for that product.

What I have so far is the observer limiting the products by customer group:

$collection = $observer->getCollection();
$collection->addAttributeToSelect('scode') //custom attribute
           ->addFieldToFilter('scode', array('in' => $filter)); //array of values pulled from a custom table based on customer group id.

For the majority of pages this is fine, however when in Category X (id 6) or when searching, how do I filter the collection so any products in Category X need to be limited to those with product id in array (values to be drawn from another custom table).

If this was just being applied to the category listings, then I would do something like:

$cat = Mage::registry('current_category');
if($cat && $cat->getId() == 6) {
    $collection->addFieldToFilter('product_id', array('in' => $product_ids));
}

but that does not help for search pages where I want to return all products in all categories except products in category X that are not white-listed.

How do I add a filter to my collection to do as I want in the above scenario?

Was it helpful?

Solution

This is the solution I came up with. It loads my custom model to get product ids that the customer can purchase, loads the product ids for category X, removes the valid ids from the rest of the ids, and does a not-in filter on the main collection (the function loadByAttribute is a custom method that returns an array of rows from the database):

//only do this for logged in customers.
$customer_id = Mage::getSingleton('customer/session')->getCustomer()->getId();
if(!is_null($customer_id)) {

    //get all products for this customer
    $whiteList= Mage::getModel('my_module/my_model')->loadByAttribute('customer_id', $customer_id)->toArray();
    $ids = array();
    foreach($whiteList as $item) {
        $ids[] = $item['product_id'];
    }

    //get all products for category X
    $category = Mage::getModel('catalog/category')->load(6);
    $xCollection = Mage::getModel('catalog/product')->getCollection()
                                                    ->addCategoryFilter($category);

    //get ids of products to not include
    $bIds = $xCollection->getAllIds();
    $xCollection->addFieldToFilter('entity_id', array('in' => $ids));
    $b2Ids = $xCollection->getAllIds();
    $doNotIncludeIds = array_diff($bIds, $b2Ids);

    //remove category x product ids that customer cannot buy
    $collection->addFieldToFilter('entity_id', array('nin' => $doNotIncludeIds));
}

OTHER TIPS

You can try this event catalog_product_collection_load_before

$productIds = array(1,2,3,4);

$observer->getCollection()->addIdFilter($productIds);

EDIT

For the specific category filter you can try

$category = Mage::getModel('catalog/category')->load(6);

$observer->getCollection()->addCategoryFilter($category);
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top