Как переопределить функцию из модуля?

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;
}
user9359
источник

Ответы:

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
@Clive, вы отвечаете абсолютно правильно с точки зрения лучшей практики разработки Drupal. Но в случае, когда вам нужно изменить только одну небольшую строку в какой-то функции - это не очень хороший подход для создания пользовательского форматера. Потому что чем больше пользовательского кода вы пишете, тем больше ошибок вы добавляете. И вы предлагаете user9359 создать 4 хука, большинство из которых будут скопированы из существующего коммерческого модуля !!! Я думаю, что использование небольшого патча гораздо более подходит для этой ситуации.
Евгений Фиделин
2
@ Евгений Да, это действительно суждение, у каждого человека, вероятно, будет другое определение «уместно» в этой ситуации. Лично я предпочитаю метод long, так как он означает, что мне не нужно поддерживать файлы исправлений, и любая причудливая логика управления версиями, которая у меня есть, не будет затронута этим мошенническим «измененным» файлом модуля; но это только я, если вам удобно поддерживать патч-файлы, вам потребуется гораздо меньше усилий, чем заново реализовать всю эту функциональность. Этот ответ определенно соответствовал тому, как , а не обязательно почему :)
Клайв
снова сойти с дороги
Вишал
2

Кажется, вы не можете переопределить эту функцию, потому что она не использует тему или рабочий процесс подключения.

Единственный способ - это напрямую изменить commerce_price_table_display_quantity_headers()функцию. Затем создайте патч с вашими изменениями.

Позже, если вы обновите модуль Commerce - вам нужно будет применить ваш патч.

Евгений Фиделин
источник
Да, это то, чего я пытался избежать, но это кажется заманчивым после быстрого взгляда на предложение Клайва!
user9359
1

Я думаю, что ответ Евгения правильный, что вы не можете сделать это без перезаписи напрямую.

Однако, что я нашел полезным, так это то, что, если это абсолютно необходимо, переместите этот модуль из своего sites/all/modules/contribкаталога в каталог, sites/all/modules/customчтобы вы могли быть в курсе и отслеживать тот факт, что вы сделали пользовательские изменения.

nedwardss
источник
Да, спасибо за совет, я бы прочитал об этом раньше
user9359