Überschreiben der Funktion eines Moduls in einem anderen Modul

7

Modul1 hat eine Funktion namens 'function1'. 'function1' ist keine Art von Hook, aber es ist ein Menü-Rückruf oder wird innerhalb eines Hooks aufgerufen.

Modul2 möchte 'Funktion1' mit allen Variablen überschreiben, die für Funktion1 in Modul1 verfügbar sind.

Ich kann function1 mit aufrufen module_load_include(), muss aber die aufgerufene Funktion überschreiben.

Wie kann ich das erreichen?

navneet
quelle
Sie sollten die richtige Antwort wählen
Vishal

Antworten:

7

Wenn Sie einen anderen Menü-Rückruf verwenden möchten, können Sie hook_menu_alter () implementieren , um den Menü-Rückruf zu ändern. Angenommen, Sie möchten den Menü-Rückruf überschreiben, den Drupal für die Suche definiert , und Sie könnten den folgenden Code verwenden.

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

Von können mymodule_search_view()Sie search_view () aufrufen, ohne zuerst die Datei einzuschließen, die es enthält, wie dies von Drupal aus erfolgt, bevor Sie den Menü-Rückruf aufrufen.

Ein ähnlicher Code könnte ausgeführt werden, wenn der Menü-Rückruf ein Formular zurückgibt , mit der Ausnahme, dass Sie anstelle des Seitenrückrufs ( wahrscheinlich drupal_get_form () ) die Seitenargumente ändern würden, um als erstes Argument den Rückrufnamen des zu verwenden Funktion, die das Formulararray zurückgibt. Anstatt dies zu tun, sollten Sie hook_form_alter () implementieren und die nicht erforderlichen Formularelemente mit $form['element']['#access'] = FALSE', and not withunset ($ form ['element']) ` ausblenden .

Zum Ersetzen einer Funktion, die von einem Hook aufgerufen wird, können Sie die Hook-Implementierung entfernen, die diese Funktion aufruft, und sie durch eine andere Implementierung ersetzen. Dies ist nur mit Drupal 7 möglich und muss sorgfältig durchgeführt werden. (Ich werde erklären, warum richtig.)
Angenommen, Sie möchten die in menu_node_update () (die Implementierung von hook_node_update () ) aufgerufene Funktion von menu_node_save () in ändernmymodule_node_save() . Sie können den folgenden Code verwenden.

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();
}

Auf diese Weise menu_node_update()würde nicht mehr aufgerufen, sondern mymodule_node_update()würde.

Normalerweise prüfen Module, die von einem von einem anderen Modul implementierten Hook abhängen, nicht, ob dieser Hook ausgeführt wird. Sie überprüfen, ob das Modul aktiviert ist (und nehmen an, dass der Hook aufgerufen wird), oder sie fügen dieses Modul als ihre Abhängigkeit hinzu. Das Vermeiden eines Hooks kann zu Problemen mit anderen Modulen führen, die möglicherweise schwer zu verfolgen sind. Wenn es wirklich notwendig ist, zu vermeiden, dass ein von einem anderen Modul implementierter Hook ausgeführt wird, sollten Sie zuerst auf einer Test-Site überprüfen, ob alles wie erwartet funktioniert. Denken Sie daran, dass die zukünftige Drupal-Version Ihren Code beschädigen kann und der Code, den Sie schreiben, auch auf der zukünftigen Drupal-Version getestet werden sollte (sofern verfügbar).

kiamlaluno
quelle
2

Sie sollten ein module_invoke_all ausprobieren

Angenommen, Ihr Modul Ein Rückruf gibt die Variable $ output wie folgt zurück:

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

Fügen Sie Folgendes hinzu: 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;
}

Sie haben gerade den Hook hook_module_a_alter ($ args) erstellt. Erstellen Sie in Ihrem Modul B die entsprechende Hook-Implementierung

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

Hier eine zweite Methode, schneller, unter Verwendung von Variablen, die als Referenz übergeben werden:

 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;
}

Erstellen Sie in Ihrem Modul B die entsprechende Hook-Implementierung

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

Schauen Sie sich das für ein Mini-Tuto an. Sie können auch ein module_invoke verwenden, mit dem Sie das Modul angeben können, das Ihren Hook-Aufruf abhört.

Bobylapointe
quelle
1
Drupal Alter Hooks werden mit drupal_alter () aufgerufen . Ich gehe davon aus, dass die Frage für den allgemeinen Fall gestellt wird, als das OP Modul1 nicht entwickelt hat. Wenn das OP Modul1 entwickelt hat, ist es besser, einen Alter Hook von diesem Modul zu unterstützen.
Kiamlaluno
0

Dies ist eher ein Problem mit der PHP-Sprache als mit Drupal an sich ....

Sie können eine Funktion in PHP nicht standardmäßig neu definieren. Sie könnten versuchen, die Runkit-Erweiterung zu verwenden, mit der Sie dies tun können, aber meines Wissens wird die Verwendung von Runkit auf Produktionsservern nicht empfohlen, da es ziemlich schwer werden kann.

In den Fällen, in denen Sie unbedingt die Funktionalität eines anderen Moduls ändern müssen, ist ein gut gewarteter Patch wahrscheinlich besser geeignet.

In Drupal 8 sollte diese Art weitaus weniger problematisch sein, da sich der Fokus viel mehr auf einen OO-Kern verlagert (was natürlich absolut fantastisch ist), aber im Moment bleiben wir bei Problemumgehungen für diese Art von Situationen.

Clive
quelle
Das OP fragt, wie ein Menü-Rückruf oder eine Funktion, die von einem Hook aufgerufen wird, ersetzt werden soll. In beiden Fällen handelt es sich nicht um Probleme mit der PHP-Sprache.
Kiamlaluno
@kiam Ich dachte das zuerst auch, aber das OP sagt, es sei keine Art von Hook, sondern ein Menü-Rückruf oder ein Aufruf innerhalb eines Hooks. hook_menu_alter()wäre in Ordnung für den Menü-Rückruf, aber für eine zufällige Funktion, die innerhalb eines Hooks aufgerufen wird, müssten Sie die Hook-Implementierung überschreiben, um die aufgerufene Funktion zu ändern (kommt mir bekannt vor;)) ... oder die vorhandene Funktion durch eine andere ersetzen, die kommen würde bis eher zu einem Sprachproblem IMO. Ich könnte jedoch falsch verstanden haben, es ist ziemlich schwierig, ohne ein Codebeispiel zu arbeiten
Clive
1
Es war besser, wenn die Frage nach einem bestimmten Fall gestellt wurde; auf diese Weise würden wir keine abstrakte Argumentation machen.
Kiamlaluno
-2

Versuchen Sie, diese Funktion die Ausgabe überschrieben durch eine andere Funktion, wo sie beide treffen sich in jedem anderen Haken (wie Sie die Funktion erwähnt wird in einem Haken genannt wird).

Ashish
quelle
1
Ich habe nicht nach unten Abstimmung, aber diese Antwort ist nicht hilfreich. Was meinst du mit „zwingender Ausgabe der diese Funktion durch eine andere Funktion“? Wenn der Haken ruft function1(), wie machen Sie es nennen , function2()statt?
kiamlaluno
durch zusätzliche Haken in Ihrer Funktion , die ausgeführt werden, nachdem ersten.
Das OP spricht von einer Funktion, die von einem Hook aufgerufen wird, der von einem anderen Modul implementiert wurde. Er möchte die von diesem Hook aufgerufene Funktion durch eine andere ersetzen.
Kiamlaluno