Jak wdrożyć aktualizację wtyczki WordPress, która modyfikuje bazę danych?

10

Tworzę wtyczkę WordPress, która ma kilka własnych tabel baz danych. Wtyczka tworzy te tabele po aktywacji i usuwa je po usunięciu / odinstalowaniu.

Muszę wdrożyć proces aktualizacji wtyczki, który aktualizuje kod wtyczki oraz strukturę tabel. Najprostszym przypadkiem byłoby dodanie nowej kolumny do jednej z tabel. Bardziej złożonym przypadkiem byłoby utworzenie nowej struktury tabel i odpowiednia aktualizacja treści.

Jak poleciłbyś rozwiązać ten problem? Czy są jakieś wbudowane funkcje WordPress, które mogą pomóc?

Misza Moroszko
źródło

Odpowiedzi:

4

Prawidłowym sposobem na zrobienie tego w dzisiejszych czasach jest dołączenie schematu jako pliku do źródła wtyczki i użycie wbudowanej funkcji WordPress dbDelta () do aktualizacji bazy danych w razie potrzeby za pomocą tego schematu. Rzeczywisty wymagany kod jest bardzo prosty:

$sql = file_get_contents( plugin_dir_path(__FILE__) . "/schema.sql" );
dbDelta( $sql );

Spowoduje to utworzenie i aktualizację bazy danych zgodnie z wymaganiami. Kiedy ostatnio sprawdziłem, nie usunęło starych nieużywanych kolumn, więc musisz to kodować za pomocą kontroli wersji. To piękna funkcja WordPressa i ogromna oszczędność czasu. Podczas tworzenia pliku schema.sql należy zachować ostrożność, kopiując odstępy w eksporcie schematu mysql dokładnie tak, jak uważa się, że kod dbDelta () jest bardzo wybredny w kwestii odstępów. Powinieneś również przetestować wersję bazy danych, a jeśli nie jest najnowsza, zadzwoń powyżej, aby zaktualizować bazę danych. Może być również konieczne wykonanie określonych aktualizacji w celu uwzględnienia zmian, które nie są poprawne w dbDelta () (np. Usunięcie kolumny). Łatwo jest napisać prosty logiczny test, aby sprawdzić, czy wersja została zaktualizowana i wykonać te ręczne aktualizacje za pomocą $ wpdb. Na przykład możesz upuścić kolumnę, która jest teraz nieużywana.

$installed_ver = get_option(MY_DB_VERSION);
$wpp = $wpdb->prefix . "mypluginname";
if ($installed_ver < 102)
        $wpdb->query("ALTER TABLE ${wpp}_movies DROP nft_date");
if ($installed_ver < 107)
        $wpdb->query("ALTER TABLE ${wpp}_movies CHANGE lastupdated "
        . "lastupdated TIMESTAMP on update CURRENT_TIMESTAMP "
        . "NOT NULL DEFAULT CURRENT_TIMESTAMP");

update_option(MY_DB_VERSION, $db_version);

Jest to uproszczone od uruchamiania kodu, przepraszam, jeśli złamałem go w trakcie upraszczania go do publikacji.

Należy również pamiętać, że od WordPress 3.9.2 WordPress nie zawsze uruchamia hak aktywacyjny podczas aktualizacji wtyczki (w szczególności, jeśli masowa aktualizacja jest wykonywana ze strony Aktualizacje pulpitu nawigacyjnego).

Brian C.
źródło
Obecnie zacząłem brać wersję DB od czasu modyfikacji pliku schema.sql. Oznacza to, że wystarczy zaktualizować plik schemat.sql, aby spowodować aktualizację bazy danych; nie trzeba pamiętać o edycji wersji bazy danych. Coś w stylu: $ db_version = filemtime („schema.sql”);
Brian C
1
Tak więc, jeśli czas pliku zmienia się z czegoś zewnętrznego, jak przenoszenie serwerów, zmieniają się wersje mtime i db?
Walf
Czas na plik jest zawsze w GMT, a serwery rzadko różnią się o kilka sekund, więc jest prawie niemożliwe, aby został wywołany dwukrotnie. Jednak nawet jeśli zostanie ponownie wyzwolony, nie zostanie wyrządzona żadna szkoda, ponieważ uruchamia się raz i porównuje z aktywną bazą danych, oczywiście bez zmiany niczego. To jest piękne w dbDelta () - może działać wiele razy bez problemu. Dobre pytanie, dzięki.
Brian C
3

Krótko mówiąc, tak - $wpdbklasa. Aby uzyskać więcej informacji, zobacz Kodeks .

Ilekroć wchodzisz w interakcję z niestandardową tabelą (lub dowolną tabelą, naprawdę) powinieneś przejść przez $wpdb- w szczególności upewnij się, że znasz preparemetodę, która może pomóc uniknąć zapytań i zapobiec wstrzyknięciom.

Powinieneś już być zaznajomiony, ponieważ powinieneś go używać do tworzenia tabeli. Na haku instalacyjnym powinieneś mieć coś takiego:

$charset_collate = '';
if ( ! empty($wpdb->charset) )
    $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
if ( ! empty($wpdb->collate) )
    $charset_collate .= " COLLATE $wpdb->collate";

//Create custom table
$sql_custom_table ="CREATE TABLE {$wpdb->prefix}my_table (
    id bigint(20) unsigned NOT NULL auto_increment,
    column_a varchar(255) default NULL,
    column_b varchar(255) default NULL,
    PRIMARY KEY  (id)
    ) $charset_collate; ";

require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_custom_table);

Ten kod jest faktycznie uruchamiany za każdym razem, gdy wtyczka jest aktywowana (tj. Nie tylko zainstalowana). Więc to będzie działać, gdy ktoś aktualizuje wtyczki automatycznie . Uwaga: jeśli uaktualnią się one ręcznie, zastępując wtyczkę - to nie zrobi tego - więc będziesz musiał uruchomić powyższy kod admin_initpodczas aktualizacji wtyczki (zapisz numer wersji w tabeli opcji, sprawdź w porównaniu z bieżącą wersją) .

Teraz normalnie nie chcesz, aby CREATE TABLEpolecenie SQL było uruchamiane za każdym razem, gdy aktualizujesz wtyczkę - tutaj się dBDelta()pojawia.

Przed uruchomieniem powyższego polecenia - sprawdza, czy tabela istnieje. Co więcej, sprawdza typy kolumn. Więc jeśli tabela nie istnieje, tworzy ją, jeśli tak, ale niektóre typy kolumn zmieniły ją, aktualizuje je, a jeśli kolumna nie istnieje - dodaje ją.

Niestety - jeśli usuniesz kolumnę z powyższego, nie usunie ona automatycznie kolumny. Aby usunąć kolumny / tabele, musisz DROPje dokładnie zaznaczyć (sprawdzając, czy istnieją przed tobą).

Stephen Harris
źródło