web-dev-qa-db-ja.com

hook_post_update_NAME()を再実行する方法

Drupal 8 導入されたhook_post_update_NAME() これは _hook_update_n_ よりもいくつかの利点があり、モジュールの更新に役立ちます。

hook_post_update_NAME()は1回だけ実行する必要がありますが、開発中に更新フックをデバッグしているときなど、再実行したい場合があります。 _hook_update_n_を使用すると、 データベースのスキーマバージョンをリセット できます。

どのようにhook_post_update_NAME()を再実行しますか?

11
bryanbraun

実行された「post_update」フックは、データベースのkey_value テーブル、 post_updateコレクションですが、データはシリアル化されており、直接更新するのは面倒です。

@kiamlalunoの回答の詳細の一部を使用して、単一のフックをリセットするために使用できる drushスクリプト を作成しました。ここに基本的なバージョンがあります( 長いバージョンはここにあります ):

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

コマンドラインから実行したときの例を次に示します。

./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
11
bryanbraun

以下は、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);'

Drush updatedbを再実行すると、post_update_hookが実行されるのを待っているのがわかります。

2

UpdateRegistry::getPendingUpdateFunctions() には次のコードが含まれています。コメントの内容をご覧ください。

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

pdateRegistry :: $ updateType は_'post_update'_に設定されます。
_$this->keyValue_は UpdateRegistryFactory::create() から$this->container->get('keyvalue')->get('post_update')の値で設定されます。

そのキー値コレクションを取得するための同等の手続き型コードは次のコードです。

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

existing_updatesを空の配列に設定し、Drupalは、更新後のコールバックが呼び出されていないと考えます。

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

そのキー値のexisting_updatesキーからコールバック名を削除します。Drupalは、更新後のコールバックがまだ行われていないと見なします呼び出されました。

1
kiamlaluno

hook_update_n()内から呼び出してから、以前と同じように実行します。

0
nvahalik