Возможно ли заставить запуск модуля обновления вашего модуля?

18

Я являюсь автором модуля Date iCal, и новая основная версия, над которой я работаю (3.x), требует обновления схемы из двух частей для пользователей, у которых установлен 2.x. Я написал хук обновления, который вносит эти изменения, но если один из моих пользователей не сможет запустить скрипт обновления базы данных, он получит сообщение об ошибке, касающееся их импортеров каналов iCal.

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

Так есть ли способ показать сообщение пользователям, которые не запустили обновление? Или каким-то образом принудительно выполнить хук обновления в первый раз, когда загрузка страницы происходит, когда 3.x устанавливается поверх 2.x?

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

Ответы:

4

Продолжая комментарий от Jimajamma:

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

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

Дополнительно используйте hook_requirements, чтобы оставить отзыв на странице отчета о состоянии:

Проверьте требования к установке и сделайте отчет о состоянии.
(...)
Фаза «времени выполнения» не ограничивается чисто требованиями к установке, но также может использоваться для получения более общей информации о состоянии, например задач обслуживания и проблем безопасности.

Андре Баумайер
источник
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
kenorb
источник
1
О, хорошо, я не знал о drupal_set_installed_schema_version(). Это было бы очень удобно для отладки обновлений!
coredumperror
1
Таким образом, основная проблема при его установке hook_install()- запуск длинных пакетных (изолированных) обновлений. В идеальной ситуации должен быть способ запуска обновлений таким же образом, как update.phpи при перезапуске потока PHP для предотвращения тайм-аутов. Муравьиные идеи, как это сделать?
Алексей Скрипник
@ Alex.Designworks Вы можете добавить, ini_set('max_execution_time', 0);прежде чем запускать обновления.
Кенорб
1

(Перефразировано в ответ)

Вы можете «ВЫБЕРИТЬ схему_версии FROM system», чтобы определить, было ли выполнено обновление. Если нет, то отказаться от запуска (с сообщением об ошибке).

user18099
источник
Пожалуйста, перефразируйте ваш ответ и попробуйте привести пример использования.
Елин Й.
Игнорировать этот комментарий.
coredumperror
Боюсь, что это не сработает, потому что рассматриваемая функциональность является плагином для другого модуля, и я не могу помешать этому модулю позволить пользователям связываться со своими импортерами.
coredumperror
Вы не можете проверить версию схемы модуля, которую вы собираетесь отслеживать на наличие обновлений?
user18099
0

Я согласен с вышеизложенными предложениями - мое единственное добавление было бы также для изучения «Триггеров и действий» - кажется, что вам нужно действие (уведомить пользователя или запустить обновление), которое должно происходить при нажатии триггера (пользователь проверяет страницу администратора и т. Д.) , Примеры использования см. В разделе «Примеры», здесь есть примеры кода действий и триггера. :)

mechhfly
источник
0

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

Алекс Скрипник
источник