Au cours de la durée de vie de votre table personnalisée, vous constaterez probablement que vous devez modifier son contenu ou son mode de stockage. Cela peut être dû au besoin de stocker plus (ou moins) de données. Il se peut que la conception initiale de votre base de données n'ait pas été conçue pour traiter (efficacement) ce que votre base d'utilisateurs demande maintenant. Quoi qu'il en soit, nous devons savoir comment adapter notre table à nos nouveaux besoins. C’est ce que nous verrons dans ce tutoriel, et nous nous concentrerons principalement sur la fonction dbDelta ()
que nous avons rencontré pour la première fois dans la première partie.
Heureusement, la plupart des démarches dans la gestion des modifications de la base de données sont effectuées par la fonction WordPress dbDelta ()
. Nous avons utilisé cette fonction dans la première partie pour créer notre table, mais cela en fait beaucoup plus: avant d'exécuter la requête que nous lui avons donnée, il vérifie si la table existe déjà. Sinon, il crée la table, mais s’il existe, il compare la différence (d’où le nom) et crée certains changements. C'est pourquoi dans la première partie, nous n'avons pas vérifié manuellement si la table existait déjà..
Si la table existe déjà, mais est différente de la table indiquée par le code SQL (par exemple, la table existante a une colonne manquante ou un classement de colonne différent), puis dbDelta ()
applique automatiquement ces mises à jour. De cette façon, nous pouvons publier une nouvelle version de notre plug-in qui modifie notre table en appliquant simplement 'dbDelta ()' avec le code SQL modifié. Presque.
Malheureusement, dbDelta ()
ne s'applique pas tout changements. Supposons que dans notre dernière version de plug-in, nous n’avons pas besoin d’une colonne et nous voulons la supprimer. Nous le supprimons donc de la requête SQL de la première partie et de l'appel de routine de mise à niveau. wptuts_create_tables ()
. Après la mise à niveau, nous découvrirons que la colonne est toujours là. Pire que cela: les utilisateurs passant de l'ancienne version à la nouvelle version auront alors une table structurellement différente de celle qui commence par la nouvelle version.
Remarque: dbDelta ()
est non destructif: c’est-à-dire qu’il va ajouter des colonnes manquantes ou modifier les colonnes modifiées, mais ne supprimera pas les colonnes ni les index.
Alors qu'est-ce que dbDelta ()
effectivement faire?
Rappelons-nous la requête SQL à laquelle nous passons dbDelta ()
lors de la création de la table:
$ sql_create_table = "CREATE TABLE". $ wpdb-> wptuts_activity_log. "(log_id bigint (20) unsigned NOT NULL auto_increment, user_id bigint (20) unsigned NOT NULL par défaut '0', activité varchar (20) NOT NULL par défaut 'mis à jour', object_id bigint (20) non signé NULL par défaut '0', type d'objet varchar (20) NOT NULL par défaut 'post', date_activité_actuelle NON NULL par défaut '0000-00-00 00:00:00', PRIMARY KEY (id_log), KEY id_utilisateur (id_utilisateur)) $ charset_collate ; "; dbDelta ($ sql_create_table);
Tout d'abord, il extrait tous les CREER LA TABLE
requêtes (vous pouvez transmettre plusieurs requêtes à dbDelta ()
à la fois, en les séparant par un ';
', mais pour améliorer la lisibilité, je préfère ne pas). A partir de là, prend le nom de la table, $ table
, et court
$ wpdb-> get_results ("DESCRIBE $ table;");
Cela retourne un tableau de colonnes existantes - chaque colonne est en fait un objet contenant des informations relatives à cette colonne (son nom, son type, sa valeur par défaut, etc.). Par exemple notre log_id
la colonne ressemble à:
Objet stdClass ([Field] => log_id [Type] => bigint (20) unsigned [Null] => NO [Key] => PRI [Par défaut] => [Extra] => auto_increment)
Si la table n'existe pas, un tableau vide est renvoyé et la table est créée. Autrement dbDelta ()
parcourt ensuite chaque ligne de la requête transmise, extrait les colonnes et les stocke dans un tableau $ cfields
. Il en va de même avec chacune des clés (y compris primaire).
Ensuite, il passe par chacun des existant colonnes. S'ils sont présents dans le tableau ci-dessus, $ cfields
, ils sont enlevés. Il compare ensuite leur type, s’ils ne correspondent pas, il génère automatiquement un ALTER TABLE
requête à effectuer plus tard. Après cela, les seules colonnes restantes dans $ cfields
sont ceux qui n'existent pas déjà. De cela, il génère plus ALTER TABLE
requêtes pour créer ces colonnes.
Il effectue ensuite une procédure presque identique pour les clés.
La capacité de dbDelta ()
faire toute cette analyse a un coût: sa falsification de ce qu’elle acceptera (ou interprétera correctement). Par exemple:
user_id bigint (20) unsigned NOT NULL par défaut '0', activity varchar (20) NOT NULL par défaut 'updated',
agira comme si le activité
la colonne n'est pas présente. Le format correct est:
user_id bigint (20) unsigned NOT NULL par défaut '0', activity varchar (20) NOT NULL par défaut 'updated',
KEY (user_id)]
il devrait plutôt être
KEY user_id (user_id)
(bien que le nom ne doive pas nécessairement être identique à la colonne).
CLÉ PRIMAIRE
et la déclaration de colonne: (log_id)
. Par exemple, PRIMARY KEY (log_id),
provoquera une erreur. Le format correct est:
PRIMARY KEY (log_id),
Ce n'est pas une liste complète, comme règle générale vous devez éviter les espaces supplémentaires autour et entre les mots-clés, tels que CRÉER
et TABLE
et il ne devrait y avoir aucun espace supplémentaire autour des colonnes. Les internes de dbDelta ()
compter sur l'utilisation preg_match ()
extraire des informations de l'instruction SQL transmise - et en tant que tel, les choses peuvent mal se passer assez facilement si cette instruction n'est pas correctement formatée.
Certaines de ces erreurs se produiront en silence (par exemple, si vous ne donnez pas une CLÉ
un nom, dbDelta ()
continuera à le dupliquer). Pour cette raison, il est important que vous inspectiez votre table manuellement (avec phpMyAdmin ou similaire) pour vérifier que votre code fonctionne correctement..
Avec dbDelta ()
, c'est très simple - supposons que nous voulions faire object_id
un index, ajouter une colonne supplémentaire user_ip
pour stocker l'adresse IP de l'utilisateur et modifier le type de la colonne d'activité en varchar (30)
, nous remplaçons simplement la requête SQL d'origine par:
$ sql_create_table = "CREATE TABLE". $ wpdb-> wptuts_activity_log. "(log_id bigint (20) unsigned NOT NULL auto_increment, user_id bigint (20) unsigned NOT NULL par défaut '0', user_ip varchar (15), activité par varchar (30) NON NULL par défaut 'updated', object_id bigint (20) unsigned NOT NULL par défaut '0', type d'objet varchar (20) NOT NULL par défaut 'post', date_activité datetime NON NULL par défaut '0000-00-00 00:00:00', PRIMARY KEY (id_log), KEY identifiant_utilisateur (id_utilisateur), KEY id_objet (id_objet),) $ charset_collate; ";
Ensuite, nous nous assurons que nous appelons wptuts_create_tables ()
dans la routine de mise à niveau, et les modifications prendront effet.
Puisque dbDelta ()
ne supprimera pas les colonnes, le simple fait de supprimer la ligne appropriée de la requête ne suffira pas (il faut quand même). Au lieu de cela, nous devons faire les choses manuellement.
Commencez par extraire un tableau de colonnes existantes:
$ existing_columns = $ wpdb-> get_col ("DESC $ wpdb-> wptuts_activity_log", 0);
Ensuite, si les colonnes que nous souhaitons supprimer sont présentes, nous pouvons les supprimer avec un ALTER TABLE
question:
$ remove_columns = array ('object_id'); // Tableau de colonnes à supprimer $ remove_columns = array_intersect ($ remove_columns, $ existing_columns); if (! empty ($ remove_columns)) $ wpdb-> query ("ALTER TABLE $ wpdb-> wptuts_activity_log DROP COLUMN" .implode (', DROP COLUMN', $ remove_columns). ';');
Comme nous l’avons fait avec les colonnes, obtenons d’abord un tableau d’index:
$ existing_keys = $ wpdb-> get_col ("SHOW INDEX FROM $ wpdb-> wptuts_activity_log WHERE nom_clé! = 'PRIMARY';", 2);
Ensuite, si les clés que nous souhaitons supprimer existent, nous pouvons les supprimer comme ci-dessus, mais en utilisant DROP INDEX
$ remove_keys = array ('user_id'); // Tableau de clés à supprimer $ remove_keys = array_intersect ($ remove_keys, $ existing_keys); if (! empty ($ remove_keys)) $ wpdb-> requête ("ALTER TABLE $ wpdb-> wptuts_activity_log DROP INDEX" .implode (', DROP INDEX', $ remove_keys). ';');
Maintenant que nous savons comment mettre à niveau notre base de données, voyons comment nous devrions gérer cela dans notre plug-in. Nous allons stocker toute notre gestion de mise à niveau à l'intérieur de la fonction: wptuts_activity_log_upgradecheck ()
. Notez que le crochet d’activation du plug-in ne pas déclenché lors de la mise à jour d'un plug-in: afin de nous assurer que notre routine de mise à niveau fonctionne, nous allons nous accrocher à admin_init
.
Pour vérifier les routines de mise à niveau à effectuer, nous stockons la version du plug-in dans la base de données. Nous allons comparer cette version (la version installée) à la version actuelle (activée) du plug-in:
add_action ('admin_init', 'wptuts_activity_log_upgradecheck'); function wptuts_activity_log_upgradecheck () // Version du plugin actuellement activé $ current_version = '1.3'; // Version de la base de données - cela peut nécessiter une mise à niveau. $ installed_version = get_option ('wptuts_activity_log_version'); if (! $ installed_version) // Pas de version installée - nous supposerons qu'elle vient d'être installée add_option ('wptuts_activity_log_version', $ current_version); elseif ($ installed_version! = $ current_version) / * * S'il s'agit d'une ancienne version, effectuez des mises à jour. * / // La version installée est antérieure à 1.1 - mise à niveau vers 1.1 si (version_compare ('1.1', $ installed_version)) // Code pour la mise à niveau vers la version 1.1 // La version installée est antérieure à 1.3 - mise à niveau vers 1.3 si (version_compare ( '1.3', $ installed_version)) // Code de mise à niveau vers la version 1.3 // La base de données est maintenant à jour: mettez à jour la version installée vers la dernière version update_option ('wptuts_activity_log_version', $ current_version);
Remarque: Il est important que cette routine de mise à niveau soit présente dans le initiale release car cela ajoutera la version initiale (1.0) à la base de données. Ne pas le faire peut causer des problèmes pour ceux qui passent de 1.0 à 1.1.
Chacune des routines de mise à niveau doit s'assurer que la base de données est à jour en utilisant le code décrit dans les sections précédentes. Fait important, si nous apportons des modifications à CREATE TABLE SQL, vous devez vous rappeler d’exécuter cette requête via dbDelta ()
(dans notre exemple, en appelant wptuts_create_tables ()
dans le cadre de la routine de mise à niveau) pour que les modifications prennent effet.
Soyez prudent avec la façon dont vous gérez les mises à jour lorsque vous utilisez dbDelta
. N'oubliez pas que certains utilisateurs peuvent effectuer une mise à niveau sur deux mises à jour ou plus. Donc, si de telles modifications ne peuvent pas être effectuées en parallèle - vous devrez alors effectuer la mise à niveau par étapes, en appelant plusieurs fois 'dbDelta ()', en effectuant les modifications appropriées pour cette étape..
Pendant que nous y sommes, examinons le nettoyage après la désinstallation du plug-in. Ce sont généralement des routines très simples: il suffit de supprimer la table de la base de données, les options enregistrées et les tâches cron que votre plug-in a activées. Nous accrochons notre routine au crochet de désinstallation à l'aide de register uninstall hook ()
enregistrer la désinstallation en attente (__ FILE __, 'wptuts_uninstall_plugin'); function wptuts_uninstall_plugin () global $ wpdb; // Supprime notre table (si elle existe) $ wpdb-> query ("DROP TABLE IF EXISTS $ wpdb-> wptuts_activity_log"); // Supprime la version de la base de données delete_option ('wptuts_activity_log_version'); / * Supprimez toutes les autres options installées par votre plug-in et supprimez toutes les tâches cron de plug-in * /