Chapitre VI Introduction à la création de modules▲
Développer un module Drupal peut parfois vous sauver si une fonctionnalité n'existe pas ou si vous souhaitez modifier certains comportements de Drupal. S'attaquer à cette tâche peut d'abord paraître insurmontable, mais finalement elle s'avère assez simple.
Le but de ce chapitre est de vous permettre de commencer en douceur la programmation avec Drupal. Il vous présentera toute une palette d'outils qui vous faciliteront votre vie de développeur Drupal.
VI-A. Environnement de développement ▲
Pour développer des modules Drupal, un éditeur de texte suffit - Notepad++ pour Windows ou Gedit pour Linux -, mais un environnement de développement tel qu'Eclipse, vous simplifiera la vie grâce à la complétion automatique et à des options de débogage que vous découvrirez par la suite (chap. Déboguer avec EclipseDéboguer avec Eclipse ).
Cette section est donc facultative si vous êtes uniquement intéressé par la programmation Drupal. Le cas échéant, vous pouvez passer directement au chap. Architecture d'un moduleArchitecture d'un module .
VI-A-1. Installation et configuration d'Eclipse ▲
Pour développer un module Drupal avec Eclipse, le plus simple est de choisir la distribution PDT (PHP Developement Tools - Outils de développement PHP). Vous pourrez la trouver à l'adresse suivante : http://www.eclipse.org/pdt/downloads. Cependant, si Eclipse est déjà installé sur votre configuration, il est possible d'installer PDT sous forme de plugins. Ce type d'installation ne sera pas détaillé ici.
VI-A-1-a. Installation sous Windows ▲
-> Rendez-vous à l'adresse http://www.eclipse.org/pdt/downloads.
-> Téléchargez le package All-In-One Windows 32-bit (version PDT 2.2.0 utilisée pour ce livre).
-> Extrayez le contenu de l'archive dans un répertoire (c:\Programmes\eclipse pour ce livre).
Eclipse est un programme écrit en Java, il faut donc que l'environnement d'exécution Java soit également installé (JRE - http://www.java.com/fr/download/).
-> Exécutez eclipse.exe (c:\Programmes\eclipse\eclipse.exe pour ce livre).
-> Sélectionnez le répertoire de Workspace par défaut et cochez la case Use this as the default and do not ask again
Le Workspace est l'espace de travail (un répertoire) ou Eclipse va stocker des données de configuration dans le sous-dossier .metadata. Lorsque vous créez un nouveau projet, c'est également ce répertoire qui sera utilisé.
Veillez donc à ne pas choisir un sous-répertoire de c:\wamp, car vous n'allez pas créer un nouveau projet, mais en créer à partir du répertoire Drupal existant, et il n'est pas possible d'importer un projet inclus dans le répertoire Workspace.
Il est possible de changer de Workspace à partir d'Eclipse dans le menu File - Switch Workspace.
-> Cliquez sur OK.
Vous arrivez alors sur votre espace de travail. Il faut maintenant configurer Eclipse pour Drupal. Rendez-vous au chap. Configuration d'Eclipse pour DrupalConfiguration d'Eclipse pour Drupal .
VI-A-1-b. Installation sous Ubuntu ▲
Installer Java
Eclipse est un programme écrit en Java, il faut donc tout d'abord que votre installation puisse exécuter un programme Java.
Vous pouvez consulter la documentation du site ubuntu-fr pour installer Java d'une autre façon : http://doc.ubuntu-fr.org/java.
Il faut tout d'abord ajouter les dépôts qui contiennent l'environnement Java.
-> Démarre Synaptic.
-> Onglet Autres logiciels.
-> Sélectionner la ligne Partenaires de Canonical.
-> Bouton Fermer.
-> Puis, bouton Recharger de la fenêtre principale de Synaptic.
Il suffit maintenant d'installer les paquets Java :
sudo apt-get install sun-java6-jre sun-java6-plugin sun-java6-fonts
Installer Eclipse
Vous pouvez consulter la documentation du site ubuntu-fr pour installer Eclipse d'une autre façon : http://doc.ubuntu-fr.org/eclipse.
-> Rendez-vous à l'adresse http://www.eclipse.org/pdt/downloads.
-> Téléchargez le package Linux x86/GTK 2 32-bit ou 64-bit(version PDT 2.2.0 utilisée pour ce livre).
-> Extrayez le contenu de l'archive dans un répertoire (/home/atelier/eclipse)...
-> Exécutez le programme /home/atelier/eclipse/eclipse
VI-A-1-c. Configuration d'Eclipse pour Drupal ▲
Association de fichiers
Un module Drupal comporte des fichiers contenant du code php, et qui ont des extensions différentes de .php. C'est le cas pour les fichiers *.module, *.install, *.theme et *.engine. Il faut donc configurer Eclipse pour qu'il traite ces fichiers comme des fichiers php classiques.
-> Dans Eclipse, cliquez sur Window - Preferences.
-> Dans la liste de gauche sélectionnez la ligne General - Content Types.
-> Dans la zone Content types, sélectionnez la ligne Text - PHP Content Type
-> Bouton Add...
-> Ajoutez *.module dans la zone de texte.
-> Faites de même pour les extensions *.install, *.theme et *.engine.
Les quatre nouvelles extensions devraient maintenant apparaître dans la zone File associations.
-> Validez la fenêtre des préférences en cliquant sur OK.
Indentation
Par convention, tous les fichiers de Drupal doivent être indentés par deux espaces. Eclipse indente par défaut d'une tabulation de quatre blancs, mais il est possible de modifier ce comportement.
-> Dans Eclipse, cliquez Window - Preferences.
-> Dans la liste de gauche, sélectionnez la ligne General - Editors - Text Editors.
-> À la ligne Displayed tab width, indiquez 2.
-> Cochez la case Insert spaces for tabs
Les préférences permettent de régler un nombre important de paramètres dans Eclipse. La zone de texte située en haut à gauche de la fenêtre permet de faire une recherche parmi toutes les préférences. Par exemple, sur la copie d'écran précédente, seuls les items contenant le mot tab ont été sélectionnés.
-> Bouton OK.
-> Puis menu File - Restart pour que les préférences modifiées soient prises en compte.
Création d'un projet à partir d'un dossier Drupal
Un projet sous Eclipse PDT comporte l'ensemble des fichiers du site web. Pour une installation Drupal, c'est donc le répertoire racine de votre site qu'il va falloir importer dans le projet.
-> Menu File - New - PHP Project.
-> Donnez un nom à votre projet dans la zone Project name (drupal pour ce livre).
-> Sélectionnez l'option Create project at existing location (from existing source) et pointez vers votre répertoire d'installation Drupal (c:\wamp\www\drupal).
-> Bouton Finish.
-> Fermez la fenêtre Welcome.
Vous pouvez maintenant vérifier que les fichiers *.module s'ouvrent bien avec l'éditeur PHP et qu'ils sont bien colorisés.
Eclipse est maintenant prêt à être utilisé pour développer un nouveau module Drupal !
Vous en apprendrez plus sur Eclipse au chap. Déboguer avec EclipseDéboguer avec Eclipse .
VI-A-2. Architecture d'un module ▲
Dans ce chapitre, vous créerez votre premier module qui affichera un bloc contenant le fameux message « Hello World ! » Il est bien sûr possible de créer un bloc de façon plus simple via la page de gestion des blocs, mais cela vous permettra de comprendre quelques éléments essentiels de la programmation Drupal.
VI-A-2-a. Le répertoire du module et le fichier .info ▲
Comme pour les thèmes, chaque module possède son propre répertoire.
-> Le module s'appellera Hello, il faut donc créer le répertoire sites/all/modules/hello.
Il est possible de créer un répertoire ou des fichiers directement depuis l'arborescence d'Eclipse : clic droit à l'endroit où vous voulez créer le répertoire puis New - Folder.
Comme pour les thèmes, les informations générales des modules sont inscrites dans un fichier .info.
-> Créez le fichier hello.info dans votre répertoire hello.
-> Copiez-y le code suivant :
; $Id:
name = Hello
description = Hello from Atelier Drupal.
core = 7.x
version = 7.x-0.x-dev
package = Atelier Drupal
files[] = hello.module
-> Créez un fichier hello.module vide dans le répertoire du module.
Ce fichier doit exister pour que Drupal affiche les informations relatives aux modules.
-> Rendez-vous sur la page d'activation : menu Modules
Le module hello apparaît dans la liste à une nouvelle section ATELIER DRUPAL.
Voici une description de chaque ligne du fichier .info.
; $Id: | Ligne utilisée par le CVS de Drupal pour la gestion des versions du fichier. |
name | Nom du module, affiché dans la colonne NOM. |
description | Description du module, affichée dans la colonne DESCRIPTION. |
core | Indique avec quelle version de Drupal le module est compatible, ici, toutes les versions 7. |
version | Version du module, affichée dans la colonne VERSION. |
package | Section dans laquelle le module sera affiché. |
files[] | Liste des fichiers du module. |
VI-A-2-b. Les hooks ▲
Vous êtes maintenant prêt à écrire le code PHP de votre module.
Ce module hello devra afficher un bloc « Hello World ! ».
Les blocs sont gérés par le module Block de Drupal, ce module propose entre autres une page de configuration des blocs (menu Structure - lien Blocs) qui permet de choisir la région dans laquelle le bloc sera affiché et se charge ensuite d'afficher les blocs dans chaque région.
Pour le module Hello, il s'agit de dire au module Block : « Je propose un nouveau bloc » qui a pour nom Hello World, pour titre « My first module say » et pour contenu « Hello World !!! ».
Pour que les modules puissent se « parler », Drupal utilise un système de hooks. Les modules peuvent proposer des services (hooks) que les autres peuvent utiliser.
Par exemple, Block propose hook_block_info qui réunira les informations sur les blocs de tous les modules afin de construire sa page (menu Structure - lien Blocs). C'est la première hook que vous allez utiliser :
-> dans le fichier hello.module, insérez le texte suivant :
<?php
function
hello_block_info() {
$block
[
'hello-block'
]
=
array
(
'info'
=>
'Hello world !'
,
);
return
$block
;
}
voyez maintenant le résultat de ce code :
-> activez le module Hello ;
-> menu Structure - lien Blocs
Voici maintenant l'explication du code :
<?php | Indique que le script contient du code PHP. Remarquez qu'il n'y a pas de balise fermante à la fin du script (?>) c'est une règle de Drupal. |
function hello_block_info() | Pour implémenter une hook, il faut créer une fonction ayant pour nom <nom_du_module>_<nom_de_la_hook>. Cette fonction du module hello implémente donc hook_block_info. |
$block['hello-block'] = array( | Cette hook attend en valeur de retour un tableau associatif contenant la liste des blocs du module. |
'info' => 'Hello world !' | L'élément info du tableau associatif indique la description du bloc telle qu'elle sera affichée sur la page menu Structure - lien Blocs. |
return $block; | La fonction retourne le tableau $block |
En résumé, lorsque la page menu Structure - lien Blocs est affichée, le module Block démarre sa hook hook_block_info. Drupal cherche alors dans les modules activés s'ils comportent une fonction portant le nom <nom_du_module>_block_info. Si c'est le cas, il retourne au module Block les tableaux associatifs qui décrivent les blocs des modules.
VI-A-2-c. Rechercher de la documentation sur http://api.drupal.org ▲
Vous avez appris grâce à ce livre comment hook_block_info fonctionnait : le nom de la hook, le type de valeur à retourner, les éléments du tableau associatif à retourner, etc. Mais comment faire pour savoir quelles autres hooks existent et comment elles s'utilisent ? La réponse est sur http://api.drupal.org.
-> Rendez-vous sur le site http://api.drupal.org.
-> Dans la zone de recherche entrez hook_block
Dans la liste qui apparaît, vous pouvez retrouver hook_block_info, mais également hook_block_view qui permet d'afficher les blocs et hook_block_configure, qui permet de personnaliser la page de configuration d'un bloc, etc.
-> Cliquez maintenant sur la ligne hook_block_info
Sur cette page vous pouvez retrouver une description de la hook :
- un lien vers la documentation du module block (block.api.php) est proposé ;
- une explication du fonctionnement de la hook est proposée.
Plus bas, une section Return Value est importante, elle indique que :
- la hook attend en retour un tableau associatif (Return value : An associative array) dont chaque élément est un bloc et les clés attendues (key-value pairs) ;
- une seule clé est obligatoire (required), c'est la clé info ;
- d'autres sont optionnelles : cache permet de gérer la façon dont le bloc sera mis en cache. weight, statuts, region, visibility, pages permettent de régler les valeurs par défaut de votre bloc.
VI-A-2-d. hook_block_view : afficher des blocs ▲
Il s'agit maintenant de définir le titre du bloc (My first module says), son contenu (Hello World !), et de demander au module block de l'afficher. Pour cela, il faut utiliser hook_block_view.
La page de documentation indique que :
- cette hook prend un paramètre $delta qui permet d'identifier le block qui s'affiche. En effet, un module peut proposer d'afficher plusieurs blocs ;
- la valeur de retour attendue est un tableau associatif ;
- ce tableau associatif devra comporter deux éléments qui ont pour clés « subject » et « content ».
-> Voici donc le code à ajouter au fichier hello.module pour implémenter hook_block_view
function hello_block_view($delta
=
''
) {
$block
=
array(
'
subject
'
=>
'
My First module say :
'
,
'
content
'
=>
'
Hello World !!!
'
);
return $block
;
}
La déclaration de fonction doit être identique à celle trouvée sur api.drupal.org. Ne vous privez donc pas d'un copier/coller depuis ce site et n'oubliez pas ensuite de changer le mot hook_ par le nom de votre module (ici hello_block_view).
-> Allez sur la page menu Structure - lien Blocs et mettez ce bloc en Sidebar First sous Bartik.
Vous devriez maintenant voir apparaître le bloc !
VI-A-2-e. Conventions et finitions ▲
Votre module s'affiche, certes, mais il comporte encore quelques défauts pour devenir un module Drupal accepté par la communauté !
Commentaires
La première raison pour laquelle un module Drupal doit être correctement commenté est qu'il est plus facile à reprendre et à maintenir. La seconde est que Drupal utilise ces commentaires de façon mécanique pour générer sa documentation. Les deux pages que vous avez visitées sur api.drupal.org proviennent directement du code source de Drupal ! Cette prouesse est réalisée grâce au logiciel Doxygen (http://www.doxygen.org).
Voici le fichier hello.module correctement commenté :
<?php
/**
* @file
* Display a Hello World block
*/
/**
* Implementation of hook_block_info()
*/
function
hello_block_info() {
$block
[
'hello-block'
]
=
array
(
'info'
=>
'Hello world !'
,
);
return
$block
;
}
/**
* Implementation of hook_block_view()
*/
function
hello_block_view($delta
=
''
) {
$block
=
array
(
'subject'
=>
'First module say :'
,
'content'
=>
'Hello World !!!'
);
return
$block
;
}
Un fichier de code source doit débuter avec un commentaire @file qui décrit la fonction principale du fichier.
Chaque fonction doit être décrite avec ses paramètres. Si cette fonction implémente une hook, indiquez juste son nom.
Pour en savoir plus sur la génération automatique de documentation par Doxygen, rendez-vous à la page http://drupal.org/node/1354.
Comme vous avez pu le voir au chap. Site multilingueSite multilingue , chaque chaîne de l'interface d'un module peut être traduite via différents modules. Cela sera possible pour vos propres modules si vous utilisez la fonction t() (pour Translate) autour de chaque chaîne de caractères de votre module :
$block
[
'
hello-block
'
]
=
array(
'
info
'
=>
t('
Hello world !
'
),
);
$block
=
array (
'
subject
'
=>
t('
First module say :
'
),
'
content
'
=>
t('
Hello World !!!
'
)
);
Pour certains champs, il ne faut pas utiliser la fonction t(), car elle est automatiquement appelée.
Tout module doit implémenter cette hook qui permet d'utiliser le module Help.
/**
* Implementation of hook_help()
*/
function hello_help($path
,
$arg
) {
switch ($path
) {
case '
admin/help#hello
'
:
return '
<p>
'
.
t('
Sample module from Atelier Drupal book. This module just provide a hello world block.
'
) .
'
</p>
'
;
}
}
Cette hook prend en argument le chemin d'accès à la page d'aide. Le chemin ici est admin/help (page d'aide de Drupal) section hello :
Si ce lien n'apparaît pas, effacez tous les caches.
Utilisez le module chap. Le module CoderLe module Coder pour voir si votre module respecte les conventions de codage.
Le module Hello que vous avez développé tout au long de cette section vous a permis de découvrir comment débuter avec la programmation Drupal. Mais il ne faisait rien à proprement parler. C'est pourquoi dans la prochaine section, vous allez développer votre premier vrai module Drupal grâce à l'environnement que vous avez mis en place.
VI-B. Votre premier module Drupal ▲
Tout au long de cette section, vous créerez un module qui permet de produire un résumé de votre installation Drupal.
À la fin de cette section, ce module aura une page à l'URL /summary, qui affichera la liste des modules activés, les vocabulaires de taxonomy, et les types de contenus.
Une page de configuration du module permettra de sélectionner les sections à afficher et de modifier les titres de celles-ci.
Il y a donc du travail !
VI-B-1. La page Summary ▲
VI-B-1-a. Démarrage ▲
Comme pour le module Hello, il faut créer :
-> un répertoire pour le module sites/default/modules/summary (ou sites/all/modules/summary) ;
-> un fichier summary.info
; $Id:
name = Summary
description = Display a Summary of your Drupal Installation.
core = 7.x
package = Atelier Drupal
files[] = summary.module
-> et enfin un fichier summary.module avec un commentaire descriptif et une page d'aide :
<?php
/*
* @file
* Display a Summary of your Drupal Installation.
*/
/**
* Implementation of hook_help()
*/
function
summary_help($path
,
$arg
) {
switch
($path
) {
case
'admin/help#summary'
:
return
'<p>'
.
t('Sample module from Atelier Drupal book. This module provide a summary page of your Drupal Installation.'
) .
'</p>'
;
}
}
VI-B-1-b. hook_menu() : créez une page associée à une URL▲
Il s'agit de créer une nouvelle page dont le chemin sera /summary et le titre Summary of your site. Pour cela il faut utiliser la hook hook_menu().
La longue page de documentation de la hook indique que la valeur de retour doit être un tableau associatif dont chaque élément est un menu, car il est bien sûr possible d'avoir plusieurs pages pour un module. La clé de chaque élément doit décrire son chemin.
La hook_menu() ne définit donc pas un item de menu, mais associe une page avec une URL.
Pour chaque menu, un tableau associatif doit être décrit. Ici, vous utiliserez les clés « title », « access arguments », « type » et « page callback ».
-> Ajoutez ce code au fichier summary.module :
/*
* Implementation of hook_menu()
*/
function summary_menu() {
$items
[
'
summary
'
]
=
array(
'
title
'
=>
'
Summary of your site
'
,
'
access arguments
'
=>
array(true),
'
type
'
=>
MENU_CALLBACK,
'
page callback
'
=>
'
summary_content
'
,
);
return $items
;
}
/*
* Content of the summary page
*/
function summary_content() {
return '
Hello World !!!
'
;
}
Voici une description des clés utilisées pour cet exemple :
'title' | Titre de la page. La fonction t() est automatiquement appelée. |
'access arguments' | Permet de définir les droits d'accès. Ici, tout le monde a le droit d'accéder à cette page. |
'type' | Type de page et de menu, permet d'indiquer si le menu doit être affiché dans le bloc d'admin, dans le fil d'Arianne, si c'est une sous-page, etc. |
'page callback' | Nom de la fonction qui sera appelée pour retourner le contenu. |
En PHP, une fonction peut prendre en argument le nom d'une autre fonction et demander son exécution par la suite. Elle est alors appelée fonction callback.
-> Activez le module Summary.
-> Pointez votre navigateur vers l'URL /summary
Il reste maintenant à générer le contenu de cette page.
VI-B-1-c. Liste des modules activés ▲
La première section du module doit afficher la liste des modules. Après recherche sur http://api.drupal.org, la fonction module_list() semble être créée pour cela. Testez la fonction dans le bloc Execute PHP de Devel.
Chap. Devel : simplifiez votre vie de développeurDevel : simplifiez votre vie de développeur .
La fonction module_list() retourne donc un tableau (Array) contenant la liste des modules activés. Il suffit donc de modifier la fonction summary_content et de traiter le tableau.
VI-B-1-d. Liste des vocabulaires de taxonomy ▲
De la même façon que pour les modules, le site http://api.drupal.org informe que la fonction
taxonomy_get_vocabularies() existe.
taxonomy_get_vocabularies retourne donc un tableau d'objets (stdClass). Chacun de ces objets décrit un vocabulaire. Le nom du vocabulaire est dans la propriété name des objets. Il faut donc parcourir chaque élément du tableau et récupérer le nom du vocabulaire :
-> ajoutez ce code à la fonction summary_content :
// List of vocabularies
$summary_vocabularies
=
taxonomy_get_vocabularies();
$summary_vocabularies_list
=
''
;
foreach ($summary_vocabularies
as $vocab
){
$summary_vocabularies_list
.=
$vocab
->
name .
'
,
'
;
}
$summary_vocabularies_list
=
t('
<h3>Vocabularies</h3>
'
) .
$summary_vocabularies_list
;
$output
.=
$summary_vocabularies_list
;
return $output
;
VI-B-1-e. Exercice : liste des types de nodes ▲
- Ajoutez le code nécessaire à la fonction summary_content() pour lister les types de nodes existants.
Corrigé
La fonction node_type_get_types retourne un tableau d'objets (stdClass).
//List of node types
$summary_node_types
=
node_type_get_types();
$summary_node_types_list
=
array();
foreach ($summary_node_types
as $node_type
) {
$summary_node_types_list
[]
=
$node_type
->
name;
}
$summary_node_types_list
=
t('
<h3>Node types</h3>
'
).
implode($summary_node_types_list
,
'
,
'
);
$output
.=
$summary_node_types_list
;
VI-B-2. La page de configuration du module ▲
VI-B-2-a. hook_menu() : ajout d'une deuxième page pour le module ▲
La page de configuration du module summary sera accessible à partir de l'URL
admin/config/system/summary. Il faut donc ajouter un élément au tableau de la hook_menu.
function summary_menu(){
$items
[
'
summary
'
]
=
array(
'
title
'
=>
t('
Summary of your site
'
),
'
page callback
'
=>
'
summary_content
'
,
'
access arguments
'
=>
array(true),
'
type
'
=>
MENU_CALLBACK,
);
$items
[
'
admin/config/system/summary
'
]
=
array(
'
title
'
=>
t('
Summary settings
'
),
'
description
'
=>
t('
Summary configuration page
'
),
'
page callback
'
=>
'
drupal_get_form
'
,
'
page arguments
'
=>
array('
summary_admin_settings
'
),
'
access arguments
'
=>
array('
administer site configuration
'
),
'
type
'
=>
MENU_NORMAL_ITEM,
);
return $items
;
}
L'URL de la page (admin/config/system/summary) permet d'ajouter un lien dans la page de configuration (config) à la section système (system).
Le lien Menu item du bloc Devel permet de connaître les informations des différentes pages.
Cette page de configuration sera en fait un formulaire HTML. Pour composer un formulaire, Drupal propose une API bien particulière qui sera décrite plus tard.
'page_callback' | Ici, on appelle une fonction Drupal (drupal_get_form) qui construira le formulaire. |
'page arguments' | Liste des arguments à passer à la fonction callback. |
'access argument' | Vérifie que l'utilisateur a les droits d'administration du site avant d'afficher la page. |
'type' | Nom de la fonction qui sera appelée pour retourner le contenu. |
Le but est de créer un formulaire, Drupal propose pour cela la fonction drupal_get_form. Cette fonction prend en argument le nom d'une autre fonction qui décrit les éléments qui composeront le formulaire.
La fonction qui décrira le formulaire s'appellera summary_admin_settings, donc hook_menu appellera drupal_get_form(summary_admin_settings) lorsque la page devra s'afficher.
VI-B-2-b. Form API : créer des formulaires HTML dans Drupal ▲
La page d'administration proposera une case à cocher pour chaque section de summary permettant à l'administrateur de choisir si la section doit s'afficher ou non.
-> Ajoutez le code suivant au fichier summary.module :
/*
* Define the adminsitration form
*/
function summary_admin_settings(){
$form
[
'
summary_display
'
]
=
array(
'
#type
'
=>
'
checkboxes
'
,
'
#title
'
=>
t('
Sections of the summary
'
),
'
#description
'
=>
t('
Check the sections to show in the summary page
'
),
'
#options
'
=>
array('
module
'
=>
t('
Module list
'
),
'
vocabulary
'
=>
t('
Vocabulary list
'
),
'
content_type
'
=>
t('
Content types
'
)),
);
return $form
;
}
Un tableau $form est donc créé, chaque élément de ce tableau est un élément du formulaire et peut se paramétrer grâce à des propriétés. Voici la liste des propriétés utilisées :
'#type' | Type de widget à utiliser. Ici des cases à cocher. |
'#title' | Titre à afficher au-dessus du widget. |
'#description' | Texte d'aide en dessous du widget. |
'#options' | Propriété propre aux cases à cocher, tableau listant les cases à cocher à afficher et leurs étiquettes. |
Une description de tous les éléments pouvant être insérés dans un formulaire est disponible à la page : http://api.drupal.org/api/drupal/developer-topics--forms_api_reference.html.
Le lien Hook_elements() du bloc Devel affiche la liste des éléments disponibles.
-> Menu Configuration - lien Summary settings
VI-B-2-c. system_settings_form : ajouter le bouton de sauvegarde ▲
Il manque le bouton de sauvegarde à votre formulaire. Il serait possible d'en créer un en ajoutant un nouvel élément de #type submit au tableau $form, mais il est préférable d'utiliser la fonction system_settings_form qui ajoute les boutons nécessaires par défaut des formulaires de configuration.
-> Modifiez la dernière ligne de la fonction summary_admin_settings comme ceci :
return system_settings_form($form
);
Le bouton est bien là, mais les paramètres ne sont pas encore enregistrés.
VI-B-2-d. variable_get : sauvegarder des données dans la table variable ▲
Voici comment modifier le code pour que les valeurs soient sauvegardées :
function summary_admin_settings(){
$form
[
'
summary_display
'
]
=
array(
'
#type
'
=>
'
checkboxes
'
,
'
#title
'
=>
t('
Things to show for the summary
'
),
'
#description
'
=>
t('
Check the things to show in the summary page
'
),
'
#options
'
=>
array('
module
'
=>
t('
Module list
'
),
'
vocabulary
'
=>
t('
Vocabulary list
'
),
'
content_type
'
=>
t('
Content types
'
)),
'
#default_value
'
=>
variable_get('
summary_display
'
,
array('
module
'
,
'
vocabulary
'
)),
);
return system_settings_form($form
);
}
La fonction variable_get permet de récupérer des variables enregistrées dans le tableau de variables globales $conf, lui-même stocké dans la table variables de la base de données de Drupal.
Elle prend deux paramètres, le premier, obligatoire, est le nom de la variable à récupérer, le second, optionnel, est la valeur que retourne variable_get si aucune variable n'est trouvée dans $conf.
Ici, on initialise donc le formulaire avec des valeurs par défaut qui seront, soit prises dans le tableau $conf si elles sont présentes, soit prises dans le second paramètre qui indique que les cases module et vocabulary sont cochées par défaut.
global $conf
;
dpm($conf
);
Dernière question ; comment sont sauvegardées ces valeurs ? Eh bien c'est la fonction system_settings_form qui s'occupe de tout !
Pour que la fonction system_settings_form sauvegarde automatiquement les paramètres, il faut veiller à ce que le nom de l'élément de formulaire - $form['summary_display'] - soit identique à celui du premier paramètre de variable_get - variable_get('summary_display').
VI-B-2-e. Exercice : personnalisation des titres des sections ▲
- Ajoutez des éléments textfield permettant à l'utilisateur de modifier les titres des sections ;
- Ajoutez des éléments fieldset pour les cases à cocher et un autre pour les labels.
Corrigé
Ajoutez des éléments textfield permettant à l'utilisateur de modifier les titres des sections
$form
[
'
summary_module_label
'
]
=
array(
'
#type
'
=>
'
textfield
'
,
'
#title
'
=>
t('
Label of the module section
'
),
'
#description
'
=>
t('
Change the label of the module section
'
),
'
#default_value
'
=>
variable_get('
summary_module_label
'
,
'
Activated modules
'
),
);
$form
[
'
summary_taxonomy_label
'
]
=
array(
'
#type
'
=>
'
textfield
'
,
'
#title
'
=>
t('
Label of the taxonomy section
'
),
'
#description
'
=>
t('
Change the label of the taxonomy section
'
),
'
#default_value
'
=>
variable_get('
summary_taxonomy_label
'
,
'
Taxonomy vocabularies
'
),
);
$form
[
'
summary_content_types
'
]
=
array(
'
#type
'
=>
'
textfield
'
,
'
#title
'
=>
t('
Label of the content types section
'
),
'
#description
'
=>
t('
Change the label of the content types section
'
),
'
#default_value
'
=>
variable_get('
summary_content_types
'
,
'
Content types
'
),
);
Ajoutez des éléments fieldset pour les cases à cocher et un auteur pour les labels
/*
* Define the adminsitration form
*/
function summary_admin_settings(){
$form
[
'
checkbox_visible
'
]
=
array(
'
#type
'
=>
'
fieldset
'
,
'
#title
'
=>
t('
Section visibility
'
),
'
#description
'
=>
t('
Things to show for the summary
'
),
'
#collapsible
'
=>
TRUE,
'
#collapsed
'
=>
TRUE,
);
$form
[
'
checkbox_visible
'
][
'
summary_display
'
]
=
array(
'
#type
'
=>
'
checkboxes
'
,
'
#title
'
=>
t('
Things to show for the summary
'
),
'
#description
'
=>
t('
Check the things to show in the summary page
'
),
'
#options
'
=>
array('
module
'
=>
t('
Module list
'
),
'
vocabulary
'
=>
t('
Vocabulary list
'
),
'
content_type
'
=>
t('
Content types
'
)),
'
#default_value
'
=>
variable_get('
summary_display
'
,
array('
module
'
,
'
vocabulary
'
)),
);
$form
[
'
labels
'
]
=
array(
'
#type
'
=>
'
fieldset
'
,
'
#title
'
=>
t('
Labels of sections
'
),
'
#description
'
=>
t('
Change the labels of the summary
'
),
'
#collapsible
'
=>
TRUE,
'
#collapsed
'
=>
TRUE,
);
$form
[
'
labels
'
][
'
summary_module_label
'
]
=
array(
'
#type
'
=>
'
textfield
'
,
'
#title
'
=>
t('
Label of the module section
'
),
'
#description
'
=>
t('
Change the label of the module section
'
),
'
#default_value
'
=>
variable_get('
summary_module_label
'
,
'
Activated modules
'
),
);
$form
[
'
labels
'
][
'
summary_taxonomy_label
'
]
=
array(
'
#type
'
=>
'
textfield
'
,
'
#title
'
=>
t('
Label of the taxonomy section
'
),
'
#description
'
=>
t('
Change the label of the taxonomy section
'
),
'
#default_value
'
=>
variable_get('
summary_taxonomy_label
'
,
'
Taxonomy vocabularies
'
),
);
$form
[
'
labels
'
][
'
summary_content_types
'
]
=
array(
'
#type
'
=>
'
textfield
'
,
'
#title
'
=>
t('
Label of the content types section
'
),
'
#description
'
=>
t('
Change the label of the content types section
'
),
'
#default_value
'
=>
variable_get('
summary_content_types
'
,
'
Content types
'
),
);
return system_settings_form($form
);
}
VI-B-3. Utilisation des paramètres pour la page Summary ▲
Il faut maintenant récupérer les paramètres sauvegardés dans la table variables par la page de configuration.
Les valeurs des cases à cocher sont stockées à la ligne summary_display de la table variables. La fonction variable_get() permet de récupérer ces valeurs :
-> à la page de configuration du module Summary, cochez uniquement la section Vocabulary list ;
-> bouton Enregistrer la configuration
Le lien Variable editor du bloc Devel affiche les valeurs des lignes de la table variables.
summary_display est retournée sous forme de tableau associatif. Si la section n'est pas à afficher, sa valeur est à 0 (false), sinon, sa valeur est le nom de la clé (true).
Il suffit donc de tester cette valeur avant d'ajouter chaque section.
-> Modifiez la fonction summary_content comme cela :
function summary_content() {
//List of all activated modules
$summary_module_list
=
module_list();
$summary_module_list
=
t('
<h3>Activated modules</h3>
'
) .
implode($summary_module_list
,
'
,
'
);
// List of vocabularies
$summary_vocabularies
=
taxonomy_get_vocabularies();
$summary_vocabularies_list
=
''
;
foreach ($summary_vocabularies
as $vocab
){
$summary_vocabularies_list
.=
$vocab
->
name .
'
,
'
;
}
$summary_vocabularies_list
=
t('
<h3>Vocabularies</h3>
'
) .
$summary_vocabularies_list
;
// List of content types
$summary_node_types
=
node_type_get_types();
$summary_node_types_list
=
''
;
foreach ($summary_node_types
as $node_types
){
$summary_node_types_list
.=
$node_types
->
name .
'
,
'
;
}
$summary_node_types_list
=
t('
<h3>Node type</h3>
'
) .
$summary_node_types_list
;
$display
=
variable_get('
summary_display
'
,
array());
$output
=
''
;
if ($display
[
'
module
'
]
) {
$output
.=
$summary_module_list
;
}
if ($display
[
'
vocabulary
'
]
) {
$output
.=
$summary_vocabularies_list
;
}
if ($display
[
'
content_type
'
]
) {
$output
.=
$summary_node_types_list
;
}
return $output
;
}
VI-B-3-a. Exercice : affichage des labels personnalisés ▲
Modifiez la fonction summary_content pour qu'elle affiche les labels de la page de configuration du module.
Corrigé
Les valeurs des labels sont stockées dans les lignes summary_module_label, summary_taxonomy_label et summary_content_types de la table variables. La fonction variable_get() permet de récupérer ces valeurs.
summary_taxonomy_label est donc retournée sous forme de chaîne de caractères correspondant à la valeur du label. Si rien n'est retourné, il faut préciser une valeur par défaut dans la fonction variable_get.
Voici donc la ligne modifiée pour la section liste des vocabulaires :
$summary_vocabularies_list
=
t('
<h3>Vocabularies</h3>
'
) .
$summary_vocabularies_list
;
Modifiée en :
$summary_vocabularies_list
=
'
<h3>
'
.
variable_get('
summary_taxonomy_label
'
,
t('
Vocabularies
'
)) .
'
</h3>
'
.
$summary_vocabularies_list
;
Répétez l'opération pour les autres sections.
VI-B-4. Exécuter des requêtes SQL dans un module en récupérer le résultat ▲
Il existe un grand nombre de fonctions dans l'API Drupal, et qui interrogent la base de données à votre place. Mais il est parfois nécessaire de faire ses propres requêtes.
VI-B-4-a. Requête simple retournant une seule ligne ▲
Vous allez commencer par afficher le nombre de nodes publiées dans Drupal. La requête SQL est :
SELECT
count
(*)
FROM
node
WHERE
status
=
1
Chap. La Base de données de DrupalLa base de données de Drupal .
La requête ne retourne qu'une seule valeur : le nombre de nodes.
Vous allez maintenant modifier le fichier summary.module pour qu'il affiche une nouvelle section Number of nodes.
Modifiez la fin de la fonction summary_content() ainsi :
//Number of nodes
$query
=
'
SELECT count(*) FROM node WHERE status = 1
'
;
$summary_node_count
=
db_query($query
)->
fetchField();
$summary_node_count
=
t('
<h3>Number of nodes</h3>
'
) .
$summary_node_count
;
$display
=
variable_get('
summary_display
'
,
array());
$output
=
''
;
if ($display
[
'
module
'
]
)
$output
.=
$summary_module_list
;
if ($display
[
'
vocabulary
'
]
)
$output
.=
$summary_vocabularies_list
;
if (array_key_exists('
content_type
'
,
$display
) &&
$display
[
'
content_type
'
]
)
$output
.=
$summary_node_types_list
;
$output
.=
$summary_node_count
;
return $output
;
La fonction : db_query prend en paramètre la requête SQL et retourne un objet. Une méthode de cet objet est fetchField qui retourne le résultat de la requête.
Noms de tables
La requête précédente retourne le résultat escompté, et pourtant elle pose un problème. Il est en effet possible de préfixer les tables avec une chaîne de caractères à l'installation de Drupal. Ainsi, la table node n'aura peut-être pas pour nom node mais drupal_node (si les tables sont préfixées drupal_). Pour que Drupal gère cela, il faut entourer le nom des tables par des accolades.
La requête devient donc :
$query
=
'
SELECT count(*) FROM {node} WHERE status = 1
'
;
VI-B-4-b. Requête avec résultat sur plusieurs lignes ▲
Pour modifier votre nouveau paragraphe pour qu'il affiche le nombre de nodes par type, la requête SQL devient :
SELECT
type
, count
(*)
AS
"Nombre nodes"
FROM
node
GROUP
BY
type
Dans le module summary, la requête devient donc :
//Number of nodes per type
$query
=
'
SELECT type, count(*) FROM {node} GROUP BY type
'
;
L'objet retourné par db_query (de type DatabaseStatementBase) permet d'exécuter plusieurs méthodes :
Il y a donc plusieurs solutions possibles pour arriver au même résultat.
- Exemple de traitement des résultats en utilisant la méthode fetchAllAssoc() :
//Number of nodes per type
$query
=
'
SELECT type, count(*) AS count FROM {node} GROUP BY type
'
;
$result
=
db_query($query
)->
fetchAllAssoc('
type
'
);
$summary_node_count_type
=
''
;
foreach($result
as $row
) {
$summary_node_count_type
.=
$row
->
type.
'
:
'
.
$row
->
count.
'
<br/>
'
;
}
$summary_node_count
=
t('
<h3>Number of nodes per type</h3>
'
).
$summary_node_count_type
;
- Exemple de traitement des résultats en utilisant la méthode fetchAssoc() :
$query
=
'
SELECT type, count(*) AS count FROM {node} GROUP BY type
'
;
//Avec la méthode fetchAssoc
$result
=
db_query($query
);
$summary_node_count_type
=
''
;
while ($row
=
$result
->
fetchAssoc()) {
$summary_node_count_type
.=
$row
[
'
type
'
].
'
:
'
.
$row
[
'
count
'
].
'
<br/>
'
;
}
$summary_node_count
=
t('
<h3>Number of nodes per type</h3>
'
).
$summary_node_count_type
;
VI-B-4-c. Requête avec variables ▲
Vous aurez parfois besoin de positionner des variables dans vos requêtes.
Voici par exemple une requête qui sélectionne le titre des nodes publiées de type article :
$query
=
'
SELECT title FROM {node} WHERE type="article" AND status=1
'
;
$result
=
db_query($query
);
Imaginez maintenant que vous avez deux variables $type et $status contenant respectivement le type et le statut des nodes à afficher, la requête devient alors :
$query
=
'
SELECT title FROM {node} WHERE type = :type AND status = :status
'
;
$result
=
db_query($query
,
array( '
:type
'
=>
$type
,
'
:status
'
=>
$status
));
Il faut donc utiliser des jokers (:type, :status), leurs valeurs sont ensuite remplacées lors de l'exécution de la fonction db_query. Celle-ci prend un tableau en deuxième argument qui contient la liste des valeurs et des jokers.
VI-B-4-d. Requête avec le constructeur de requêtes ▲
La requête précédente est une requête simple, mais le système des jokers peut vite devenir confus si votre requête comporte un grand nombre de paramètres. Drupal propose alors tout un système de construction de requêtes via PHP.
Voici par exemple ce que deviendrait la requête précédente :
$query
=
db_select(node,
n);
$query
->
fields('
n
'
,
array('
title
'
))
->
condition('
type
'
,
$type
)
->
condition('
status
'
,
$status
);
$result
=
$query
->
execute
();
L'idée est donc de commencer par créer un objet de type SelectQuery en appelant la fonction db_select et ensuite de le modifier en lui ajoutant des directives SQL. Lorsque celle-ci est construite, il faut lancer la méthode execute() pour récupérer le résultat de la requête.
La fonction db_select prend en premier argument le nom de la table à utiliser (node) et en deuxième argument un alias (n). C'est cet alias qui sera utilisé dans les autres directives SQL (fields('n', array('title')).
Cette méthode permet de construire une requête tout au long d'un script PHP sans avoir à manipuler de longues chaînes de caractères pour former une requête SQL valide.
Vous pouvez utiliser les méthodes DeleteQuery, InsertQuery et UpdateQuery pour des requêtes SQL delete, insert et update.
VI-B-5. Theming du contenu ▲
Dans le module Summary, vous avez inséré quelques balises HTML directement dans le code PHP (balise H3 pour les titres). Dans cette section, vous permettrez aux créateurs de thèmes de modifier l'apparence du contenu de votre module.
Pour bien comprendre cette section, lisez le chap. Les thèmesChapitre V Les thèmes Drupal dans son ensemble.
VI-B-5-a. Affichage du nombre de nodes sous forme de tableau ▲
Il serait plus lisible d'afficher le nombre de nodes par type de contenu sous forme de tableau :
Pour cela, il faut utiliser la fonction de theme Drupal theme_table. Vous pouvez rechercher comment elle s'utilise sur api.drupal.org.
Vous pouvez retrouver la liste des fonctions de thème à la page
http://api.drupal.org/api/group/themeable/7.
Lorsqu'elles sont utilisées à l'intérieur de Drupal, il faut appeler les fonctions de thème par la fonction theme() de cette façon :
- theme_table($variables) devient theme('table', $variables) ;
- theme_date($variables) devient theme('date', $variables) ;
- etc.
La fonction theme_table prend en paramètre un tableau qui contient lui-même deux tableaux. Le premier doit contenir les en-têtes (header), le second les lignes (rows).
Voici comment implémenter cette fonction pour le nombre de nodes par type :
VI-B-5-b. Implémentation de hook_theme ▲
Vous allez maintenant créer votre propre fonction de thème que d'autres développeurs et créateurs de thèmes pourront utiliser.
Cette fonction permettra de présenter un paragraphe du module summary :
Pour cela, votre module doit implémenter la hook hook_theme() qui prend en paramètre la liste des fonctions de thème du module.
Il faut préciser les paramètres qu'aura chaque fonction. Ici, vous avez besoin du titre de la section et de son contenu.
/**
* Implementation of hook_theme
*/
function summary_theme () {
$functions
=
array(
'
summary_paragraph
'
=>
array (
'
variables
'
=>
array('
title
'
=>
NULL,
'
content
'
=>
NULL)
)
);
return $functions
;
}
-> Videz les caches.
-> Lien Theme registry du bloc devel (devel/theme/registry).
VI-B-5-c. Création d'une fonction par défaut pour le module ▲
Il faut maintenant fournir une fonction par défaut dans le module au cas où le thème actif ne surcharge pas la fonction de thème.
Cette fonction affiche uniquement le titre dans une balise <h4> et le contenu dans une balise <p>
VI-B-5-d. Appel de la fonction de thème dans le module ▲
Vous utiliserez votre fonction dans le module pour présenter vos paragraphes. Il suffit de passer en paramètre les deux chaînes composants le titre et le contenu dans un tableau associatif :
$title
=
variable_get('
summary_content_types
'
,
t('
Content types
'
));
$content
=
implode($summary_node_types_list
,
'
,
'
);
$summary_node_types_list
=
theme('
summary_paragraph
'
,
array('
title
'
=>
$title
,
'
content
'
=>
$content
));
-> Modifiez le module pour qu'il utilise la fonction pour chacun des paragraphes.
VI-B-5-e. Création d'un template par défaut ▲
Pour un créateur de thèmes, il est plus facile d'utiliser un template de type .tpl.php. Et cela n'est pas beaucoup plus compliqué à fournir qu'une fonction de thème.
Tout d'abord, il faut préciser un nom de template dans la fonction hook_theme :
/**
* Implementation of hook_theme
*/
function summary_theme () {
$functions
=
array(
'
summary_paragraph
'
=>
array (
'
variables
'
=>
array('
title
'
=>
NULL,
'
content
'
=>
NULL),
'
template
'
=>
'
summary_paragraph
'
,
)
);
return $functions
;
}
Drupal ajoute automatiquement le suffixe .tpl.php au nom du template.
Il reste à créer le template par défaut summary_paragraph.tpl.php dans le répertoire du module summary :
<?php
/**
* @file
* Default theme implementation for each paragraph in the summary module.
*
* Available variables:
* - $title: Title of the paragraph.
* - $content: Content of the paragraph
*/
?>
<
li class=
"
summary_item
"
>
<
h3>
<?php
print
$title
?>
</
h3>
<
div class=
"
summary_content
"
>
<?php
print
$content
?>
</
div>
</
li>
-> Videz les caches.
-> Rechargez votre page
Pour des raisons de performances, évitez de fournir un template lorsque celui-ci sera appelé de nombreuses fois sur une page.
Le but de cette section était de vous ouvrir les portes de la programmation avec Drupal. Si vous désirez aller plus loin, je vous conseille de parcourir le site http://api.drupal.org ou de lire le livre Pro Drupal Developement (http://www.drupalbook.com/).
VI-C. Les outils pour mieux développer avec Drupal ▲
VI-C-1. Devel : simplifiez votre vie de développeur ▲
Le module Devel est une boite à outils pour aider le développeur de modules Drupal.
-> Installez et activez le module Devel (version utilisée dans ce livre : 7.x-1.0).
VI-C-1-a. Le bloc Développement ▲
-> Activez le bloc Développement en barre de gauche de Bartik.
-> Allez sur la page d'accueil de votre site.
S'affiche alors un bloc contenant un menu permettant d'accéder aux fonctionnalités de Devel :
Devel settings | Accéder à la page de configuration de Devel. |
Empty cache | Permet de vider l'ensemble des caches de Drupal. |
Execute PHP Code | Ouvre une page contenant une zone de texte permettant d'exécuter du code PHP. |
Field info | Affiche les informations de chaque champ pouvant être attaché à un contenu. |
Function reference | Affiche la liste de toutes les fonctions utilisées sur le site. Si celles-ci sont dans l'API Drupal 7, un lien vers leur documentation est proposé. |
Hook_elements() | Liste des éléments pouvant être inclus dans un formulaire. |
Lancer le traitement régulier | Lance le cron. |
Menu item | Détaille les paramètres d'un menu (hook_menu). Par exemple : devel/menu/item&path=admin/config/system/site-information, détaillera le menu admin/config/system/site-information. |
PHPinfo() | Affiche des informations détaillées sur votre configuration PHP. |
Rebuild menus | Reconfigure l'ensemble des menus. Tous les menus reprennent leur configuration par défaut. |
Reinstall modules | Désinstalle et réinstalle tous les modules du site. |
Session viewer | Affiche des informations sur la session en cours. |
Theme registry | Affiche la liste de toutes les fonctions de thème du site. |
Variable editor | Affiche la liste de toutes les variables de $conf. Il est également possible de les éditer à partir de cette interface. |
VI-C-1-b. Le bloc Execute PHP ▲
-> Activez le bloc Execute PHP en pied de page de Bartik et de Seven.
Il est ensuite possible d'exécuter du code PHP à partir de cette zone de texte.
VI-C-1-c. Les fonctions de débogage ▲
Plusieurs fonctions de débogage sont livrées avec Devel. Vous pouvez les insérer n'importe où dans votre code (y compris dans l'interface Drupal).
S'affiche avec Krumo | S'affiche en haut de page | S'affiche en zone de notification | |
dpm() | X | X | |
dvm() | X | ||
kpr() | X | X | |
dpr() | X |
VI-C-1-d. Le générateur de contenu ▲
Ce module permet de créer n'importe quel type de contenu pour tester votre site, il permet également de créer des commentaires, des utilisateurs, des vocabulaires et des termes de taxonomy.
-> Activez le module Devel generate.
-> Menu Configuration - lien Développement.
Vous avez alors accès à différents menus permettant de créer du contenu, des utilisateurs et de la taxonomy.
-> Cliquez sur Generate content.
- Vous pouvez alors régler les différents paramètres avant de générer le contenu en cliquant sur Do it !
VI-C-1-e. Le Profiler SQL ▲
Devel permet de connaître la liste des requêtes qui ont été exécutées pour l'affichage d'une page.
-> Menu Configuration - lien Développement.
-> Cochez la case Afficher la liste des requêtes.
-> Cliquez sur Enregistrer.
VI-C-2. Le module Coder ▲
Le module Coder inspecte le code des modules et indique s'ils ne respectent pas les conventions de codages de Drupal (http://drupal.org/node/318).
-> Installez le module (version utilisée dans ce livre : 7.x-1.0-beta6) - http://drupal.org/project/coder.
-> Activez les modules Coder et Coder Review.
-> Menu Modules
-> Cliquez sur le lien Code Review de votre module.
-> Constatez le nombre d'erreurs à corriger !
VI-C-3. Drupal for Firebug ▲
Ce module permet de déboguer certaines parties de vos modules à partir de Firebug, module de Firefox.
Installation
Pour que ce module fonctionne, il faut activer le module Drupal et le module Firefox.
-> Installez le module Drupal For Firebug(version utilisée dans ce livre : 7.x-1.2) - http://drupal.org/project/drupalforfirebug.
-> Activez les modules Drupal for Firebug Preprocessor et Drupal for Firebug.
-> Téléchargez et activez le module Drupal For Firebug de Firefox (version utilisée dans ce livre : 0.0.7) - https://addons.mozilla.org/en-US/firefox/addon/drupal-for-firebug/.
Lors de la rédaction de ce livre, le plugin pour Firefox ne fonctionnait pas. C'est pourquoi les copies d'écran ont été prises avec Google chrome avec l'extension Drupal for Chrome.
Utilisation
Chargez une page de Drupal, lancez Firebug, un nouvel onglet Drupal apparaît, il est alors possible d'avoir des informations sur cette page :
Plusieurs sous-onglets sont alors disponibles :
Informations | Vous pouvez utiliser la fonction firep() pour afficher des informations dans cet onglet. |
Forms | Affiche les paramètres des composants des formulaires de la page. |
Sql | Affiche les requêtes SQL exécutées pour la page si l'option du Profiler SQL est activée (chap. Le Profiler SQLLe Profiler SQL). |
User | Affiche les informations liées à l'utilisateur. |
Node | Affiche les informations liées aux nodes chargées sur la page (y compris celles des vues). |
View | Affiche les informations liées aux vues chargées sur la page. |
PHP | Fonctionne de la même façon que le bloc Execute PHP du module Devel (chap. Le bloc Execute PHPLe bloc Execute PHP). |
VI-C-4. Déboguer avec Eclipse ▲
Lorsque vous développerez des modules complexes, pouvoir déboguer avec une interface graphique peut vous faire gagner du temps : pouvoir mettre des points d'arrêt, exécuter le programme pas à pas et voir directement l'évolution des valeurs des variables peut aider à mieux comprendre ses erreurs.
Dans cette section, vous installerez le débogueur Xdebug sur votre serveur, et vous l'utiliserez avec Eclipse.
VI-C-4-a. Installation de Xdebug sur WampServer ▲
Xdebug est installé par défaut sur Wampserver, mais il n'est pas configuré en mode remote (débogage à distance) :
-> menu Rapports - lien Tableau de bord d'administration ;
-> lien plus d'informations de la ligne PHP.
Pour modifier la configuration de Xdebug :
-> éditez votre fichier php.ini (icône Wampserver - PHP - php.ini) ;
-> modifiez ainsi les lignes de la section ; XDEBUG Extension du fichier :
[xdebug]
xdebug.remote_enable=on
xdebug.remote_host="127.0.0.1"
xdebug.remote_port=9000
xdebug.remote_handler="dbgp"
xdebug.remote_mode=req
-> enregistrez le fichier et redémarrez WampServer.
VI-C-4-b. Installation de Xdebug sur Ubuntu ▲
Commencez par installer le paquet Xdebug
sudo apt-get install php5-xdebug
Puis éditez le fichier de configuration de Xdebug :
sudo gedit /etc/php5/conf.d/xdebug.ini
Ajoutez au fichier les lignes suivantes :
xdebug.remote_enable=on
xdebug.remote_host="127.0.0.1"
xdebug.remote_port=9000
xdebug.remote_handler="dbgp"
xdebug.remote_mode=req
Sauvegardez le fichier et redémarrez Apache :
sudo /etc/init.d/apache2 restart
Vous pouvez vérifier si Xdebug s'est bien installé :
-> menu Rapports - lien Tableau de bord d'administration ;
-> lien plus d'informations de la ligne PHP
VI-C-4-c. Module easy Xdebug pour Firefox ▲
Il existe un module pour Firefox qui permet de simplifier le démarrage d'une session xdebug.
-> Dans le menu Modules complémentaires de Firefox, recherchez l'extension easy xdebug (version utilisée pour ce livre easy Xdebug 1.5).
-> Installer le module.
-> Redémarrez Firefox.
Deux icônes s'affichent en bas à droite de Firefox, l'une pour démarrer une session de débogage, l'autre pour la stopper.
Vous pouvez afficher ou cacher la barre des modules de Firefox grâce au menu Options - Barre des modules.
VI-C-4-d. Configuration d'Eclipse pour xdebug ▲
Il s'agit maintenant d'indiquer à Eclipse que vous utiliserez Xdebug pour déboguer votre projet Drupal.
-> Menu Window - Preferences.
-> Sélectionnez l'item PHP - Debug.
-> À la ligne PHP Debugger choisissez XDebug.
-> Cliquez sur le lien configure... de XDebug.
-> Sélectionnez XDebug dans la liste Installed Debuggers.
-> Bouton Configure.
-> Dans la liste Accept remote session (JIT), choisissez any
Vous pouvez également décocher la case Show super globals in variable views qui vous permettra de limiter le nombre de variables affichées lors du débogage.
-> Bouton OK.
-> Bouton OK.
VI-C-4-e. Utiliser xdebug ▲
Vous allez maintenant déboguer votre fonction summary_content(). Elle est utilisée lors de l'affichage de la page /summary.
-> Ouvrez le fichier sites/all/modules/summary/summary.module.
-> Dans la marge de la première ligne de la fonction, faites un clic droit et choisissez Toggle Breakpoints
Un point bleu signifiant le point d'arrêt devrait apparaître dans la marge. Lorsque le programme atteindra cette ligne, il arrêtera de s'exécuter et vous informera sur son état.
Vous pouvez également positionner vos points d'arrêts dans le fichier template de vos thèmes et modules.
-> Dans Firefox, pointez vers l'URL /summary.
-> Démarrez la session xdebug grâce à l'icône Start Xdebug Session de easy Xdebug.
-> Rechargez la page (F5).
Eclipse demande alors le type de perspective qu'il doit utiliser pour la session de débogage
-> Bouton Yes.
Eclipse s'arrête alors à la première ligne du index.php de Drupal. Utilisez la barre de boutons de la vue Debug d'Eclipse pour naviguer dans le programme.
-> Bouton Resume (F8).
Le script se déroule alors jusqu'au prochain point d'arrêt qui est celui que vous avez ajouté dans la fonction summary_content().
-> Continuez à dérouler le script pas à pas (Bouton Step Over (F6)).
-> Remarquez l'évolution des variables dans la vue Variables
Si Eclipse ne s'arrête pas sur votre point d'arrêt, il se peut que votre code ne soit pas exécuté par Drupal, car le code HTML généré est en cache. Cela est fréquent pour le contenu des blocs.
Videz alors le cache et rechargez la page.
Bonne route !
J'espère que c'est avec plaisir que vous avez découvert les possibilités de Drupal. Ce livre ne se prétend pas exhaustif, car le sujet est très vaste. J'ai essayé de vous donner les clés pour ouvrir le maximum de portes pour explorer le vaste monde de Drupal. Maintenant, à vous de découvrir LA fonctionnalité que vous recherchez !
À bientôt au détour d'un forum !