Ist es möglich, die Ausführung des Update-Hooks Ihres Moduls zu erzwingen?

18

Ich bin der Autor des Date iCal-Moduls und die neue Hauptversion, an der ich arbeite (3.x), erfordert ein zweiteiliges Schema-Update für Benutzer, auf denen 2.x installiert war. Ich habe den Update-Hook geschrieben, der diese Änderungen vornimmt. Wenn jedoch einer meiner Benutzer das Datenbankaktualisierungsskript nicht ausführt, wird eine Fehlermeldung bezüglich der Importeure von iCal-Feeds angezeigt.

Die richtige Lösung ist, dass sie das Update-Skript ausführen. Wenn sie jedoch die Nachricht manuell ändern, um sie zu entfernen, bleiben ihre Importeure dauerhaft fehlerhaft (da der zweite Teil des Schema-Updates dies nicht tut) wurden hingerichtet).

Gibt es also eine Möglichkeit, Benutzern, die das Update nicht ausgeführt haben, eine Nachricht anzuzeigen? Oder führen Sie den Update-Hook irgendwie gewaltsam aus, wenn zum ersten Mal eine Seite geladen wird, wenn 3.x über 2.x installiert wird?

Coredumperror
quelle
2
Ich könnte mir vorstellen, dass Sie variable_set()in Ihrer Aktualisierungsfunktion eine Variable festlegen könnten, die bei erfolgreicher Ausführung in a _preprocess_page()angezeigt wird, aber Sie würden sie jedes Mal anzeigen, wenn Sie nicht sicher wären, wie leistungsfreundlich dies wäre.
Jimajamma

Antworten:

4

Erweiterung auf Kommentar von Jimajamma:

tut eine variable_set()in Ihrer Update - Funktion , die eine Variable setzt , wenn es erfolgreich ausgeführt wurde , dass man sich in einem _preprocess_page aussehen könnte ()

und anstatt dies bei jedem Laden der Seite zu überprüfen, tun Sie dies nur, wenn Sie im Admin-Bereich surfen und wenn die installierte Version 3.0 ist (3.1, 3.2, beenden Sie diese Überprüfung, wenn Sie die alte Version nicht mehr als Upgrade-Pfad unterstützen).

Nutzen Sie zusätzlich hook_requirements , um Feedback auf der Statusberichtsseite zu geben:

Überprüfen Sie die Installationsanforderungen und führen Sie Statusberichte durch.
(...)
Die Laufzeitphase ist nicht auf reine Installationsanforderungen beschränkt, sondern kann auch für allgemeinere Statusinformationen wie Wartungsaufgaben und Sicherheitsprobleme verwendet werden.

Andre Baumeier
quelle
15

Es gibt nur wenige Möglichkeiten, die Aktualisierung des Moduls zu erzwingen.

  1. Update-Funktion direkt aufrufen.

    $sandbox = [];
    module_load_include('install', 'FOO');
    FOO_update_7001($sandbox);
  2. Setzen Sie die Schemaversion auf den gewünschten Wert zurück und führen Sie die Aktualisierungen wie gewohnt erneut aus.

    drupal_set_installed_schema_version('module_name', '7000');

    Oder setzen Sie das Programm zurück, um nur das neueste Aktualisierungsschema erneut auszuführen:

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

    Anmerkungen:

    • Dies kann hook_installeingefügt werden, sodass während des Aktualisierungsprozesses alle nachfolgenden Aktualisierungs-Hooks ausgeführt werden.
    • Um diese Funktion außerhalb der Installationsdatei nutzen zu können, müssen Sie install.inczuerst Drupal und die Installationsdatei des Moduls einfügen, z

      require_once DRUPAL_ROOT . '/includes/install.inc';
      module_load_include('install', 'foo');
    • Erwägen Sie das Hinzufügen ini_set('max_execution_time', 0);längerer Installationsupdates, um PHP-Timeouts zu vermeiden.
  3. Verwenden drush. Nachfolgend einige Beispiele:

    • 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
quelle
1
Oh schön, ich wusste nichts davon drupal_set_installed_schema_version(). Das wäre super praktisch zum Debuggen von Update-Hooks!
Coredumperror
1
Das Hauptproblem beim hook_install()Einspielen ist es also, lange Batch-Updates (Sandbox-Updates) auszuführen. Im Idealfall sollte es eine Möglichkeit geben, Updates auf die gleiche Weise auszulösen wie update.phpbeim Neustart des PHP-Threads, um Zeitüberschreitungen zu vermeiden. Ameise Ideen, wie das geht?
Alex Skrypnyk
@ Alex.Designworks Sie können ini_set('max_execution_time', 0);vor dem Auslösen der Updates hinzufügen .
Kenorb
1

(In eine Antwort umformuliert)

Mit "SELECT schema_version FROM system" können Sie feststellen, ob ein Update durchgeführt wurde. Wenn nicht, lehnen Sie die Ausführung ab (mit einer Fehlermeldung).

user18099
quelle
Bitte formulieren Sie Ihre Antwort neu und versuchen Sie, ein Verwendungsbeispiel anzugeben.
Елин Й.
Ignoriere diesen Kommentar.
Coredumperror
Ich fürchte, das wird nicht funktionieren, da die fragliche Funktionalität ein Plugin für ein anderes Modul ist und ich nicht verhindern kann, dass dieses Modul Benutzer mit ihren Importeuren in Konflikt bringt.
Coredumperror
Sie können die Schemaversion des Moduls, das Sie auf Updates überwachen möchten, nicht überprüfen?
user18099
0

Ich stimme den obigen Vorschlägen zu - mein einziger Zusatz wäre, auch "Trigger und Aktionen" zu untersuchen - es scheint, dass Sie eine Aktion benötigen (Benutzer benachrichtigen oder Aktualisierung ausführen), wenn ein Trigger ausgelöst wird (Benutzer prüft die Admin-Seite usw.) . Anwendungsbeispiele finden Sie im Beispielmodul. Es gibt sowohl Aktions- als auch Trigger-Beispielcode. :)

mechhfly
quelle
0

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

Alex Skrypnyk
quelle