別のモジュールでのモジュールの機能のオーバーライド


7

Module1には、「function1」という名前の関数があります。「function1」はフックのタイプではありませんが、メニューコールバックであるか、フック内で呼び出されます。

Module2は、Module1内のfunction1で使用可能なすべての変数を使用して、「function1」をオーバーライドしようとしています。

を使用してfunction1を呼び出すことができmodule_load_include()ますが、呼び出された関数をオーバーライドする必要があります。

どうすればこれを達成できますか?


正しい答えを選択する必要があります
vishal

回答:


7

別のメニューコールバックを使用する場合は、hook_menu_alter()を実装してメニューコールバックを変更できます。Drupalがsearchに対して定義するメニューコールバックをオーバーライドする場合は、次のコードを使用できます。

function mymodule_menu_alter(&$items) {
  if (isset($items['search'])) {
    $items['search']['page callback'] = 'mymodule_search_view';
  }
}

mymodule_search_view()呼び出すことができますsearch_viewを()それは、メニューのコールバックを呼び出す前に、Drupalのから行われているように、まずそれを含むファイルを含めずに。

メニューコールバックがフォームを返す場合も同様のコードを実行できますが、ページコールバック(おそらくdrupal_get_form())を変更する代わりに、ページ引数を変更して、最初の引数としてコールバック名を使用します。フォーム配列を返す関数。これを行うのではなく、hook_form_alter()を実装し、不要なフォーム要素を$form['element']['#access'] = FALSE', and not withunset($ form ['element']) `で非表示にする必要があります。

フックから呼び出される関数の置き換えについては、その関数を呼び出すフックの実装を削除し、別の実装に置き換えることができます。これはDrupal 7でのみ可能であり、慎重に行う必要があります。(私はなぜ右説明します。)
あなたが呼び出された関数に変更したいとしましょう)(menu_node_updateを(の実装hook_node_update() )からmenu_node_save()mymodule_node_save()。次のコードを使用できます。

function mymodule_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'node_update') {
    $group = $implementations['mymodule'];
    unset($implementations['mymodule']);
    unset($implementations['menu']);

    $implementations = array('mymodule' => group) + $implementations;
  }
}

function mymodule_node_update($node) {
  mymodule_node_save();
}

このようにして、menu_node_update()もう呼び出されませんが、呼び出されますmymodule_node_update()

通常、別のモジュールによって実装されたフックに依存するモジュールは、そのフックが実行されているかどうかをチェックしません。彼らは、モジュールが有効になっている(そしてフックが呼び出されていると想定している)ことを確認するか、そのモジュールを依存関係として追加します。フックの実行を回避すると、他のモジュールに問題が発生し、追跡が困難になる可能性があります。別のモジュールによって実装されたフックが実行されるのを避けることが本当に必要な場合は、まずテストサイトですべてが期待どおりに機能していることを確認する必要があります。Drupalの将来のバージョンではコードが壊れる可能性があることに注意してください。作成しているコードは、Drupalの将来のバージョンでもテストする必要があります(可能な場合)。


2

あなたはmodule_invoke_allを試すべきです

モジュールを想定すると、コールバックは次のように変数$ outputを返します。

function module_a_callback($args){
$output =... your calculs ...
return $output;
}

これを追加:module_invoke_all( 'module_a_alter');

function module_a_callback($args){
$output = ... your calculs ...

// call all module implementing your 'module_a_alter' hook
$alter =  module_invoke_all('module_a_alter', $args);

//if there is an answer, 
$final_output = isset($alter[0]) ? $alter[0] : $output;
return $output;
}

これで、hook_module_a_alter($ args)フックが作成されました。モジュールBで、対応するフック実装を作成します

function module_b_module_a_alter($args){
 $output =... your calculs from module B ...
return $output;
}

ここで、参照渡しの変数を使用した、より高速な2つ目の方法:

 function module_a_callback($args){
 $output = ... your calculs ...

// call all module implementing your 'module_a_alter' hook
module_invoke_all('module_a_alter', $output,  $args);

return $output;
}

モジュールBで、対応するフック実装を作成します

function module_b_module_a_alter(&$output, $args){
 $output =... your calculs from module B ...
}

ミニチュットはこちらをご覧ください。フック呼び出しをリッスンするモジュールを指定できるmodule_invokeを使用することもできます。


1
Drupalの変更フックはdrupal_alter()で呼び出されます。OPがModule1を開発しなかったときに、質問が一般的なケースについて尋ねられると思います。OPがModule1を開発した場合、そのモジュールからの変更フックをサポートすることをお勧めします。
kiamlaluno

0

これはDrupal自体よりもphp言語の問題です...

デフォルトでは、phpで関数を再定義することはできません。あなたはそれを可能にするrunkit拡張機能を使用することを試みることができますが、私が知る限り、運用サーバーでのrunkitの使用はかなり重くなる可能性があるためお勧めしません。

別のモジュールの機能を絶対に変更する必要がある場合は、適切に保守されたパッチがおそらくより適切です。

Drupal 8では、OOコア(もちろん、これは本当に素晴らしい)にフォーカスが移っているので、この種の問題ははるかに少なくなるはずですが、今のところ、これらの種類の状況の回避策に悩まされています。


OPは、メニューコールバック、またはフックから呼び出される関数を置き換える方法を尋ねています。どちらのケースもPHP言語の問題ではありません。
kiamlaluno

@kiam私も最初はそう思っていましたが、OPによるとフックの一種ではありませんが、メニューコールバックであるか、フック内で呼び出されます。 hook_menu_alter()メニューのコールバックは問題ありませんが、フック内で呼び出されるランダム関数の場合、呼び出された関数を変更するためにフックの実装をオーバーライドする必要があります(おなじみのように聞こえます;))...または既存の関数を別の関数に置き換えると、言語問題のIMOの詳細まで。誤解しているかもしれませんが、コード例がないと作業が難しい
Clive

1
質問が特定のケースを尋ねた場合の方が良かった。そのように、私たちは抽象的な推論をしません。
kiamlaluno

-2

この関数の出力を別の関数で上書きしてみてください。両方とも他のフックで出会います(関数はフック内で呼び出されていると述べたように)。


1
反対投票はしませんでしたが、この回答は役に立ちません。「この関数の出力を別の関数で上書きする」とはどういう意味ですか?フックがを呼び出している場合、代わりにfunction1()どのように呼び出しfunction2()ますか?
kiamlaluno

最初の関数の後に実行される関数内に追加のフックを適用することによって。
Ashish

OPとは、別のモジュールから実装されたフックから呼び出される関数のことです。そのフックから呼び出された関数を別の関数に置き換えたいと考えています。
kiamlaluno
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.