¿Es posible forzar la ejecución del enlace de actualización de su módulo?


18

Soy el autor del módulo Date iCal, y la nueva versión principal en la que estoy trabajando (3.x) requiere una actualización de esquema de dos partes para los usuarios que tenían instalado 2.x. He escrito el enlace de actualización que realiza estos cambios, pero si uno de mis usuarios no puede ejecutar el script de actualización de la base de datos, recibirán un mensaje de error relacionado con sus importadores de feeds iCal.

La solución correcta es que ejecuten el script de actualización ... pero si solo entran y cambian manualmente sus importadores para deshacerse del mensaje, sus importadores permanecerán rotos permanentemente (porque la segunda parte de la actualización del esquema no han sido ejecutados).

Entonces, ¿hay alguna forma de mostrar un mensaje a los usuarios que no han ejecutado la actualización? ¿O de alguna manera ejecutar por la fuerza el enlace de actualización la primera vez que se produce una carga de página cuando 3.x se instala sobre 2.x?


2
Me imagino que podría hacer una variable_set()función de actualización que establezca una variable cuando se ejecute con éxito que podría mirar dentro de un _preprocess_page()pero que lo estaría mirando todo el tiempo, así que no estoy seguro de cuán amigable sería el rendimiento.
Jimajamma

Respuestas:


4

extendiendo el comentario de Jimajamma:

haga una función variable_set()en su función de actualización que establezca una variable cuando se ejecutó con éxito que podría ver dentro de una _preprocess_page ()

y en lugar de verificar esto en cada carga de página, hágalo solo si navega por el área de administración y si la versión instalada es 3.0 (3.1, 3.2, elimine esa verificación si deja de admitir la versión anterior como ruta de actualización).

Además, utilice hook_requirements para proporcionar comentarios sobre la página del informe de estado:

Verifique los requisitos de instalación y haga informes de estado.
(...)
La fase de "tiempo de ejecución" no se limita a los requisitos de instalación pura, sino que también se puede utilizar para obtener información de estado más general, como tareas de mantenimiento y problemas de seguridad.


15

Hay pocas formas de forzar la actualización del módulo.

  1. Llamando a la función de actualización directamente.

    $sandbox = [];
    module_load_include('install', 'FOO');
    FOO_update_7001($sandbox);
  2. Restablecer la versión del esquema al punto de interés y ejecutar las actualizaciones nuevamente como siempre

    drupal_set_installed_schema_version('module_name', '7000');

    O reinicie para volver a ejecutar solo el último esquema de actualización:

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

    Notas:

    • Esto se puede colocar hook_install, por lo que durante el proceso de actualización se ejecutarán todos los ganchos de actualización posteriores.
    • Para utilizar esta función fuera del archivo de instalación, install.incprimero debe incluir Drupal y el archivo de instalación del módulo, p. Ej.

      require_once DRUPAL_ROOT . '/includes/install.inc';
      module_load_include('install', 'foo');
    • Considere agregar ini_set('max_execution_time', 0);actualizaciones de instalación más largas para evitar tiempos de espera de PHP.
  3. Utilizando drush. Encuentra a continuación algunos ejemplos:

    • 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
Oh bien, no lo sabía drupal_set_installed_schema_version(). ¡Eso sería muy útil para depurar los ganchos de actualización!
coredumperror

1
Entonces, el principal problema con ponerlo en hook_install()está ejecutando actualizaciones de lotes largos (sandboxed). En una situación ideal, debería haber una forma de activar las actualizaciones de la misma manera que lo update.phphace al reiniciar el hilo de PHP para evitar tiempos de espera. ¿Ideas de hormigas cómo hacer eso?
Alex Skrypnyk

@ Alex.Designworks Puede agregar ini_set('max_execution_time', 0);antes de activar las actualizaciones.
kenorb

1

(Reescrito en una respuesta)

Puede "SELECCIONAR versión del esquema del sistema" para detectar si se ha realizado una actualización. De lo contrario, rechace la ejecución (con un mensaje de error).


Reformule su respuesta e intente dar un ejemplo de uso.
Елин Й.

Ignora este comentario.
coredumperror

Me temo que eso no funcionará, porque la funcionalidad en cuestión es un complemento para otro módulo, y no puedo evitar que ese módulo permita a los usuarios meterse con sus importadores.
coredumperror

¿No puede verificar la versión de esquema del módulo que tiene la intención de monitorear para actualizaciones?
user18099

0

Estoy de acuerdo con las sugerencias anteriores, mi única adición sería investigar también "Disparadores y acciones", parece que necesita una acción (notificar al usuario o ejecutar una actualización) cuando se activa un disparador (el usuario verifica la página de administración, etc.) . Para ver ejemplos de uso, consulte el módulo Ejemplos, hay código de ejemplo de acción y desencadenante. :)


0

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.