So führen Sie hook_post_update_NAME () erneut aus

11

Drupal 8 wurde eingeführthook_post_update_NAME() und bietet einige Vorteilehook_update_n für die Aktualisierung von Modulen.

Jedes hook_post_update_NAME()sollte nur einmal ausgeführt werden, aber manchmal möchte ich es erneut ausführen, beispielsweise wenn ich den Update-Hook während der Entwicklung debugge. Mit hook_update_nkönnen Sie die Schemaversion in der Datenbank zurücksetzen .

Wie rennst du noch einmal hook_post_update_NAME()?

Bryanbraun
quelle

Antworten:

11

Ausgeführte "post_update" -Hooks werden in der Datenbank, in der key_valueTabelle und in der post_updateSammlung gespeichert , aber die Daten sind serialisiert und können nur schwer direkt aktualisiert werden.

Ich habe einige Details aus der Antwort von @ kiamlaluno verwendet, um ein Drush-Skript zu erstellen, mit dem Sie einen einzelnen Hook zurücksetzen können. Hier ist eine Basisversion ( längere Version ist hier ):

#!/usr/bin/env drush

$key_value = \Drupal::keyValue('post_update');
$update_list = $key_value->get('existing_updates');

$choice = drush_choice($update_list, dt('Which post_update hook do you want to reset?'));

if ($choice) {
  $removed_el = $update_list[$choice];
  unset($update_list[$choice]);
  $key_value->set('existing_updates', $update_list);
  drush_print("$removed_el was reset");
} else {
  drush_print("Reset was cancelled");
}

Und hier ist ein Beispiel dafür, wie es aussieht, wenn Sie es über die Befehlszeile ausführen:

./scripts/reset_hook_post_update_NAME.drush

Which post_update hook do you want to reset?
 [0]   :  Cancel
 [1]   :  system_post_update_add_region_to_entity_displays
 [2]   :  system_post_update_hashes_clear_cache
 [3]   :  system_post_update_recalculate_configuration_entity_dependencies
 [4]   :  system_post_update_timestamp_plugins
 [5]   :  my_module_post_update_example_hook

# The script pauses for user input. 
5 

my_module_post_update_example_hook was reset
Bryanbraun
quelle
3
Haben Sie darüber nachgedacht, dies wieder zu drush beizutragen, github.com/drush-ops/drush ?
powpow12
1
Dies ist ein ziemlich süßes Feature, aber es ist ein bisschen zu nisch für Core Drush. Vielleicht macht jemand eine Befehlsdatei dafür.
Moshe Weitzman
2

Hier ist ein Beispiel, das Sie über die Befehlszeile mit drush php-eval verwenden können:

drush php-eval -e '$update_hook_name = "<my_hook_post_update_name>";
$key_value = \Drupal::keyValue('post_update');
$existing_updates = $key_value->get('existing_updates');
$index = array_search($update_hook_name,$existing_updates); 
unset($existing_updates[$index]);
$key_value->set('existing_updates', $existing_updates);'

Wenn Sie drush updatedb erneut ausführen, wird Ihr post_update_hook darauf warten, ausgeführt zu werden.

Jason Yarrington
quelle
Dies funktionierte gut für mich, nur um zu erwähnen, dass es in Drush 9 istdrush php:eval 'command'
powpow12
Sehr nützlich, wenn in einer schreibgeschützten Umgebung. Vielen Dank;)
Mirsoft
1

UpdateRegistry::getPendingUpdateFunctions()enthält den folgenden Code. Sehen Sie, was der Kommentar sagt.

  // First figure out which hook_{$this->updateType}_NAME got executed
  // already.
  $existing_update_functions = $this->keyValue->get('existing_updates', []);

UpdateRegistry :: $ updateType ist auf gesetzt 'post_update'.
$this->keyValuewird UpdateRegistryFactory::create()mit dem Wert von gesetzt $this->container->get('keyvalue')->get('post_update').

Der entsprechende Prozedurcode zum Abrufen dieser Schlüsselwertauflistung ist der folgende.

$key_value = \Drupal::keyValue('post_update');

Setzen Sie vorhandene_Updates auf ein leeres Array, und Drupal glaubt, dass keiner der Rückrufe nach der Aktualisierung aufgerufen wurde.

$key_value = \Drupal::keyValue('post_update');
$key_value->set('existing_updates', []);

Entfernen Sie den Rückrufnamen aus dem vorhandenen_updates- Schlüssel dieses Schlüsselwerts, und Drupal wird annehmen, dass der Rückruf nach der Aktualisierung noch nicht aufgerufen wurde.

kiamlaluno
quelle
0

Rufen Sie es von innen an hook_update_n()und tun Sie dann, was Sie zuvor getan haben.

nvahalik
quelle
1
Das scheint keine gute Idee zu sein, da der gesamte Zweck des Hook_post_update-Mechanismus darin besteht, ein voll funktionsfähiges Drupal zur Verfügung zu haben, nachdem alle Updates ausgeführt wurden. Es wurde eingeführt, da es keine Garantien für den Status von Drupal während Updates gibt.
Eelke Blok