Jak ponownie uruchomić hook_post_update_NAME ()

11

Wprowadzonohook_post_update_NAME() Drupal 8, który ma pewne zalety whook_update_n zakresie aktualizacji modułów.

Każdy hook_post_update_NAME()powinien uruchomić się tylko raz, ale czasami chcę go ponownie uruchomić, na przykład podczas debugowania haka aktualizacji podczas programowania. Za pomocą hook_update_nmożesz zresetować wersję schematu w bazie danych .

Jak się ponownie uruchamiasz hook_post_update_NAME()?

bryanbraun
źródło

Odpowiedzi:

11

Haki „post_update”, które zostały uruchomione, są przechowywane w bazie danych, w key_valuetabeli, w post_updatekolekcji, ale dane są serializowane i niewygodne do bezpośredniej aktualizacji.

Użyłem niektórych szczegółów z odpowiedzi @ kiamlaluno, aby utworzyć skrypt drush, którego można użyć do zresetowania pojedynczego haka. Oto podstawowa wersja ( jest tutaj dłuższa wersja ):

#!/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");
}

A oto przykład tego, jak to wygląda po uruchomieniu go z wiersza poleceń:

./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
źródło
3
czy myślałeś o tym, aby wesprzeć to drush, github.com/drush-ops/drush ?
powpow12
1
Jest to całkiem słodka funkcja, ale jest nieco zbyt niszowa dla podstawowego Drusha. Być może ktoś utworzy do tego plik poleceń.
moshe weitzman
3

Oto przykład, którego możesz użyć z wiersza poleceń z drush php-eval:

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);'

Po ponownym uruchomieniu drush updatedb zobaczysz swój post_update_hook czekający na uruchomienie.

Jason Yarrington
źródło
Działa to dla mnie dobrze, żeby wspomnieć, że w Drush 9 to jestdrush php:eval 'command'
powpow12
Bardzo przydatne, jeśli w środowisku tylko do odczytu. Wielkie dzięki;)
Mirsoft
1

UpdateRegistry::getPendingUpdateFunctions()zawiera następujący kod. Zobacz, co mówi komentarz.

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

UpdateRegistry :: $ updateType jest ustawiony na 'post_update'.
$this->keyValuejest ustawiany UpdateRegistryFactory::create()za pomocą wartości $this->container->get('keyvalue')->get('post_update').

Równoważny kod proceduralny umożliwiający pobranie tej kolekcji wartości klucza jest następujący.

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

Ustaw istniejącą aktualizację na pustą tablicę, a Drupal pomyśli, że nie wywołano żadnego wywołania zwrotnego po aktualizacji.

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

Usuń nazwę wywołania zwrotnego z istniejącego klucza aktualizacji tej wartości klucza, a Drupal pomyśli, że wywołanie zwrotne po aktualizacji nie zostało jeszcze wywołane.

kiamlaluno
źródło
0

Zadzwoń od wewnątrz, hook_update_n()a następnie zrób to, co robiłeś wcześniej.

nvahalik
źródło
1
Nie wydaje się to dobrym pomysłem, ponieważ głównym celem mechanizmu hook_post_update jest zapewnienie w pełni funkcjonalnego Drupala dostępnego po uruchomieniu wszystkich aktualizacji. Zostało wprowadzone, ponieważ nie ma żadnych gwarancji dotyczących stanu Drupala podczas aktualizacji.
Eelke Blok