去年,我们为用户开发了一些定制的EPR系统。客户的文件中指出他们需要运行一些在config.xml中定义的方法,在出口订单的时候用方法代码作为ID。很快,根据订单的付款代码他们想在出口订单时添加一些自定义计算。如果你对我们如何实现的感兴趣,那么继续阅读吧。 举例会让解释变得简单。首先创建我们的config.xml,最后我们将让Magento呼应我们的模块。 Step 1: Creating module’s configuration(创建模型配置)这里只是个简单的示例代码,你可以用它创建app/code/local/Alwayly/XmlMethodCall/etc/config.xml < ?xml version="1.0"?> <config> <modules> <alwayly_xmlmethodcall> <version>1.0.0.0</version> </alwayly_xmlmethodcall> </modules> <global> <xml_method_call> <payment_checkmo> <name>Check / Money order </name> <code>checkmo</code> <add> <model>alwayly_xmlmethodcall/checkmoAddVal</model> <method>addValue</method> </add> <return> <model>alwayly_xmlmethodcall/checkmoGetCod</model> <method>getCode</method> </return> </payment_checkmo> </xml_method_call> <xml_method_call> <payment_ccsave> <name>Credit Card (saved) </name> <code>ccsave</code> <add> <model>alwayly_xmlmethodcall/ccsaveAddVal</model> <method>addValue</method> </add> <return> <model>alwayly_xmlmethodcall/ccsaveGetCod</model> <method>getCode</method> </return> </payment_ccsave> </xml_method_call> <models> <alwayly_xmlmethodcall> <class>Alwayly_XmlMethodCall_Model</class> <resourcemodel>alwayly_xmlmethodcall_mysql4</resourcemodel> </alwayly_xmlmethodcall> </models> </global> <frontend> <routers> <alwayly_xmlmethodcall> <use>standard</use> <args> <module>Alwayly_XmlMethodCall</module> <frontname>xmlmethodcall</frontname> </args> </alwayly_xmlmethodcall> </routers> </frontend> </config> 深入研究下xml_method_call结点和全球结点的第一子节点。你会看到两兄弟有同样的名字, xml_method_call结点。 让我们描述下下一个xml块: <payment_checkmo> <name>Check / Money order </name> <code>checkmo</code> <add> <model>alwayly_xmlmethodcall/checkmoAddVal</model> <method>addValue</method> </add> <return> <model>alwayly_xmlmethodcall/checkmoGetCod</model> <method>getCode</method> </return> </payment_checkmo>
现在我希望你对我们需要怎么实现有一个清晰的认识。在订单出口的时候我们调用一些方法做计算并返回结果。要求是方法需要是可配置的,这样非开发人员可以通过配置文件来改变它们。当然,你可以在system.xml中做到这点。 Step 2: Creating module’s models, described in config.xml(创建模块的模型,在config.xml中写描述)Create files:
分别添加下面的代码到对应的文件中: < ?php /** * */ class Alwayly_XmlMethodCall_Model_CheckmoAddVal extends Mage_Core_Model_Abstract { public function addValue() { return 1; } } < ?php /** * */ class Alwayly_XmlMethodCall_Model_CheckmoGetCod extends Mage_Core_Model_Abstract { public function getCode() { return 'a'; } } < ?php /** */ class Alwayly_XmlMethodCall_Model_CcsaveAddVal extends Mage_Core_Model_Abstract { public function addValue() { return 2; } } < ?php /** * */ class Alwayly_XmlMethodCall_Model_CcsaveGetCod extends Mage_Core_Model_Abstract { public function getCode() { return 'b'; } } 因为是一个简单的教学示例,我们将只创建控制器并在里面的几个列数组里的订单。 Step 3: Creating controller(创建控制器)< ?php /** * */ class Alwayly_XmlMethodCall_IndexController extends Mage_Core_Controller_Front_Action { public function indexAction() { $orders = array(); $orders[] = array ( 'order_no' => 101, 'method' => 'checkmo', 'amount' => 99 ); $orders[] = array ( 'order_no' => 102, 'method' => 'ccsave', 'amount' => 100 ); $orders[] = array ( 'order_no' => 101, 'method' => 'checkmo', 'amount' => 199 ); foreach ($orders as $row) { $orderNo = $row['order_no']; $conf = Mage::getSingleton('core/config')->init() ->getXpath('global/xml_method_call//code[.="' . $row['method'] . '"]/..'); if ($conf) { $conf = new Varien_Object(current($conf)->asArray()); $add = new Varien_Object($conf->getAdd()); $code = new Varien_Object($conf->getReturn()); if (method_exists(Mage::getModel($add->getModel()), $add->getMethod())) { $amountValue = $row['amount'] + Mage::getModel($add->getModel())->{$add->getMethod()}(); } if (method_exists(Mage::getModel($code->getModel()), $code->getMethod())) { $codeValue = Mage::getModel($code->getModel())->{$code->getMethod()}(); } } else { //throw an error die("or exit... or something goes wrong..."); } echo "<pre>" . PHP_EOL; echo 'ID: ' . $orderNo . PHP_EOL; echo 'VALUE: ' . $amountValue . PHP_EOL; echo 'CODE: ' . $codeValue . PHP_EOL; } print_r($orders); } } 首先,我们创建了包含一些$orders里数据的订单集合。这可能是一个真实的集合,但是现在为了简化,我决定用个简单的二维数组。 下一个重要的部分是: $conf = Mage::getSingleton('core/config')->init()->getXpath('global/xml_method_call//code[.="' . $row['method'] . '"]/..'); 如你所见,我们调用code/config模型里的XPath。如果你不知道this ->getXpath(‘global/xml_method_call//code[.=”‘ . $row[‘method’] . ‘”]/..’)的意思,那么你可以去w3schools/XPath学些新东西。 我们将要实例化$conf对象,把xml_method_call作为根节点。我们不知道哪一个是它,但我们知道方法的代码并可以在config.xml搜索它。 "//"意味着同一级别。比temp结点深,确认你所能找到的所有结点然后挑选出含有你所需值的那个。 "/.."意味着返回当前位置的上一级结点,获取你想要的xml_method_call结点。这样所有事情就变得简单了。 下一个有趣的部分是: $conf = new Varien_Object(current($conf)->asArray()); $add = new Varien_Object($conf->getAdd()); $code = new Varien_Object($conf->getReturn()); 设置我们的$conf, $add和$code作为Varien_Object实例(我们将有自己的getter和setter)。 最后确认我们的方法是否存在。如果存在就在显示器上打印出结果。 那么让Magento配置对象呼应我们的模块,接着访问我们的控制器。 Step 4: Magento, we are here!(Magento,我们在这儿!)用下面的代码创建文件app/etc/modules/Alwayly_Xmlmethodcall.xml <?xml version="1.0"?> <config> <modules> <Alwayly_XmlMethodCall> <active>true</active> <codePool>local</codePool> </Alwayly_XmlMethodCall> </modules> </config> Step 5: Visit something like: http://magento1510.loc/index.php/xmlmethodcall(访问类似http://magento1510.loc/index.php/xmlmethodcall的地址)你会看到类似这样的结果: ID: 101 VALUE: 100 CODE: a ID: 102 VALUE: 102 CODE: b ID: 101 VALUE: 200 CODE: a Array ( [0] => Array ( [order_no] => 101 [method] => checkmo [amount] => 99 ) [1] => Array ( [order_no] => 102 [method] => ccsave [amount] => 100 ) [2] => Array ( [order_no] => 101 [method] => checkmo [amount] => 199 ) ) 我希望你们中的一些人能看到如何使用Varien_Object以及使用XPath表达式会让事情变得多么有趣。 (责任编辑:好模板) |