1

I have an interesting use case for disabling a Bundle's options 'cache':

Controller:

public function indexAction()
{
    Mage::register('my_flag',true);
    //...other stuff
}

app/code/local/MyCompany/MyModule/Block/Product/View/Type/Bundle.php:

#class rewrite of Mage_Bundle_Block_Catalog_Product_View_Type_Bundle
public function getOptions()
{
    if (!$this->_options || Mage::registry('my_flag')) { // this is the undesired hack
        $product = $this->getProduct();
        $typeInstance = $product->getTypeInstance(true);
        $typeInstance->setStoreFilter($product->getStoreId(), $product);

        $optionCollection = $typeInstance->getOptionsCollection($product);

        $selectionCollection = $typeInstance->getSelectionsCollection(
            $typeInstance->getOptionsIds($product),
            $product
        );

        $this->_options = $optionCollection->appendSelections($selectionCollection, false,
            Mage::helper('catalog/product')->getSkipSaleableCheck()
        );
    }

    return $this->_options;
}

Currently I'm rewriting this and requiring it to fetch/append from the collection if a Mage::registry value exists. This feels.... messy.

I'd love a clever solution that doesn't require me to set a Mage::registry value in the controller. I considered forcing the view to set $this->_options to null: but I'd rather the rewrite, quite honestly, than have that sort of logic in the view.

Edit:

From the same Bundle.php rewrite:

public function getProduct() {
    if (!$this->hasData('product') || Mage::registry('my_flag')) { // same hack
        $product = Mage::registry('product');
        if (is_null($product->getTypeInstance(true)->getStoreFilter($product))) {
            $product->getTypeInstance(true)->setStoreFilter(Mage::app()->getStore(), $product);
        }
        $this->setData('product', $product);
    }
    return $this->getData('product');
}
9
  • 1
    Are you using registry to provide controller-calculated value to the view?
    – benmarks
    Commented Feb 3, 2014 at 19:32
  • 1
    What's the condition for setting the registry value? It might help to post a bit more of what your custom code does to have a bit more context.
    – beeplogic
    Commented Feb 3, 2014 at 19:44
  • If accessing a particular route, we flag in the app (via registry) to handle some display logic. Essentially build a multi-bundle pricing component on a custom product page. This allows us to track selections, pricing of potentially dozens of bundle items on one page while still utilizing the default Magento options behavior. However, when building out the options html for secondary, tertiary (and so on) products on the page they are reflecting the base product's bundle options and not their own (due to the options cache).
    – philwinkle
    Commented Feb 3, 2014 at 19:49
  • Can't you use a different instance of the block Mage_Bundle_Block_Catalog_Product_View_Type_Bundle for each product? O simply create you own class that extends the block mentioned above, where you can add a method resetOptions(){$this->_options = null} that you can call after rendering each product.
    – Marius
    Commented Feb 3, 2014 at 20:04
  • 1
    How does $this->getProduct() know which to render if it's not a separate instance of the block? Unless you're doing $childBlock->setProduct($_product) while looping through the list of bundle products you're rendering.
    – beeplogic
    Commented Feb 3, 2014 at 20:33

1 Answer 1

2

If you've got a custom layout handle to work with, it might be possible to <reference> the block and set a flag there. It wont prevent you from having to rewrite the block type class but at least you avoid using the registry.

Controller:

$this->getLayout()->getUpdate()->addHandle('custom_bundle_view');

local.xml or custom module's layout XML file:

<custom_bundle_view>
    <reference name="product.info.bundle">
        <action method="setSkipOptionsCache"><value>1</value></action>
    </reference>
<custom_bundle_view>

app/code/local/MyCompany/MyModule/Block/Product/View/Type/Bundle.php:

if (!$this->_options || $this->getSkipOptionsCache()) {

1
  • Great minds think alike - this was the first approach (much like the addRenderer methods in the same bundle blocks) ... I like this and it would be useful if this were the only place we had to perform the change; in that case the registry is more expressive because we don't have to apply it to two other blocks. But I do like this. Upboats.
    – philwinkle
    Commented Feb 3, 2014 at 20:29

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.