È possibile forzare l'esecuzione dell'hook di aggiornamento del modulo?


18

Sono l'autore del modulo Date iCal e la nuova versione principale su cui sto lavorando (3.x) richiede un aggiornamento dello schema in due parti per gli utenti che hanno installato 2.x. Ho scritto l'hook di aggiornamento che apporta queste modifiche, ma se uno dei miei utenti non riesce a eseguire lo script di aggiornamento del database, riceveranno un messaggio di errore relativo ai loro importatori di feed iCal.

La soluzione giusta è che eseguano lo script di aggiornamento ... ma se entrano e cambiano manualmente i loro importatori per sbarazzarsi del messaggio, i loro importatori rimarranno permanentemente interrotti (perché la seconda parte dell'aggiornamento dello schema non lo farà è stato eseguito).

Quindi c'è un modo per mostrare un messaggio agli utenti che non hanno eseguito l'aggiornamento? O in qualche modo eseguire forzatamente l'hook di aggiornamento la prima volta che si verifica un caricamento della pagina quando 3.x viene installato sopra 2.x?


2
Immagino che potresti eseguire una variable_set()funzione di aggiornamento che imposta una variabile quando è stata eseguita con successo che puoi guardare all'interno di un _preprocess_page()ma lo guarderesti ogni volta, quindi non sei sicuro di quanto sia amichevole il rendimento.
Jimajamma,

Risposte:


4

prolungando il commento di Jimajamma:

fare variable_set()nella vostra funzione di aggiornamento che imposta una variabile quando è stato eseguito con successo che si poteva guardare all'interno di un _preprocess_page ()

e invece di controllare questo ad ogni caricamento della pagina fallo solo se navighi nell'area di amministrazione e se la versione installata è 3.0 (3.1, 3.2, uccidi quel controllo se smetti di supportare la vecchia versione come percorso di aggiornamento).

Utilizza inoltre hook_requirements per fornire feedback sulla pagina del rapporto sullo stato:

Verificare i requisiti di installazione ed eseguire rapporti sullo stato.
(...)
La fase di "runtime" non si limita ai semplici requisiti di installazione, ma può anche essere utilizzata per informazioni sullo stato più generali come attività di manutenzione e problemi di sicurezza.


15

Esistono alcuni modi per forzare l'aggiornamento del modulo.

  1. Chiamare direttamente la funzione di aggiornamento.

    $sandbox = [];
    module_load_include('install', 'FOO');
    FOO_update_7001($sandbox);
  2. Ripristinare la versione dello schema sul punto di interesse ed eseguire nuovamente gli aggiornamenti come al solito.

    drupal_set_installed_schema_version('module_name', '7000');

    O reimpostare per rieseguire solo l'ultimo schema di aggiornamento:

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

    Appunti:

    • Questo può essere inserito hook_install, quindi durante il processo di aggiornamento verrebbero eseguiti tutti gli hook di aggiornamento sequenziali.
    • Per utilizzare questa funzione al di fuori del file di installazione, è necessario includere install.incprima Drupal e il file di installazione del modulo, ad es

      require_once DRUPAL_ROOT . '/includes/install.inc';
      module_load_include('install', 'foo');
    • Prendi in considerazione di aggiungere ini_set('max_execution_time', 0);aggiornamenti di installazione più lunghi per evitare timeout PHP.
  3. Usando drush. Di seguito alcuni esempi:

    • 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 bello, non lo sapevo drupal_set_installed_schema_version(). Sarebbe molto utile per il debug degli hook di aggiornamento!
coredumperror,

1
Quindi il problema principale con l'inserimento hook_install()è l'esecuzione di aggiornamenti batch lunghi (sandbox). Nella situazione ideale, dovrebbe esserci un modo per attivare gli aggiornamenti allo stesso modo del update.phpriavvio del thread PHP per evitare timeout. Idee di formiche come farlo?
Alex Skrypnyk,

@ Alex.Designworks È possibile aggiungere ini_set('max_execution_time', 0);prima di attivare gli aggiornamenti.
Kenorb,

1

(Riformulato in una risposta)

È possibile "SELEZIONARE schema_versione DA sistema" per rilevare se è stato eseguito un aggiornamento. In caso contrario, rifiutare di eseguire (con un messaggio di errore).


Si prega di riformulare la risposta e provare a dare un esempio di utilizzo.
Елин Й.

Ignora questo commento.
coredumperror,

Temo che non funzionerà, perché la funzionalità in questione è un plug-in per un altro modulo e non posso impedire a quel modulo di lasciare che gli utenti facciano casino con i loro importatori.
coredumperror,

Non puoi controllare la versione dello schema del modulo che intendi monitorare per gli aggiornamenti?
user18099,

0

Sono d'accordo con i suggerimenti di cui sopra - la mia unica aggiunta sarebbe quella di indagare anche su "Trigger e azioni" - sembra che sia necessaria un'azione (notifica all'utente o esegui aggiornamento) quando si verifica un trigger (l'utente controlla la pagina dell'amministratore, ecc.) . Per esempi di utilizzo, consultare il modulo Esempi, sono presenti sia codice di azione che trigger. :)


0

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.