Whoever worked with Magento probably noticed Magento helpers. Helper is a common element of every module and can be used for different purposes. I will give my thoughts on how Magento helpers should be used and hopefully start a community discussion regarding this topic.

So the first thing that’s important when mentioning helpers in Magento is that they can be used and are meant to be used almost everywhere. It’s easy to get helper instance pretty much anywhere in your application and call its methods. All you need to do is:

Mage::helper('modulename')->someMethod();

For start let’s see what this Mage::helper() method actually does:

app/Mage.php

/** * Retrieve helper object * * @param string $name the helper name * @return Mage_Core_Helper_Abstract */ public static function helper($name) { if (strpos($name, '/') === false) { $name .= '/data'; } $registryKey = '_helper/' . $name; if (!self::registry($registryKey)) { $helperClass = self::getConfig()->getHelperClassName($name); self::register($registryKey, new $helperClass); } return self::registry($registryKey); }

So it basically retrieves helper class from registry or instantiates it and stores it in a registry if it’s not already there. That means you will get the same helper instance in entire application.

Helpers criticism

You would often hear in OOP design discussion that helpers are generally thought of as antipatterns. Here are the the two main reasons for it.

Global scope

Possibility to access variables or methods globally is often considered a code smell. One of the main reasons for this is that with global methods for example it’s harder to have control of where they are used since they can be accessed from anywhere. Debugging is also harder because with this approach it’s not easy to find all the elements that are involved.

SOLID principle violation

According to SOLID principles (the S – Single Responsibility one to be more precise), one class should have only one responsibility. Helpers by definition do not have one responsibility and they don’t deal with only one problem domain. Even in Magento core files you can see that Magento helpers cover wide range of issues. One could also say that by creating helper methods a programmer cannot define where they should actually belong, so they are put in “class for everything”.

Helpers benefits

There are also some good points regarding helpers:

Easy to set up test

It would be very easy to set up a helper unit test. Blocks are dependant on layout and controllers are dependant on http request so you would have to do more work in order to set up test for these. Of course, easiness to test some particular methods depends on what’s called in that method.

Reusable functionality

Good thing about helpers is that you can put some reusable functionality in them. No need to create the same methods across different blocks or rewrite abstract block class.

Good places for methods that don’t really belong anywhere

Usually in a project there is some stuff you can’t really put anywhere else. There are problems that do not have a specific problem domain and do not belong to any specific part of Magento application.

Use cases

Here is some stuff that could be put inside a helper:

Pure functions

Pure function is a function that does not depend on some external state and has no visible side effects (such as changing values of class properties for example). It will always return the same result for same input. Such function can obviously be used in any context since it does not depend on anything externally. Converting centimetres to inches could be an example of pure function. This behaviour guarantees that the method could be called anywhere with no side effects.

Retrieving config values

Storing config path in a class constant and creating a method that would call Mage::getStoreConfig() would be a good idea. Config path probably won’t change over time and wrapping Mage super class method getStoreConfig in a helper method ensures that you won’t have to check the path all the time. Some additional work that needs to be done in order to make these config values usable such as casting for example can also be put in such methods. Here is an example:

app/code/core/Mage/Catalog/Helper/Data.php

class Mage_Catalog_Helper_Data extends Mage_Core_Helper_Abstract { //... const XML_PATH_MSRP_ENABLED = 'sales/msrp/enabled'; //... /** * Check if Minimum Advertised Price is enabled * * @return bool */ public function isMsrpEnabled() { return (bool)Mage::getStoreConfig(self::XML_PATH_MSRP_ENABLED, $this->_storeId); } //... }

Retrieving hardcoded values

Let’s say you need months of the year or some other hardcoded array in a template. It would be better to put that stuff in a helper method than adding additional weight to your template. Same goes for constants.

Usage

There is another topic I would like to cover in this article. Sometimes it’s not so clear whether some functionality should be put in block or helper. Same goes for model or helper situation.

Helpers and blocks

I would say that it’s easier to make a choice in a block vs helper situation. If some functionality is meant to be used in a lot of different places throughout the application, put it in a helper. If it’s meant to be called in a specific template and you don’t think it’s reusable put it in a block.

Helpers and models

With models it’s a bit different, since both models and helpers can be called from anywhere in Magento. Models have a very specific problem domain. They usually represent an entity but they can be in charge of other tasks such as cron jobs or event observing. Helpers on the other hand have a loosely defined problem domain so for example in catalog helper you can find anything that is in some way related to catalog so it’s a lot less specific. Therefore if you notice that you are doing too much in helper you should consider creating a specific model for that functionality instead. Another difference is that models are meant to hold a certain state (loaded, non-loaded for example), where in helpers you should avoid holding a state. That’s why if you need class properties you should probably move your methods to model. Helpers are more like some single functionalities grouped so it doesn’t make sense to keep a property that would probably be totally unrelated to the helper class itself. One tradeoff Magento core team made is keeping instances of objects in class properties in order to prevent querying the database and instantiating classes more times than needed. I think it’s an architecture sacrifice that’s acceptable.

Wrap up

Helpers can definitely be very useful if used wisely. These are only my thoughts that are coming from my experience. You are welcome to share your opinion on helper usage.