Jestem autorem modułu Date iCal, a nowa główna wersja, nad którą pracuję (3.x) wymaga dwuczęściowej aktualizacji schematu dla użytkowników, którzy zainstalowali wersję 2.x. Napisałem hak aktualizacji, który wprowadza te zmiany, ale jeśli jeden z moich użytkowników nie uruchomi skryptu aktualizacji bazy danych, otrzyma komunikat o błędzie dotyczący importerów kanałów iCal.
Właściwym rozwiązaniem jest uruchomienie skryptu aktualizacji ... ale jeśli po prostu wejdą i ręcznie zmienią swoich importerów, aby pozbyć się wiadomości, ich importerzy pozostaną trwale uszkodzeni (ponieważ druga część aktualizacji schematu nie zostały stracone).
Czy jest więc jakiś sposób na wyświetlenie komunikatu użytkownikom, którzy nie uruchomili aktualizacji? Czy jakoś wymusić wykonanie haka aktualizacji przy pierwszym załadowaniu strony, gdy 3.x zostanie zainstalowany ponad 2.x?
variable_set()
w swojej funkcji aktualizacji, która ustawia zmienną, kiedy została pomyślnie uruchomiona, którą możesz zajrzeć do wewnątrz,_preprocess_page()
ale będziesz na nią patrzył za każdym razem, więc nie jestem pewien, czy byłaby to przyjazna dla wydajności.Odpowiedzi:
rozszerzenie na komentarz Jimajammy:
i zamiast sprawdzania tego na każdym ładowaniu strony, rób to tylko wtedy, gdy przeglądasz obszar administratora i jeśli zainstalowana jest wersja 3.0 (3.1, 3.2, zabij to sprawdzenie, jeśli przestaniesz obsługiwać starą wersję jako ścieżkę uaktualnienia).
Dodatkowo skorzystaj z hook_requirements, aby przekazać opinię na stronie raportu o stanie:
źródło
Istnieje kilka sposobów wymuszenia aktualizacji modułu.
Bezpośrednie wywołanie funkcji aktualizacji.
Resetowanie wersji schematu do interesującego miejsca i uruchamianie aktualizacji jak zwykle.
Lub zresetuj, aby ponownie uruchomić tylko najnowszy schemat aktualizacji:
Uwagi:
hook_install
, aby podczas procesu aktualizacji wykonywane były wszystkie sekwencyjne przechwyty aktualizacji.Aby korzystać z tej funkcji poza plikiem instalacyjnym, musisz
install.inc
najpierw dołączyć Drupal i plik instalacyjny modułu, npini_set('max_execution_time', 0);
dłuższych aktualizacji instalacji, aby zapobiec przekroczeniu limitu czasu PHP.Korzystanie
drush
. Znajdź poniżej kilka przykładów: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
źródło
drupal_set_installed_schema_version()
. To byłoby bardzo przydatne do debugowania haków aktualizacji!hook_install()
jest uruchamianie długich partii (piaskownicy). W idealnej sytuacji powinien istnieć sposób na uruchamianie aktualizacji w taki sam sposób, jakupdate.php
przy ponownym uruchomieniu wątku PHP, aby zapobiec przekroczeniu limitu czasu. Pomysły na mrówki, jak to zrobić?ini_set('max_execution_time', 0);
przed uruchomieniem aktualizacji.(Przeredagowany na odpowiedź)
Możesz „WYBRAĆ wersję schematu z systemu”, aby wykryć, czy aktualizacja została wykonana. Jeśli nie, odmów uruchomienia (z komunikatem o błędzie).
źródło
Zgadzam się z powyższymi sugestiami - moim jedynym dodatkiem byłoby zbadanie „Wyzwalaczy i akcji” również - wydaje się, że potrzebujesz akcji (powiadom użytkownika lub uruchom aktualizację), aby nastąpiło po uruchomieniu wyzwalacza (użytkownik sprawdza stronę administratora itp.) . Przykłady użycia znajdują się w module Przykłady, istnieje zarówno przykładowy kod akcji, jak i wyzwalacza. :)
źródło
function MYMODULE_install() { $functions = get_defined_functions(); foreach ($functions['user'] as $function) { if (strpos($function, 'MYMODULE_update_') === 0) { call_user_func($function); } } }
źródło