Etendre la Web Debug Toolbar
Par Ryan Weaver
La barre de débogage web, web debug toolbar
(WDT
), de symfony regroupe des outils qui permettent de déboguer et d'améliorer les performances d'une application. Elle est constituée d'outils appelés panneaux de débogage web, web debug panels, chacun donnant des informations relatives au cache, à la configuration, aux fichiers de logs, à la consommation mémoire, au temps d'exécution ou bien encore concernant la version de symfony. Symfony 1.3 introduit deux nouveaux panneaux, un pour la vue
et l'autre pour la gestion des emails
.
Depuis symfony 1.2 il est possible de créer et d'ajouter ses propres panneaux de débogage web. Tout au long de ce chapitre, il s'agira de créer un nouvel onglet de débogage en étudiant par la même occasion les outils et les options qui permettent de le personnaliser. Il est de plus possible de se référer au plugin ac2009WebDebugPlugin qui contient de nombreux panneaux supplémentaires s'appuyant sur les techniques expliquées dans la suite de ce chapitre.
Créer un Nouveau Panneau de Débogage Web
Les composants de la barre de débogage web sont appelés web debug panels, ou bien panneaux de débogage web pour les puristes francophones. Ils étendent la classe sfWebDebugPanel
. Ajouter un nouveau panel est particulièrement simple puisqu'il s'agit tout d'abord de créer un nouveau fichier sfWebDebugPanelDocumentation.class.php
dans le dossier lib/debug/
du projet. Le répertoire lib/debug
doit être créé manuellement.
// lib/debug/sfWebDebugPanelDocumentation.class.php class acWebDebugPanelDocumentation extends sfWebDebugPanel { public function getTitle() { return '<img src="/legacy/images/documentation.png" alt="Documentation Shortcuts" height="16" width="16" /> docs'; } public function getPanelTitle() { return 'Documentation'; } public function getPanelContent() { $content = 'Placeholder Panel Content'; return $content; } }
Tous les panneaux doivent implémenter au minimum les méthodes getTitle()
, getPanelTitle()
et getPanelContent()
.
sfWebDebugPanel::getTitle()
définit l'apparence du panneau dans la barre de débogage. Il s'agit généralement d'un nom court accompagné d'une icône.sfWebDebugPanel::getPanelTitle()
définit le nom du panneau qui est affiché dans le tagh1
de l'onglet ouvert. Il sert aussi d'attributtitle
au lien de la barre de débogage. Cette méthode ne doit pas retourner de code HTML.sfWebDebugPanel::getPanelContent()
génère le code HTML affiché lorsque l'onglet est ouvert.
Pour finir cette implémentation, il ne reste plus qu'à informer l'application que l'on souhaite inclure ce nouvel onglet à la barre de débogage. Pour ce faire, il est nécessaire d'ajouter un nouvel écouteur sur l'événement debug.web.load_panels
. Cet événement est notifié lorsque la barre de débogage recherche ses panneaux. Il suffit donc de modifier le contenu du fichier config/ProjectConfiguration.class.php
afin de lui faire implémenter cet écouteur.
// config/ProjectConfiguration.class.php public function setup() { // ... $this->dispatcher->connect('debug.web.load_panels', array( 'acWebDebugPanelDocumentation', 'listenToLoadDebugWebPanelEvent' )); }
L'étape suivante consiste à ajouter la méthode listenToLoadDebugWebPanelEvent()
à la classe acWebDebugPanelDocumentation.class.php
afin d'ajouter le nouvel onglet dans la base d'outils. Cette méthode sera appelée lorsque l'évènement debug.web.load_panels
sera notifié.
// lib/debug/sfWebDebugPanelDocumentation.class.php public static function listenToLoadDebugWebPanelEvent(sfEvent $event) { $event->getSubject()->setPanel( 'documentation', new self($event->getSubject()) ); }
Voilà ! Il ne reste plus qu'à rafraîchir le navigateur et apprécier le résultat.
tip
Depuis symfony 1.3, un paramètre sfWebDebugPanel
peut être ajouté à l'URL
d'une page pour charger automatiquement un panneau de débogage. Si l'on ajoute
par exemple la chaîne ?sfWebDebugPanel=documentation
à la fin de l'URL, le
nouveau panneau sera ajouté à la page. C'est particulièrement utile lorsqu'il
s'agit de développer des panneaux personnalisés.
Les Trois Types de Panneaux de Débogage Web
En réalité, il existe trois différents types de panneaux de débogage web. Les lignes qui suivent les décrivent les uns après les autres afin de mieux comprendre les intérêts de chacun.
Le Type Icon-Only
Ce type de panneau se contente d'afficher une icône et du texte dans la barre d'outil. C'est typiquement le cas du panneau memory
qui affiche la mémoire consommée sans aucun lien supplémentaire. Pour créer un panel de type icon-only, la méthode getPanelContent()
doit retourner une chaine vide. La seule sortie de l'onglet provient en réalité de la méthode getTitle()
.
public function getTitle() { $totalMemory = sprintf('%.1f', (memory_get_peak_usage(true) / 1024)); return '<img src="'.$this->webDebug->getOption('image_root_path').'/memory.png" alt="Memory" /> '.$totalMemory.' KB'; } public function getPanelContent() { return; }
Le Type Link
Au même titre que le panneau de type Icon-Only, l'onglet de type link n'a pas de contenu, mais dispose cependant d'un lien supplémentaire. L'URL de ce lien est défini par la méthode getTitleUrl()
.
Pour créer un panneau de type link, la méthode getPanelContent()
doit retourner une chaine vide tandis que la méthode getTitleUrl()
doit être ajoutée à la classe comme le montre l'exemple ci-dessous.
public function getTitleUrl() { // link to an external uri return '/api/1_3/'; // or link to a route in your application return url_for('homepage'); } public function getPanelContent() { return; }
Le Type Content
Enfin, le panneau de type content est le plus courant de tous puisqu'il s'agit d'un onglet qui affiche un bloc de code HTML lorsque l'on clique dessus dans la barre de débogage web.
Pour créer ce type de panneau de contenu, la méthode getPanelContent()
doit retourner autre chose qu'une chaine vide.
Personnaliser le Contenu d'un Onglet
Maintenant que le nouveau panneau de contrôle a été ajouté à la barre de débogage de symfony, il convient de lui attribuer du contenu à l'aide de la méthode getPannelContent()
. Symfony fournit plusieurs méthodes capables de rendre ce contenu à la fois riche et ergonomique.
La Méthode sfWebDebugPanel::setStatus()
La couleur de fond des onglets est grise par défaut. Elle peut néanmoins être modifiée par de l'orange ou bien par du rouge lorsqu'il s'agit d'attirer l'attention du développeur sur un élément précis du panneau.
Pour changer la couleur de fond du panel, la solution consiste à utiliser la méthode setStatus()
. Cette méthode accepte toutes les constantes priority
de la classe sfLogger.
Il existe en particulier trois niveaux qui correspondent respectivement aux trois couleurs de fond que peut prendre le panel (gris, orange et rouge). La méthode setStatus()
est généralement appelée depuis la méthode getPanelContent()
si certains événements nécessitent d'attirer l'attention du développeur.
public function getPanelContent() { // ... // set the background to gray (the default) $this->setStatus(sfLogger::INFO); // set the background to orange $this->setStatus(sfLogger::WARNING); // set the background to red $this->setStatus(sfLogger::ERR); }
La Méthode sfWebDebugPanel::getToggler()
Il existe une fonction fréquemment rencontrée dans les panneaux de contrôle. Il s'agit du toggler
. C'est une croix qui affiche ou cache alternativement du contenu lorsque l'on clique dessus. On pourrait généraliser son comportement à celui d'un interrupteur domestique qui allume ou éteint une ampoule par exemple.
Le toggler
peut être utilisé par le panneau de contrôle en invoquant la méthode getToggler()
. Le code ci-dessous explique comment appliquer le toggler
sur une liste d'éléments contenus dans l'onglet de contrôle.
public function getPanelContent() { $listContent = '<ul id="debug_documentation_list" style="display: none;"> <li>List Item 1</li> <li>List Item 2</li> </ul>'; $toggler = $this->getToggler('debug_documentation_list', 'Toggle list'); return sprintf('<h3>List Items %s</h3>%s', $toggler, $listContent); }
Cette méthode getToggler()
accepte deux arguments : l'identifiant DOM, id
, de l'élément sur lequel doit être appliqué le toggler
, et une chaîne pour l'attribut title
du lien du toggler
.
La Méthode sfWebDebugPanel::getToggleableDebugStack()
Au même titre que la méthode getToggler()
, la méthode getToggleableDebugStack()
crée une flèche cliquable qui affiche ou masque un élément du contenu. Cette méthode génère le contenu HTML d'une trace de débogage d'une pile d'appels de fonctions.
Cette fonction est particulièrement utile lorsqu'il s'agit d'afficher les logs d'une des classes du projet. Par exemple, si une classe myCustomClass
a besoin d'enregistrer des informations dans les logs, alors ces derniers seraient créés de la manière suivante depuis l'intérieur de cette classe.
class myCustomClass { public function doSomething() { $dispatcher = sfApplicationConfiguration::getActive() ->getEventDispatcher(); $dispatcher->notify(new sfEvent($this, 'application.log', array( 'priority' => sfLogger::INFO, 'Beginning execution of myCustomClass::doSomething()', ))); } }
Pour l'exemple de ce chapitre, il s'agit d'afficher une liste des logs de la classe myCustomClass
en accompagnant chacun d'eux par sa propre trace de débogage de la pile d'appels.
public function getPanelContent() { // retrieves all of the log messages for the current request $logs = $this->webDebug->getLogger()->getLogs(); $logList = ''; foreach ($logs as $log) { if ($log['type'] == 'myCustomClass') { $logList .= sprintf('<li>%s %s</li>', $log['message'], $this->getToggleableDebugStack($log['debug_backtrace']) ); } } return sprintf('<ul>%s</ul>', $logList); }
note
Les logs de la classe myCustomClass
se trouvent toujours dans le panneau
Logs
. Utiliser un onglet personnalisé permet ainsi de les isoler et de les
présenter autrement.
La Méthode sfWebDebugPanel::formatFileLink()
Depuis symfony 1.3, il est possible d'ouvrir un fichier dans son éditeur favoris depuis la barre de débogage web. Davantage d'informations concernant cette fonctionnalité sont disponibles sur Internet, il suffit pour cela de se référer à l'article "What's new" de symfony 1.3.
Pour bénéficier de cette fonctionnalité, il faut impérativement faire appel à la méthode formatFileLink()
. En plus du nom du fichier à ouvrir, cette méthode peut aussi recevoir comme second paramètre le numéro de la ligne incriminée à atteindre. L'exemple suivant montre comment atteindre la ligne 15 du fichier config/ProjectConfiguration.class.php
:
public function getPanelContent() { $content = ''; // ... $path = sfConfig::get('sf_config_dir') . '/ProjectConfiguration.class.php'; $content .= $this->formatFileLink($path, 15, 'Project Configuration'); return $content; }
Les deuxième et troisième arguments, sont respectivement le numéro de la ligne et le nom du lien, et sont également optionnels. Si le nom du lien n'est pas renseigné, c'est le chemin du fichier ciblé qui sera utilisé à la place.
note
Avant de tester, il convient de s'assurer de bien avoir configuré la nouvelle
fonctionnalité de lien de fichier. Cela peut être réalisé à l'aide de l'option
sf_file_link_format
dans le fichier settings.yml
ou bien avec l'option
file_link_format
de
xdebug. Cette dernière
méthode permet aussi à votre projet de ne pas dépendre d'un IDE.
Autres Informations à Connaître au Sujet de la WDT
L'intérêt de la barre de débogage réside dans les informations qu'elle affiche. Il s'agit maintenant d'étudier les autres possibilités offertes par la barre de débogage web de symfony.
Enlever les Onglets par Défaut
La barre de débogage charge par défaut plusieurs panneaux qui peuvent être enlevés en utilisant l'événement debug.web.load_panels
. Il s'agit ici de faire appel à la même méthode écouteur déclarée plus haut, en remplaçant son contenu par la méthode removePanel()
. Le code suivant supprime l'onglet memory
de la barre de débogage web.
static public function listenToLoadDebugWebPanelEvent(sfEvent $event) { $event->getSubject()->removePanel('memory'); }
Accéder aux Paramètres de la Requête depuis un Onglet
Les paramètres de la requête sont souvent nécessaires dans les onglets. Il convient donc maintenant d'afficher des informations concernant un objet Event
provenant de la base de données à partir d'un paramètre de requête event_id
.
$parameters = $this->webDebug->getOption('request_parameters'); if (isset($parameters['event_id'])) { $event = Doctrine::getTable('Event')->find($parameters['event_id']); }
Masquer le Panneau sous Certaines Conditions
Parfois, l'onglet ne dispose pas d'informations utiles à afficher. Dans ce cas, il est préférable de le masquer. Pour mieux comprendre comment mettre cela en place, le code suivant s'appuiera sur l'exemple précédent. Il s'agit de masquer le panneau de contrôle si aucun paramètre event_id
n'a été transmis dans la requête. Pour ce faire, la méthode getTitle()
doit retourner une chaine vide.
public function getTitle() { $parameters = $this->webDebug->getOption('request_parameters'); if (!isset($parameters['event_id'])) { return; } return '<img src="/acWebDebugPlugin/legacy/images/documentation.png" alt="Documentation Shortcuts" height="16" width="16" /> docs'; }
Conclusion
La barre de débogage de symfony est là pour faciliter la vie du développeur. Elle est aussi bien plus qu'un simple panneau d'informations passif puisqu'en lui ajoutant des onglets personnalisés, les fonctionnalités de la barre d'outils ne seront limitées que par l'imagination du développeur.
Le plugin ac2009WebDebugPlugin ne contient qu'un aperçu des panneaux pouvant être créés, alors n'hésitez pas à ajouter les vôtres également.
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.