Comment implémenter la mise à jour du plugin WordPress qui modifie la base de données?

10

Je développe un plugin WordPress, qui possède ses propres tables de base de données. Le plugin crée ces tables lorsqu'il est activé et les supprime lorsqu'il est supprimé / désinstallé.

Je dois implémenter un processus de mise à jour du plugin qui met à jour le code du plugin ainsi que la structure des tables. Le cas le plus simple serait d'ajouter une nouvelle colonne à l'un des tableaux. Le cas le plus complexe serait de créer une nouvelle structure de tableaux et de mettre à jour le contenu en conséquence.

Comment recommanderiez-vous de résoudre ce problème? Existe-t-il des fonctions WordPress intégrées qui peuvent vous aider?

Misha Moroshko
la source

Réponses:

4

La bonne façon de le faire ces jours-ci est d'inclure votre schéma en tant que fichier dans la source du plugin et d'utiliser la fonction WordPress intégrée dbDelta () pour mettre à jour la base de données selon les besoins en utilisant ce schéma. Le code réel requis est très simple:

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

Cela créera et mettra à jour la base de données pour vous selon les besoins. Lors de ma dernière vérification, il n'a pas supprimé les anciennes colonnes inutilisées, vous devez donc coder pour cela via une vérification de version. C'est une belle fonctionnalité de WordPress et un énorme gain de temps. Attention lors de la création du fichier schema.sql que vous copiez l'espacement dans une exportation de schéma mysql exactement comme le code dbDelta () est réputé être très pointilleux sur l'espacement. Vous devez également tester la version de la base de données, et si ce n'est pas la dernière, appelez ce qui précède pour mettre à jour la base de données. Vous devrez peut-être également effectuer des mises à jour spécifiques pour couvrir les modifications que dbDelta () n'obtient pas correctement (par exemple, supprimer une colonne). Il est facile d'écrire un test if logique simple pour voir si la version a été mise à jour et faire ces mises à jour manuelles via $ wpdb. Par exemple, vous pouvez supprimer une colonne qui n'est plus utilisée.

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

Ceci est simplifié de l'exécution de code, excuses si je l'ai cassé dans le processus de simplification pour la publication.

Gardez également à l'esprit que depuis WordPress 3.9.2, WordPress n'exécute pas toujours le crochet d'activation lors de la mise à jour du plugin (en particulier, si une mise à jour en masse est effectuée à partir de la page Mises à jour du tableau de bord).

Brian C
la source
Ces jours-ci, j'ai commencé à prendre la version de la base de données à partir de l'heure de modification du fichier schema.sql. Cela signifie que la simple mise à jour du fichier scheme.sql est suffisante pour provoquer une mise à niveau de la base de données; pas besoin de se souvenir de modifier la version de la base de données. Quelque chose comme: $ db_version = filemtime (“schema.sql”);
Brian C
1
Donc, si l'heure du fichier change de quelque chose d'extérieur comme le déplacement des serveurs, le mtime et la version db changent?
Walf
Le temps de fichier est toujours en GMT, et les serveurs diffèrent rarement de quelques secondes, il est donc presque impossible qu'il se déclenche deux fois par cela. Cependant, même s'il se déclenche à nouveau, aucun mal n'est fait car il s'exécute une fois et fait une comparaison avec la base de données en direct, évidemment sans rien changer. C'est la belle chose à propos de dbDelta () - il peut s'exécuter plusieurs fois sans problème. Bonne question, merci.
Brian C
3

Bref, oui la - $wpdbclasse. Voir Codex pour plus d'informations.

Chaque fois que vous interagissez avec une table personnalisée (ou n'importe quelle table, vraiment), vous devez passer par $wpdb- en particulier assurez-vous que vous êtes familier avec la prepareméthode qui peut aider à échapper aux requêtes et à empêcher les injections.

Vous devez déjà être familier, car vous devez l'utiliser pour créer la table. Sur votre crochet d'installation, vous devriez avoir quelque chose comme:

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

Ce code est en fait exécuté chaque fois que le plug-in est activé (c'est-à-dire non seulement installé). Il s'exécutera donc lorsque quelqu'un mettra à jour le plug-in automatiquement . Remarque: S'ils mettent à niveau en remplaçant le plug-in manuellement - alors ce ne sera pas le cas - vous devrez donc déclencher le code ci-dessus admin_initlorsque votre plug-in est mis à niveau (stocker le numéro de version dans le tableau des options, comparer avec la version actuelle) .

Maintenant, vous ne voudriez normalement pas que la CREATE TABLEcommande SQL soit exécutée à chaque fois que vous mettez à jour le plug-in - c'est là dBDelta()qu'intervient.

Avant d'exécuter la commande ci-dessus - il vérifie si la table existe. De plus, il vérifie les types de colonnes. Donc, si la table n'existe pas, elle la crée, si c'est le cas, mais certains types de colonnes ont changé, elle les met à jour, et si une colonne n'existe pas - elle l'ajoute.

Malheureusement - si vous supprimez une colonne de ce qui précède, cela ne supprime pas automatiquement la colonne. Pour supprimer des colonnes / tableaux, vous devez les spécifiquement DROP(en vérifiant qu'ils existent avant vous).

Stephen Harris
la source