====== Ajouter une procédure d'installation de plugin ======
===== Introduction =====
Parfois, un plugin peut avoir besoin de paramètres supplémentaires ou de modifier le schéma de la base de données. Cette étape est couverte par la procédure d'installation automatique. En réalité cette procédure est semi-automatique laissant une assez grande flexibilité au développeur pour réaliser une procédure d'installation et de mise à jour de son travail.
===== Le fichier _install.php =====
Toute la procédure d'installation et mise à jour automatique passe par le fichier **_install.php** contenu dans votre plugin. Si un tel fichier existe, il sera appelé à chaque fois qu'un utilisateur se rendra sur le tableau de bord de son blog dans l'interface d'administration.
Le contenu de ce fichier est un code PHP indiquant son statut de trois manières :
* **return true** : le plugin a été installé
* **return** : rien à faire, aucun message (à utiliser quand rien n'est nécessaire)
* **throw new Exception**('message erreur') : en cas d'erreur
Voyons un exemple simple. Notre plugin s'appelle toto et va enregistrer sa version dans la table des versions.
plugins->moduleInfo('toto','version');
# On lit la version du plugin dans la table des versions
$i_version = $core->getVersion('toto');
# La version dans la table est supérieure ou égale à
# celle du module, on ne fait rien puisque celui-ci
# est installé
if (version_compare($i_version,$m_version,'>=')) {
return;
}
# La procédure d'installation commence vraiment là
$core->setVersion('toto',$m_version);
?>
===== Créer de nouvelles préférences =====
Votre plugin peut avoir besoin de préférences pour fonctionner. Utiliser l'auto installation pour les créer est une bonne idée.
Voici un exemple d'un système d'installation automatique ajoutant une préférence globale :
plugins->moduleInfo('toto','version');
$i_version = $core->getVersion('toto');
if (version_compare($i_version,$m_version,'>=')) {
return;
}
# Création du setting (s'il existe, il ne sera pas écrasé)
$settings = new dcSettings($core,null);
$settings->setNamespace('toto');
$settings->put('toto_setting',true,'boolean','toto setting',false,true);
$core->setVersion('toto',$m_version);
?>
Le paramètre de setNamespace() ne doit contenir aucune majuscule, chiffre ou caractère accentué.
Permis : [a-z]
Le paramètre $type de put peut-être 'string', 'integer', 'float', 'boolean' ou 'null'.
Si $type est 'null' et que setting existe, le type courant sera conservé.
En dehors, le type 'string' sera appliqué.
FIXME créer une page sur le système de préférences
===== Modifier le schéma de la base de données =====
Une des possibilités les plus intéressantes du système d'installation est de pouvoir très facilement modifier le schéma de la base de données. Vous pouvez donc facilement créer de nouvelles tables, ajouter un champ dans une table existante, créer des index ou des références.
==== UDBS ====
UDBS signifie "Universal DataBase Schema". Ce système permet de définir un schéma de base de données puis le comparer avec celui existant pour éventuellement le mettre à jour.
Du fait de sa capacité à travailler avec plusieurs types de bases de données, UDBS présente quelques limites :
* Aucun champ ne sera supprimé. UDBS ne fait que des création ou des mise à jour.
* UDBS peut renommer un index ou en changer les champs mais pas les deux en même temps (il créera un nouvel index)
* Seuls un certain nombre de types de données sont permis.
==== Types de données autorisés ====
Devant fonctionner à la fois avec MySQL, PostgreSQL et SQLite, UDBS ne permet qu'un certain nombre de types de données :
| **smallint** | Entier signé de 2 octets |
| **integer** | Entier signé de 4 octets |
| **bigint** | Entier signé de 8 octets |
| **real** | Nombre flottant de 4 octets |
| **float** | Nombre flottant de 8 octets |
| **numeric** | Valeur numérique exacte |
| **date** | Date calendaire (jour, moins, année) |
| **time** | Heure de la journée |
| **timestamp** | Date et heure |
| **char** | Une chaîne de longueur fixe de n caractères |
| **varchar** | Une chaîne de longueur variable de n caractères |
| **text** | Un texte de longueur variable |
==== Instance d'un objet dbStruct ====
En créant une instance de **dbStruct** vous allez pouvoir définir un schéma (complet ou partiel).
$s = new dbStruct($core->con,$core->prefix);
La classe prend un object de type connection et les préfixe que l'on souhaite utiliser. Dans l'exemple précédant et les suivants, nous utiliserons les objects disponibles avec Dotclear.
==== Définir une table ====
**dbStruct** et **dbStructTable** proposent des particularités bien pratiques.
* La plupart des méthodes renvoient **$this** ce qui permet de les chaîner entre-elles.
* Tout appel à une propriété inexistante de **dbStruct** revient à créer un objet **dbStructTable** s'il n'existe pas et à récupérer l'instance.
* Tout appel à une méthode inexistante de **dbStructTable** revient à appeler la méthode **field** qui ajoute un champs dans la table.
Voici un exemple classique n'utilisant pas les propriétés avancées de **dbStruct** :
$s = new dbStruct($core->con,$core->prefix);
$t = $s->table('matable');
$t->field('champ1','varchar',255,false,"'-'");
$t->field('champ2','smallint',0,true);
Dans cet exemple, nous définissons la table **matable** à laquelle nous ajoutons deux champs :
* **champ1**, de type varchar de longueur 255 ne pouvant être nul et ayant la valeur par défaut '-'
* **champ2**, de type smallint pouvant être nul et n'ayant pas de valeur par défaut.
Ce premier exemple fonctionne très bien mais voici également comment on peut l'écrire pour faire exactement la même chose :
$s = new dbStruct($core->con,$core->prefix);
$s->matable
->champ1('varchar',255,false,"'-'")
->champ2('smallint',0,true)
;
C'est tout de même plus pratique.
==== Ajouter un index ====
Pour ajouter un index à votre extension du schéma :
$s->matable->index('idx_matable_champ1','btree','champ2');
La méthode **index** prend comme paramètres : le nom de l'index, le type ("btree" uniquement) et au moins un nom de champ concerné. Vous pouvez ajouter d'autres champs comme paramètres supplémentaires à la méthode.
==== Ajouter une clé primaire à une table ====
$s->matable->primary('pk_matable','champ1');
Comme pour la méthode **index**, cette méthode peut prendre plus de deux paramètres si la clé est réalisée sur plusieurs champs de la table.
==== Ajouter une clé unique ====
$s->matable->unique('uk_matable','champ2');
Comme pour la méthode **index**, cette méthode peut prendre plus de deux paramètres si la clé est réalisée sur plusieurs champs de la table.
==== Ajouter une référence à une autre table ====
Les références permettent d'indiquer si le champ d'une table est lié à celui d'une autre. Elles permettent d'assurer l'intégrité des données et d'automatiser certains processus tels que la suppression ou la mise à jour. On les appelle aussi "clés étrangères".
$s->category->reference('fk_category_blog','blog_id','blog','blog_id','cascade','cascade');
Cet exemple crée la référence **fk_category_blog** sur le champ **blog_id** de la table **category** référençant le champ **blog_id** de la table **blog**. Les deux derniers paramètres sont les actions possibles dans les cas respectifs de mise à jour et de suppression d'une valeur référencée.
==== Synchronisation du schéma ====
Une fois un schéma écrit, il est nécessaire de le synchroniser. Voici comment faire avec le code précédent :
$s = new dbStruct($core->con,$core->prefix);
$s->matable
->champ1('varchar',255,false,"'-'")
->champ2('smallint',0,true)
;
$si = new dbStruct($core->con,$core->prefix);
$changes = $si->synchronize($s);
Comme vous le voyez, on crée une nouvelle instance de **dbStruct** puis on appelle la méthode **synchronize** en lui passant l'instance de **dbStruct** précédente. Cette méthode va retourner le nombre de changements réalisés.