7

This confuses me a bit. I wonder why I didn't notice it before. When I look for helper definition of Mage_Sales core module, it surprised me that, I couldn't find helper defintion there. This confuses me a lot. Hence I tried this code

print_r(get_class(Mage::helper('sales')));

and it gave me this result

Mage_Sales_Helper_Data

Then where is the sales alias for Mage_Sales_Helper_Data is defined in magento. In other words, where should I can find this code snippet?

<global>
    <helpers>
         <sales>
             <class>Mage_Sales_Helper</class>
         </sales>
    </helpers>
</global>

I have also checked all xml files that are available for Mage_Sales's etc module. None of them holds helper definition. So how magento assigned sales alias to helper class Mage_Sales_Helper_Data.

Please enlighten me with your valuable thoughts

2 Answers 2

9

The sort answer is that it is not defined anywhere. If you trace back how Mage::helper works you get to the function Mage_Core_Model_Config::getGroupedClassName

This will try to load any rewrites firstly, then the definition directly from the config and then finally just assume it starts with mage_

if (empty($className)) {
    if (!empty($config)) {
        $className = $config->getClassName();
    }
    if (empty($className)) {
        $className = 'mage_'.$group.'_'.$groupType;
    }
    if (!empty($class)) {
        $className .= '_'.$class;
    }

    $className = uc_words($className);
}

So in the end the class name will be Mage_Sales_Helper_Data, this is why when creating your own extension is you miss off the helper or other definitions you get an error that it is trying to looks for Mage_Your_Module_Something

3
  • Awasome .. @David ....upvote from me
    – Amit Bera
    Commented Aug 7, 2014 at 18:18
  • I was digging in getGroupedClassName(). Now I am realizing.. I was so close to the answer !!. This completely wiped out my doubt. Now I can sleep with a calm mind. So +1 for make my mind clean :) Commented Aug 7, 2014 at 18:25
  • As @benmarks taught me, it's just a bunch of string manipulation to build class names that get autoloaded.
    – pspahn
    Commented Aug 8, 2014 at 1:56
2

With help of David above answer,Hope David would not mind.

I am try explain more in detail

start with Mage.php and go to function helper

public static function helper($name)
{
    $registryKey = '_helper/' . $name;
    if (!self::registry($registryKey)) {
        $helperClass = self::getConfig()->getHelperClassName($name);
        self::register($registryKey, new $helperClass);
    }
    return self::registry($registryKey);
}

a) $registryKey = '_helper/' . $name;

result: $registryKey = _helper/sales

b) check now registry key exits ot not,if not then set a registry variable

 if (!self::registry($registryKey)) {

its becomes true when system is first times for a session:

c) $helperClass = self::getConfig()->getHelperClassName($name); that means

$name=sales send to Mage_Core_Model_Config class function getHelperClassName for getting helper class send param

d)Then set class name is registry variablee

 self::register($registryKey, new $helperClass);

Result: may be proper class name Mage_Sales_Helper_Data

Now goes to getHelperClassName function of class Mage_Core_Model_Config

a) This function Retrieve helper class name string $name string

public function getHelperClassName($helperName)
{
    if (strpos($helperName, '/') === false) {
        $helperName .= '/data';
    }
    return $this->getGroupedClassName('helper', $helperName);
}

explain of function:

 $helperName is sales 

the logic:

 if (strpos($helperName, '/') === false) {

becomes true as $helperName=sales then set $helperName=sales/data

b) return $this->getGroupedClassName('helper', $helperName);

Details:

call function getGroupedClassName with params 'helper','sales/data' 
and getGroupedClassName return    class name of helper class

Now goto function getGroupedClassName('helper','sales/data',null)

public function getGroupedClassName($groupType, $classId, $groupRootNode=null)
{
    if (empty($groupRootNode)) {
        $groupRootNode = 'global/'.$groupType.'s';
    }

    $classArr = explode('/', trim($classId));
    $group = $classArr[0];
    $class = !empty($classArr[1]) ? $classArr[1] : null;

    if (isset($this->_classNameCache[$groupRootNode][$group][$class])) {
        return $this->_classNameCache[$groupRootNode][$group][$class];
    }

    $config = $this->_xml->global->{$groupType.'s'}->{$group};

    // First - check maybe the entity class was rewritten
    $className = null;
    if (isset($config->rewrite->$class)) {
        $className = (string)$config->rewrite->$class;
    } else {
        /**
         * Backwards compatibility for pre-MMDB extensions.
         * In MMDB release resource nodes <..._mysql4> were renamed to <..._resource>. So <deprecatedNode> is left
         * to keep name of previously used nodes, that still may be used by non-updated extensions.
         */
        if ($config->deprecatedNode) {
            $deprecatedNode = $config->deprecatedNode;
            $configOld = $this->_xml->global->{$groupType.'s'}->$deprecatedNode;
            if (isset($configOld->rewrite->$class)) {
                $className = (string) $configOld->rewrite->$class;
            }
        }
    }

    // Second - if entity is not rewritten then use class prefix to form class name
    if (empty($className)) {
        if (!empty($config)) {
            $className = $config->getClassName();
        }
        if (empty($className)) {
            $className = 'mage_'.$group.'_'.$groupType;
        }
        if (!empty($class)) {
            $className .= '_'.$class;
        }
        $className = uc_words($className);
    }

    $this->_classNameCache[$groupRootNode][$group][$class] = $className;
    return $className;
}

**this function task **

retrieve class name by class group
param   string $groupType currently supported helper
param   string $classId slash separated class identifier, ex. group/class
param   string $groupRootNode optional config path for group config
return  string

a)$classArr = explode('/', trim($classId));

result:explode helper name(sales/data by /) for getting classs name in array $classArr

b)$class = !empty($classArr[1]) ? $classArr[1] : null;

Result:as $classArr[1] is data then value of $class is data

c) $config = $this->_xml->global->{$groupType.'s'}->{$group};

details:get config setting then $config = $this->_xml->global->helpers->sales;

d)$className = null;

Details:set $className null.

e) check rewrite class exits in config.xml files, check if class is rewrite then you can easly get code: if (isset($config->rewrite->$class)) { result:if (isset($config->rewrite->data)) {

f)for default magento ,it false to goto else

skip if ($config->deprecatedNode) {

 as deprecatedNode is for model($grouptype) and ,it only used for _mysql4

g) if (empty($className)) {

result:

if sales helper not rewrite then if (empty($className)) { becomes true

h)if (!empty($config)) {

Result

:false

if (!empty($config)) {  becomes false;`

i) if (empty($className)) { Result:as $className is till null then this code is true

j) make class $className = 'mage_'.$group.'_'.$groupType;
result:

$group=sales
$groupTyp=helper
$className =  'mage_sales_helper';

k)

if (!empty($class)) {
                $className .= '_'.$class;
            }

result:

as $class = data the this condition  is true and $className =  'mage_sales_helper_data';

l)** make in upper case $className = uc_words($className); Now return class return $className; which is Mage_Sales_Helper_Data**

Thanks to

David Manners and Rajeev K Tomy

1
  • Eventhough I have analysed this whole thing through mind, it is more understandable and helpful when it seems as this detailed answer. a big thanks for Amit who spend a lot of time to prepare this answer for me and for the entire community. Respect :) Commented Aug 8, 2014 at 3:43

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.