Cum să implementezi actualizarea unui plugin WordPress care modifică baza de date?

6 oct. 2012, 16:08:46
Vizualizări: 15.5K
Voturi: 15

Dezvolt un plugin WordPress, care are mai multe tabele proprii în baza de date. Pluginul creează aceste tabele la activare și le șterge când este dezinstalat.

Trebuie să implementez un proces de actualizare a plugin-ului care să actualizeze atât codul, cât și structura tabelelor. Cel mai simplu caz ar fi adăugarea unei coloane noi într-unul din tabele. Un caz mai complex ar fi crearea unei structuri noi de tabele și actualizarea conținutului în consecință.

Cum ați recomanda să rezolv această problemă? Există funcții încorporate în WordPress care ar putea ajuta?

0
Toate răspunsurile la întrebare 2
0

Pe scurt, da - clasa $wpdb. Consultați Codex pentru mai multe informații.

Ori de câte ori interacționați cu un tabel personalizat (sau orice tabel, de fapt), ar trebui să folosiți $wpdb - în special asigurați-vă că sunteți familiarizat cu metoda prepare, care poate ajuta la evitarea injecțiilor SQL prin escaparea interogărilor.

Ar trebui să fiți deja familiarizat cu aceasta, deoarece ar trebui să o folosiți pentru a crea tabelul. În hook-ul de instalare, ar trebui să aveți ceva de genul:

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

// Crearea tabelului personalizat
$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);

Acest cod este de fapt executat de fiecare dată când plugin-ul este activat (adică nu doar instalat). Deci va rula când cineva actualizează plugin-ul automat. Notă: Dacă actualizarea se face prin înlocuirea manuală a plugin-ului - atunci nu se va executa - așa că va trebui să declanșați codul de mai sus pe admin_init când plugin-ul este actualizat (stocați numărul versiunii în tabelul de opțiuni și verificați împotriva versiunii curente).

În mod normal, nu ați dori ca comanda SQL CREATE TABLE să ruleze de fiecare dată când actualizați plugin-ul - aici intervine dbDelta().

Înainte de a executa comanda de mai sus - verifică dacă tabelul există. Mai mult decât atât, verifică tipurile de coloane. Deci, dacă tabelul nu există, îl creează; dacă există, dar unele tipuri de coloane s-au schimbat, le actualizează; iar dacă o coloană nu există - o adaugă.

Din păcate - dacă eliminați o coloană din codul de mai sus, aceasta nu va fi eliminată automat. Pentru a elimina coloane/tabele, trebuie să utilizați în mod explicit DROP (verificând mai întâi dacă există).

6 oct. 2012 17:22:21
3

Modul corect de a face acest lucru în zilele noastre este să includeți schema ca fișier în sursa plugin-ului și să utilizați funcția încorporată WordPress dbDelta() pentru a actualiza baza de date conform necesităților folosind acea schemă. Codul efectiv necesar este foarte simplu:

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

Acest lucru va crea și actualiza baza de date pentru tine conform necesităților. Când am verificat ultima dată, nu șterge coloanele vechi neutilizate, așa că va trebui să codifici pentru asta printr-o verificare a versiunii. Aceasta este o caracteristică frumoasă a WordPress și un mare economisitor de timp. Atenție când creați fișierul schema.sql să copiați spațierea într-o exportare de schemă mysql exact, deoarece codul dbDelta() este reputat a fi foarte sensibil la spațiere. De asemenea, ar trebui să testați versiunea bazei de date și, dacă nu este cea mai recentă, să apelați cele de mai sus pentru a actualiza baza de date. De asemenea, poate fi nevoie să faceți actualizări specifice pentru a acoperi modificările pe care dbDelta() nu le face corect (de exemplu, ștergerea unei coloane). Este ușor să scrieți un simplu test logic if pentru a vedea dacă versiunea s-a actualizat și să faceți aceste actualizări manuale prin $wpdb. De exemplu, puteți renunța la o coloană care nu mai este utilizată.

$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);

Aceasta este o versiune simplificată din codul funcțional, scuze dacă am stricat-o în procesul de simplificare pentru publicare.

De asemenea, rețineți că începând cu WordPress 3.9.2, WordPress nu rulează întotdeauna cârligul de activare la actualizarea plugin-ului (mai exact, dacă se face o actualizare în masă din pagina Dashboard Updates).

21 sept. 2014 03:44:06
Comentarii

În ultima vreme am început să iau versiunea bazei de date din timpul de modificare al fișierului schema.sql. Asta înseamnă că este suficient să actualizezi fișierul schema.sql pentru a declanșa o actualizare a bazei de date; nu mai este nevoie să-ți amintești să editezi versiunea bazei de date. Ceva de genul: $db_version = filemtime(“schema.sql”);

Brian C Brian C
19 sept. 2019 12:40:00

Deci, dacă timpul fișierului se schimbă din cauza unui factor extern precum mutarea pe alte servere, mtime și versiunea bazei de date se schimbă?

Walf Walf
13 nov. 2019 04:17:57

Timpul fișierului este întotdeauna în GMT, iar serverele diferă rareori cu câteva secunde, așa că este aproape imposibil să fie declanșat de două ori din această cauză. Cu toate acestea, chiar dacă se declanșează din nou, nu se produce niciun prejudiciu, deoarece rulează o singură dată și face o comparație cu baza de date live, evident fără a schimba nimic. Acesta este frumusețea funcției dbDelta() - poate rula de mai multe ori fără probleme. Bună întrebare, mulțumesc.

Brian C Brian C
13 nov. 2019 08:39:19