在为 Joomla 1.5.26 修复 Virtuemart 1.1.9 的 Flex2 运输模块中的错误时出现 PHP 范围问题
Posted
技术标签:
【中文标题】在为 Joomla 1.5.26 修复 Virtuemart 1.1.9 的 Flex2 运输模块中的错误时出现 PHP 范围问题【英文标题】:PHP scope issue while fixing error in the Flex2 shipping module of Virtuemart 1.1.9 for Joomla 1.5.26 【发布时间】:2012-08-15 00:40:45 【问题描述】:背景
当前免费的 Flex2 运费模块存在一个错误,导致运费金额的税金计算不正确。该错误导致所有计算中都使用国内税率,即使货物是国际的。另外,我正在尝试扩展模块的功能。
在目前的形式下,Flex2 允许为国内和国际销售单独设置运费。但是,税率可能仅为每个变体的特定值(即国内的一种税率,国际的一种税率)。
我的祖国(加拿大)要求在国内市场适用不同的税率,具体取决于我要运送到哪个省份。我敢肯定还有其他国家/司法管辖区有类似的要求。我已经能够成功更改管理屏幕以允许设置一个指标,该指标允许基于 VirtueMart TAX_MODE 值的可变税率(根据商店位置、买家位置或欧盟区域选择不同的税率) )。
问题 - 在没有参数的情况下将信息从“A”类传递到“B”类
结帐时出现问题。 VirtueMart 的结账模块包含在文件 ps_checkout.php 中。函数“calc_order_shipping”以如下代码sn-p开头:
function calc_order_shipping( &$d )
$auth = $_SESSION['auth'];
$shipping_total = $this->_SHIPPING->get_rate( $d );
$shipping_taxrate = $this->_SHIPPING->get_tax_rate();
这是“核心”VirtueMart系统的一部分,所以我不想修改它。
第一个函数调用从数组“$d”中提取运费总额(即结帐流程开始时执行的税款计算的结果)。第二行旨在检索用于进行此计算的税率。所有运输模块的当前实现是返回静态税率。正如你所看到的,数组“$d”没有被传递给第二个函数,所以我没有足够的信息来确定客户是国外还是国内(这个信息可以从送货地址信息中得出,即$d 数组的一部分)。
不幸的是,在我要求 Flex2 可变税率之前,每个国内/国际区域只允许一个税率 - 这是在配置运输模块期间手动设置的。因此,价值“改变”是不可能的。可以(过去)从运输模块的静态配置文件中简单地提取税率。但是,对于我新需要的功能,我可能需要在结帐期间更改税率(基于购物者可能选择默认地址以外的送货地址的可能性)。
“B类”详情
这两个函数都驻留在同一个源代码文件中:flex2.php,在类 flex2 中。
为了完整起见,这里是这两个函数的代码:
function get_rate( &$d )
$shipping_rate_id = $d["shipping_rate_id"];
$is_arr = explode("|", urldecode(urldecode($shipping_rate_id)) );
$order_shipping = (float)$is_arr[3];
return $order_shipping;
function get_tax_rate()
/** Read current Configuration ***/
require_once(CLASSPATH ."shipping/".__CLASS__.".cfg.php");
if( intval(FLEX2_TAX_CLASS)== 0 )
return( 0 );
else
require_once( CLASSPATH. "ps_tax.php" );
$tax_rate = ps_tax::get_taxrate_by_id( intval(FLEX2_TAX_CLASS) );
return $tax_rate;
Flex2 中的“bug”(不是本题的主题)在于参数“FLEX2_TAX_CLASS”仅与国内运输相关。国际运输的相应参数“FLEX2_TAX_CLASS_I”未在任何地方引用。为了确定是使用国内版本还是国际版本的变量,我必须检查存储在 $d 数组中的送货地址。
要克服的挑战 - 也就是这篇文章的原因
所以,这是我的问题...
有没有什么方法可以定义对 $d 的引用,该引用具有相对于类的全局范围;然后修改“get_rate”函数,以便将其 $d 输入数组的副本存储在这个类范围的引用变量中,以便可以在“get_tax_rate”函数中引用?如果可能的话,定义类范围变量、将 &$d 的值分配给该变量的正确语法是什么,以及从“get_tax_rate”函数访问新创建的变量的正确语法是什么?
我之前研究过一些关于 PHP 变量作用域的通用问题,并找到了一些似乎是正确的答案,但我不敢在没有得到更具体建议的情况下尝试它们,因为我找到了答案没有解决函数“x”从不同类中的函数接收变量“通过引用”的特定要求,并创建一种允许函数“y”也检索(和更新)的方式通过引用来自同一数组的信息。
这是我在这个论坛上的第一个问题,我想尽可能具体地提出我的要求。感谢您的帮助。
附:一旦我解决了这个问题,我将把“增强的”Flex2 运输模块作为非商业附件提交给 Joomla/Virtuemart 社区。我希望 Flex2 组件的原作者能够继续支持它,因为我对 PHP 的了解并没有达到应有的水平。
【问题讨论】:
【参考方案1】:我还没有找到所提出的技术问题的答案,但我发现了解决业务问题的可行解决方法。
VirtueMart 中的 php_checkout 模块执行许多函数,其中一些(如上面的两个函数)调用来自不同类的函数。
我在 php_checkout.php 文件中发现了一个代码 sn-p,它显示了一些承诺。如下图供参考:
// Export the order_id so the checkout complete page can get it
$d["order_id"] = $order_id;
/*
* Let the shipping module know which shipping method
* was selected. This way it can save any information
* it might need later to print a shipping label.
*/
if( is_callable( array($this->_SHIPPING, 'save_rate_info') ))
$this->_SHIPPING->save_rate_info($d);
显然,ps_checkout.php 可能包含对运输模块中函数“save_rate_info”的调用。目前,“flex2.php”文件中不存在此代码。但是,如果要添加它,我将有机会使用我想要传递给结帐模块的信息来更新“$d”数组,而无需直接在“get_tax_rate”函数中进行。
我仍然希望收到我最初提出的技术问题的答案,但我希望这项解决办法可以帮助那些在将可变税率应用于运费方面遇到类似问题的人。
【讨论】:
以上是关于在为 Joomla 1.5.26 修复 Virtuemart 1.1.9 的 Flex2 运输模块中的错误时出现 PHP 范围问题的主要内容,如果未能解决你的问题,请参考以下文章
Joomla、Falang 集成组件...致命错误:在 null 上调用成员函数 getTable()