Cách chạy lại hook_post_update_NAME ()


11

Drupal 8 giới thiệuhook_post_update_NAME()có một số lợi ích trênhook_update_n , để cập nhật mô-đun.

Mỗi cái hook_post_update_NAME()chỉ nên chạy một lần, nhưng đôi khi tôi muốn chạy lại nó, như khi tôi gỡ lỗi hook cập nhật trong quá trình phát triển. Với hook_update_n, bạn có thể đặt lại phiên bản lược đồ trong cơ sở dữ liệu .

Làm thế nào để bạn chạy lại hook_post_update_NAME()?

Câu trả lời:


11

Các móc "post_update" đã được chạy được lưu trữ trong cơ sở dữ liệu, trong key_valuebảng, post_updatebộ sưu tập, nhưng dữ liệu được tuần tự hóa và lúng túng để cập nhật trực tiếp.

Tôi đã sử dụng một số chi tiết từ câu trả lời của @ kiamlaluno để tạo ra một kịch bản drush mà bạn có thể sử dụng để đặt lại một hook. Đây là phiên bản cơ bản ( phiên bản dài hơn ở đây ):

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

Và đây là một ví dụ về giao diện của nó khi bạn chạy nó từ dòng lệnh:

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

3
Bạn đã nghĩ đến việc đóng góp lại cho drush, github.com/drush-ops/drush chưa?
powpow12

1
Đây là một tính năng khá ngọt ngào, nhưng nó hơi quá phù hợp với lõi Drush. Có lẽ ai đó tạo ra một lệnh cho nó.
moshe weitzman

2

Dưới đây là một ví dụ bạn có thể sử dụng từ dòng lệnh với 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);'

Khi bạn chạy lại drush updateb, bạn sẽ thấy post_update_hook của bạn đang chờ để được chạy.


Điều này làm việc tốt với tôi, chỉ cần đề cập rằng trong drush 9, nó làdrush php:eval 'command'
powpow12

Rất hữu ích, nếu trên môi trường chỉ đọc. Rất cám ơn;)
Mirsoft

1

UpdateRegistry::getPendingUpdateFunctions()chứa mã sau đây. Xem những gì bình luận nói.

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

UpdateRegistry :: $ updateType được đặt thành 'post_update'.
$this->keyValueđược đặt từ UpdateRegistryFactory::create()với giá trị của $this->container->get('keyvalue')->get('post_update').

Mã thủ tục tương đương để có được bộ sưu tập keyvalue đó là mã sau đây.

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

Đặt current_updates thành một mảng trống và Drupal sẽ nghĩ rằng không có cuộc gọi lại cập nhật bài đăng nào được gọi.

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

Xóa tên gọi lại khỏi khóa hiện tại của khóa đó và Drupal sẽ nghĩ rằng cuộc gọi lại cập nhật bài đăng chưa được gọi.


0

Gọi nó từ bên trong hook_update_n()và sau đó làm những gì bạn đang làm trước đây.


1
Điều đó dường như không phải là một ý tưởng tốt, vì toàn bộ mục đích cho cơ chế hook_post_update là có sẵn một Drupal đầy đủ chức năng sau khi tất cả các bản cập nhật đã chạy. Nó được giới thiệu vì không có gì đảm bảo về tình trạng của Drupal trong quá trình cập nhật.
Eelke Blok
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.