Engine23
blogBannerImage
By Engine23

Magento - Blocks Why some rewrites do not work for example Mage_Bundle_Block_Catalog_Product_View_Type_Bundle_Option_Checkbox

Most of the time doing a rewrite of a Block is pretty simple.  However you will run into issues when you want to do something as simple as remove the + from a Bundle product price.  

Most of the time, you can just do a rewrite of the block in XML and its done. However when you try to do this with some blocks, they just dont work!  The reason....some blocks are not called using the factory method.  These blocks are the ones that are extended from, so they are just part of the php code.  The way to get at those is by rewriting the blocks we can do a rewrite ( for example Mage_Bundle_Block_Catalog_Product_View_Type_Bundle_Option_Checkbox ).  Then we can extend our version of Mage_Bundle_Block_Catalog_Product_View_Type_Bundle_Option.

Here is how I achieve this for Bundle Products and the checkbox options for the children products.

 

app/etc/modules/Test_Bundle.xml

<config>
<modules>
<Test_Bundle>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Bundle/>
</depends>
</Test_Bundle>
</modules>
</config>

app/code/local/Test/etc/config.xml

<?xml version="1.0"?>
<config>
<modules>
<Test_Bundle>
<version>0.0.1</version>
</Test_Bundle>
</modules>
<global>
<blocks>
<bundle>
<rewrite>
<catalog_product_view_type_bundle_option_checkbox>Test_Bundle_Block_Catalog_Product_View_Type_Bundle_Option_checkbox</catalog_product_view_type_bundle_option_checkbox>
</rewrite>
</bundle>
</blocks>
</global>
</config>

app/code/local/Test/Bundle/Block/Catalog/Product/View/Type/Bundle/Option/Checkbox.php

Note that I am not extending the original Block as is typical, I am extending my own.  The good news is this has no affect on other calls to the original Classes.  Just those that use my rewritten block, so its pretty safe. PLEASE test things out before you rely on this method entirely.

<?php
class Ecreamery_Bundle_Block_Catalog_Product_View_Type_Bundle_Option_Checkbox extends Test_Bundle_Block_Catalog_Product_View_Type_Bundle_Option
{
/**
* Set template
*
* @return void
*/
protected function _construct()
{
$this->setTemplate('bundle/catalog/product/view/type/bundle/option/fixed-checkbox.phtml');
}

}

app/design/frontend/default/default/template/bundle/catalog/product/view/type/bundle/option/fixed-checkbox.phtml.

The thing to note her is that the original function $this->getSelectionQtyTitlePrice($_selection) has been changed to $this->getSelectionQtyTitleNoPrice($_selection).  The reason is I wanted to NOT show the +$0.00 next to each product in this bundle.  There were some other modfications to this too, but that is the one worht mentioning.

 

<?php /* @var $this Test_Bundle_Block_Catalog_Product_View_Type_Bundle_Option_Checkbox */ ?>
<?php $_option = $this->getOption() ?>
<?php $_selections = $_option->getSelections() ?>
<dt><label<?php if ($_option->getRequired()) echo ' class="required"' ?>><?php echo $this->escapeHtml($_option->getTitle()) ?><?php if ($_option->getRequired()) echo '<em>*</em>' ?></label></dt>
<dd<?php if ($_option->decoratedIsLast){?>class="last"<?php }?>>
<div class="input-box">
<?php if (count($_selections) == 1 && $_option->getRequired()): ?>
<?php echo $this->getSelectionQtyTitlePrice($_selections[0]) ?>
<input type="hidden" name="bundle_option[<?php echo $_option->getId() ?>]" value="<?php echo $_selections[0]->getSelectionId() ?>"/>
<?php else:?>
<ul class="options-list">
<?php foreach($_selections as $_selection): ?>
<li>
<div style="height: 1px; width: 1px; overflow: hidden;">
<input class="change-container-classname checkbox bundle-option-<?php echo $_option->getId() ?><?php if ($_option->getRequired()) echo 'validate-one-required-by-name' ?>" id="bundle-option-<?php echo $_option->getId() ?>-<?php echo $_selection->getSelectionId() ?>" type="checkbox" name="bundle_option[<?php echo $_option->getId() ?>][]"<?php if ($this->_isSelected($_selection)) echo ' checked="checked"' ?><?php if (!$_selection->isSaleable()) echo ' disabled="disabled"' ?>value="<?php echo $_selection->getSelectionId() ?>"/>
</div>
<span class="label"><label for="bundle-option-<?php echo $_option->getId() ?>-<?php echo $_selection->getSelectionId() ?>"><?php echo $this->getSelectionQtyTitleNoPrice($_selection) ?></label></span>
<?php if($_option->getRequired()): ?>
<?php echo $this->setValidationContainer('bundle-option-'.$_option->getId().'-'.$_selection->getSelectionId(), 'bundle-option-'.$_option->getId().'-container') ?>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<div id="bundle-option-<?php echo $_option->getId() ?>-container"></div>
<?php endif; ?>
</div>
</dd>

Finally my block that was not able to be rewritten.

app/code/local/Test/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php

This has that new method getSelectionQtyTitleNoPrice() to NOT show the + and the price of the bundle product. 

<?php
class Test_Bundle_Block_Catalog_Product_View_Type_Bundle_Option extends Mage_Bundle_Block_Catalog_Product_View_Type_Bundle_Option
{


/**
* Returns the formatted string for the quantity chosen for the given selection
*
* @param Mage_Catalog_Model_Proudct $_selection
* @param bool $includeContainer
* @return string
*/
public function getSelectionQtyTitleNoPrice($_selection, $includeContainer = true)
{
$price = $this->getProduct()->getPriceModel()->getSelectionPreFinalPrice($this->getProduct(), $_selection);
$this->setFormatProduct($_selection);
$priceTitle = $_selection->getSelectionQty() * 1 . ' x ' . $this->escapeHtml($_selection->getName());

$priceTitle .= ' &nbsp; ' . ($includeContainer ? '<span class="price-notice">' : '')

. ($includeContainer ? '</span>' : '');

return $priceTitle;
}


}