Comment réexécuter hook_post_update_NAME ()

11

Drupal 8 introduit,hook_post_update_NAME() ce qui présente certains avantages par rapporthook_update_n à la mise à jour des modules.

Chacun hook_post_update_NAME()ne doit s'exécuter qu'une seule fois, mais parfois je veux le réexécuter, comme lorsque je débogue le crochet de mise à jour pendant le développement. Avec hook_update_n, vous pouvez réinitialiser la version du schéma dans la base de données .

Comment relancez-vous hook_post_update_NAME()?

bryanbraun
la source

Réponses:

11

Les hooks "post_update" qui ont été exécutés sont stockés dans la base de données, dans la key_valuetable, la post_updatecollection, mais les données sont sérialisées et difficiles à mettre à jour directement.

J'ai utilisé certains détails de la réponse de @ kiamlaluno pour créer un script drush que vous pouvez utiliser pour réinitialiser un seul crochet. Voici une version de base ( une version plus longue est ici ):

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

Et voici un exemple de ce à quoi il ressemble lorsque vous l'exécutez à partir de la ligne de commande:

./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
la source
3
avez-vous pensé à contribuer de nouveau à drush, github.com/drush-ops/drush ?
powpow12
1
C'est une fonctionnalité assez agréable, mais c'est un peu trop niche pour le noyau Drush. Peut-être que quelqu'un crée un fichier de commandes pour cela.
moshe weitzman
3

Voici un exemple que vous pouvez utiliser à partir de la ligne de commande avec 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);'

Lorsque vous réexécutez drush updatedb, vous verrez votre post_update_hook en attente d'exécution.

Jason Yarrington
la source
Cela a bien fonctionné pour moi, juste pour mentionner que dans drush 9, c'estdrush php:eval 'command'
powpow12
Très utile, si sur un environnement en lecture seule. Merci beaucoup;)
Mirsoft
1

UpdateRegistry::getPendingUpdateFunctions()contient le code suivant. Voyez ce que dit le commentaire.

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

UpdateRegistry :: $ updateType est défini sur 'post_update'.
$this->keyValueest défini à partir de UpdateRegistryFactory::create()avec la valeur de $this->container->get('keyvalue')->get('post_update').

Le code procédural équivalent pour obtenir cette collection de valeurs-clés est le suivant.

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

Définissez existing_updates sur un tableau vide, et Drupal pensera qu'aucun des rappels post-mise à jour n'a été appelé.

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

Supprimez le nom de rappel de la clé existing_updates de cette valeur de clé, et Drupal pensera que le rappel après mise à jour n'a pas encore été invoqué.

kiamlaluno
la source
0

Appelez-le de l'intérieur hook_update_n()et faites ce que vous faisiez auparavant.

nvahalik
la source
1
Cela ne semble pas être une bonne idée, car l'objectif du mécanisme hook_post_update est d'avoir un Drupal entièrement fonctionnel disponible après l' exécution de toutes les mises à jour. Il a été introduit car il n'y a aucune garantie sur l'état de Drupal lors des mises à jour.
Eelke Blok du