使用xpath和varien_object运行模块xml文件中指定的方法

redmaomail 2024-07-24 18:12 阅读数 64 #Magento

红帽云邮外贸主机

去年,我们为用户开发了一些定制的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>
  • payment_checkmo 包含一些数据的唯一结点
  • name 这个唯一结点的名字,与代码无关
  • code 支付方式的代码(id)
  • add,return 两种方法定义他们应该调用的东西(模块/模型和方法调用的定义)

现在我希望你对我们需要怎么实现有一个清晰的认识。在订单出口的时候我们调用一些方法做计算并返回结果。要求是方法需要是可配置的,这样非开发人员可以通过配置文件来改变它们。当然,你可以在system.xml中做到这点。

Step 2: Creating module’s models, described in config.xml(创建模块的模型,在config.xml中写描述)

Create files:

  • – app/code/local/Alwayly/XmlMethodCall/Model/CheckmoAddVal.php
  • – app/code/local/Alwayly/XmlMethodCall/Model/CheckmoGetCod.php
  • – app/code/local/Alwayly/XmlMethodCall/Model/CcsaveAddVal.php
  • – app/code/local/Alwayly/XmlMethodCall/Model/CcsaveGetCod.php

分别添加下面的代码到对应的文件中:

< ?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表达式会让事情变得多么有趣。

电商网站开发服务


红帽云邮外贸主机

分享到:
版权声明:本站内容源自互联网,如有内容侵犯了你的权益,请联系删除相关内容。
    红帽云邮外贸主机
热门
    红帽云邮外贸主机
    红帽云邮外贸主机