====== 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);
?>
Attention, le nom passé à l'appel à //moduleInfo// n'est pas forcément le nom du plugin défini dans //_define.php//: il s'agit du nom du répertoire où se trouve votre plugin !
===== 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é)
$core->blog->settings->addNamespace('toto');
$settings->toto->put('toto_setting',true,'boolean','toto setting',false,true);
$core->setVersion('toto',$m_version);
?>
Le paramètre de addNamespace() ne doit contenir que des chiffres ou des lettres sans accent.
Permis : [a-zA-Z][a-zA-Z0-9]
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é.
Voyez la documentation sur les [[.:settings|paramètres]] pour utiliser les paramètres après l'installation.
===== 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, mois, 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 objet de type connexion et les préfixes que l'on souhaite utiliser. Dans l'exemple précédent et les suivants, nous utiliserons les objets 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 champ 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.
==== Interaction avec le plugin Import/Export ====
* [[http://tips.dotaddict.org/fiche/Sauvez-sauvez-il-en-restera-toujours-quelque-chose|Sauvegarder la table lors de l'export d'un blog]]