Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between the different *get helper* methods in Magento?

Tags:

magento

I've seen several different approaches to getting a particular helper, and I'm hoping someone can explain the pros/cons of each approach. For example, in template/checkout/cart/sidebar/default.phtml, you'll see both $this->helper('checkout') and Mage::helper('checkout'). Is there a good reason for these two different methods in the same template?

Below are all the different ways of getting a helper I could find in Magento:

abstract class Mage_Core_Block_Abstract extends Varien_Object
{
…
    /**
     * Return block helper
     *
     * @param string $type
     * @return Mage_Core_Block_Abstract
     */
    public function getHelper($type)
    {
        return $this->getLayout()->getBlockSingleton($type);
    }

    /**
     * Returns helper object
     *
     * @param string $name
     * @return Mage_Core_Block_Abstract
     */
    public function helper($name)
    {
        if ($this->getLayout()) {
            return $this->getLayout()->helper($name);
        }
        return Mage::helper($name);
    }
…
}

class Mage_Core_Model_Layout extends Varien_Simplexml_Config
{
…
    /**
     * Enter description here...
     *
     * @param string $type
     * @return Mage_Core_Helper_Abstract
     */
    public function getBlockSingleton($type)
    {
        if (!isset($this->_helpers[$type])) {
            $className = Mage::getConfig()->getBlockClassName($type);
            if (!$className) {
                Mage::throwException(Mage::helper('core')->__('Invalid block type: %s', $type));
            }

            $helper = new $className();
            if ($helper) {
                if ($helper instanceof Mage_Core_Block_Abstract) {
                    $helper->setLayout($this);
                }
                $this->_helpers[$type] = $helper;
            }
        }
        return $this->_helpers[$type];
    }

    /**
     * Retrieve helper object
     *
     * @param   string $name
     * @return  Mage_Core_Helper_Abstract
     */
    public function helper($name)
    {
        $helper = Mage::helper($name);
        if (!$helper) {
            return false;
        }
        return $helper->setLayout($this);
    }
…
}
like image 659
kojiro Avatar asked Feb 17 '12 19:02

kojiro


1 Answers

Mage_Core_Block_Abstract::getHelper()

The Mage_Core_Model_Layout::getBlockSingleton() method doesn't return a Magento helper object, but rather an instance of the Magento object type block.
I believe this is legacy code, such as the Mage::getBlockSingleton() method is deprecated.

In both cases a block instance is created from a Magento class id.

The method getBlockSingleton() stores the instance in the $_helpers property of the layout object, the method createBlock() will store it in the $_blocks property.

Only blocks from the $_blocks array can be referenced (and overwritten) using layout XML.

The method getBlockSingleton() is useful if you want an instance of a specific block class, and you want to make sure not to create a new instance of the block if it already exists.
To achieve (almost) the same effect with the instances created via createBlock() you would need the following code:

public function alternativeGetBlockSingleton($classId)
{
    foreach (Mage::app()->getLayout()->getAllBlocks() as $block)
    {
        if ($block->getType() == $classId)
        {
            return $block;
        }
    }
    return $this->createBlock($classId);
}

Mage_Core_Block_Abstract::helper()

The Mage_Core_Block_Abstract::helper() method returns an instance of what in Magento is commonly referred to as a helper.
The only difference to calling Mage::helper($name) directly is that the layout object is set as a property on the helper instance.

One might argue that using $this->helper() in template files is cleaner then Mage::helper(), because is reduces the number of hardcoded references (and thus the dependency) to the Mage class, but in case of Magento that argument is futile, because every module is very dependent on Mage and some of the Mage_Core classes anyway.

In practice there probably no functional reason to prefer one over the other, except that Mage::helper() is far more common and well known, It will be less confusing for other developers to read the code, which makes it more maintainable.

On the other hand, Magento is all about choice, and having many ways to accomplish a given task.

like image 123
Vinai Avatar answered Oct 23 '22 09:10

Vinai