官术网_书友最值得收藏!

Factory names and functions

Magento makes use of factory methods to instantiate models, helpers, and block classes. A factory method is a design pattern that allows us to instantiate an object without using the exact class name and using a class alias instead.

Magento implements the following factory methods:

  • Mage::getModel()
  • Mage::getResourceModel()
  • Mage::helper()
  • Mage::getSingleton()
  • Mage::getResourceSingleton()
  • Mage::getResourceHelper()

Each of these methods takes a class alias that is used to determine the real class name of the object that we are trying to instantiate. For example, if we want to instantiate a product object, we can do so by calling the getModel() method:

$product = Mage::getModel('catalog/product'); 

Notice that we are passing a factory name composed of group_classname/model_name. Magento will resolve this to the actual class name of Mage_Catalog_Model_Product. Let's take a closer look at the inner workings of getModel():

public static function getModel($modelClass = '', $arguments = array())
    {
        return self::getConfig()->getModelInstance($modelClass, $arguments);
    }

getModel calls the getModelInstance from the Mage_Core_Model_Config class.

public function getModelInstance($modelClass='', $constructArguments=array())
{
    $className = $this->getModelClassName($modelClass);
    if (class_exists($className)) {
        Varien_Profiler::start('CORE::create_object_of::'.$className);
        $obj = new $className($constructArguments);
        Varien_Profiler::stop('CORE::create_object_of::'.$className);
        return $obj;
    } else {
        return false;
    }
}

In return, getModelInstance() calls the getModelClassName() method that takes a class alias as a parameter. Then, it tries to validate the existence of the returned class, and if the class exists, it creates a new instance of that class and returns it to our getModel() method:

public function getModelClassName($modelClass)
{
    $modelClass = trim($modelClass);
    if (strpos($modelClass, '/')===false) {
        return $modelClass;
    }
    return $this->getGroupedClassName('model', $modelClass);
}

The getModelClassName() method calls the getGroupedClassName() method, which is actually in charge of returning the real class name of our model.

The getGroupedClassName() method takes two parameters, namely $groupType and $classId. The $groupType parameter refers to the type of object that we are trying to instantiate. Currently, only models, blocks, and helpers are supported. The $classId that we are trying to instantiate is as follows:

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};
    $className = null;
    if (isset($config->rewrite->$class)) {
        $className = (string)$config->rewrite->$class;
    } else {
        if ($config->deprecatedNode) {
            $deprecatedNode = $config->deprecatedNode;
            $configOld = $this->_xml->global->{$groupType.'s'}->$deprecatedNode;
            if (isset($configOld->rewrite->$class)) {
                $className = (string) $configOld->rewrite->$class;
            }
        }
    }
    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;
}

As we can see, getGroupedClassName() is actually doing all the work. It grabs our class alias catalog/product and creates an array by exploding the string on the slash character.

Then, it loads an instance of Varien_Simplexml_Element and passes the first value in our array (group_classname). It also checks if the class has been rewritten, and if it has, we will use the corresponding group name.

Magento also uses a custom version of the uc_words() function that will capitalize the first letters and convert separators of the class alias if needed.

Finally, the function will return the real class name to the getModelInstance() function. In our example case, this will return Mage_Catalog_Model_Product:

主站蜘蛛池模板: 东阳市| 永修县| 镇巴县| 焦作市| 西安市| 南投市| 郧西县| 遂宁市| 黄浦区| 通化县| 抚远县| 本溪市| 图们市| 长春市| 丰原市| 北流市| 莆田市| 根河市| 旬阳县| 成武县| 即墨市| 滦平县| 武威市| 仪征市| 甘南县| 延川县| 瓮安县| 九江市| 杂多县| 清流县| 吉隆县| 安阳县| 本溪| 冷水江市| 迁西县| 星子县| 黄山市| 永州市| 牡丹江市| 浪卡子县| 乌拉特中旗|