Question

Synopsis

I have a problem where by a Magento Store I am working on has been configured to use grouped products with associated simple products. These products can be filtered by the products attributes/values as configured in the admin.

Current behaviour

  • The simple products' visibilities are set to Not visible individually.
  • The simple products when searched are displayed by their group product.

When the end-user filters the products results by colour and for example red, the grouped products with simple associated products that have an attribute value for colour of red are displayed.

Expected behaviour (after customization)

  • The simple products' visibilities are set to Not visible individually.
  • The simple products when searched are displayed by their group product.

When the end-user filters the products results by colour (only) that instead of the grouped products being displayed, that simple product should be displayed.

My logic was - I could detect the filters through the request parameters. When the colour filter has been set, I override the products results somehow.

When I say somehow what I mean is, this is the part where I have trouble solving my simple problem. How can I solve this problem?

Conclusion / Attempts

Below are the list of attempts i've thought of and played around with to either find it doesn't entirely solve my problem or simply doesn't solve my problem at all.

Observe the catalog_controller_category_init_before:

I thought when I observe the _initCategory() method I could override the layout in that I could potentially change the Magento configuration to display simple products and not grouped products.

However it appears $this->loadLayout() is never called, so I have to override the getLayout or viewAction methods on the CategoryController itself.

Override the CategoryController explicitly to implement layout changes:

I reverted the above and decided to pursue my second option of overriding the functionality. Starting with extending the Mage_Catalog_CategoryController controller.

My first trial was to override the loadLayout, after learning this is never called I then decided to override the getLayout at this point I wasn't sure what I was going to do.

Override the Mage_Catalog_Block_Product_List:

I decided that the better option was to extend the actual block which has the models and collections necessary. Within my block I override the getProductsListHtml method, I quickly learn the entire HTML has already been parsed, executed and generated.

So I couldn't simply.

  • Listen for the $this->getRequest()->getParams();
  • Iterate over the grouped products to get their associated products that match my filter;

Observe the catalog_product_collection_load_after event:

This time I thought fine I could observe the model collection and change the questy to alter the results when my filters have been set. Whereby I get $observer->getEvent()->getCollection() and update the query based on my filters.

This doesn't work because I can remove the grouped products, but the simple products wont show up because of the visibility.

Was it helpful?

Solution

Although this doesn't explicitly provide a solution, this answer is currently what I have done in order to achieve my goal.

I essentially created an observer to catalog_product_collection_load_after. I then re-create the query to collect only the data I want.

$event      = $observer->getEvent();
$collection = $event->getCollection();
$select     = $collection->getSelect();

// Adapter is the database resource adapter (an example, probably not the best)
$adapter = Mage::getResource('core/resource');

// Reset the entire query (using the Zend reset method).
$select->reset();

$select->from([ 'main_table' => $adapter->getTableName('catalog/product') ], [
    // stuff to get
])

// inner joins and things.

OTHER TIPS

I don't have a full code sample available, but what about creating a custom module and overriding Mage_Catalog_Model_Layer->prepareProductCollection()? You could use Mage::app->->getRequest()->getParams() to find if the attribute that you want to use is present, and if it is, don't run Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection) that is there now.

An example:

public function prepareProductCollection($collection)
{
    if (!in_array(Mage::app->->getRequest()->getParams(), 'colour')) {
        return parent::prepareProductCollection($collection);
    }

    $collection
        ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
        ->addMinimalPrice()
        ->addFinalPrice()
        ->addTaxPercents()
        ->addUrlRewrite($this->getCurrentCategory()->getId());

    Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
    // Don't filter by "visible in catalog" if filtering by colour
    // Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);

    return $this;
}

I hope this at least gets you closer.

According to your requirement, I don't find it suitable to show simple product on selection of filters. As much as I can observer you are looking to show the image of that color product which you can achieve in configurable listed product as well. You can have associated product details while rendering the list, Just trigger the flags to check if filter is selected or not which is used to configure the product, if selected then fetch the respective image. Rebuilding the complete structure doesn't make sense. Either create a block file to render the simple products and switch the block rendering at filter selection. But I'll prefer the first option. Write for any query.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top