Il arrive fréquemment qu'un thème ou une extension ait besoin de ses propres tables.
Les nouvelles tables seront ajoutées à la base de données WordPress afin que le site puisse trouver toutes les données dont il a besoin à partir d'une seule base de données.
En effet, si on avait créé une deuxième base de données, il aurait fallu créer un autre objet pour interroger cette BD. Puisque ceci rendrait le code inutilement complexe, il est préférable d'ajouter vos tables dans la BD originale de votre site WordPress.
La fonction dbDelta() permet de créer et de mettre à jour ces tables de façon intéressante et efficace.
Attention : il ne faut jamais modifier la structure des tables qui font partie du noyau de WordPress.
Si vous le faites, vous risquez de perdre vos modifications lors de la prochaine mise à jour.
L'idée de base de dbDelta() est la suivante :
La fonction dbDelta() ne fait pas partie du noyau WordPress. Elle est définie dans le fichier wp-admin/includes/upgrade.php. Il faut donc ajouter une instruction require_once() avant son utilisation :
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
$taches_realisees = dbDelta(...);
La valeur de retour de dbDelta() est souvent inutilisée. Pourtant, elle permet de savoir ce qui a été réalisé dans la structure de la table, par exemple :
[gds5_monprefixebd_matable] => Created table gds5_monprefixebd_matable]
ou
[gds5_monprefixebd_matable.nouveauchamp] => Added column gds5_monprefixebd_matable.nouveauchamp
Le meilleur endroit pour créer les tables personnalisées est lors de l'activation du thème ou de l'extension. Le code sera donc placé à l'un des endroits suivants :
Si les tables sont utilisées par un thème, on utilisera le hook after_switch_theme dans le fichier functions.php du thème ou dans un de ses sous-fichiers, par exemple tableau-de-bord-tables.php.
add_action( "after_switch_theme", "monprefixe_creer_tables" );
Si les tables sont utilisées par une extension, on utilisera la fonction register_activation_hook() dans la classe de l'extension. Dans l'exemple suivant, l'appel à register_activation_hook() a lieu dans le constructeur de la classe. La méthode creer_tables() est, elle aussi, définie dans la classe de l'extension.
register_activation_hook( __FILE__, array( $this, 'creer_tables' ) );
Attention : lors du développement de votre thème ou de votre extension, si vous créez des tables en utilisant after_switch_theme ou register_activation_hook(), vous devrez, dans votre tableau de bord, activer un autre thème puis revenir à votre thème ou encore désactiver puis réactiver l'extension pour que la fonction de rappel soit exécutée.
Ce problème ne se posera pas lorsqu'un autre site utilisera votre thème ou votre extension : dès qu'il l'activera, la fonction de rappel sera exécutée.
Afin d'éviter les conflits avec les extensions ou avec le noyau WordPress, il est important d'ajouter les précautions suivantes :
Le nom complet sera du genre prefixe_monprefixebd_manouvelletable. Ex : fjdk4_christiane_categories.
Notez que dans la plupart des cas, ce préfixe sera le même que celui utilisé pour assurer que vos fonctions portent un nom unique. Cependant, ceci n'est pas obligatoire puisqu'il n'y a aucun lien entre les deux.
La structure de la table doit être définie à l'aide d'une requête CREATE TABLE.
Afin de vous assurer que la table utilise le bon jeu de caractères et le bon interclassement, il est astucieux de lire ces configurations dans le fichier wp-config.php à l'aide de la méthode $wpdb->get_charset_collate().
Lors de la définition de la requête SQL, il faut absolument respecter les règles suivantes :
Il ne faut pas entourer le nom des champs par des guillemets obliques (en anglais : backticks).
Exemple à ne pas faire :
`description` varchar(50)
Il faut plutôt faire :
description varchar(50)
Voici un extrait de code pour créer une table personnalisée :
/**
* Crée les tables personnalisées pour mon thème enfant.
* @author Christiane Lagacé <christiane.lagace@hotmail.com>
*
* Utilisation : add_action( "after_switch_theme", "monprefixe_creer_tables" );
*/
function monprefixe_creer_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_matable = $wpdb->prefix . 'monprefixebd_matable';
$sql = "CREATE TABLE $table_matable (
id bigint(20) unsigned NOT NULL auto_increment,
description varchar(50) NOT NULL,
autrechamp int NULL,
PRIMARY KEY (id)
) $charset_collate;";
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
$taches_realisees = dbDelta( $sql );
monprefixe_log_debug($taches_realisees);
$erreur_sql = $wpdb->last_error;
if ('' != $erreur_sql) {
// réagir en cas de problème
monprefixe_log_debug("Erreur lors de la création de la table $table_matable.");
// ...
}
}
Si vous allez voir la structure des tables du noyau WordPress, vous remarquerez que les identifiants sont tous de type bigint(20) unsigned. Il serait sage d'employer ce même type pour les identifiants de vos tables personnalisées.
De plus, si une de vos tables contient une clé étrangère liée à un de ces identifiants, vous devrez prendre soin de lui donner à elle aussi le type bigint(20) unsigned.
Si vous avez besoin d'ajouter des données initiales dans la table, vous pouvez utiliser la fonction $wpdb->insert() après avoir appelé dbDelta().
Dans cet exemple, un seul enregistrement est ajouté. Je vous propose un algorithme pour insérer plusieurs enregistrements sur la fiche « Insérer plusieurs enregistrements dans une table ».
$reussite = $wpdb->insert(
$table_matable,
array(
'description' => 'blablabla',
'autrechamp' => 1
),
array(
'%s',
'%d'
)
);
if ( ! $reussite ) {
// réagir en cas de problème
monprefixe_log_debug( $wpdb->last_error );
// ...
}
Attention : tenez compte du fait qu'un thème ou une extension peut être activée et désactivée plusieurs fois. Votre code devra s'assurer que les insertions de données ne soient effectuées qu'une fois...
Une technique intéressante consiste à vérifier si la table visée par dbDelta() contient des enregistrements.
On pourrait aussi choisir de vérifier la présence d'un enregistrement précis.
L'algorighme suivant évitera que les données initiales soient insérées plusieurs fois si le thème ou l'extension était activée et désactivée plusieurs fois.
$requete = "SELECT COUNT(*) FROM $table_matable";
$presence_donnees = $wpdb->get_var( $requete );
if ( is_null( $presence_donnees ) ) {
$presence_donnees = 0; // valeur si on ne réussissait pas à retrouver l'info dans la BD
}
if ( ! $presence_donnees ) {
// insertion des données initiales
// ...
}
« Creating Tables with Plugins ». Codex WordPress. http://codex.wordpress.org/Creating_Tables_with_Plugins
« Chapter 11 Data Types ». MySQL. https://dev.mysql.com/doc/refman/8.0/en/data-types.html
▼Publicité