Чи можна змусити запустити гак оновлення модуля?


18

Я є автором модуля Date iCal, і нова основна версія, над якою я працюю (3.x), вимагає оновлення схеми з двох частин для користувачів, які встановили 2.x. Я написав гачок оновлення, який вносить ці зміни, але якщо хтось із моїх користувачів не запустить сценарій оновлення бази даних, він отримає повідомлення про помилку, пов’язане з імпортерами каналів iCal.

Правильне рішення полягає в тому, щоб вони запустили сценарій оновлення ... але якщо вони просто заходять і вручну поміняють своїх імпортерів, щоб позбутися від повідомлення, їхні імпортери залишаться назавжди порушеними (тому що друга частина оновлення схеми не буде були страчені).

Так чи є спосіб відобразити повідомлення користувачам, які не запустили оновлення? Або якось примусово виконати гачок оновлення першого разу, коли завантаження сторінки відбувається, коли 3.x встановлюється поверх 2.x?


2
Я б міг уявити, що ви можете виконати variable_set()функцію оновлення, яка встановлює змінну, коли вона успішно виконується, щоб ви могли дивитись всередині, _preprocess_page()але ви будете дивитись на неї кожен раз, так що не знаєте, наскільки це буде сприятливим для продуктивності.
Jimajamma

Відповіді:


4

продовження на коментар від Jimajamma:

зробіть variable_set()у своїй функції оновлення, яка встановлює змінну після її успішного запуску, щоб ви могли переглянути внутрішню сторінку _preprocess_page ()

і замість того, щоб перевіряти це на кожному завантаженні сторінки, робіть це лише при перегляді області адміністратора та якщо встановлена ​​версія 3.0 (3.1, 3.2, знищуйте цю перевірку, якщо ви перестаєте підтримувати стару версію як шлях до оновлення).

Додатково скористайтеся крючковими вимогами, щоб надати зворотній зв’язок на сторінці звіту про стан:

Перевірте вимоги до установки та складіть звіт про стан.
(...)
Етап "часу виконання" не обмежується чистими вимогами до встановлення, але також може бути використаний для отримання більш загальної інформації про стан, наприклад, завдання технічного обслуговування та проблеми безпеки.


15

Існує кілька способів примусового оновлення модуля.

  1. Виклик функції оновлення безпосередньо.

    $sandbox = [];
    module_load_include('install', 'FOO');
    FOO_update_7001($sandbox);
  2. Скидання версії схеми до цікавої точки та запустіть оновлення знову, як зазвичай.

    drupal_set_installed_schema_version('module_name', '7000');

    Або скиньте для повторного запуску лише останню схему оновлення:

    drupal_set_installed_schema_version('foo', drupal_get_installed_schema_version('foo') - 1);

    Примітки:

    • Це може бути розміщено hook_install, тому під час процесу оновлення всі послідовні гаки оновлення будуть виконані.
    • Щоб використовувати цю функцію поза інсталяційним файлом, потрібно включити install.incспочатку Drupal та інсталяційний файл модуля, наприклад

      require_once DRUPAL_ROOT . '/includes/install.inc';
      module_load_include('install', 'foo');
    • Розгляньте можливість додавання ini_set('max_execution_time', 0);більш тривалих оновлень для встановлення, щоб запобігти очікуванню PHP.
  3. Використання drush. Нижче наведено кілька прикладів:

    • drush eval 'module_load_include('install', 'foo'); $s = []; foo_update_7001($s);'
    • drush sqlq "UPDATE system SET schema_version = 7000 WHERE name = 'foo'" && drush -y updb

1
О, добре, я не знав про це drupal_set_installed_schema_version(). Це було б дуже зручно для налагодження гаків оновлення!
coredumperror

1
Тож головна проблема з його введенням - це hook_install()тривалі пакетні оновлення (пісочниці). В ідеальній ситуації повинен бути спосіб запускати оновлення так само, як update.phpі при перезапуску потоку PHP для запобігання таймаутів. Мурашині ідеї, як це зробити?
Олексій Скрипник

@ Alex.Designworks Ви можете додати, ini_set('max_execution_time', 0);перш ніж запускати оновлення.
kenorb

1

(Перероблено у відповідь)

Ви можете "ВИБРАТИ schema_version FROM system", щоб виявити, чи було виконано оновлення. Якщо ні, то відмовтеся від запуску (із повідомленням про помилку).


Будь ласка, переформулюйте свою відповідь та спробуйте навести приклад використання.
Елін Й.

Ігноруйте цей коментар.
coredumperror

Я боюся, що це не спрацює, тому що функціонал, про який йде мова, є плагіном для іншого модуля, і я не можу запобігти тому, щоб цей модуль дозволяв користувачам возитися зі своїми імпортерами.
coredumperror

Ви не можете перевірити версію схеми модуля, який ви маєте намір відстежувати на предмет оновлень?
user18099

0

Я погоджуюся з наведеними вище пропозиціями - моїм єдиним доповненням було б також дослідити "Тригери та дії" - здається, що вам потрібна дія (сповістити користувача або запустити оновлення), коли відбудеться тригер (користувач перевіряє сторінку адміністратора тощо). . Для прикладів використання див. Модуль "Приклади", є як приклад дії, так і код тригера. :)


0

function MYMODULE_install() { $functions = get_defined_functions(); foreach ($functions['user'] as $function) { if (strpos($function, 'MYMODULE_update_') === 0) { call_user_func($function); } } }

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.