<?xml version="1.0" encoding="UTF-8"?> <!-- <!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook V4.1//EN"> --> <chapter id="customization"> <title>Personnalisation de Bugzilla</title> <section id="cust-templates"> <title>Personnalisation des modèles</title> <para> Les administrateurs peuvent configurer l'aspect et la convivialité de Bugzilla sans avoir à éditer des fichiers Perl ou à être confrontés au cauchemar des conflits massifs de fusion quand, plus tard, ils mettront à niveau avec une version plus récente. </para> <para> L'utilisation de modèles rend également possible, pour la première fois, les versions de Bugzilla adaptées selon la région. Il est possible de faire en sorte que la langue de l'interface utilisateur de Bugzilla soit déterminée par le navigateur de l'utilisateur. Vous trouverez davantage d'informations dans <xref linkend="template-http-accept"/>. </para> <section id="template-directory"> <title>Structure du répertoire de modèles</title> <para> La structure de répertoires des modèles est composée d'un répertoire de haut niveau nommé <filename>template</filename>, qui contient un répertoire pour chaque région installée. Le niveau suivant définit la langue utilisée dans les modèles. Bugzilla est livré avec des modèles en anglais, le nom du répertoire est donc <filename>en</filename>, et nous parlerons de <filename>template/en</filename> dans toute la documentation. En dessous de ça, template/en est un répertoire <filename>default</filename> qui contient tous les modèles standard fournis avec Bugzilla. </para> <warning> <para> Un répertoire <filename>data/templates</filename> existe aussi ; c'est là où Template Toolkit met les versions compilées à partir des répertoires par défaut ou personnalisés. N'éditez <emphasis>pas</emphasis> directement les fichiers dans ce répertoire, ou alors toutes vos modifications seront perdues la prochaine fois que Template Toolkit recompilera les modèles. </para> </warning> </section> <section id="template-method"> <title>Choix d'une méthode de personnalisation</title> <para> Si vous voulez éditer des modèles Bugzilla, la première choix à faire est de décider comment vous allez vous y prendre. Il y a deux possibilités et celle que vous utiliserez dépend principalement de la portée de vos modifications, et de la méthode que vous prévoyez d'utiliser pour mettre à niveau Bugzilla. </para> <para> La première méthode pour personnaliser les modèles consiste à éditer directement ceux qui sont dans <filename>template/en/default</filename>. C'est probablement la meilleure méthode pour de petites modifications si vous comptez utiliser la méthode de mise à niveau par CVS, parce qu'alors, si vous exécutez un <command>cvs update</command>, toute correction dans un modèle s'intègrera automagiquement dans les versions que vous aurez mises à jour. </para> <note> <para> Si vous utilisez cette méthode, et si des conflits CVS surviennent pendant une mise à jour, les modèles en conflit (et éventuellement d'autres parties de votre installation) ne fonctionneront pas tant qu'ils ne seront pas résolus. </para> </note> <para> L'autre méthode consiste à copier les modèles à modifier dans une arborescence de répertoires miroir sous <filename>template/en/custom</filename>. Les modèles de cette arborescence de répertoire prennent le pas sur tous les modèles de même nom et situés au même endroit dans le répertoire <filename>default</filename>. </para> <note> <para> Le répertoire <filename>custom</filename> n'existe pas initialement et doit être créé si vous voulez l'utiliser. </para> </note> <para> C'est la technique que vous devez utiliser si vous utilisez la méthode de mise à niveau par réécriture, parce qu'autrement vos modifications seront perdues. Cette méthode est peut-être également la meilleure si vous utilisez la méthode de mise à niveau par CVS et que vous comptez faire des modifications majeures, car il est garanti que le contenu de ce répertoire ne sera pas touché au cours d'une mise à niveau, et vous pouvez alors décider soit de continuer en utilisant votre propre modèle, soit de faire l'effort d'intégrer à la main vos modifications dans les nouvelles versions. </para> <para> Avec cette méthode, votre installation peut être perdue en cas de modifications incompatibles faites à l'interface des modèles. Si de telles modifications sont faites, elles seront détaillées dans la notice de la version, à condition que vous utilisiez une version stable de Bugzilla. Si vous utilisez du code instable, vous devrez vous occuper de ça vous-même, bien que, autant que possible, les modifications seront citées, avant qu'elles ne s'appliquent, dans la partie <quote>À éviter</quote> de la notice de la précédente version stable. </para> <note> <para> Quelle que soit la méthode que vous avez choisie, il est recommandé d'exécuter <command>./checksetup.pl</command> après la création ou l'édition de tout modèle dans le répertoire <filename>template/en/default</filename>, et après l'édition de tout modèle dans le répertoire <filename>custom</filename>. </para> </note> <warning> <para> Il est <emphasis>indispensable</emphasis> d'exécuter <command>./checksetup.pl</command> après la création d'un nouveau modèle, dans le répertoire <filename>custom</filename>. Si vous ne le faites pas, cela entraînera un message d'erreur incompréhensible. </para> </warning> </section> <section id="template-edit"> <title>Méthode d'édition de modèles</title> <note> <para> Si vous apportez des modifications aux modèles que vous souhaitez voir inclus dans le Bugzilla standard, il faut lire les parties correspondantes du <ulink url="http://www.bugzilla.org/docs/developer.html">guide des développeurs</ulink>. </para> </note> <para> La syntaxe du langage de Template Toolkit dépasse le cadre de ce guide. Elle est assez facile à comprendre en regardant les modèles actuels ; vous pouvez également lire le manuel, disponible sur la <ulink url="http://www.template-toolkit.org">page d'accueil de Template Toolkit</ulink>. </para> <para> Cependant, une chose à laquelle vous devriez apporter un soin particulier est la nécessité de filtrer correctement, par rapport au langage HTML, les données qui ont été transmises dans le modèle. Cela signifie que si les données sont susceptibles de contenir des caractères HTML spéciaux comme <, et que les données ne sont pas sensées être du HTML, elles doivent être converties sous la forme d'entité, c'est-à-dire &lt; on utilise le filtre <quote>html</quote> de Template Toolkit pour faire cela. Si vous ne le faîtes pas, vous pouvez exposer votre installation à des attaques par scripts à l'intérieur du site. </para> <para> Notez également que Bugzilla inclut de lui-même quelques filtres, qui ne sont pas dans le Template Toolkit standard. En particulier, le filtre <quote>url_quote</quote> peut convertir les caractères qui sont illégaux ou qui ont un sens particulier dans les URL, comme &, en une forme encodée, c'est-à-dire %26. En fait, celui-ci encode la plupart des caractères (mais pas les plus fréquents comme les lettres et les nombres et cætera), y compris les caractères HTML spéciaux, de sorte que, par la suite, vous n'avez jamais besoin de filtrer par rapport au langage HTML. </para> <para> Editer des modèles est une bonne façon de faire les <quote>champs personnalisés du pauvre</quote>. Par exemple, si vous n'utilisez pas le Tableau Blanc mais que vous souhaitez disposer d'une boîte d'entrée de texte de forme libre pour le <quote>Identifiant de Création</quote>, vous pouvez vous contenter d'éditer les modèles pour changer le nom des champs. Ca s'appellera toujours status_whiteboard en interne, mais vos utilisateurs n'ont pas besoin de le savoir. </para> </section> <section id="template-formats"> <title>Formats et type des modèles</title> <para> Certains CGI sont capables d'utiliser plus d'un modèle. Par exemple, <filename>buglist.cgi</filename> peut générer des listes de bogues en RDF ou en 2 formes différentes de HTML (complexe et simple). Le mécanisme qui fournit ce dispositif est extensible. </para> <para> Bugzilla peut supporter différents types de sorties, qui peuvent eux aussi avoir des formats multiples. Pour demander un certain type, vous pouvez joindre le &ctype=<contenttype> (tel que rdf ou html) au lien <filename><cginame>.cgi</filename>. Si vous souhaitez rechercher un certain format, vous pouvez utiliser le &format=<format> (comme simple ou complex) dans l'URL. </para> <para> Pour savoir si un CGI supporte plusieurs formats de sortie et plusieurs types, effectuez un grep sur le CGI pour <quote>GetFormat</quote>. S'il n'y en a pas, l'ajout de support de plusieurs formats/types n'est pas trop dur ; regardez comment c'est fait dans d'autres CGI, i.e. config.cgi. </para> <para> Pour faire un nouveau modèle de format pour un CGI qui supporte ça, ouvrez un modèle existant pour ce CGI et prenez note du commentaire INTERFACE (s'il est présent). Ce commentaire définit quelles variables sont passées dans ce modèle. S'il n'y en a pas, j'ai bien peur que vous deviez lire le modèle et le code pour voir ce que vous avez comme informations. </para> <para> Vous pouvez écrire votre modèle dans n'importe quel style de balisage ou de texte qui convient. </para> <para> Il vous faut maintenant choisir le type de contenu dans lequel vous voulez qu'il soit utilisé. Les types de contenu sont définis dans le fichier <filename>Bugzilla/Constants.pm</filename> dans la constante <filename>contenttypes</filename>. Si votre type de contenu ne s'y trouve pas, ajoutez le. Mémorisez l'étiquette de trois ou quatre lettres affectée à votre type de contenu. Cette étiquette fera partie du nom de fichier du modèle. </para> <note> <para> Après l'ajout ou la modification d'un type de contenu, il convient d'éditer <filename>Bugzilla/Constants.pm</filename> afin de répercuter les modifications. En outre, le fichier doit être conservé à jour après une mise à jour si des types de contenu ont été personnalisés dans le passé. </para> </note> <para> Enregistrez le modèle sous <filename><stubname>-<formatname>.<contenttypetag>.tmpl</filename>. Testez le modèle en appelant le CGI par <filename><cginame>.cgi?format=<formatname>&ctype=<type></filename>. </para> </section> <section id="template-specific"> <title>Modèles particuliers</title> <para> Il y a quelques modèles qui pourraient vous intéresser tout particulièrement pour personnaliser votre installation. </para> <para> <command>index.html.tmpl</command> : c'est la page d'accueil de Bugzilla. </para> <para> <command>global/header.html.tmpl</command> : définit l'en-tête qui apparaît sur toutes les pages de Bugzilla. L'en-tête inclut la bannière, qui est ce qui apparaît aux utilisateurs et qui est probablement ce que vous voulez éditer plutôt que l'en-tête. Cependant, l'en-tête inclut également la section HTML HEAD, vous pourriez donc par exemple ajouter une feuille de style ou une balise META en éditant l'en-tête. </para> <para> <command>global/banner.html.tmpl</command> : contient la <quote>bannière</quote>, la partie de l'en-tête qui apparaît en haut de toutes les pages de Bugzilla. La bannière par défaut est assez sommaire, vous voudrez donc probablement la personnaliser pour donner à votre installation son propre aspect et sa propre convivialité. Il est recommandé de conserver le numéro de version Bugzilla sous une forme ou une autre pour permettre de déterminer la version que vous utilisez, et que les utilisateurs sachent quelle documentation ils doivent lire. </para> <para> <command>global/footer.html.tmpl</command> : définit le pied de page qui apparaît sur toutes les pages de Bugzilla. En l'éditant, vous avez un autre moyen de donner rapidement son propre aspect et sa propre convivialité à votre installation Bugzilla. </para> <para> <command>global/variables.none.tmpl</command> : définit une liste de termes qui peuvent être modifiés afin <quote>d'estampiller</quote> l'instance Bugzilla. De cette manière, les termes tels que <quote>bugs</quote> peuvent être remplacés par <quote>problèmes</quote> dans toute l'installation Bugzilla. Le nom <quote>Bugzilla</quote> et d'autres mots peuvent être tout aussi bien personnalisés. </para> <para> <command>list/table.html.tmpl</command> : ce modèle gère l'apparence des listes de bogues créées par Bugzilla. En éditant ce modèle, on peut modifier la largeur et le titre des colonnes une par une, la taille maximale de l'affichage pour chaque entrée, et le comportement de l'enveloppe des entrées longues. Pour les longues listes de bogues, Bugzilla insère un <quote>break</quote> tous les 100 bogues par défaut ; ce comportement est également géré par ce modèle, et c'est là que cette valeur pourra être modifié. </para> <para> <command>bug/create/user-message.html.tmpl</command> : message qui apparaît près du haut de la page de soumission de bogues. En le modifiant, vous pouvez dire à vos utilisateurs comment soumettre des bogues. </para> <para> <command>bug/process/midair.html.tmpl</command> : ceci est le modèle utilisé si deux personnes modifient un bug simultanément. La deuxième personne a soumettre une modification verra apparaître cette page indiquant la modification apportée par la première personne et demandant s'ils veulent écraser cette modification ou revenir sur le bogue. Le titre et l'en-tête par défaut de cette page est <quote>Collision en plein vol détectée !</quote> Si vous travaillez dans l'industrie aero-nautique ou un autre milieu ou ceci peut géner quelqu'un (oui, on nous a rapporté des histoires vraies à ce sujet), vous voudrez peut-être changer cette phrase. </para> <para> <command>bug/create/create.html.tmpl</command> et <command>bug/create/comment.txt.tmpl</command> : vous n'avez peut-être pas envie de vous casser la tête à créer des zones personnalisées dans Bugzilla, mais vous voulez être sûr que chaque rapport de bogue contienne un nombre d'informations importantes pour lesquelles il n'y a pas de zone spéciale. Le système d'entrée de bogues a été conçu sous une forme extensible pour vous permettre d'ajouter arbitrairement des gadgets HTML, tels que listes déroulantes et zones de texte, à la page d'entrée de bogues et de faire apparaître leurs valeurs formatées dans la description initiale. Un champ caché qui indique le format doit être ajouté à l'intérieur du formulaire afin de rendre le modèle fonctionnel. Sa valeur doit être le suffixe de nom du fichier du modèle. Par exemple, si le fichier s'appelle <filename>create-cust.html.tmpl</filename>, alors </para> <programlisting> <input type="hidden" name="format" value="cust"> </programlisting> <para> doit être utilisé à l'intérieur du formulaire. </para> <para> Un exemple en est le <ulink url="http://landfill.bugzilla.org/bugzilla-tip/enter_bug.cgi?product=WorldControl&format=guided">formulaire de soumission de bogues</ulink> de mozilla.org. Le code pour cela est livré avec la distribution Bugzilla comme exemple à copier par vous. Vous le trouverez dans les fichiers <filename>create-guided.html.tmpl</filename> et <filename>comment-guided.html.tmpl</filename>. </para> <para> Donc pour utiliser ce dispositif, créez un modèle personnalisé pour <filename>enter_bug.cgi</filename>. Le modèle par défaut, sur lequel vous pouvez vous baser, est <filename>custom/bug/create/create.html.tmpl</filename>. Nommez le <filename>create-<formatname>.html.tmpl</filename> et ajoutez y des gadgets pour chaque information que vous aimeriez voir collectée : un numéro de création, l'ensemble des étapes pour le reproduire. </para> <para> Puis, créez un modèle comme <filename>custom/bug/create/comment.txt.tmpl</filename>, et nommez le <filename>comment-<formatname>.txt.tmpl</filename>. Ce modèle doit renvoyer aux champs du formulaire que vous avez créé en utilisant la syntaxe <filename>[% form.<fieldname> %]</filename>. Quand un rapport de bogue est soumis, le commentaire initial joint au rapport de bogue sera formaté d'après la disposition de ce modèle. </para> <para> Par exemple, si votre modèle enter_bug possédait un champ </para> <programlisting> <input type="text" name="buildid" size="30"> </programlisting> <para> et que votre comment.txt.tmpl avait </para> <programlisting> BuildID : [% form.buildid %] </programlisting> <para> alors </para> <programlisting> BuildID : 20020303 </programlisting> <para> apparaîtrait dans le commentaire initial. </para> </section> <section id="template-http-accept"> <title>Configurer Bugzilla pour détecter la langue de l'utilisateur</title> <para> Bugzilla prend en compte l'en-tête HTTP Accept: de l'utilisateur. Vous pouvez installer des modèles dans d'autres langues, et Bugzilla retiendra le plus approprié d'après l'ordre de priorités que vous avez défini. Beaucoup de modèles de langue peuvent être récupérés à partir de <ulink url="http://www.bugzilla.org/download.html#localizations"/>. Les instructions pour intégrer de nouvelles langues sont aussi disponibles à cet endroit. </para> <para> Après avoir décompressé les localisations (ou créé les vôtres) dans le répertoire <filename class="directory">BUGZILLA_ROOT/template</filename>, vous devez mettre à jour le paramètre <option>languages</option> pour contenir toutes les adaptations que vous aimeriez laisser. Vous pouvez également, si vous le souhaitez, modifier le paramètre <option>defaultlanguage</option> en remplaçant <quote>en</quote> par autre chose si vous ne voulez pas l'anglais comme langue par défaut. </para> </section> </section> <section id="cust-hooks"> <title>Crochets de modèles</title> <warning> <para> Les crochets Template ont besoin du Template Toolkit version 2.12 ou plus, ou l'application d'un correctif. Voir le <ulink url="http://bugzilla.mozilla.org/show_bug.cgi?id=239112">bogue 239112</ulink> pour plus d'informations. </para> </warning> <para> Les crochets Template permettent aux extensions de Bugzilla d'insérer du code dans les modèles Bugzilla standard sans modifier les fichiers du modèle eux-mêmes. Le mécanisme de crochets définit une API cohérente pour étendre les modèles standards de manière à séparer proprement le code standard du code d'extension. Les crochets réduisent les conflits de fusion et facilitent l'écriture d'extensions qui fonctionnent pour de multiples versions de Bugzilla, ce qui facilite la mise à jour d'une installation Bugzilla avec des extensions installées. </para> <para> Un crochet de modèle est juste un emplacement nommé dans un fichier de modèle standard où les fichiers du modèle d'extension pour ce crochet sont traités. Chaque crochet a un répertoire correspondant dans l'arborescence de Bugzilla. Accrocher un modèle d'extension à un crochet est aussi simple que de mettre le fichier d'extension dans le répertoire du crochet. Les crochets eux-mêmes peuvent être ajoutés dans un modèle standard sur demande des auteurs de l'extension. </para> <para> Pour utiliser des crochets afin d'étendre un modèle Bugzilla, assurez vous d'abord qu'il y a un crochet à l'emplacement approprié dans le modèle que vous voulez étendre. Les crochets apparaissent dans les modèles standard Bugzilla en tant que simple directive dans le format <literal role="code">[% Hook.process("<varname>nom</varname>") %]</literal>, où <varname>nom</varname> est (dans ce modèle) l'unique nom du crochet. </para> <para> Si vous n'êtes pas sûr quel modèle vous voulez étendre ou que vous voulez juste passer en revue les crochets disponibles, vous pouvez soit utiliser votre outil de recherche multi-fichiers préféré (i.é. <command>grep</command>) pour chercher parmi les modèles standards les occurrences de <methodname>Hook.process</methodname>, soit passer en revue l'arborescence Bugzilla dans <filename>BUGZILLA_ROOT/template/en/extension/hook/</filename>, qui contient un répertoire pour chaque crochets à l'emplacement suivant : </para> <para> <filename>BUGZILLA_ROOT/template/en/extension/hook/CHEMIN_VERS_MODÈLE_STANDARD/NOM_MODÈLE_STANDARD/NOM_CROCHET/</filename> </para> <para> S'il n y a pas de crochets à l'emplacement approprié dans le modèle Bugzilla que vous voulez étendre, faites <ulink url="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=User%20Interface">un rapport de bogue pour en demander un</ulink>, en spécifiant : un lien vers les informations à propos de votre extension, s'il y en a. S'il n'y a pas de crochets à l'endroit approprié dans le modèle Bugzilla que vous souhaitez étendre, <ulink url="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=User%20Interface">rapportez un bug pour en demander un</ulink>, en précisant : </para> <simplelist> <member>le modèle pour lequel vous demandez un crochet </member> <member> où vous aimeriez que le crochet soit placé dans le modèle (numéro de ligne/position pour la dernière version de modèle dans le CVS ou description du but du crochet) ; </member> <member>le but de ce crochet ;</member> <member> un lien vers les informations à propos de votre extension, s'il y en a. </member> </simplelist> <para> Les responsables de l'examen des bogues de Bugzilla examineront sans délai chaque demande de crochet, nommeront le crochet et l'ajouteront au modèle, vérifieront les nouvelles versions du modèle dans le CVS, et créeront le répertoire correspondant dans <filename>BUGZILLA_ROOT/template/en/extension/hook/</filename>. </para> <para> Vous pouvez en option joindre un correctif au bogue qui implémente le crochet et l'enregistrer vous-même après avoir reçu l'accord d'un vérificateur Bugzilla. Les développeurs peuvent suggérer des modifications de l'emplacement d'un crochet en se basant sur l'analyse de vos besoins ou pour que le crochet puisse satisfaire les besoins d'extensions multiples mais la procédure permettant d'approuver et d'enregistrer les crochets n'est pas aussi rigoureuse que la procédure pour les modifications générales de Bugzilla, et toute extension, qu'elle soit sortie ou toujours en développement, peut avoir des crochets ajoutés pour répondre à leurs besoins. </para> <para> Après vous être assuré que le crochet dont vous avez besoin existe (ou après l'avoir récupéré si ce n'est pas le cas), ajoutez votre modèle d'extension au répertoire de l'arborescence correspondant au crochet. </para> <para> Oui, c'est tout ! Maintenant, quand le modèle standard contenant le crochet sera traité, votre modèle d'extension sera traité à l'endroit où le crochet apparaît. </para> <para> Par exemple, disons que vous avez une extension nommée Projman qui ajoute les possibilités de gestion de projet à Bugzilla. Projman a une interface d'administration <filename>edit-projects.cgi</filename> et vous voulez ajouter un lien vers elle dans la barre de navigation en bas de toutes les pages Bugzilla pour ceux parmi les utilisateurs qui sont autorisés à administrer les projets. </para> <para> La barre de navigation est générée par le fichier <filename>useful-links.html.tmpl</filename> du modèle, qui est placé dans le sous-répertoire <filename>global/</filename> sur le chemin <filename>BUGZILLA_ROOT/template/en/default/</filename> d'un modèle Bugzilla standard. Si vous regardez dans <filename>useful-links.html.tmpl</filename>, vous trouverez le crochet suivant à la fin de la liste des liens d'administration Bugzilla standard : </para> <programlisting><![CDATA[ ... [% ', <a href="editkeywords.cgi">keywords</a>' IF user.groups.editkeywords %] [% Hook.process("edit") %] ... ]]></programlisting> <para> Le répertoire correspondant pour ce crochet est <filename>BUGZILLA_ROOT/template/en/extension/hook/global/useful-links.html.tmpl/edit/</filename>. </para> <para> Vous mettez un modèle nommé <filename>projman-edit-projects.html.tmpl</filename> dans ce répertoire avec le contenu suivant : </para> <programlisting><![CDATA[ ...[% ', <a href="edit-projects.cgi">projects</a>' IF user.groups.projman_admins %] ]]></programlisting> <para> Voilà ! Le lien apparaît maintenant après les autres liens d'administration dans la barre de navigation pour les utilisateurs du groupe <literal>projman_admins</literal>. </para> <para> Astuces : </para> <itemizedlist> <listitem> <para> Vous aurez peut être envie de préfixer vos noms de modèle d'extension avec le nom de votre extension, par exemple <filename>projman-foo.html.tmpl</filename> pour qu'ils n'entrent pas en conflit avec les noms des modèles installés par d'autres extensions. </para> </listitem> <listitem> <para> Si votre extension englobent complètement de nouveaux modèles en plus des extensions des modèles standards, il faut qu'elle installe ces nouveaux modèles dans un sous-répertoire du répertoire <filename>BUGZILLA_ROOT/template/en/extension/</filename> spécifique aux extensions. Le répertoire <filename>extension/</filename>, tout comme les répertoires <filename>default/</filename> and <filename>custom/</filename>, fait partie du chemin de recherche de modèle, et donc en mettant des modèles à cet endroit là, le processeur de modèles pourra les trouver. </para> <para> Le processeur de modèles cherche les modèles d'abord dans le répertoire <filename>custom/</filename> (modèles ajoutés par une installation spécifique), puis dans le répertoire <filename>extension/</filename> (modèles ajoutés par des extensions), et finalement dans le répertoire <filename>default/</filename> (les modèles Bugzilla standard). Donc les modèles d'extension peuvent prendre le pas sur des modèles standard mais les modèles à installation particulière prennent le pas sur tous les deux. </para> <para> Notez que l'annulation de modèles standard vous donne un grand pouvoir mais rend également la mise à jour d'une installation plus difficile. Comme avec un modèle personnalisé, nous vous recommandons d'utiliser cette fonctionnalité avec parcimonie et seulement quand c'est absolument nécessaire. </para> </listitem> <listitem> <para> Les personnalisateurs d'installation peuvent aussi profiter des crochets quand ils ajoutent du code à un modèle Bugzilla. Pour ce faire, créez des répertoires dans <filename>BUGZILLA_ROOT/template/en/custom/hook/</filename> équivalents aux répertoires dans <filename>BUGZILLA_ROOT/template/en/extension/hook/</filename> pour les crochets que vous voulez utiliser puis placez vos modèles de personnalisation dans ces répertoires. </para> <para> Evidemment cette méthode de personnalisation de Bugzilla vous laisse seulement ajouter du code à vos modèles standard ; vous ne pouvez pas modifier le code existant. Cependant, pour ces personnalisations qui ne font qu'ajouter du code, cette méthode peut réduire les conflits quand la fusion est modifiée, rendant la mise à jour de votre installation Bugzilla personnalisée plus facile. </para> </listitem> </itemizedlist> </section> <section id="cust-change-permissions"> <title>Personnalisation : Qui peut faire quoi ?</title> <warning> <para> Cette fonctionnalité devrait être considérée comme expérimentale ; le code Bugzilla que vous allez changer n'est pas stable et est susceptible de changer ou d'être déplacé suivant les versions. Il faut savoir que si vous effectuez des modifications comme celles indiquées ci-dessous, il se peut que vous ayez à les refaire ou à les porter en cas de changement interne dans une nouvelle version de Bugzilla et que vous passiez à cette version. </para> </warning> <para> Les entreprises ont souvent des règles dictant quels employés, ou quelles catégories d'employés, sont autorisés à changer certaines parties dans le système de bogues. Par exemple, seul le Contact Assurance Qualité assigné au bogue devrait avoir la permission de donner à un bogue le statut VERIFY. Bugzilla a été conçu pour vous faciliter l'écriture de vos propres règles personnalisées afin de définir qui a la permission d'effectuer telle ou telle sorte de changement de valeur. </para> <para> Pour une flexibilité maximale, ce type de personnalisation implique l'édition du code Perl de Bugzilla. Ceci donne à l'administrateur tout contrôle sur qui exactement est autorisé à faire quoi. La fonction appropriée s'appelle <filename>CheckCanChangeField()</filename> et se situe dans <filename>process_bug.cgi</filename> dans votre répertoire de Bugzilla. Si vous ouvrez ce fichier et que vous cherchez la chaîne <quote>sub CheckCanChangeField</quote>, vous la trouverez. </para> <para> Cette fonction est accompagnée d'un commentaire détaillé afin de vous permettre de comprendre exactement comment elle fonctionne, et vous donner une idée sur la manière d'y effectuer des changements. Certaines sections sont marquées comme ne devant pas être changées : il s'agit de la partie <quote>tuyauterie</quote> qui fait marcher tout le reste. Entre ces sections, vous pourrez trouver des petits bouts de code comme : </para> <programlisting> # Permettre au propriétaire de tout changer. if ($ownerid eq $whoid) { return 1; } </programlisting> <para> Ce que fait ce bout de code est assez évident. </para> <para> Alors, comment s'y prend-on pour changer cette fonction ? Et bien, des changements simples peuvent êtres effectués juste en supprimant des morceaux ; par exemple, si vous vouliez empêcher tout utilisateur de rajouter un commentaire à un bogue, supprimez simplement les lignes marquées <quote>Autoriser toute personne à changer les commentaires</quote>. Si vous ne voulez pas que le rapporteur du bogue ait des droits particuliers sur les bogues qu'elle a soumis, supprimez simplement toute la section qui le concerne. </para> <para> Les personnalisations plus complexes ne sont pas beaucoup plus difficiles. En gros, vous ajoutez un test au bon endroit dans la fonction, c'est-à-dire après que toutes les variables que vous utilisez aient été initialisées. Ainsi, ne touchez pas à la variable $ownerid avant d'avoir obtenu $ownerid depuis la base de données. Vous pouvez soit ajouter un test positif, qui renvoie 1 (permission accordée) si certaines conditions sont vraies ou un test négatif, qui retourne 0 (permission refusée). Par exemple : </para> <programlisting> if ($field eq "qacontact") { if (Bugzilla->user->groups("quality_assurance")) { return 1; } else { return 0; } } </programlisting> <para> Cela fait que seuls les utilisateurs du groupe <quote>quality_assurance</quote> peuvent changer le champ Contact QA d'un bug. </para> <para> Un exemple plus bizarre : </para> <programlisting><![CDATA[ if (($field eq "priority") && (Bugzilla->user->email =~ /.*\@example\.com$/)) { if ($oldvalue eq "P1") { return 1; } else { return 0; } } ]]></programlisting> <para> Cela fait que si l'utilisateur essaie de changer le champ priorité et que son adresse électronique est @example.com, il n'y parviendra qu'à la condition que la précédente valeur du champ ait été <quote>P1</quote>. Pas très utile, mais démonstratif. </para> <warning> <para> Si vous modifiez <filename>process_bug.cgi</filename> de quelque manière que ce soit, ne changez pas le code délimité par les blocs DO_NOT_CHANGE. Ceci pourrait compromettre la sécurité ou causer l'arrêt complet du fonctionnement de votre installation. </para> </warning> <para> Pour une liste des noms de champs possibles, consultez la liste appelée <filename>@::logcolumns</filename> dans le fichier <filename>data/versioncache</filename>. Si vous avez besoin d'aide pour écrire des règles personnalisées pour votre entreprise, demandez dans le groupe de discussion. </para> </section> <section id="dbmodify"> <title>Modifier votre système en fonctionnement</title> <para> Bugzilla optimise les opérations de consultation de la base de données en stockant toute information relativement statique dans le fichier <filename>versioncache</filename>, situé dans le sous-répertoire <filename class="directory">data/</filename> dans votre répertoire d'installation. </para> <para> Si vous effectuez un changement dans les données structurelles de votre base de données (dans la table des versions par exemple), ou dans les <quote>constantes</quote> encodées dans <filename>defparams.pl</filename>, vous devrez supprimer du répertoire de données le contenu mis en cache (en effectuant un <command>rm data/versioncache</command>) sinon vos changements n'apparaîtront pas. </para> <para> Comme <filename>versioncache</filename> est regénéré automatiquement dès lors qu'il existe depuis plus d'une heure, Bugzilla finira par remarquer vos changements de lui-même, mais généralement on préfère qu'il en tienne compte immédiatement, afin que vous puissiez faire des tests. </para> </section> <section id="dbdoc"> <title>Introduction à la base de données MySQL de Bugzilla</title> <para>Ces informations sont tirées de mon expérience personnelle. J'ai dû apprendre comment Bugzilla organise la base de données à cause des pinaillages d'utilisateurs demandant de minuscules changements dans le choix des termes plutôt que d'attendre que les gens se rééduquent par eux-même ou comprennent comment utiliser nos procédures. Ça craint mais vous y passerez peut-être aussi, donc apprenez comment fonctionne le schéma pour pouvoir vous débrouiller quand ça arrivera.</para> <para>Donc, vous en êtes là avec votre installation toute neuve de Bugzilla. Vous avez installé MySQL, Apache tourne bien, Perl DBI et DBD communiquent parfaitement avec la base. Peut-être avez-vous même rentré quelques bogues de test pour vérifier que le courrier électronique fonctionne bien ; les gens semblent être avertis des nouveaux bogues ou modifications et vous pouvez créer ou éditer des bogues comme bon vous semble. Vous avez peut-être rencontré des problèmes lors de la configuration d'une passerelle de connexion destinée à permettre aux gens de soumettre des bogues à votre base de données par courrier électronique, vous avez demandé à des personnes de tester votre installation et reçu des retours enthousiastes de la part de vos bêta-testeurs.</para> <para>Quelle est la suite au programme ? Esquisser une stratégie de formation de votre équipe de développement et leur demander de se précipiter sur le nouvel outil auquel vous avez consacré des heures de travail.</para> <para> Votre première session de formation débute très bien ! Votre auditoire captivé semble émerveillé par l'efficacité intrinsèque de cette chose qui s'appelle <quote>Bugzilla</quote>. Vous êtes complètement absorbé par la description des caractéristiques pratiques : comment les gens peuvent sauvegarder leurs requêtes favorites dans la base de données, les mettre en tête ou en pied de leur page, personnaliser leur mise en page, générer des rapports, suivre le statut avec une efficacité plus grande que jamais, atteindre le sommet d'un gratte-ciel d'un seul bond, sauver Jane des griffes de la Mort personnifiée ! </para> <para> Mais la Mort personnifiée prend la parole : une petite voix, venue d'un coin sombre de la salle de conférence. La voix sort de l'ombre : <quote>J'ai une remarque au sujet de l'utilisation du mot <literal>verified</literal>.</quote> </para> <para> La salle, jusque là remplie d'un joyeux babil, plonge dans un silence religieux tandis que la Mort personnifiée (plus connue sous le nom de Vice-Président du Département Génie Logiciel) poursuit. <quote>Vous voyez, cela fait deux ans que nous utilisons le mot <quote>verified</quote> pour indiquer le fait qu'un développeur ou un ingénieur qualité a confirmé qu'un bogue était valide. Je ne veux pas perdre deux ans de formation à un nouveau logiciel. Vous devez remplacer le statut <literal>verified</literal> d'un bogue par <quote>approved</quote> dès que possible. Pour éviter toute confusion, bien sûr.</quote> </para> <para> Oh non ! La peur vous frappe de plein fouet alors que vous balbultiez <quote>oui, oui, je pense que ça ne sera pas un problème,</quote> vous examinez les changements avec la Mort personnifiée et continuez à baragouiner, <quote>non, ça ne représente pas une grosse modification. Je veux dire, nous avons le code source, n'est-ce pas ? Vous savez bien, <quote>Utiliser le code source tu dois, Luke</quote> et tout ça... aucun problème,</quote> pendant tout ce temps vous frémissez intérieurement comme une méduse échouée qui fait des gargouillis, des glougloutis et qui rôtit sur le sable brûlant d'une dune jamaïquaine... </para> <para> Ainsi commence votre aventure au cœur de Bugzilla. Vous êtes condamné à faire connaissance avec les champs enum() fixes, les colonnes de varchar et les définitions des tinyint. Prêt pour l'aventure ! </para> <section> <title>Les fondamentaux de la base de données de Bugzilla</title> <para> Si, comme je l'étais, vous êtes totalement ignorant des mécanismes internes de MySQL à ce stade, et si vous n'étiez pas sous les ordres du Vice-Président, vous vous moqueriez de la différence qui existe entre un champ <quote>bigint</quote> et un <quote>tinyint</quote> dans MySQL. Je vous recommande de consulter la <ulink url="http://www.mysql.com/documentation/">documentation MySQL</ulink> en ligne. Vous trouverez ci-dessous les rudiments nécessaires pour comprendre la base de données de Bugzilla. Consultez la documentation MySQL ci-dessus pour plus d'informations.</para> <para> <orderedlist> <listitem> <para>Pour vous connecter à votre base de données :</para> <para> <prompt>bash#</prompt> <command>mysql</command> <parameter>-u root</parameter> </para> <para> Si cela fonctionnne sans demander de mot de passe, <emphasis>honte sur vous</emphasis> ! Vous auriez dû mettre en place un verrouillage de sécurité comme cela était expliqué dans les instructions d'installation. Vous pouvez trouver plus d'informations concernant le verrouillage de votre base de données dans la FAQ de Bugzilla de ce répertoire (dans la partie <quote>Sécurité</quote>), ou des généralités plus solides sur la sécurité dans la <ulink url="http://dev.mysql.com/doc/refman/5.0/fr/index.html">documentation consultable de MySQL</ulink>. </para> </listitem> <listitem> <para>Vous devez maintenant voir une invite de commande qui ressemble à celle-ci :</para> <para> <prompt>mysql></prompt> </para> <para>À l'invite, si <quote>bugs</quote> est le nom que vous avez choisi dans le fichier <filename>localconfig</filename> pour votre base de données Bugzilla, tapez :</para> <para> <prompt>mysql</prompt> <command>use bugs;</command> </para> </listitem> </orderedlist> </para> <section> <title>Les tables de la base de données de Bugzilla</title> <para> Imaginez votre base de données MySQL comme une série de feuilles de calcul d'un tableur, et vous ne serez pas loin de la vérité. Si vous tapez cette commande : </para> <para> <prompt>mysql></prompt> <command>show tables from bugs;</command> </para> <para> vous pourrez voir le nom de toutes les <quote>feuilles de calcul</quote> (tables) dans votre base de données. </para> <para> À partir de la commande tapée ci-dessus, vous devriez obtenir une réponse qui ressemble à celle-ci : </para> <programlisting> +-------------------+ | Tables in bugs | +-------------------+ | attachments | | bugs | | bugs_activity | | cc | | components | | dependencies | | fielddefs | | groups | | keyworddefs | | keywords | | logincookies | | longdescs | | milestones | | namedqueries | | products | | profiles | | profiles_activity | | tokens | | versions | | votes | | watch | +-------------------+ </programlisting> <para> Voici un aperçu de ce que fait chaque table. La plupart des colonnes de chaque table possèdent un nom descriptif qui permet de comprendre relativement rapidement leur rôle. </para> <variablelist> <varlistentry> <term>attachments</term> <listitem><para> cette table contient tous les fichiers joints aux bogues. Cette table tend à être la plus grande mais généralement aussi celle qui comporte le moins d'entrées car les fichiers joints sont (relativement) gros. </para></listitem> </varlistentry> <varlistentry> <term>bugs</term> <listitem><para> c'est le cœur de votre système. La table bugs contient la plupart des informations concernant les bogues à l'exception des informations stockées dans les autres tables. </para></listitem> </varlistentry> <varlistentry> <term>bugs_activity</term> <listitem><para> conserve les informations concernant les changements apportés aux bogues — un fichier d'historique. </para></listitem> </varlistentry> <varlistentry> <term>cc</term> <listitem><para> cette petite table conserve simplement toutes les informations de copie carbone (CC) des bogues dont le champ CC est renseigné. Notez que, comme la plupart des autres tables dans Bugzilla, il n'est pas fait référence aux utilisateurs par le biais de leur nom d'utilisateur, mais par leur seul identifiant utilisateur, stocké dans la table profiles comme clé primaire. </para></listitem> </varlistentry> <varlistentry> <term>components</term> <listitem><para> stocke les programmes et les composants (ou les produits et les composants dans le nouveau langage de Bugzilla) de Bugzilla. Curieusement, le champ <quote>program</quote> (product) est le nom complet du produit et non un autre identifiant unique, comme bug_id et user_id le sont ailleurs dans la base de données. </para></listitem> </varlistentry> <varlistentry> <term>dependencies</term> <listitem><para> contient les données sur ces supers arbres de dépendance. </para></listitem> </varlistentry> <varlistentry> <term>fielddefs</term> <listitem><para> table pratique qui définit les autres tables. Par exemple lorsque vous validez un formulaire qui change la valeur de <quote>AssignedTo</quote>, cette table permet le transfert de l'information vers le champ actuel dont le nom est <quote>assigned_to</quote> pour une entrée de MySQL. </para></listitem> </varlistentry> <varlistentry> <term>groups</term> <listitem><para> définit les masques binaires pour les groupes. Un masque binaire est un nombre qui peut identifier de manière unique les appartenances à un groupe. Par exemple, disons que le groupe qui a le droit d'apporter quelques petites modifications aux paramètres est affecté d'une valeur <quote>1</quote>, le groupe qui a la droit d'éditer les utilisateurs est affecté d'une valeur <quote>2</quote> et le groupe qui peut créer de nouveaux groupes est affecté d'un masque binaire de <quote>4</quote>. Simplement en combinant les masques binaires des groupes (tout comme la commande chmod d'UNIX,) vous pouvez identifier un utilisateur qui a le droit de modifier légèrement les paramètres et de créer des groupes mais pas d'éditer les utilisateurs, en lui affectant un masque binaire de <quote>5</quote>, ou bien un utilisateur ayant le droit d'éditer des utilisateurs et de créer des groupes, mais pas de modifier les paramètres, en lui donnant un masque binaire de <quote>6</quote>. Simple, hein ? </para> <para> Si vous n'avez pas compris, essayer en tapant ceci à l'invite de commande de mysql : </para> <programlisting> mysql> select * from groups; </programlisting> <para> Vous verrez la liste, c'est plus compréhensible de cette manière. </para></listitem> </varlistentry> <varlistentry> <term>keyworddefs</term> <listitem><para> définition des mots-clés utilisés. </para></listitem> </varlistentry> <varlistentry> <term>keywords</term> <listitem><para> à l'inverse de ce que vous pensez, cette table dit quels mots-clés sont associés avec quels identifiants de bogues. </para></listitem> </varlistentry> <varlistentry> <term>logincookies</term> <listitem><para> cette table stocke tous les cookies de connexion qui vous sont assignés pour chaque machine à partir de laquelle vous vous êtes connecté à Bugzilla. Curieusement, elle ne gère pas le nettoyage ; je retrouve des cookies que je n'ai pas utilisés depuis des mois. Cependant, comme Bugzilla ne donne pas de date d'expiration aux cookies, cela se comprend. </para></listitem> </varlistentry> <varlistentry> <term>longdescs</term> <listitem><para> la substance de Bugzilla : voici où sont stockés tous les commentaires des utilisateurs ! Vous disposez uniquement de 2^24 octets par commentaire (il s'agit d'un champ de type mediumtext), donc soyez concis ; cela représente seulement l'espace que l'Ancien Testament prendrait (16 mégaoctets, non compressé). Tout commentaire reçoit comme clé le bug_id du bogue auquel il est lié de telle manière que l'ordre soit nécessairement chronologique car les commentaires sont retournés dans l'ordre où ils ont été reçus. </para></listitem> </varlistentry> <varlistentry> <term>milestones</term> <listitem><para> c'est une bonne chose que les jalons soient associés à un produit particulier dans cette table mais Bugzilla ne supporte pas encore les jalons qui diffèrent en fonction des produits via l'interface de configuration standard. </para></listitem> </varlistentry> <varlistentry> <term>namedqueries</term> <listitem><para> c'est ici que chacun stocke ses <quote>requêtes personnelles</quote>. Caractéristique très sympa ; avec cela, plus besoin de se casser la tête à mettre un signet sur chaque requète sympa que vous élaborez. </para></listitem> </varlistentry> <varlistentry> <term>products</term> <listitem><para> indique les produits dont vous disposez, si les nouveaux ajouts de bogues sont permis pour ce produit, sur quel jalon vous travaillez avec ce produit, les votes, etc. Ce sera bien lorsque la table components contiendra les mêmes attributs, de telle façon que l'on puisse bloquer l'ajout de nouveaux bogues pour un composant particulier sans bloquer un produit entier... </para></listitem> </varlistentry> <varlistentry> <term>profiles</term> <listitem><para> ah, alors vous vous demandiez où vos précieuses informations d'utilisateur étaient gardées ? C'est ici ! Avec les mots de passe en clair pour tout le monde ! (mais chuut... n'en parlez pas à vos utilisateurs !) </para></listitem> </varlistentry> <varlistentry> <term>profiles_activity</term> <listitem><para> vous avez besoin de savoir qui a fait quoi à quel profil utilisateur ? C'est ici que vous le saurez, il s'agit d'un historique assez complet. </para></listitem> </varlistentry> <varlistentry> <term>versions</term> <listitem><para> informations sur la version de chaque produit. </para></listitem> </varlistentry> <varlistentry> <term>votes</term> <listitem><para> qui a voté pour quoi et quand. </para></listitem> </varlistentry> <varlistentry> <term>watch</term> <listitem><para> qui (relativement au userid) consulte les bogues de qui (relativement à leur userid). </para></listitem> </varlistentry> </variablelist> <section> <title>Les détails</title> <para> Ah, alors vous vous demandez que faire des informations ci-dessus ? À l'invite de commande vous pouvez visualiser les informations sur n'importe quelle colonne d'une table grâce à cette commande (où <quote>table</quote> est le nom de la table que vous souhaitez voir) : </para> <programlisting> mysql> show columns from table; </programlisting> <para> Vous pouvez aussi voir toutes les données contenues dans une table avec cette commande : </para> <programlisting> mysql> select * from table; </programlisting> <note><para> il est fortement déconseillé de le faire sur, par exemple, la table <quote>bugs</quote> si vous avez 50 000 bogues. Vous pourriez rester planté là un bon moment avant de faire un ctrl-c ou à attendre que les 50 000 bogues s'affichent à l'écran. </para></note> <para> Vous pouvez limiter un peu l'affichage ci-dessus avec cette commande où <quote>colonne</quote> est le nom de la colonne à laquelle vous voulez restreindre l'affichage d'information : </para> <programlisting> mysql> select * from table where (column = "some info"); </programlisting> <para> — ou l'inverse de cela </para> <programlisting> mysql> select * from table where (column != "some info"); </programlisting> <para> Reprenons l'exemple de l'introduction et supposons que vous ayez besoin de changer le mot <quote>verified</quote> par <quote>approved</quote> dans le champ de résolution. Nous savons depuis la partie précédente que la résolution doit se trouver dans la table <quote>bugs</quote>. Notez que nous devrons changer un peu le code perl en plus de la modification de la base de données mais je ne vais pas aborder cela dans ce document. Vérifions que l'information est bien stockée dans la table <quote>bugs</quote> : </para> <programlisting> mysql> show columns from bugs (résultat bien trop long, on l'a raccourci) | bug_status| enum('UNCONFIRMED','NEW','ASSIGNED','REOPENED','RESOLVED','VERIFIED','CLOSED')||MUL | UNCONFIRMED|| </programlisting> <para> Désolé de cette longue ligne. Nous voyons à partir du résultat que la colonne <quote>bug status</quote> est de type <quote>enum field</quote>, ce qui est une particularité de MySQL où un champ de type chaîne de caractères ne peut prendre que certaines valeur en entrée. Bien que je trouve cela vraiment sympa, il ne s'agit pas de SQL standard. Néanmoins, nous avons besoin d'ajouter <quote>APPROVED</quote> dans les valeurs possibles du champ <quote>enum</quote> en modifiant la table <quote>bugs</quote>. </para> <programlisting> mysql> ALTER table bugs CHANGE bug_status bug_status -> enum("UNCONFIRMED", "NEW", "ASSIGNED", "REOPENED", "RESOLVED", -> "VERIFIED", "APPROVED", "CLOSED") not null; </programlisting> <para> (notez que vous pouvez entrer trois lignes ou plus ; tout ce que vous placerez avant le point virgule sera compris comme une seule expression) </para> <para> Maintenant si vous faites cela : </para> <programlisting> mysql> show columns from bugs; </programlisting> <para> vous verrez que le champ bug_status dispose d'un <quote>APPROVED</quote> supplémentaire dans <quote>enum</quote> ! Une autre chose sympa serait que ce changement soit aussi propagé jusqu'à votre page de requête ; vous pouvez effectuer une requête au moyen du nouveau statut. Mais comment cela se propage-t-il dans la réalité des choses ? </para> <para> Il semble que vous deviez retourner chercher les instances du mot <quote>verified</quote> dans le code perl de Bugzilla ; partout où vous trouvez <quote>verified</quote>, remplacez le par <quote>approved</quote> et voilà, ça roule (assurez-vous que la recherche n'est pas sensible à la casse). Bien que vous puissiez effectuer des requêtes grâce au champ <quote>enum</quote>, vous ne pouvez donner le statut <quote>APPROVED</quote> à quoi que ce soit avant d'avoir réalisé les changements dans le code perl. Notez que ce changement que j'ai mentionné peut aussi être réalisé en éditant checksetup.pl, qui automatise un bon nombre de choses. Mais vous avez besoin de connaître ce truc aussi, pas vrai ? </para> </section> </section> </section> </section> <!-- Integrating Bugzilla with Third-Party Tools --> &integration; </chapter> <!-- Keep this comment at the end of the file Local variables: mode: sgml sgml-always-quote-attributes:t sgml-auto-insert-required-elements:t sgml-balanced-tag-edit:t sgml-exposed-tags:nil sgml-general-insert-case:lower sgml-indent-data:t sgml-indent-step:2 sgml-local-catalogs:nil sgml-local-ecat-files:nil sgml-minimize-attributes:nil sgml-namecase-general:t sgml-omittag:t sgml-parent-document:("Bugzilla-Guide.xml" "book" "chapter") sgml-shorttag:t sgml-tag-region-if-active:t End: -->