如何覆盖模块中的功能?


8

首先,很抱歉,如果这个答案在其他地方有所涵盖。我已经做了很多搜索,只能找到有关覆盖主题功能和挂钩的信息。

我正在使用一个模块来为Drupal Commerce项目建立价格表。有一个格式化表格标题的函数:

/**
 * Helper function that takes care of the quantity displayed in the headers of 
 * the price table.
 */
function commerce_price_table_display_quantity_headers($item) {
  // Set the quantity text to unlimited if it's -1.
  $max_qty = $item['max_qty'] == -1 ? t('Unlimited') : $item['max_qty'];
  // If max and min qtys are the same, only show one.
  if ($item['min_qty'] == $max_qty) {
    $quantity_text = $item['min_qty'];
  }
  else {
    $quantity_text = $item['min_qty'] . ' - ' . $max_qty;
  }
  return $quantity_text;
}

如您所见,这不是主题函数,我可以在template.php中覆盖它,但可以调整一些输出。

显然,我不想编辑模块本身,以防将来被更新,那么,如何重新定义此功能,以便进行修改和更改?

到目前为止我的工作

到目前为止,我已经尝试将其创建为一个单独的模块,并进行了一些细微的更改以显示其是否正常工作,但是它并未覆盖任何输出。

信息文件

; $id$
name = Price Table: Tweaked Display
description = A different layout for the price table as shown on the product display nodes
package = Commerce (contrib)
core = 7.x

dependencies[] = commerce_product
dependencies[] = commerce_price
dependencies[] = commerce_price_table

模块文件

 /**
 * Override of the helper function that takes care of the quantity displayed in the headers of 
 * the price table.
 */
function commerce_table_tweak_display_quantity_headers($item) {
  // Set the quantity text to unlimited if it's -1.
  $max_qty = $item['max_qty'] == -1 ? t('Unlimited gnhh') : $item['max_qty'];
  // If max and min qtys are the same, only show one.
  if ($item['min_qty'] == $max_qty) {
    $quantity_text = $item['min_qty'];
  }
  else {
    $quantity_text = $item['min_qty'] . ' - this is working - ' . $max_qty;
  }
  return $quantity_text;
}

Answers:


12

这是Drupal ...总有一种方法,但是花费的时间可能会让您三思而后行:)

如果您可以更进一步地看食物链,您会发现此函数专用于commerce_price_table_field_formatter_view(),它声明了用于commerce_price_table字段类型的字段格式化程序。

考虑到这一点,您可以轻松地实现自己的字段格式化程序,将其分配给commerce_price_table字段类型,并根据需要使用尽可能多的自定义代码,始终与最佳实践保持一致。

基本上,您需要实现hook_field_formatter_info()

function MYMODULE_field_formatter_info() {
  return array(
    'MYMODULE_commerce_multiprice_default' => array(
      'label' => t('MyModule Price chart'),
      'field types' => array('commerce_price_table'),
      'settings' => array(
        'calculation' => FALSE,
        'price_label' => t('Price'),
        'quantity_label' => t('Quantity'),
        'table_orientation' => t('Orientation'),
      ),
    ),
  );
}

然后实现hook_field_formatter_view()field_formatter_settings_form()和(可选)hook_field_formatter_summary()

对于这些函数中的每一个,只需从contrib模块中的同一函数中获取代码,然后在需要的地方进行更改即可。


感谢您的好回答。我会仔细检查一下代码,看看这是否是星期五下午我能解决的工作!
user9359 2012年

@Clive,从Drupal开发的最佳实践的角度来看,您的回答是绝对正确的。但是,如果您只需要在某些函数中更改一个小字符串,则创建自定义格式器不是一种好方法。因为您编写的自定义代码越多-您添加的错误也越多。并且您建议user9359创建4个钩子,其中大多数钩子将从现有的商业模块中复制粘贴!!!我认为使用小补丁更适合这种情况。
尤金·菲德林

2
@Eugene是的,这确实是一个判断电话,在这种情况下,每个人可能对“适当的”有不同的定义。就我个人而言,我更喜欢使用long方法,因为它意味着我不必维护补丁文件,而且任何我喜欢的版本控制逻辑都不会受到这个流氓“更改”的模块文件的影响;但这只是我,如果您愿意维护补丁文件,那么与重新实现所有这些功能相比,这样做的工作量要少得多。这个答案肯定是按照“ 如何”(不一定是“ 为什么”)的思路进行的:
克莱夫(Clive)

再次克莱夫到毒害的耐受力
维沙尔

2

似乎您无法覆盖此功能,因为它不使用主题或挂钩工作流程。

唯一的方法-是直接更改commerce_price_table_display_quantity_headers()功能。然后用您的更改创建一个补丁

稍后,如果您更新Commerce模块-您将需要应用补丁。


是的,这就是我要避免的方法,但是快速浏览一下Clive的建议似乎确实很吸引人!
user9359'8

1

我认为Eugene的答案是正确的,如果不直接覆盖就无法做到。

但是,我发现有用的是,如果绝对有必要执行此操作,请将此模块从sites/all/modules/contrib目录移动到sites/all/modules/customdir,以便您可以了解并跟踪自定义更改的事实。


是的,感谢您的提示,我之前已经读过有关该内容
user9359 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.