<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog Symfony2 - Lexik Montpellier &#187; Symfony</title>
	<atom:link href="http://www.lexik.fr/blog/symfony/category/symfony/feed" rel="self" type="application/rss+xml" />
	<link>http://www.lexik.fr/blog/symfony</link>
	<description>Blog sur le développement Web PHP avec Symfony 2</description>
	<lastBuildDate>Thu, 02 Feb 2012 14:00:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Installation de SuPHP sur Ubuntu</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/installation-de-suphp-sur-ubuntu-1665</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/installation-de-suphp-sur-ubuntu-1665#comments</comments>
		<pubDate>Fri, 26 Aug 2011 08:00:40 +0000</pubDate>
		<dc:creator>laurent</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Symfony2]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1665</guid>
		<description><![CDATA[Un problème récurrent pour beaucoup de développeurs utilisant Symfony est l&#8217;éternel conflit avec l&#8217;utilisateur &#171;&#160;www-data&#160;&#187; lors des accès, par exemple, aux fichiers du cache et aux logs. Sur Symfony 2 ce problème devient encore plus visible avec l&#8217;utilisation massive du &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/installation-de-suphp-sur-ubuntu-1665">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Un problème récurrent pour beaucoup de développeurs utilisant Symfony est l&#8217;éternel conflit avec l&#8217;utilisateur &laquo;&nbsp;www-data&nbsp;&raquo; lors des accès, par exemple, aux fichiers du cache et aux logs. Sur Symfony 2 ce problème devient encore plus visible avec l&#8217;utilisation massive du répertoire cache même en environnement &laquo;&nbsp;dev&nbsp;&raquo;.</p>
<p>Le cas de conflit le plus flagrant est certainement le <code>app/console cache:clear</code> qui renvoie une erreur car le cache a été généré par www-data lors du chargement du site par apache. Le bon gros <code>sudo rm -rf app/cache/*</code> n&#8217;est pas une solution acceptable, tout juste une rustine.<span id="more-1665"></span></p>
<p>Il existe différents moyens d&#8217;éviter ces conflits, que ce soit via scripts personnalisés, configurations avancées, ou packages additionnels. SuPHP est un module pour Apache très facile à mettre en place pour un environnement de &laquo;&nbsp;dev&nbsp;&raquo;, et il va répondre à notre problème d&#8217;une manière très simple: Apache ne va plus éxécuter les sites via &#8216;www-data&#8217;, mais via l&#8217;utilisateur propriétaire des fichiers éxécutés, c&#8217;est-à-dire le plus souvent le compte du développeur.</p>
<p>L&#8217;installation comprend deux packages dispos sur synaptic ou directement depuis la console:</p>
<pre>sudo apt-get install suphp-common libapache2-mod-suphp</pre>
<p>Pour une station de dev, une configuration fonctionnelle et simple est très bien décrite sur <a href="http://doc.ubuntu-fr.org/suphp#installation_de_suphp">http://doc.ubuntu-fr.org/suphp#installation_de_suphp</a>. Cette configuration empêche l&#8217;intervention de suphp dans les répertoires de /usr/share pour permettre entre autres à phpmyadmin (dans son emplacement par défaut) de continuer à fonctionner sans problèmes.</p>
<p>Il faudra éventuellement supprimer les fichiers de sessions en cours appartenent encore à www-data (dans /var/lib/php5 par défaut).</p>
<p>Si vos projets ne sont pas stockés dans les répertoires /var/www ou ~/public_html, il faut éditer la valeur de &laquo;&nbsp;docroot&nbsp;&raquo; dans /etc/suphp/suphp.conf pour y ajouter les répertoires supplémentaires. Par exemple, mes projets sont dans ~/www/ :</p>
<pre>docroot=/var/www:${HOME}/public_html</pre>
<p>devient alors:</p>
<pre>docroot=/var/www:${HOME}/public_html:${HOME}/www</pre>
<p>Pensez à nettoyer vos fichiers appartenant encore à www-data (cette fois avec des <code>sudo rm</code> par contre), comme les répertoires cache et logs, et redémarrez simplement Apache (<code>sudo service apache2 restart</code>). Après ça vous ne devriez plus voir de www-data dans vos projets, et vous pourrez oublier ce mauvais réflexe du <code>sudo rm -rf</code> à tout bout de champ !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/installation-de-suphp-sur-ubuntu-1665/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Envoi d&#8217;email avec Symfony et Mailjet</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/envoi-de-mails-avec-symfony-et-mailjet-1526</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/envoi-de-mails-avec-symfony-et-mailjet-1526#comments</comments>
		<pubDate>Thu, 14 Apr 2011 08:17:03 +0000</pubDate>
		<dc:creator>cedric</dc:creator>
				<category><![CDATA[Symfony]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[mailjet]]></category>
		<category><![CDATA[SwiftMailer]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1526</guid>
		<description><![CDATA[Petit constat : La gestion des expéditions de mails dans les projets Web est souvent laborieuse. En effet, les serveurs ne sont pas toujours bien configurés pour ça. Il arrive que les emails partent en spam ou encore qu&#8217;ils soient &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/envoi-de-mails-avec-symfony-et-mailjet-1526">...</a></p>]]></description>
			<content:encoded><![CDATA[<h4>Petit constat :</h4>
<p>La gestion des expéditions de mails dans les projets Web est souvent laborieuse. En effet, les serveurs ne sont pas toujours bien configurés pour ça. Il arrive que les emails partent en spam ou encore qu&#8217;ils soient bloqués avant même d&#8217;entrer dans la boite mails des utilisateurs&#8230; Bref, c&#8217;est jamais pratique et le suivi se fait très difficilement.<br />
<span id="more-1526"></span></p>
<h2>Quelques services d&#8217;envoi :</h2>
<p>La solution réside bien souvent dans le fait de déporter l&#8217;expédition sur une plateforme spécialisée. Il en existe des dizaines :<br />
Amazon a récemment sorti une plateforme <a href="http://aws.amazon.com/fr/ses/">Amazon SES</a> qui permet d&#8217;expédier ses emails via un simple appel à une API. Cette solution est très pratique mais a pour inconvénient de changer un peu le processus d&#8217;envoi d&#8217;email, il faudra donc faire quelques adaptations dans le code de votre application.<br />
Il existe également d&#8217;autres solutions :</p>
<ul>
<li>MailChimp : <a href="http://www.mailchimp.com/">http://www.mailchimp.com/</a></li>
<li>Campaign Monitor : <a href="http://www.campaignmonitor.com/">http://www.campaignmonitor.com/</a></li>
<li>AWeber : <a href="http://www.aweber.com/">http://www.aweber.com/</a></li>
</ul>
<p>pour en citer quelques uns&#8230;</p>
<p>Ces solutions sont idéales pour gérer des newsletters mais sont contraignantes pour les emails transactionnels. Eh oui, il faut souvent se rendre sur l&#8217;interface du site pour faire ses expéditions ou tout traiter via leur API.</p>
<h2>Une solution intéressante : Mailjet</h2>
<p>Les emails de vos projets Web sont souvent délivrés via un serveur SMTP, <a href="http://fr.mailjet.com/">Mailjet</a> est un service en ligne qui a eu la bonne idée de proposer d&#8217;exploiter un serveur <strong>SMTP authentifié et donc optimisé pour assurer la délivrabilité des emails</strong>. L&#8217;autre avantage indéniable de cette solution est qu&#8217;il suffit de <strong>changer les paramètres du SMTP</strong> de votre application et le tour est joué, vos emails sont délivrés par Mailjet. En prime Mailjet vous propose un système de statistiques sur les expéditions que vous pouvez consulter sur leur plateforme ou encore interroger à distance, via leur API.</p>
<p>Nous avons testé cette solution sur un projet pour envoyer des mails transactionnels tels que des mails d&#8217;inscriptions, de notifications ainsi qu&#8217;une newsletter hebdomadaire. <a href="http://fr.mailjet.com/">Mailjet</a> propose plusieurs offres dont une gratuite permettant d&#8217;envoyer jusqu&#8217;à 6000 mails par mois ce qui dans notre cas était suffisant.</p>
<p>Exemple de configuration du SMTP :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1526code2'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p15262"><td class="code" id="p1526code2"><pre class="yml" style="font-family:monospace;"># apps/&lt;app_name&gt;/config/factories.yml
prod:
  mailer:
    param:
      transport:
        class: Swift_SmtpTransport
        param:
          host:       in.mailjet.com
          port:       465
          encryption: ssl
          username:   &quot;your-username&quot;
          password:   &quot;your-pass&quot;</pre></td></tr></table></div>

<p>Une fois cette petite configuration faite vos mails seront délivrés par le SMTP de Mailjet qui s&#8217;occupe d&#8217;envoyer vos mails et qui fera aussi en sorte de limiter les risques de non livraison des mails.</p>
<p>PS : Non, non, non ce billet n&#8217;est pas sponsorisé! C&#8217;est juste que cette solution est vraiment pratique et souhaitions la partager.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/envoi-de-mails-avec-symfony-et-mailjet-1526/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Présentation du lxErrorLoggerPlugin</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/presentation-du-lxerrorloggerplugin-1433</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/presentation-du-lxerrorloggerplugin-1433#comments</comments>
		<pubDate>Wed, 16 Feb 2011 10:31:12 +0000</pubDate>
		<dc:creator>cedric</dc:creator>
				<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1433</guid>
		<description><![CDATA[Voici le petit dernier des plugins Symfony de chez Lexik, lxErrorLoggerPlugin, son but est simple : vous alerter en cas d&#8217;erreurs PHP ou Exceptions sur vos projets Symfony. Le besoin est simple, être alerté et éventuellement logger chaque erreurs, qu&#8217;elles &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/presentation-du-lxerrorloggerplugin-1433">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Voici le petit dernier des plugins Symfony de chez Lexik, <a href="https://github.com/lexik/lxErrorLoggerPlugin">lxErrorLoggerPlugin</a>, son but est simple : <strong>vous alerter en cas d&#8217;erreurs PHP ou Exceptions sur vos projets Symfony</strong>.<br />
Le besoin est simple, être alerté et éventuellement logger chaque erreurs, qu&#8217;elles soient PHP, Exception ou erreurs remontées par Symfony. En effet le logger de base de Symfony s&#8217;arrête aux erreurs remontées par ses soins mais ne remontent pas forcément aux erreurs PHP. Le système de notification du plugin est très flexible grâce à une série de &laquo;&nbsp;notifier&nbsp;&raquo; que l&#8217;on peut activer ou non de façon indépendante les uns des autres.</p>
<p><span id="more-1433"></span></p>
<p>Voici les différents notifiers que nous proposons :</p>
<ul>
<li>stockage en base de données (celle par défaut, ou via un dsn personnalisé) ;</li>
<li>stockage en fichier XML ;</li>
<li>stockage en fichier de log classique (fichier texte) ;</li>
<li>notification via un envoi de mail ;</li>
<li>notification via <a href="http://hoptoadapp.com/" target="_blank">Hoptoad</a>, un webservice de log d&#8217;erreur.</li>
</ul>
<p>Le plugin va par défaut logger toutes les exceptions levées, par contre pour les erreurs PHP il est évidement possible de configurer l&#8217;<strong>error_reporting</strong>, ce qui permet de remonter seulement les erreurs et non les notices par exemple. La configuration du plugin se fait tout simplement dans le fichier app.yml de votre application (ou du projet). Chaque &laquo;&nbsp;notifier&nbsp;&raquo; possède ses propres options, pour plus de détail je vous invite à regarder le <a href="https://github.com/lexik/lxErrorLoggerPlugin">README</a> du plugin.</p>
<p>Voici par exemple une capture d&#8217;écran d&#8217;un email envoyé par <a href="https://github.com/lexik/lxErrorLoggerPlugin">lxErrorLoggerPlugin</a> :</p>
<p><img src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2011/02/lxCoreExampleProject1.png" alt="" title="lxCoreExampleProject" width="512" height="450" class="aligncenter size-full wp-image-1500" /></p>
<p>Comme il a été précisé en introduction, lxErrorLoggerPlugin permet de notifier les erreurs <strong>mais également de les stocker</strong>. Le stockage se fait via une base de données ou un fichier XML. Cela apporte 2 avantages indéniables :</p>
<ul>
<li>la possibilité de repérer des erreurs similaires à d&#8217;autres, il est alors possible de prévenir les notifiers tels que le notifier email pour ne pas envoyer un email doublon, tout ceci est configurable ;</li>
<li>la possibilité de générer un flux RSS des erreurs, l&#8217;URL du flux sera protégé par un token paramètrable par vos soins.</li>
</ul>
<h4>Exemple d&#8217;utilisation :</h4>
<p>Supposons que nous avons besoin de logger les erreurs qui se produisent sur notre application frontend.</p>
<p><strong>1. Activer le plugin :</strong></p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1433code6'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p14336"><td class="code" id="p1433code6"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// config/ProjectConfiguration.class.php</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setup<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">enablePlugins</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>
      <span style="color: #339933;">...,</span>
      <span style="color: #0000ff;">'lxErrorLoggerPlugin'</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><strong>2. Configurer le plugin dans l&#8217;application souhaité, frontend dans cet exemple :</strong><br />
Ici nous allons utiliser la notification des erreurs en base de données et par email.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1433code7'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p14337"><td class="code" id="p1433code7"><pre class="yml" style="font-family:monospace;"># apps/frontend/config/app.yml
all:
  lx_error_logger_plugin:
    enabled:              true # Enable error notification
    php_error_reporting:  &lt;?php echo (E_ALL | E_STRICT).&quot;\n&quot; ?&gt;
    rss:
      token:              264864156479631564841687 # token to access to the rss
      items:              10 # items in the rss
    notifier:
      db:
        enabled:          true
        options:
          similar_error:  true
      mail:
        enabled:          true
        options:
          to:             [bob@example.com, chuck@example.com]
          subject:        A new error occured on your website
          always_send:    true # always send an email even if db or xml notifiers detect the error as similar</pre></td></tr></table></div>

<p><strong>3. Activer le flux RSS des dernières erreurs :</strong><br />
Dans cet exemple la notification des erreurs en base de données est activée donc le flux RSS peut récupérer des données.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1433code8'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p14338"><td class="code" id="p1433code8"><pre class="yml" style="font-family:monospace;"># apps/frontend/config/settings.yml
all:
  .settings:
    enabled_modules: [..., lxErrorNotifierRss]</pre></td></tr></table></div>

<p>Le flux RSS est maintenant accessible avec l&#8217;url :</p>
<p>http://super-website.com/lx-error/rss.xml?token=264864156479631564841687</p>
<p>Et c&#8217;est tout <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p><i><u>Note</u> : le plugin ne fournit aucune interface permettant de lister les erreurs loggées, libre à chacun de créer son CRUD, module d&#8217;admin generator ou autre interface comme il le souhaite en fonction du besoin.</i></p>
<p>Dépôt du plugin sur Github : <a href="https://github.com/lexik/lxErrorLoggerPlugin">https://github.com/lexik/lxErrorLoggerPlugin</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/presentation-du-lxerrorloggerplugin-1433/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Présentation du plugin lxJavascriptPlugin</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/presentation-du-plugin-lxjavascriptplugin-1408</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/presentation-du-plugin-lxjavascriptplugin-1408#comments</comments>
		<pubDate>Tue, 18 Jan 2011 09:53:28 +0000</pubDate>
		<dc:creator>laurent</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[Méthodologie]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[error]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1408</guid>
		<description><![CDATA[L&#8217;article d&#8217;hier sur les bonnes pratiques Javascript dans un projet Symfony faisait mention d&#8217;un plugin que nous utilisons en interne et qui est maintenant disponible sur Github: lxJavascriptPlugin. Ce court article va brièvement présenter son fonctionnement et son utilisation. L&#8217;installation &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/presentation-du-plugin-lxjavascriptplugin-1408">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>L&#8217;article d&#8217;hier sur les bonnes pratiques Javascript dans un projet Symfony faisait mention d&#8217;un plugin que nous utilisons en interne et qui est maintenant disponible sur Github: lxJavascriptPlugin. Ce court article va brièvement présenter son fonctionnement et son utilisation.</p>
<p><span id="more-1408"></span></p>
<p>L&#8217;installation du plugin est très rapide:</p>
<ul>
<li>téléchargez <a href="https://github.com/lexik/lxJavascriptPlugin" target="_blank">les sources sur Github</a> dans le répertoire plugins de votre projet,</li>
<li>éditez le fichier config/settings.yml pour y inclure le helper lxJavascript:

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1408code17'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p140817"><td class="code" id="p1408code17"><pre class="yml" style="font-family:monospace;">all:
  .settings:
    standard_helpers: [ ... , lxJavascript ]</pre></td></tr></table></div>

</li>
</ul>
<p>Et c&#8217;est tout! Voyons maintenant le fonctionnement.</p>
<p>Le premier but du plugin est de solutionner les problèmes de granularité du code Javascript dans un projet Symfony. Lorsque l&#8217;on utilise par exemple des widgets JQuery, des partials pour les réseaux sociaux, ou des composants pour des GoogleMap, on se retrouve vite avec du code Javascript éparpillé dans tout notre projet, et par conséquent tout autant éparpillé dans le code des pages générées.</p>
<p>Pour régler ce problème lxJavascriptPlugin propose un premier outil: le helper lxJavascriptHelper. Son utilisation est très similaire à celle du javascriptHelper de Symfony, mais avec la méthode lx_javascript:</p>
<ul>
<li>pour inclure un fichier source externe à la page:

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1408code18'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p140818"><td class="code" id="p1408code18"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> lx_javascript<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

</li>
<li>pour inclure directement du code javascript, par exemple le bout de code pour Google Analytics, le fonctionnement est similaire à celui d&#8217;un slot:

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1408code19'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p140819"><td class="code" id="p1408code19"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> lx_javascript<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #000000; font-weight: bold;">var</span> _gaq <span style="color: #339933;">=</span> _gaq <span style="color: #339933;">||</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  _gaq<span style="color: #339933;">.</span>push<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'_setAccount'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'*********'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  _gaq<span style="color: #339933;">.</span>push<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'_trackPageview'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">var</span> ga <span style="color: #339933;">=</span> document<span style="color: #339933;">.</span>createElement<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'script'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    ga<span style="color: #339933;">.</span>src <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'https:'</span> <span style="color: #339933;">==</span> document<span style="color: #339933;">.</span>location<span style="color: #339933;">.</span>protocol ? <span style="color: #0000ff;">'https://ssl'</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'http://www'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">'.google-analytics.com/ga.js'</span><span style="color: #339933;">;</span>
    ga<span style="color: #339933;">.</span>setAttribute<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'async'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'true'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    document<span style="color: #339933;">.</span>documentElement<span style="color: #339933;">.</span>firstChild<span style="color: #339933;">.</span>appendChild<span style="color: #009900;">&#40;</span>ga<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> lx_end_javascript<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Ici la balise &lt;script&gt; n&#8217;est pas nécessaire, mais vous pouvez l&#8217;utiliser si vous le souhaitez (par exemple pour garder la coloration syntaxique de votre IDE)</li>
<li>pour insérer tout le code javascript déclaré via lx_javascript() à la fin de votre layout.php:

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1408code20'); return false;">View Code</a> HTML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p140820"><td class="code" id="p1408code20"><pre class="html" style="font-family:monospace;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
  &lt;head&gt;
    ...
  &lt;/head&gt;
  &lt;body&gt;
    ...
    &lt;?php lx_include_javascripts() ?&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

</li>
</ul>
<p>Le soucis de javascript dans les templates est adressé. Reste maintenant le problème du code javascript inséré via d&#8217;autres moyens, comme par exemple un widget qui utilise JQuery. Pour cela lxJavascriptPlugin propose une classe statique lxJavascriptStorage qui offre les fonctionnalités du helper depuis n&#8217;importe où dans votre code:</p>
<ul>
<li>pour ajouter une source externe:

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1408code21'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p140821"><td class="code" id="p1408code21"><pre class="php" style="font-family:monospace;">lxJavascriptStorage<span style="color: #339933;">::</span><span style="color: #004000;">addRemoteJavascript</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

</li>
<li>pour ajouter du code javascript. Voyons par exemple la méthode render() du widget sfWidgetFormJQueryDate:

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1408code22'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p140822"><td class="code" id="p1408code22"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> render<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$attributes</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errors</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">//code</span>
  <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'date_widget'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">render</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #000088;">$attributes</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errors</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>
           <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderTag</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'input'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'type'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'hidden'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'size'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">generateId</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'_jquery_control'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'disabled'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'disabled'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>
           <a href="http://www.php.net/sprintf"><span style="color: #990000;">sprintf</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000cc; font-style: italic;">&lt;&lt;&lt;EOF
&lt;script type=&quot;text/javascript&quot;&gt;// &lt;![CDATA[
  [...]
// ]]&gt;&lt;/script&gt;
EOF</span>
    <span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">//arguments du sprintf</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Nous voyons bien le javascript retourné dans le code du widget, et donc en milieu de page. Cette fonction render() pourrait, avec lxJavascriptPlugin, ressembler à ça:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1408code23'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p140823"><td class="code" id="p1408code23"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> render<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$attributes</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errors</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">//code &lt;/code&gt;</span>
&nbsp;
  <span style="color: #000088;">$js</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/sprintf"><span style="color: #990000;">sprintf</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000cc; font-style: italic;">&lt;&lt;&lt;EOF
&lt;script type=&quot;text/javascript&quot;&gt;// &lt;![CDATA[
  [...]
// ]]&gt;&lt;/script&gt;
EOF</span>
    <span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">//arguments du sprintf</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  lxJavascriptStorage<span style="color: #339933;">::</span><span style="color: #004000;">addJavascriptCode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$js</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'date_widget'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">render</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #000088;">$attributes</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errors</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>
           <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderTag</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'input'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'type'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'hidden'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'size'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">generateId</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'_jquery_control'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'disabled'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'disabled'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Peu de changements, mais ici le javascript sera rendu avec tout le reste du javascript en pied de page. </code></li>
</ul>
<p>Notez enfin que la méthode lx_include_javascripts() rendra en premier les sources externes, puis le code javascript concaténé dans une unique balise &lt;script&gt;. Si tous les exemples précédents sont utilisés dans une application, le javascript en pied de page donnera ceci:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1408code24'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p140824"><td class="code" id="p1408code24"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js&quot;</span> type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span><span style="color: #006600; font-style: italic;">// &lt;![CDATA[</span>
  <span style="color: #006600; font-style: italic;">//javascript du widget</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> _gaq <span style="color: #339933;">=</span> _gaq <span style="color: #339933;">||</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  _gaq.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'_setAccount'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'*********'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  _gaq.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'_trackPageview'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> ga <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    ga.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'https:'</span> <span style="color: #339933;">==</span> document.<span style="color: #660066;">location</span>.<span style="color: #660066;">protocol</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">'https://ssl'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'http://www'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'.google-analytics.com/ga.js'</span><span style="color: #339933;">;</span>
    ga.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'async'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'true'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    document.<span style="color: #660066;">documentElement</span>.<span style="color: #660066;">firstChild</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>ga<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">/* ]]&gt; */</span><span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

</li>
</ul>
<p>Vous pouvez obtenir <a href="https://github.com/lexik/lxJavascriptPlugin">lxJavascriptPlugin sur Github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/presentation-du-plugin-lxjavascriptplugin-1408/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Astuces de développement javascript avec symfony</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/astuces-de-developpement-javascript-avec-symfony-1382</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/astuces-de-developpement-javascript-avec-symfony-1382#comments</comments>
		<pubDate>Mon, 17 Jan 2011 15:06:09 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1382</guid>
		<description><![CDATA[Dans cet article nous allons voir quelques astuces et bonnes pratiques, non pas directement de développement symfony mais de développement javascript au sein d’un projet symfony. Si l&#8217;on reprend quelques bases de bonnes pratiques de développement javascript, on constate : &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/astuces-de-developpement-javascript-avec-symfony-1382">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Dans cet article nous allons voir quelques astuces et bonnes pratiques, non pas directement de développement symfony mais de développement javascript au sein d’un projet symfony.</p>
<p>Si l&#8217;on reprend quelques bases de bonnes pratiques de développement javascript, on constate :</p>
<ul>
<li>que vos javascripts doivent être non-intrusifs, autrement dit là pour améliorer l&#8217;expérience utilisateur et en aucun cas être indispensable au fonctionnement d&#8217;une page ;</li>
<li>que les javascript doivent être combinés en 1 seul fichier et minifié (ceci afin de limiter le nombre de requête HTTP et car le chargement de la page est arrêté à chaque balise script, notamment à cause d&#8217;un éventuel <code>document.write();</code> ;</li>
<li>que l&#8217;appel au javascript doit être en bas de page ;</li>
</ul>
<p><em>Cette liste est bien entendu non exhaustive, vous trouverez une <a href="http://developer.yahoo.com/performance/rules.html" target="_blank">liste plus détaillée par ici</a>.</em></p>
<p>Toutes ces bonnes pratiques de développement Javascript n’ont pas toujours été facilitées dans symfony, notamment à la grande époque des helpers link_to_remote() &#038; co. qui en ont ravi certains et fait cauchemarder d’autres. Et aujourd&#8217;hui encore bon nombre de widgets de formulaire retournent directement du code javascript (dépendant de jQuery ou autre) et qui ne fonctionneront évidemment plus dès lors que vos javascripts se trouveront en bas de page.</p>
<p><span id="more-1382"></span></p>
<h4>1. Où placer les javascripts dans le document</h4>
<p>Idéalement et selon les recommandations de Yslow, en bas de page, donc juste avant la balise fermante <code><body></code> de votre layout.php. Ceci afin de ne pas ralentir inutilement le début du chargement de votre page, puisque chaque balise script bloque le chargement de la page (notamment pour gérer le <code>document.write();</code>).<br />
Source : <a href="http://developer.yahoo.com/performance/rules.html#js_bottom" target="_blank">http://developer.yahoo.com/performance/rules.html#js_bottom</a></p>
<p>Si cette méthode ne vous gênera pas pour les librairies tierces telles que jQuery, qu&#8217;en est-il par contre de vos codes javascript ? Ils doivent également se trouver dans des fichiers séparés, dissociés de votre document HTML. Néanmoins comme je vois souvent le besoin pour les développeurs d&#8217;avoir le code javascript au sein du template symfony, voici une technique pour qu&#8217;il soit tout de même placé en fin de page : via un slot.</p>
<p>Un petit exemple de code :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1382code26'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p138226"><td class="code" id="p1382code26"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// indexSuccess.php :</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> slot<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'javascript'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
  console<span style="color: #339933;">.</span><a href="http://www.php.net/log"><span style="color: #990000;">log</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'javascript @ bottom'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> end_slot<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// layout.php :</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> include_javascripts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> include_slot<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'javascript'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Vous pourrez ainsi éditer votre code javascript depuis votre template PHP, bénéficier par exemple de valeurs dynamiques de PHP et pour autant que le code soit bien inclus en bas de page. Toutefois je vous recommande d&#8217;écrire du javascript là où il doit se trouver, à savoir dans un fichier JS&#8230;</p>
<p>De plus l&#8217;inconvénient majeur du slot est qu&#8217;il ne peut contenir qu&#8217;une valeur, il est écrasé à chaque utilisation. La technique fonctionne mais est très limitée. Pour ces besoins nous avons écrit chez Lexik un petit plugin &laquo;&nbsp;lxJavascript&nbsp;&raquo;, très similaire à l&#8217;utilisation d&#8217;un slot mais optimisé pour l&#8217;inclusion de javascripts. Il gère donc le multiple ajout, supprime les éventuelles multiples balises script pour en conserver qu&#8217;une seule, etc. Vous en saurez plus demain, le plugin sort en OpenSource sur le <a href="https://github.com/lexik" target="_blank">Github de Lexik</a>.</p>
<h4>2. Compression</h4>
<p>La compression des javascripts (c&#8217;est valable aussi pour les CSS) est une des tâches d&#8217;optimisations les plus importantes et également une des plus simples, du moins via les plugins symfony. Cette technique consiste à compresser tous vos fichiers javascript en 1 seul et surtout d&#8217;y appliquer un numéro de version (un timestamp le plus souvent) afin de prévenir des problèmes de cache dans vos mises à jour.</p>
<p>Les principaux plugins :</p>
<ul>
<li><a href="http://www.symfony-project.org/plugins/sfCombinePlugin" target="_blank">sfCombinePlugin</a>
<li><a href="http://www.symfony-project.org/plugins/npAssetsOptimizerPlugin" target="_blank">npAssetsOptimizerPlugin</a></li>
<li><a href="http://www.symfony-project.org/plugins/swCombinePlugin" target="_blank">swCombinePlugin</a></li>
</ul>
<p>Chez Lexik, nous utilisons <a href="http://www.symfony-project.org/plugins/npAssetsOptimizerPlugin" target="_blank">npAssetsOptimizerPlugin</a>, un plugin de <a href="http://www.akei.com/" target="_blank">Nicolas Perriault</a>, extrêmement simple à installer et paramétrer. Sur votre environnement de production, vous obtiendrez ainsi un fichier javascript compressé <code>/js/optimized.js?1294759429</code> qui contient un timestamp permettant à chaque modifications des fichiers d&#8217;être prises en compte sans problème de cache.</p>
<p>Nous n&#8217;appliquons pas la compression pour les librairies externes telles que jQuery que nous déléguons aux <a href="http://code.google.com/apis/libraries/devguide.html" target="_blank">serveurs CDN de Google</a>, cela apporte ces avantages notables :</p>
<ul>
<li>l&#8217;avantage du <abbr title="Content Delivery Network">CDN</abbr>, à savoir de proposer des données statiques via un réseau de multiples serveurs dans de multiples points géographiques, afin de permettre un accès très court ;</li>
<li>les navigateurs sont limités sur le nombre de connexions HTTP simultanées sur un même domaine, le téléchargement d&#8217;un javascript sur les serveurs de Google se fera en parallèle ;</li>
<li>les librairies du CDN ont les bonnes en-têtes de cache, par exemple la version 1.4.4 de jQuery restera en cache pendant 1 an sur le client, cela signifie également qu&#8217;un internaute peut bénéficier du cache téléchargé depuis un autre site, pas forcément sur le votre.</li>
</ul>
<h4>3. Accéder à certaines données dynamiques depuis javascript</h4>
<p>Il peut parfois être très utile depuis javascript d&#8217;accéder à certaines données dynamiques telles que la culture de l&#8217;utilisateur, du routing pour des appels Ajax ou encore de l&#8217;i18n. Il suffit de s&#8217;appuyer sur un simple fichier de configuration via un tableau de données JSON généré depuis une action symfony. J&#8217;ai écrit sur mon blog personnel un article détaillé sur le sujet <a href="http://blog.jeremybarthe.com/post/1465024153/configurations-javascript-dynamiques-en-symfony" target="_blank">Configurations Javascript dynamiques en Symfony</a>.</p>
<h4>4. Javascript depuis les widget</h4>
<p>Maintenant que vos inclusions de javascripts se trouvent en bas de page, jQuery par exemple, que faire de nos chers widgets jQuery Autocompleter <code>sfWidgetFormJQueryAutocompleter</code> et autre Datepicker <code>sfWidgetFormJQueryDate</code> qui retournent des champs de formulaire et le javascript d’initialisation du composant ? Eh bien, ne plus les utiliser&#8230; Simplement car ils seront inclus avant jQuery et vous aurez donc droit à l’erreur &laquo;&nbsp;jQuery is not defined&nbsp;&raquo;. Sans être aussi extrême, vous pouvez charger jQuery en haut de page (via les CDN de Google) et votre script compressé en bas de page, les widgets de formulaire seront alors à nouveau fonctionnels.</p>
<p>Cela fait déjà quelques temps que chez Lexik nous avons fait le choix d&#8217;enlever tous ces widgets pour les ré-écrire et les adapter à nos besoins. Les javascripts des widgets passent par notre plugin lxJavascript ce qui permet de les inclure là où on le souhaite. Egalement, le javascript retourné par ces widgets correspond à une utilisation basique du composant, dans un cas concrêt il est souvent nécessaire d&#8217;en ré-écrire une bonne part. Il peut être pratique par contre que le widget retourne seulement la sémantique HTML adaptée, par exemple dans le cas d&#8217;un Autocomplete un champ hidden pour stocker la valeur et un champ texte pour l&#8217;autocomplete, aussi nos widgets ont une option pour retourner ou non le code javascript.</p>
<h4>5. Optimisation frontend</h4>
<p>Presque aussi important que la compression, la configuration d&#8217;apache pour mettre en cache certains de vos fichiers statiques. Typiquement, maintenant que vos fichiers javascripts et CSS sont compressés en 1 seul et possèdent un timestamp unique par version, il serait dommage de les recharger à chaque chargement de page&#8230; Vous devez donc configurer le module Expires d&#8217;apache via le fichier de config du vhost ou via le .htaccess, en voici un exemple :</p>
<pre>
<IfModule mod_expires.c>
  ExpiresActive on
  ExpiresByType text/css "access plus 1 year"
  ExpiresByType text/javascript "access plus 1 year"
</IfModule>
</pre>
<p>Vos fichiers javascript et CSS seront ainsi en cache pendant 1 an, attention du coup à ne pas avoir de fichier sans numéro de version, car ils resteraient en cache et vos internautes ne bénéficieraient pas de vos mises à jour&#8230;</p>
<p>&nbsp;</p>
<p>Dernière chose, si ce n&#8217;est pas encore fait, installez et testez <a href="http://developer.yahoo.com/yslow/" target="_blank">Yslow</a> pour trouver des pistes d&#8217;optimisations de performance de vos sites.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/astuces-de-developpement-javascript-avec-symfony-1382/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Utilisation de l&#8217;event dispatcher depuis les classes du modèle.</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-levent-dispatcher-depuis-les-classes-du-modele-1337</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-levent-dispatcher-depuis-les-classes-du-modele-1337#comments</comments>
		<pubDate>Mon, 20 Dec 2010 09:17:03 +0000</pubDate>
		<dc:creator>Samuel Breton</dc:creator>
				<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[event dispatcher]]></category>
		<category><![CDATA[model]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1337</guid>
		<description><![CDATA[Le but de cet article n&#8217;est pas d&#8217;expliquer le fonctionnement des événements symfony, la documentation officielle est très bien faite à ce sujet, et pas mal d&#8217;articles expliquant leur implementation existent déjà. Le but est juste de savoir comment faire &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/utilisation-de-levent-dispatcher-depuis-les-classes-du-modele-1337">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Le but de cet article n&#8217;est pas d&#8217;expliquer le fonctionnement des événements symfony, <a href="http://www.symfony-project.org/reference/1_4/fr/15-Events" target="_blank">la documentation officielle</a> est très bien faite à ce sujet, et pas mal d&#8217;articles expliquant leur implementation existent déjà.</p>
<p>Le but est juste de savoir comment faire pour avoir accès à l&#8217;event dispatcher depuis les classes du modèle, de manière à pouvoir lever des événements &laquo;&nbsp;métiers&nbsp;&raquo; qui permettent des traitements qui se rapprochent des trigger sql. L&#8217;avantage est de rester au sein de l&#8217;application symfony et ne pas disperser la logique. C&#8217;est une problèmatique que nous avons rencontré à plusieurs reprises dans les projets et nous avons pu trouver cette implementation grace à n1k0 de chez <a href="http://www.akei.com/fr" target="_blank">Akei</a>.</p>
<p><span id="more-1337"></span></p>
<p>(Pour la suite, je vais me servir d&#8217;une partie du modèle de Jobeet comme je l&#8217;avais fait dans <a href="http://www.lexik.fr/blog/symfony/symfony/qui-leu-crud-ou-comment-creer-un-theme-pour-les-crud-doctrine-de-symfony-1181">mon post précédent</a>)</p>
<p>A la base, l&#8217;event dispatcher se trouve dans le contexte, et donc accessible principalement depuis les actions des modules. L&#8217;idée est de le rendre accessible aux classes du modèle doctrine de manière à pouvoir notifier des événements &laquo;&nbsp;métier&nbsp;&raquo; directement depuis les méthodes. On va donc passer l&#8217;event dispatcher à la classe de base dont hérite toutes les classes du modèle. Ou plus exactement, on va rajouter une classe custom dans la pile d&#8217;héritage des classes du modèle.</p>
<p>On créé donc une classe CustomDoctrineRecord, que je place dans /lib/model/doctrine/record/CustomDoctrineRecord.class.php pour éviter qu&#8217;elle se retrouve noyée avec les classes du modèle. On va faire passer à cette classe l&#8217;event dispatcher par des méthodes statiques.<br />
Les classes de base du modèle héritent de sfDoctrineRecord, il faut donc impérativement que la classe custom hérite elle aussi de sfDoctrineRecord.</p>
<p>Fichier : /lib/model/doctrine/record/CustomDoctrineRecord.class.php</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1337code33'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p133733"><td class="code" id="p1337code33"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
abstract <span style="color: #000000; font-weight: bold;">class</span> CustomDoctrineRecord <span style="color: #000000; font-weight: bold;">extends</span> sfDoctrineRecord
<span style="color: #009900;">&#123;</span>
  static <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$dispatcher</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * Sets the EventDispatcher
   *
   * @param sfEventDispatcher $dispatcher 
   */</span>
  static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setEventDispatcher<span style="color: #009900;">&#40;</span>sfEventDispatcher <span style="color: #000088;">$dispatcher</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$dispatcher</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dispatcher</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * Returns the EventDispatcher
   *
   * @return sfEventDispatcher
   */</span>
  static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getEventDispatcher<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$dispatcher</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * Returns if EventDispatcher is available
   *
   * @return boolean
   */</span>
  static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> hasDispatcher<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">getEventDispatcher</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> instanceOf sfEventDispatcher<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Maintenant il faut spécifier à doctrine d&#8217;utiliser notre classe custom comme classe de référence des classes modèles, on utilise la méthode configureDoctrine() de sfProjectConfiguration. Aprés quoi on va avoir besoin de passer l&#8217;event dispatcher à notre classe. On va donc catcher l&#8217;événement &laquo;&nbsp;context.load_factories&nbsp;&raquo; qui est déclenché une fois que le contexte est initialisé pour aller initialiser la classe CustomDoctrineRecord.</p>
<p>Fichier : /config/ProjectConfiguration.class.php</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1337code34'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p133734"><td class="code" id="p1337code34"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <a href="http://www.php.net/dirname"><span style="color: #990000;">dirname</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php'</span><span style="color: #339933;">;</span>
sfCoreAutoload<span style="color: #339933;">::</span><span style="color: #004000;">register</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> ProjectConfiguration <span style="color: #000000; font-weight: bold;">extends</span> sfProjectConfiguration
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setup<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">setup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">enablePlugins</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'sfDoctrinePlugin'</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dispatcher</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'context.load_factories'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'listenToContextFactoriesLoaded'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * Defines the base objects' classe
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configureDoctrine<span style="color: #009900;">&#40;</span>Doctrine_Manager <span style="color: #000088;">$manager</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'doctrine_model_builder_options'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'baseClassName'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'CustomDoctrineRecord'</span>
    <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * Objects can acces the EventDispatcher
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> listenToContextFactoriesLoaded<span style="color: #009900;">&#40;</span>sfEvent <span style="color: #000088;">$event</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    CustomDoctrineRecord<span style="color: #339933;">::</span><span style="color: #004000;">setEventDispatcher</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$event</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSubject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getEventDispatcher</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Aprés ca, il nous reste à faire un petit</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1337code35'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p133735"><td class="code" id="p1337code35"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">./</span>symfony doctrine<span style="color: #339933;">:</span>build <span style="color: #339933;">--</span>all<span style="color: #339933;">-</span>classes</pre></td></tr></table></div>

<p>Et on peut vérifier l&#8217;inpact en ouvrant une classe de base, et on trouve bien que la classe hérite de notre classe CustomDoctrineRecord</p>
<p>Fichier : /lib/model/doctrine/base/BaseJobeetJob.class.php</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1337code36'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p133736"><td class="code" id="p1337code36"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #339933;">...</span>
abstract <span style="color: #000000; font-weight: bold;">class</span> BaseJobeetJob <span style="color: #000000; font-weight: bold;">extends</span> CustomDoctrineRecord
<span style="color: #009900;">&#123;</span>
<span style="color: #339933;">...</span></pre></td></tr></table></div>

<p>Il est donc maintenant possible de lever des événements depuis les classes du modèle. Pour exemple je vais lever un événement à l&#8217;insertion d&#8217;un nouveau Job. Cet événement pourra être utilisé par la suite pour faire ce que l&#8217;on veut, comme par exemple envoyer une email au modèrateur l&#8217;informant qu&#8217;un nouveau job a été saisi sur le site.</p>
<p>Fichier : /lib/model/doctrine/JobeetJob.class.php</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1337code37'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p133737"><td class="code" id="p1337code37"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> JobeetJob <span style="color: #000000; font-weight: bold;">extends</span> BaseJobeetJob
<span style="color: #009900;">&#123;</span>
  <span style="color: #009933; font-style: italic;">/**
   * @param Doctrine_Event $event 
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> postInsert<span style="color: #009900;">&#40;</span><span style="color: #000088;">$event</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">hasDispatcher</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">getEventDispatcher</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">hasListeners</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'JobeetJob.Inserted'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">getEventDispatcher</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">notify</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> sfEvent<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'JobeetJob.Inserted'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>C&#8217;est un exemple tout simple, mais les possibilités sont immenses. Attention aux événements en cascades, ca peut très vite devenir un casse tête à debugger !</p>
<p>Dernier petit tips, pour pouvoir faire des tests de vos méthodes qui lèvent des événements : c&#8217;est à mis chemin entre les tests unitaires et les tests fonctionnels. J&#8217;ai voulu tester des enchainements de méthodes qui levaient des événements, et je voulais vérifier que les règles de gestion étaient respectées. Je suis donc parti du bootstap unitaire où j&#8217;ai initialisé un contexte que je passe à ma classe de base, de manière à ce que les événements soient diffusés.</p>
<p>Fichier : /test/bootstrap/unit_event.php</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1337code38'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p133738"><td class="code" id="p1337code38"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/dirname"><span style="color: #990000;">dirname</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/unit.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$configuration</span> <span style="color: #339933;">=</span> ProjectConfiguration<span style="color: #339933;">::</span><span style="color: #004000;">getApplicationConfiguration</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'frontend'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'test'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$context</span> <span style="color: #339933;">=</span> sfContext<span style="color: #339933;">::</span><span style="color: #004000;">createInstance</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$configuration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
CustomDoctrineRecord<span style="color: #339933;">::</span><span style="color: #004000;">setEventDispatcher</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$configuration</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getEventDispatcher</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Quand on commence à utiliser les événements, il y a deux réactions possibles. Il y a les réfractaires qui disent &laquo;&nbsp;c&#8217;est null, ca sert a rien&nbsp;&raquo;, soit on devient accro et on commence à en mettre de partout. Si vous faites parti du deuxième groupe, voici quelques conseils élémentaires mais important à respecter pour éviter que le debuggage se transforme en calvaire :</p>
<ul>
<li>mettre des noms d&#8217;événements explicites ;</li>
<li>centraliser les écouteurs.</li>
</ul>
<p>Bon codage à tous, et bonnes fêtes <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-levent-dispatcher-depuis-les-classes-du-modele-1337/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Utilisation de VHost pour l&#8217;accès au backend</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-vhost-pour-lacces-au-backend-1307</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-vhost-pour-lacces-au-backend-1307#comments</comments>
		<pubDate>Wed, 27 Oct 2010 07:54:59 +0000</pubDate>
		<dc:creator>cedric</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[virtual hosts]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1307</guid>
		<description><![CDATA[L&#8217;idée est de ne plus accéder au backend de notre site web en utilisant backend.php dans l&#8217;url, mais de passer par un sous domaine. http://www.super-website.com &#8594; frontend http://admin.super-website.com &#8594; backend Supposons que mon projet Symfony se trouve dans /home/public_html/. Commençons &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/utilisation-de-vhost-pour-lacces-au-backend-1307">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>L&#8217;idée est de ne plus accéder au backend de notre site web en utilisant backend.php dans l&#8217;url, mais de passer par un sous domaine.</p>
<ul>
<li>http://www.super-website.com &rarr; frontend</li>
<li>http://admin.super-website.com &rarr; backend</li>
</ul>
<p>Supposons que mon projet Symfony se trouve dans /home/public_html/.<br />
Commençons par ajouter un vhost pour définir le sous domaine dans Apache. On précise au sous domaine que le fichier index pour ce sous domaine sera backend.php à l&#8217;aide de la directive DirectoryIndex.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1307code42'); return false;">View Code</a> CONSOLE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p130742"><td class="code" id="p1307code42"><pre class="console" style="font-family:monospace;">&lt;VirtualHost *:80&gt;
  ServerName admin.super-website.fr
  DocumentRoot &quot;/home/public_html/web&quot;
  DirectoryIndex backend.php
&nbsp;
  &lt;Directory &quot;/home/public_html/web&quot;&gt;
    AllowOverride All
    Allow from All
  &lt;/Directory&gt;
&nbsp;
  Alias /sf /home/public_html/lib/vendor/symfony/data/web/sf
  &lt;Directory &quot;/home/public_html/lib/vendor/symfony/data/web/sf&quot;&gt;
    AllowOverride All
    Allow from All
  &lt;/Directory&gt;
&lt;/VirtualHost&gt;</pre></td></tr></table></div>

<p>Ensuite il faut modifier le .htaccess de Symfony afin qu&#8217;il redirige les requêtes http du sous domaine vers le fichier backend.php.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1307code43'); return false;">View Code</a> CONSOLE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p130743"><td class="code" id="p1307code43"><pre class="console" style="font-family:monospace;">Options +FollowSymLinks +ExecCGI
&nbsp;
&lt;IfModule mod_rewrite.c&gt;
  RewriteEngine On
&nbsp;
  # uncomment the following line, if you are having trouble
  # getting no_script_name to work
  #RewriteBase /
&nbsp;
  # we skip all files with .something
  #RewriteCond %{REQUEST_URI} \..+$
  #RewriteCond %{REQUEST_URI} !\.html$
  #RewriteRule .* - [L]
&nbsp;
  # we check if the .html version is here (caching)
  RewriteRule ^$ index.html [QSA]
  RewriteRule ^([^.]+)$ $1.html [QSA]
&nbsp;
  # redirect to the backend web controller
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{HTTP_HOST}  ^admin.*
  RewriteRule ^(.*)$ backend.php [QSA,L]
&nbsp;
  # no, so we redirect to our front web controller
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php [QSA,L]
&lt;/IfModule&gt;</pre></td></tr></table></div>

<p>Au niveau de la config Symfony, nous pouvons maintenant masquer le nom du script dans les urls du backend:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1307code44'); return false;">View Code</a> CONSOLE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p130744"><td class="code" id="p1307code44"><pre class="console" style="font-family:monospace;"># apps/backend/config/settings.yml
prod:
  .settings:
    no_script_name:    true
    ...</pre></td></tr></table></div>

<p>Et pour finir ne pas oublier de vider le cache =), le backend est maintenant accessible sur http://admin.super-website.com.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-vhost-pour-lacces-au-backend-1307/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Qui l&#8217;eu CRUD ? Ou comment créer un thème pour les CRUD Doctrine de Symfony.</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/qui-leu-crud-ou-comment-creer-un-theme-pour-les-crud-doctrine-de-symfony-1181</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/qui-leu-crud-ou-comment-creer-un-theme-pour-les-crud-doctrine-de-symfony-1181#comments</comments>
		<pubDate>Mon, 09 Aug 2010 08:28:18 +0000</pubDate>
		<dc:creator>olivier</dc:creator>
				<category><![CDATA[1.3.x]]></category>
		<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[crud]]></category>
		<category><![CDATA[generate]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[theme]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1181</guid>
		<description><![CDATA[Symfony propose des outils très puissants pour faciliter le développement d&#8217;applications et surtout la génération des modules grâce à l&#8217;Admin Generator et le CRUD. Chacunes de ces solutions à ses avantages et ses inconvénients. L&#8217;admin generator permet en une commande &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/qui-leu-crud-ou-comment-creer-un-theme-pour-les-crud-doctrine-de-symfony-1181">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Symfony propose des outils très puissants pour faciliter le développement d&#8217;applications et surtout la génération des modules grâce à l&#8217;Admin Generator et le CRUD. Chacunes de ces solutions  à ses avantages et ses inconvénients.</p>
<p>L&#8217;admin generator permet en une commande d&#8217;avoir un module complet et fonctionnel avec de nombreuses fonctionnalités, le tout relativement configurable. En contre partie, l&#8217;ajout de fonctionnalités spécifiques et la mise en forme peuvent rapidement s&#8217;avérer fastidieuses. Être obligé d&#8217;aller fouiller dans le cache pour aller faire des copier/coller afin de pouvoir surcharger une action, c&#8217;est comme qui dirait, bien mais pas top&#8230;</p>
<p><span id="more-1181"></span></p>
<p>  D&#8217;autre part le CRUD permet lui aussi de générer en une seule commade un module, mais ce module est plus que limité et on se retrouve systématiquement à ré-implémenter les mêmes fonctionnalités de base comme le pager, les filters, etc. Par contre travailler avec un CRUD permet de garder la main sur le code, ce qui n&#8217;est pas négligeable.</p>
<p>C&#8217;est pourquoi je vous propose de voir comment fabriquer un thème pour le CRUD de manière à l&#8217;enrichir de quelques fonctionnalités indispensables pour ne pas avoir à les ré-écrire systematiquement et ainsi ganger du temps. Je vais en profiter pour développer ce thème au sein d&#8217;un plugin de manière à pouvoir s&#8217;en resservir facilement.</p>
<p>Pour se faire je vais partir d&#8217;un projet vierge type sandbox auquel je rajoute le plugin <a href="http://www.symfony-project.org/plugins/sfTaskExtraPlugin">sfTaskExtraPlugin</a> qui facilite grandement la génération de plugins.<br />
Pour me simplifier la vie, je vais reprendre <a href="http://www.symfony-project.org/jobeet/1_4/Doctrine/en/03#chapter_03_the_schema">le schema.yml</a> et les fixtures (<a href="http://svn.jobeet.org/doctrine/trunk/data/fixtures/affiliates.yml">affiliates.yml</a>, <a href="http://svn.jobeet.org/doctrine/trunk/data/fixtures/category.yml">category.yml</a> et <a href="http://svn.jobeet.org/doctrine/trunk/data/fixtures/jobs.yml">jobs.yml</a>) de Jobeet pour avoir un modèle sur lequel m&#8217;appuyer pour les exemples.</p>
<p>(Attention le fichier de fixture category.yml comporte les traductions, alors que le schema n&#8217;a pas le behavior I18n. Il faut au choix modifier le schema.yml pour rajouter le behavior ou modifier les categories pour supprimer les traductions)</p>
<p>Un petit <i>./symfony doctrine:build &#8211;all &#8211;and-load</i> et nous voilà parti.</p>
<h2>Let&#8217;s rock!</h2>
<p>Pour fabriquer un module de type CRUD symfony se sert de template de code pour générer les actions et les vues. Ces fichiers sont bien cachés au fin fond du symfony ! On les trouve dans</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code61'); return false;">View Code</a> PATH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118161"><td class="code" id="p1181code61"><pre class="path" style="font-family:monospace;">/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/data/generator/sfDoctrineModule/default</pre></td></tr></table></div>

</p>
<p>On va donc utiliser le thème par défaut que l&#8217;on va enrichir.</p>
<p>Tout d&#8217;abord, on va générer l&#8217;arborescence du plugin grâce à la commande generate:plugin de sfTaskExtraPlugin.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code62'); return false;">View Code</a> CONSOLE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118162"><td class="code" id="p1181code62"><pre class="console" style="font-family:monospace;">./symfony generate:plugin myCrudThemePlugin</pre></td></tr></table></div>

<p>Puis on prépare l&#8217;arborescence qui va accueillir les fichiers du template à l&#8217;intérieur du plugin.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code63'); return false;">View Code</a> CONSOLE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118163"><td class="code" id="p1181code63"><pre class="console" style="font-family:monospace;">mkdir -p plugins/myCrudThemePlugin/data/generator/sfDoctrineModule/myCrudTheme</pre></td></tr></table></div>

<p>Et on y copie tous les fichiers du thème par défaut.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code64'); return false;">View Code</a> CONSOLE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118164"><td class="code" id="p1181code64"><pre class="console" style="font-family:monospace;">cp -r lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/data/generator/sfDoctrineModule/default/* plugins/myCrudThemePlugin/data/generator/sfDoctrineModule/myCrudTheme</pre></td></tr></table></div>

<p>Si vous avez fait un checkout de symfony, les fichiers que vous avez copiés contiennent les informations de svn. Il faut nettoyer tout ça. Je vous propose une petite ligne de commande qui permet de faire ca.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code65'); return false;">View Code</a> CONSOLE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118165"><td class="code" id="p1181code65"><pre class="console" style="font-family:monospace;">find plugins/myCrudThemePlugin/data/generator/sfDoctrineModule/myCrudTheme -name .svn -exec rm -rf {} \;</pre></td></tr></table></div>

<p>Les fichiers sont prêts. A ce stade, on pourrait déjà générer un thème en utilisant notre thème. Il sufirait d&#8217;activer le plugin dans</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code66'); return false;">View Code</a> PATH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118166"><td class="code" id="p1181code66"><pre class="path" style="font-family:monospace;">/config/ProjectConfiguration.class.php</pre></td></tr></table></div>

</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code67'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118167"><td class="code" id="p1181code67"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> ProjectConfiguration <span style="color: #000000; font-weight: bold;">extends</span> sfProjectConfiguration
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setup<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">enablePlugins</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>
      <span style="color: #339933;">...</span>
      <span style="color: #0000ff;">'myCrudThemePlugin'</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Et de lancer la commande :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code68'); return false;">View Code</a> CONSOLE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118168"><td class="code" id="p1181code68"><pre class="console" style="font-family:monospace;">./symfony doctrine:generate-module --theme=&quot;myCrudTheme&quot; frontend job JobeetJob</pre></td></tr></table></div>

<p>Mais ne le faites pas ! :p Ca n&#8217;aurait pas un grand intérêt étant donné que l&#8217;on a rien changé par rapport au thème par défaut.</p>
<p>Nous allons commencer par rajouter un pager sur la page de listing. Il faut modifier l&#8217;action dans</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code69'); return false;">View Code</a> PATH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118169"><td class="code" id="p1181code69"><pre class="path" style="font-family:monospace;">/plugins/myCrudThemePlugin/data/generator/sfDoctrineModule/myCrudTheme/parts/indexAction.php</pre></td></tr></table></div>

</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code70'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118170"><td class="code" id="p1181code70"><pre class="php" style="font-family:monospace;">&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&lt;?php echo $this-&gt;getModelClass() ?&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">createQuery</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&lt;?php echo strtolower(substr($this-&gt;getModelClass(), 0, 1)) ?&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">pager</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfDoctrinePager<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&lt;?php echo $this-&gt;getModelClass() ?&gt;'</span><span style="color: #339933;">,</span> sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app_myCrudThemePlugin_pagination'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">20</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">pager</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setQuery</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">pager</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setPage</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRequestParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">pager</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">init</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Pour l&#8217;affichage du pager, je vous propose de créer un partial que l&#8217;on va inclure dans un module du plugin. Etant donné que le fonctionnement est générique, on a pas besoin qu&#8217;il soit recopié systèmatiquement dans les modules générés.</p>
<p>On va générer un module appelé shared qui va accueillir le partial du pager et éventuellement d&#8217;autres éléments que l&#8217;on voudra mutualiser.<br />
La encore sfTaskExtraPlugin nous aide bien car il intégre une commande qui fais ca.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code71'); return false;">View Code</a> CONSOLE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118171"><td class="code" id="p1181code71"><pre class="console" style="font-family:monospace;">./symfony generate:plugin-module myCrudThemePlugin shared</pre></td></tr></table></div>

<p>Il nous reste à aller créer notre partial dans</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code72'); return false;">View Code</a> PATH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118172"><td class="code" id="p1181code72"><pre class="path" style="font-family:monospace;">/plugins/myCrudThemePlugin/modules/shared/templates/_pager.php</pre></td></tr></table></div>

</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code73'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118173"><td class="code" id="p1181code73"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pager</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">haveToPaginate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;pagination&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>a title<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;First Page&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo (isset(<span style="color: #006699; font-weight: bold;">$object</span>)) ? url_for(<span style="color: #006699; font-weight: bold;">$route</span>, <span style="color: #006699; font-weight: bold;">$object</span>) : url_for(<span style="color: #006699; font-weight: bold;">$route</span>) ?&gt;?page=&lt;?php echo <span style="color: #006699; font-weight: bold;">$pager-&gt;getFirstPage</span>() ?&gt;&quot;</span><span style="color: #339933;">&gt;</span>« First<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>a title<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;Previous Page&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo (isset(<span style="color: #006699; font-weight: bold;">$object</span>)) ? url_for(<span style="color: #006699; font-weight: bold;">$route</span>, <span style="color: #006699; font-weight: bold;">$object</span>) : url_for(<span style="color: #006699; font-weight: bold;">$route</span>) ?&gt;?page=&lt;?php echo <span style="color: #006699; font-weight: bold;">$pager-&gt;getPreviousPage</span>() ?&gt;&quot;</span><span style="color: #339933;">&gt;</span>« Previous<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pager</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLinks</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #339933;">&lt;</span>a title<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo <span style="color: #006699; font-weight: bold;">$page</span> ?&gt;&quot;</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;number&lt;?php echo (<span style="color: #006699; font-weight: bold;">$page</span> == <span style="color: #006699; font-weight: bold;">$pager-&gt;getPage</span>()) ? ' current' : '' ?&gt;&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo (isset(<span style="color: #006699; font-weight: bold;">$object</span>)) ? url_for(<span style="color: #006699; font-weight: bold;">$route</span>, <span style="color: #006699; font-weight: bold;">$object</span>) : url_for(<span style="color: #006699; font-weight: bold;">$route</span>) ?&gt;?page=&lt;?php echo <span style="color: #006699; font-weight: bold;">$page</span> ?&gt;&quot;</span><span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$page</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #339933;">&lt;</span>a title<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;Next Page&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo (isset(<span style="color: #006699; font-weight: bold;">$object</span>)) ? url_for(<span style="color: #006699; font-weight: bold;">$route</span>, <span style="color: #006699; font-weight: bold;">$object</span>) : url_for(<span style="color: #006699; font-weight: bold;">$route</span>) ?&gt;?page=&lt;?php echo <span style="color: #006699; font-weight: bold;">$pager-&gt;getNextPage</span>() ?&gt;&quot;</span><span style="color: #339933;">&gt;</span>Next »<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>a title<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;Last Page&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo (isset(<span style="color: #006699; font-weight: bold;">$object</span>)) ? url_for(<span style="color: #006699; font-weight: bold;">$route</span>, <span style="color: #006699; font-weight: bold;">$object</span>) : url_for(<span style="color: #006699; font-weight: bold;">$route</span>) ?&gt;?page=&lt;?php echo <span style="color: #006699; font-weight: bold;">$pager-&gt;getLastPage</span>() ?&gt;&quot;</span><span style="color: #339933;">&gt;</span>Last »<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;clear&quot;</span><span style="color: #339933;">&gt;&lt;/</span>div<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Un pager générique qui fonctionne pour les <i>sfDoctrineRoute</i> et les <i>sfRequestRoute</i>. Il prends deux paramètres, route (obligatoire) et object (facultatif).</p>
<p>On modifie la vue indexSuccess.php pour la faire fonctionner avec le pager et ajouter le partial du pager.
<p> Dans</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code74'); return false;">View Code</a> PATH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118174"><td class="code" id="p1181code74"><pre class="path" style="font-family:monospace;">/plugins/myCrudThemePlugin/data/generator/sfDoctrineModule/myCrudTheme/template/templates/indexSuccess.php</pre></td></tr></table></div>

</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code75'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118175"><td class="code" id="p1181code75"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>h1<span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> sfInflector<span style="color: #339933;">::</span><span style="color: #004000;">humanize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPluralName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span> List<span style="color: #339933;">&lt;/</span>h1<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>table<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>thead<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>tr<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getColumns</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$column</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
      <span style="color: #339933;">&lt;</span>th<span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> sfInflector<span style="color: #339933;">::</span><span style="color: #004000;">humanize</span><span style="color: #009900;">&#40;</span>sfInflector<span style="color: #339933;">::</span><span style="color: #004000;">underscore</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$column</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPhpName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>th<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #339933;">&lt;/</span>tr<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;/</span>thead<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>tbody<span style="color: #339933;">&gt;</span>
    <span style="color: #009900;">&#91;</span>?php <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pager</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResults</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> $<span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSingularName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> ?<span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">&lt;</span>tr<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getColumns</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$column</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$column</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isPrimaryKey</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><a href="http://www.php.net/isset"><span style="color: #990000;">isset</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'route_prefix'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'route_prefix'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
      <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;[?php echo url_for('&lt;?php echo <span style="color: #006699; font-weight: bold;">$this-&gt;getUrlForAction</span>(isset(<span style="color: #006699; font-weight: bold;">$this-&gt;params</span>['with_show']) &amp;&amp; <span style="color: #006699; font-weight: bold;">$this-&gt;params</span>['with_show'] ? 'show' : 'edit') ?&gt;', $&lt;?php echo <span style="color: #006699; font-weight: bold;">$this-&gt;getSingularName</span>() ?&gt;) ?]&quot;</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#91;</span>?php <span style="color: #b1b100;">echo</span> $<span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSingularName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> sfInflector<span style="color: #339933;">::</span><span style="color: #004000;">camelize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$column</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPhpName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> ?<span style="color: #009900;">&#93;</span><span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;&lt;/</span>td<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">else</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
      <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;[?php echo url_for('&lt;?php echo <span style="color: #006699; font-weight: bold;">$this-&gt;getModuleName</span>() ?&gt;/&lt;?php echo isset(<span style="color: #006699; font-weight: bold;">$this-&gt;params</span>['with_show']) &amp;&amp; <span style="color: #006699; font-weight: bold;">$this-&gt;params</span>['with_show'] ? 'show' : 'edit' ?&gt;?&lt;?php echo <span style="color: #006699; font-weight: bold;">$this-&gt;getPrimaryKeyUrlParams</span>() ?&gt;) ?]&quot;</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#91;</span>?php <span style="color: #b1b100;">echo</span> $<span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSingularName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> sfInflector<span style="color: #339933;">::</span><span style="color: #004000;">camelize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$column</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPhpName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> ?<span style="color: #009900;">&#93;</span><span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;&lt;/</span>td<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">else</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
      <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#91;</span>?php <span style="color: #b1b100;">echo</span> $<span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSingularName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> sfInflector<span style="color: #339933;">::</span><span style="color: #004000;">camelize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$column</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPhpName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> ?<span style="color: #009900;">&#93;</span><span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #339933;">&lt;/</span>tr<span style="color: #339933;">&gt;</span>
    <span style="color: #009900;">&#91;</span>?php <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> ?<span style="color: #009900;">&#93;</span>
  <span style="color: #339933;">&lt;/</span>tbody<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>table<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #009900;">&#91;</span>?php include_partial<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'shared/pager'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'pager'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$pager</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'route'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;?php echo (isset($this-&gt;params['</span>route_prefix<span style="color: #0000ff;">']) &amp;&amp; $this-&gt;params['</span>route_prefix<span style="color: #0000ff;">']) ? $this-&gt;getUrlForAction('</span>index<span style="color: #0000ff;">') : $this-&gt;getModuleName().'</span><span style="color: #339933;">/</span>index<span style="color: #0000ff;">' ?&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> ?<span style="color: #009900;">&#93;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><a href="http://www.php.net/isset"><span style="color: #990000;">isset</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'route_prefix'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'route_prefix'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #339933;">&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;[?php echo url_for('&lt;?php echo <span style="color: #006699; font-weight: bold;">$this-&gt;getUrlForAction</span>('new') ?&gt;') ?]&quot;</span><span style="color: #339933;">&gt;</span>New<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">else</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #339933;">&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;[?php echo url_for('&lt;?php echo <span style="color: #006699; font-weight: bold;">$this-&gt;getModuleName</span>() ?&gt;/new') ?]&quot;</span><span style="color: #339933;">&gt;</span>New<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>On peut d&#8217;ores et déjà générer le crud pour tester,</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1181code76'); return false;">View Code</a> CONSOLE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118176"><td class="code" id="p1181code76"><pre class="console" style="font-family:monospace;">./symfony doctrine:generate-module --theme=&quot;myCrudTheme&quot; frontend job JobeetJob</pre></td></tr></table></div>

<p>Et vous voilà libéré de la tâche rébarbative des pagers ! :p</p>
<p>Ca faisait un petit moment que je voulais traiter ce sujet sur le blog, et je comptais continuer en intégrant les formFilter. Malheureusement, je manque de temps pour aller plus loin.<br />
Mais vous avez désormais en votre possession les éléments pour pouvoir faire votre propre thème et l&#8217;enrichir à votre guise.</p>
<p>J&#8217;espére que ca vous aura été utile et si j&#8217;en ai le temps je ferais un prochain post pour voir cette intégration des formFilter <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/qui-leu-crud-ou-comment-creer-un-theme-pour-les-crud-doctrine-de-symfony-1181/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Force-download avec Symfony</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/force-download-avec-symfony-1237</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/force-download-avec-symfony-1237#comments</comments>
		<pubDate>Tue, 20 Jul 2010 08:35:36 +0000</pubDate>
		<dc:creator>tsyr</dc:creator>
				<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[force-download]]></category>
		<category><![CDATA[session]]></category>
		<category><![CDATA[téléchargement]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1237</guid>
		<description><![CDATA[Aujourd&#8217;hui, nous allons aborder quelque chose de simple et répandu sur la plupart des sites Internet de nos jours : le téléchargement de fichiers. Bien sûr, il ne s&#8217;agit pas de permettre aux utilisateurs de télécharger votre dernier rush de &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/force-download-avec-symfony-1237">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Aujourd&#8217;hui, nous allons aborder quelque chose de simple et répandu sur la plupart des sites Internet de nos jours : le téléchargement de fichiers.</p>
<p>Bien sûr, il ne s&#8217;agit pas de permettre aux utilisateurs de télécharger votre dernier rush de photos nocturnes sous forme d&#8217;archive zip, ou encore les rapports de la dernière assemblée générale de votre association en PDF; car ceci ne nécessite en rien l&#8217;intervention de symfony.</p>
<p>Par contre, dès qu&#8217;une action doit être entreprise pour vérifier l&#8217;authenticité de l&#8217;utilisateur, ou ne serait-ce qu&#8217;une table de log pour savoir qui a téléchargé quel fichier, on va avoir besoin de symfony (à moins d&#8217;avoir envie de réinventer la roue).<br />
<span id="more-1237"></span><br />
Pour commencer, une action simple, qui affiche selon votre convenance une liste de fichiers ou le détail d&#8217;un fichier en particulier, mais surtout, un lien de téléchargement. Pour mon exemple, j&#8217;ai déjà fais l&#8217;installation du projet, et du plugin sfDoctrineGuardPlugin (avec les fixtures par défaut du plugin).</p>
<p>Mon schéma de base de données ressemble à ça:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1237code88'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p123788"><td class="code" id="p1237code88"><pre class="yml" style="font-family:monospace;">Software:
  columns:
    name: string
    path: string
    size: integer
&nbsp;
Download:
  options:
    symfony:          { form: false, filter: false }
  actAs:
    Timestampable:
      updated:        { disabled: true }
  columns:
    user_id:          { type: integer(4), notnull: true }
    software_id:      { type: integer(4), notnull: true }
  relations:
    Software:
      local:          software_id
      foreign:        id
      foreignAlias:   Downloads
    User:
      class:          sfGuardUser
      local:          user_id
      foreign:        id
      foreignAlias:   Downloads</pre></td></tr></table></div>

<p>Mes fixtures, à ça:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1237code89'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p123789"><td class="code" id="p1237code89"><pre class="yml" style="font-family:monospace;">Software:
  test:
    name:     symfony latest
    path:     &lt;?php echo sfConfig::get('sf_data_dir') ?&gt;/symfony-1.4.6.tgz
    size:     3233168</pre></td></tr></table></div>

<p>Une fois ceci chargé en base de données, on va pouvoir se lancer dans le développement, et plus particulièrement le téléchargement. Pour me simplifier la tâche lors de cet exemple, un unique fichier pourra être télécharger, ainsi, la route pour lancer le &laquo;&nbsp;download&nbsp;&raquo; du fichier est aussi simple que:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1237code90'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p123790"><td class="code" id="p1237code90"><pre class="yml" style="font-family:monospace;">download:
  class:      sfDoctrineRoute
  url:        /download/:id
  options:
    model:    Software
    type:     object
  param:
    module:   file
    action:   download</pre></td></tr></table></div>

<p>De ce fait, pour télécharger notre fichier d&#8217;exemple, il suffit sur n&#8217;importe quelle page, d&#8217;inclure un lien vers celui-ci, de cette façon:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1237code91'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p123791"><td class="code" id="p1237code91"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>p<span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> link_to<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Télécharger'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'@download'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>p<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Tout le code sera centralisé dans l&#8217;action, mais je le répète, ce n&#8217;est qu&#8217;à titre d&#8217;exemple, il serait bien plus approprié de faire un lien de ce type:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1237code92'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p123792"><td class="code" id="p1237code92"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>p<span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> link_to<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Télécharger '</span><span style="color: #339933;">.</span><span style="color: #000088;">$file</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'download'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>p<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Regardons maintenant plus en détail le contenu de notre action «download» du module «file» (cf. la route ci-dessus)</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1237code93'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p123793"><td class="code" id="p1237code93"><pre class="php" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeDownload<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isAuthenticated</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$file</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/file_exists"><span style="color: #990000;">file_exists</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Fichier introuvable'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">clearHttpHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setContentType</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'application/force-download'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHttpHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Disposition'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'attachment; filename=&quot;'</span> <span style="color: #339933;">.</span> <a href="http://www.php.net/basename"><span style="color: #990000;">basename</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHttpHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Transfer-Encoding'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'binary'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHttpHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Length'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$file</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSize</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHttpHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Connection'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'close'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setContent</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/file_get_contents"><span style="color: #990000;">file_get_contents</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">send</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>A ce niveau, deux problèmes majeurs se posent:</p>
<ul>
<li>file_get_contents est dépendant du paramètre memory_limit de php</li>
<li>la web_debug_toolbar va venir s&#8217;immiscer dans chaque download</li>
</ul>
<p>Le problème de la web_debug_toolbar peut vite être résolu en la désactivant dans l&#8217;action avec sfConfig::set(&#8216;sf_web_debug_false&#8217;, false) mais il reste le problème du téléchargement de fichiers dont la taille dépasse notre memory_limit. Ce paramètre étant généralement bas en production (128 Mo par défaut), ça peut vite être génant. La solution est d&#8217;utiliser la fonction php <a href="http://fr.php.net/manual/fr/function.readfile.php">readfile()</a> qui elle, envoit directement des blocs de 8 Ko sur la sortie, et donc n&#8217;est pas soumis à la limite d&#8217;utilisation de mémoire PHP.</p>
<p>On remplace donc:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1237code94'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p123794"><td class="code" id="p1237code94"><pre class="php" style="font-family:monospace;">    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setContent</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/file_get_contents"><span style="color: #990000;">file_get_contents</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">send</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>par</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1237code95'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p123795"><td class="code" id="p1237code95"><pre class="php" style="font-family:monospace;">    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sendHttpHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #339933;">@</span><a href="http://www.php.net/readfile"><span style="color: #990000;">readfile</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> sfStopException<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>L&#8217;exception sfStopException() est une manière un peu «crade» de mettre un terme à l&#8217;exécution du script, mais c&#8217;est moins pire qu&#8217;un &laquo;&nbsp;die&nbsp;&raquo; et du coup, ça permet dans un deuxième temps de ne pas être embêté par la web_debug_toolbar.<br />
Il arrive souvent aussi que les headers ne soient pas envoyés, c&#8217;est dû au fait que la sortie est bufferisée, ce problème se résoud avec l&#8217;utilisation des fonctions <a href="http://fr.php.net/manual/fr/function.flush.php">flush()</a> et/ou <a href="http://fr.php.net/manual/fr/function.ob-end-clean.php">ob_end_clean()</a> juste avant le readfile.</p>
<p>Maintenant, on avait pour but de passer par symfony pour enregistrer des logs sur les téléchargements. Rien de plus simple, un exemple pourrait être le code suivant à rajouter après la vérification de l&#8217;existence du fichier (file_exists()) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1237code96'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p123796"><td class="code" id="p1237code96"><pre class="php" style="font-family:monospace;">    <span style="color: #000088;">$dl</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Download<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$dl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setSoftware</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$dl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setUser</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getGuardUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// other stuff</span>
    <span style="color: #000088;">$dl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>A ce stade, tout pourrait sembler correct. C&#8217;était sans compter une fourberie de PHP, qui va bloquer toute autre action sur votre site pendant un téléchargement. En effet, les sessions fonctionnent avec un &laquo;&nbsp;LOCK&nbsp;&raquo; et vu que les sessions sont en auto_start avec symfony, le téléchargement se fait pendant une session, et aucune autre action de la part de l&#8217;utilisateur ne sera accepté pendant un téléchargement, car sa session étant identifiée comme &laquo;&nbsp;en cours d&#8217;écriture&nbsp;&raquo; (le principe de lock).<br />
Une personne ayant déjà rencontré ce problème pourrait se dire qu&#8217;en fermant la session à l&#8217;aide de</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1237code97'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p123797"><td class="code" id="p1237code97"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">shutdown</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>dans l&#8217;action résoudrait le problème, et ce n&#8217;est pas le cas, même si en effet, la fonction shutdown() va libérer la session grâce à la fonction <a href="http://fr.php.net/manual/fr/function.session-write-close.php">session_write_close()</a>, elle ne sera exécuté qu&#8217;à la fin du script, donc dans notre cas, ça n&#8217;a aucun intêret, il faut faire le session_write_close() directement dans notre action.</p>
<p>Pour finir, voici le code complet de notre action :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1237code98'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p123798"><td class="code" id="p1237code98"><pre class="php" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeDownload<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isAuthenticated</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$file</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/file_exists"><span style="color: #990000;">file_exists</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Fichier introuvable'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$dl</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Download<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$dl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setSoftware</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$dl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setUser</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getGuardUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// other stuff</span>
    <span style="color: #000088;">$dl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <a href="http://www.php.net/session_write_close"><span style="color: #990000;">session_write_close</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">clearHttpHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setContentType</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'application/force-download'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHttpHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Disposition'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'attachment; filename=&quot;'</span> <span style="color: #339933;">.</span> <a href="http://www.php.net/basename"><span style="color: #990000;">basename</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHttpHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Transfer-Encoding'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'binary'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHttpHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Length'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$file</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSize</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHttpHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Connection'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'close'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sendHttpHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//    @ob_end_clean();</span>
<span style="color: #666666; font-style: italic;">//    flush();</span>
&nbsp;
    <span style="color: #339933;">@</span><a href="http://www.php.net/readfile"><span style="color: #990000;">readfile</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> sfStopException<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>J&#8217;espère que ceci vous aidera dans vos développements actuels et futurs,<br />
@ bientôt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/force-download-avec-symfony-1237/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Exemple d&#8217;application utilisant la Graph API de Facebook</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/exemple-dapplication-utilisant-la-graph-api-de-facebook-1187</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/exemple-dapplication-utilisant-la-graph-api-de-facebook-1187#comments</comments>
		<pubDate>Wed, 07 Jul 2010 12:42:30 +0000</pubDate>
		<dc:creator>laurent</dc:creator>
				<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[developpeur]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1187</guid>
		<description><![CDATA[Facebook a lancé il y a maintenant quelque smois sa nouvelle Graph API, mais la documentation qui l'entoure se fait encore rare et peu détaillée. Je vais donc profiter de cet article pour présenter quelques aspects de cette nouvelle API à l'aide d'une petite iframe application Facebook, et avec Symfony (pour rester dans la thématique du blog !).<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/exemple-dapplication-utilisant-la-graph-api-de-facebook-1187">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Facebook a lancé il y a maintenant quelques mois sa nouvelle Graph API, qui permet d&#8217;accèder et d&#8217;interagir avec les informations Facebook de l&#8217;utilisateur encore plus simplement. Seuelement la documentation qui l&#8217;entoure se fait encore rare et peu détaillée. Je vais donc profiter de cet article pour présenter quelques aspects de cette nouvelle API à l&#8217;aide d&#8217;une petite iframe application Facebook, et avec Symfony (pour rester dans la thématique du blog !).</p>
<p><span id="more-1187"></span></p>
<p>Pour commencer nous avons bien sûr besoin de créer notre application Facebook. Cela n&#8217;étant pas le but de cet article, je vous laisse trouver la marche à suivre sur le net; les sites couvrant le sujet sont légion (par exemple <a href="http://www.creer-une-application-facebook.com" target="_blank">créer une application Facebook</a>).</p>
<p>On paramètre correctement l&#8217;application et celle-ci s&#8217;occupera ensuite de charger nos pages dynamiques depuis l&#8217;url spécifiée:</p>
<p><a href="http://www.lexik.fr/blog/symfony/wp-content/uploads/2010/07/canvas.png"><img class="alignnone size-medium wp-image-1188" title="canvas" src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2010/07/canvas-300x232.png" alt="" width="300" height="232" /></a></p>
<p>L&#8217;application Symfony n&#8217;a ici qu&#8217;un seul module &laquo;&nbsp;demo&nbsp;&raquo; qui s&#8217;occupe des quelques actions nécessaires. Editons &laquo;&nbsp;app.yml&nbsp;&raquo; pour y ajouter l&#8217;ID et le SECRET obtenus lors de la création de notre application:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code99'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p118799"><td class="code" id="p1187code99"><pre class="yml" style="font-family:monospace;">all:
  facebook:
    app_id: 116399618389033
    api_key: *******************************************
    secret: *****************************************
    base_url: http://facebook.prestataire-symfony.com
    app_url: http://apps.facebook.com/demolexik</pre></td></tr></table></div>

<p>Il nous faut ensuite récupérer <a href="http://github.com/facebook/php-sdk/downloads" target="_blank">l&#8217;api Facebook PHP sur Github</a>, que nous allons coller dans /lib/facebook/facebook.php.<br />
Afin de ne pas avoir à initialiser les appels à l&#8217;api depuis chaque action, un filter va grandement nous simplifier la tâche:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code100'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187100"><td class="code" id="p1187code100"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/filter/FacebookFilter.class.php</span>
<span style="color: #000000; font-weight: bold;">class</span> FacebookFilter <span style="color: #000000; font-weight: bold;">extends</span> sfFilter
<span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> execute<span style="color: #009900;">&#40;</span>sfFilterChain <span style="color: #000088;">$filterChain</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$context</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getContext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$request</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$context</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRequest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">//initialisation de l'appel à l'api...</span>
    <span style="color: #000088;">$facebook</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Facebook<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>
          <span style="color: #0000ff;">'appId'</span>   <span style="color: #339933;">=&gt;</span> sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app_facebook_app_id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
          <span style="color: #0000ff;">'secret'</span>  <span style="color: #339933;">=&gt;</span> sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app_facebook_secret'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
          <span style="color: #0000ff;">'cookie'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$context</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getController</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">getActionStack</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLastEntry</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">getActionInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">facebook</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$facebook</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$filterChain</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Pensez à éditer votre &laquo;&nbsp;filters.yml&nbsp;&raquo; en conséquence.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code101'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187101"><td class="code" id="p1187code101"><pre class="yml" style="font-family:monospace;">#apps/frontend/config/filters.yml
rendering: ~
security:  ~
# insert your own filters here
Facebook:
  class: FacebookFilter
cache:     ~
execution: ~</pre></td></tr></table></div>

<p>Pour l&#8217;api Javascript, nous allons éditer le layout de l&#8217;application:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code102'); return false;">View Code</a> HTML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187102"><td class="code" id="p1187code102"><pre class="html" style="font-family:monospace;">&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xmlns:fb=&quot;http://www.facebook.com/2008/fbml&quot;&gt;
  &lt;head&gt;
    &lt;?php include_http_metas() ?&gt;
    &lt;?php include_metas() ?&gt;
    &lt;title&gt;Facebook App&lt;/title&gt;
    &lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    &lt;style&gt;
      div.section {
        margin-bottom: 10px;
        background: #EEEEEE;
        padding: 5px 10px;
      }
      body {
        font-family: Arial;
        font-size: 12px;
      }
      pre {
        font-size: 10px;
        color: #333333;
        margin-left: 50px;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;fb-root&quot;&gt;&lt;/div&gt;
    &lt;script src=&quot;http://connect.facebook.net/en_US/all.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
    FB.init({
       appId  : '&lt;?php echo sfConfig::get('app_facebook_app_id') ?&gt;',
       status : true, // vérifie le status de la connection
       cookie : true, // autorise les cookies pour permettre au serveur d'accéder à la session'
       xfbml  : true  // active le parsing de XFBML
      });
    &lt;/script&gt;
    ...</pre></td></tr></table></div>

<p>Nous en profitons pour charger JQuery afin de faciliter l&#8217;ajax et le remaniement du Dom.</p>
<p>Voilà, nous sommes prêts à attaquer les actions.</p>
<p>La première action va être l&#8217;authentification de l&#8217;utilisateur Facebook, et la gestion des permissions que celui-ci devra accorder à notre application.<br />
Le nouveau modèle de Facebook veut que nous demandions à l&#8217;utilisateur, dès le premier accès à l&#8217;application, qu&#8217;il accepte simultanément toutes les permissions nécessaires. Pour plus d&#8217;informations à ce sujet, consultez la liste des permissions sur <a href="http://developers.facebook.com/docs/authentication/permissions" target="_blank">le wiki Facebook Developer</a>.<br />
Voici l&#8217;action Login, qui sera appelée lorsque l&#8217;utilisateur n&#8217;a pas accordé ces permissions, ou lors d&#8217;une première visite de l&#8217;application:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code103'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187103"><td class="code" id="p1187code103"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//apps/frontend/modules/demo/actions/actions.class.php</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeLogin<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//on génère l'url qui permettra le login à l'application</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loginUrl</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLoginUrl</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'canvas'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'fbconnect'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
            <span style="color: #666666; font-style: italic;">//ici on demande les permissions email, publication sur le mur, et changement du status</span>
            <span style="color: #0000ff;">'req_perms'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'email,publish_stream,status_update'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'next'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span>
        <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Comme nous sommes dans une application iframe, il faut charger l&#8217;url de login depuis la frame parente, et notre template va s&#8217;en charger:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code104'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187104"><td class="code" id="p1187code104"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;!--</span>loginSuccess<span style="color: #339933;">.</span>php<span style="color: #339933;">--&gt;</span>
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
top<span style="color: #339933;">.</span>location<span style="color: #339933;">.</span>href <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&lt;?php echo <span style="color: #006699; font-weight: bold;">$sf_data-&gt;getRaw</span>('loginUrl') ?&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></pre></td></tr></table></div>

<p>Il faut maintenant que notre index redirige vers ce login dans les cas précédemment cités:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code105'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187105"><td class="code" id="p1187code105"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//apps/frontend/modules/demo/actions/actions.class.php</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//on vérifie si l'utilisateur a une session facebook active</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">session</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSession</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">session</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">//sinon il doit s'identifier</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'demo/login'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//s'il a une session active, on vérifie si elle est valide pour notre application</span>
    try
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">uid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fbme</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">api</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/me'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    catch <span style="color: #009900;">&#40;</span>FacebookApiException <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">//sinon il doit à nouveau s'identifier</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'demo/login'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>On peut maintenant voir une demande de permissions s&#8217;afficher lorsque l&#8217;on se connecte à l&#8217;application:<br />
<a href="http://www.lexik.fr/blog/symfony/wp-content/uploads/2010/07/perms.png"><img class="alignnone size-medium wp-image-1189" title="perms" src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2010/07/perms-300x172.png" alt="" width="300" height="172" /></a></p>
<p>En vérifiant la validité de la session, nous avons récupéré toutes les informations sur l&#8217;utilisateur auxquelles nos permissions nous donnent accès. Voyons l&#8217;étendue de ces informations en les affichant dans notre vue:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code106'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187106"><td class="code" id="p1187code106"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;!--</span> indexSuccess<span style="color: #339933;">.</span>php <span style="color: #339933;">--&gt;</span>
<span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;section&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>h3<span style="color: #339933;">&gt;</span>Informations utilisateur<span style="color: #339933;">&lt;/</span>h3<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>pre<span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <a href="http://www.php.net/print_r"><span style="color: #990000;">print_r</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fbme</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span> <span style="color: #339933;">/</span>pre<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p><a href="http://www.lexik.fr/blog/symfony/wp-content/uploads/2010/07/infos.png"><img class="alignnone size-medium wp-image-1195" title="infos" src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2010/07/infos-300x174.png" alt="" width="300" height="174" /></a><br />
Nous accédons bien à l&#8217;adresse email comme spécifié, ainsi qu&#8217;aux informations génériques et publiques sur l&#8217;utilisateur.</p>
<p>Il est maintenant temps d&#8217;interagir avec l&#8217;utilisateur. Il nous a également accordé l&#8217;accès à son status, nous allons donc lui proposer de l&#8217;éditer via notre application:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code107'); return false;">View Code</a> HTML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187107"><td class="code" id="p1187code107"><pre class="html" style="font-family:monospace;">&lt;!-- indexSuccess.php --&gt;
...
&lt;div class=&quot;section&quot;&gt;
  &lt;a onclick=&quot;updateStatus();return false;&quot; href=&quot;#&quot;&gt;Changer mon status via Ajax et l'API PHP&lt;/a&gt;
  &lt;textarea id=&quot;status_text&quot; cols=&quot;40&quot; rows=&quot;2&quot;&gt;  &lt;/textarea&gt;
&lt;/div&gt;
...
&lt;script type=&quot;text/javascript&quot;&gt;
function updateStatus()
  {
    var status = document.getElementById('status_text').value;
&nbsp;
    $.ajax({
      type: 'post',
      url: '&lt;?php echo url_for('demo/statusUpdate') ?&gt;',
      data: 'status=' + status,
      success: function(response) {
        alert(response);
      },
      error: function(response) {
        alert(response);
      }
    });
  }
&lt;/script&gt;</pre></td></tr></table></div>

<p>La méthode js &laquo;&nbsp;updateStatus()&nbsp;&raquo; va faire un appel ajax à une nouvelle action updateStatus de notre application:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code108'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187108"><td class="code" id="p1187code108"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//apps/frontend/modules/demo/actions/actions.class.php</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeUpdateStatus<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isXmlHttpRequest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$status</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'status'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    try
    <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">//un simple appel a l'api suffit à poster un nouveau status sur le profile de l'utilisateur</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">api</span><span style="color: #009900;">&#40;</span>
          <span style="color: #0000ff;">'/me/feed'</span><span style="color: #339933;">,</span>
          <span style="color: #0000ff;">'post'</span><span style="color: #339933;">,</span>
          <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'message'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$status</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'cb'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span> <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    catch <span style="color: #009900;">&#40;</span>FacebookApiException <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderText</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Erreur: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderText</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Status mis-à-jour'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>L&#8217;api Javascript est toute aussi simple à utiliser. Proposons cette fois à l&#8217;utilisateur de parler de notre application sur son mur à l&#8217;aide de javascript:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code109'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187109"><td class="code" id="p1187code109"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;!--</span> indexSuccess<span style="color: #339933;">.</span>php <span style="color: #339933;">--&gt;</span>
<span style="color: #339933;">...</span>
<span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;section&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>a onclick<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;publishWall();return false;&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;#&quot;</span><span style="color: #339933;">&gt;</span>Poster un article sur mon mur via l<span style="color: #0000ff;">'API Javascript&lt;/a&gt;
&lt;/div&gt;
...
&lt;script type=&quot;text/javascript&quot;&gt;
function publishWall()
  {
    FB.ui(
    {
      method: '</span>stream<span style="color: #339933;">.</span>publish<span style="color: #0000ff;">',
      message: '</span><span style="color: #0000ff;">',
      attachment:
      {
        name: &quot;Démo Symfony+Facebook&quot;,
        caption: '</span><span style="color: #0000ff;">',
        description: &quot;Une démo simple d'</span>application Facebook avec Symfony et les dernières API Javascript et PHP de Facebook<span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;,
        href: &quot;</span>http<span style="color: #339933;">:</span><span style="color: #666666; font-style: italic;">//www.lexik.fr/blog/symfony/non-classe/exemple-dapplication-utilisant-la-graph-api-de-facebook-1187&quot;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      user_prompt_message<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;Application de démo Symfony+Facebook&quot;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></pre></td></tr></table></div>

<p>Le résultat obtenu en cliquant sur le lien est le pseudo-popup bien connu de Facebook:<br />
<a href="http://www.lexik.fr/blog/symfony/wp-content/uploads/2010/07/publish.png"><img class="alignnone size-medium wp-image-1190" title="publish" src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2010/07/publish-300x129.png" alt="" width="300" height="129" /></a></p>
<p>Nous venons de voir quelques méthodes simples d&#8217;accès ou de publication de données. Une liste plus complète des méthodes éxistantes est sur <a href="http://developers.facebook.com/docs/reference/rest/" target="_blank">le wiki Facebook Developer</a>.<br />
Dans le cadre d&#8217;applications plus complexes, il sera souvent utile de pouvoir formuler précisément les informations que l&#8217;on souhaite récupérer, et celles-ci ne correspondront pas nécessairement à une méthode éxistante. Pour cela Facebook met à notre disposition FQL, un langage de requète similaire à SQL dans sa syntaxe, pour générer nos requètes spécifiques.</p>
<p>Par exemple, récupérons la liste des amis de l&#8217;utilisateur avec leur nom, leur uid, et leur photo. Voici la requète FQL pour cela, et son éxécution via l&#8217;api PHP:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code110'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187110"><td class="code" id="p1187code110"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//apps/frontend/modules/demo/actions/actions.class.php</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #339933;">...</span>
    <span style="color: #666666; font-style: italic;">//récupération des amis via FQL</span>
    <span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT name, uid, pic_square FROM user WHERE uid in (SELECT uid2 FROM friend WHERE uid1 = &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">uid</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;)&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">amis</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">api</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'method'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'fql.query'</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'query'</span>     <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$query</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'callback'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span>
    <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Et l&#8217;affichage de la liste dans la vue:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1187code111'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1187111"><td class="code" id="p1187code111"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;!--</span> indexSuccess<span style="color: #339933;">.</span>php <span style="color: #339933;">--&gt;</span>
<span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;section&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>h3<span style="color: #339933;">&gt;</span>Liste d<span style="color: #0000ff;">'amis&lt;/h3&gt;
&lt;?php foreach ($amis as $ami): ?&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;img src=&quot;&lt;?php echo $ami['</span>pic_square<span style="color: #0000ff;">'] ?&gt;&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;&lt;?php echo $ami ['</span>name<span style="color: #0000ff;">'] ?&gt;&lt;/strong&gt;&lt;/li&gt;
	&lt;li&gt;uid: &lt;?php echo $ami['</span>uid<span style="color: #0000ff;">'] ?&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;?php endforeach; ?&gt;
&lt;/div&gt;</span></pre></td></tr></table></div>

<p>Cet article n&#8217;était pas dédié à Symfony, mais l&#8217;utilisait plutôt pour proposer un environnement familier à notre application. Ce survol rapide de la nouvelle Graph Api permet surtout de donner un point de départ sur l&#8217;utilisation de la nouvelle librairie à un moment ou la documentation à son sujet n&#8217;est pas vraiment fournie, en particulier en français !<br />
Vous pouvez voir l&#8217;application tourner sur <a href="http://apps.facebook.com/demoLexik" target="_blank">http://apps.facebook.com/demoLexik</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/exemple-dapplication-utilisant-la-graph-api-de-facebook-1187/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Validation d&#8217;un numéro siret : sfValidatorSiret</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/1-4-x/validation-dun-numero-siret-sfvalidatorsiret-1159</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/1-4-x/validation-dun-numero-siret-sfvalidatorsiret-1159#comments</comments>
		<pubDate>Tue, 25 May 2010 06:30:00 +0000</pubDate>
		<dc:creator>thomas</dc:creator>
				<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[siret]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[validator]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1159</guid>
		<description><![CDATA[Bonjour, comme vous avez pu le voir avec les récents posts, nous avons eu pas mal de gestion de facturation: conversion de devises, validation d&#8217;un numéro de tva intracommunautaire. Pour continuer sur la lancée, nous allons faire un petit validator &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/1-4-x/validation-dun-numero-siret-sfvalidatorsiret-1159">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Bonjour,</p>
<p>comme vous avez pu le voir avec les récents posts, nous avons eu pas mal de gestion de facturation: <a title="conversion de devises" href="http://www.lexik.fr/blog/symfony/symfony/tips-conversions-de-devises-1137" target="_blank">conversion de devises</a>, <a title="tva intracommunautaire" href="http://www.lexik.fr/blog/symfony/symfony/un-validator-tva-bien-pratique-1123" target="_blank">validation d&#8217;un numéro de tva intracommunautaire</a>.</p>
<p>Pour continuer sur la lancée, nous allons faire un petit validator sur les numéros siret.</p>
<p><span id="more-1159"></span>Un numéro siret correspond à un petit algorithme assez simple <a title="algorithme numéro siret" href="http://fr.wikipedia.org/wiki/Syst%C3%A8me_d%E2%80%99identification_du_r%C3%A9pertoire_des_%C3%A9tablissements#Calcul_et_validit.C3.A9_d.27un_num.C3.A9ro_SIRET" target="_blank">expliqué ici</a> (<a title="Luhn" href="http://fr.wikipedia.org/wiki/Luhn" target="_blank">algorithme de Luhn</a>)<br />
Le principe est le suivant : on multiplie les chiffres de rang impair à partir de la droite par 1, ceux de rang pair par 2 ; la somme des chiffres obtenus doit être congrue au modulo 10, c&#8217;est-à-dire qu&#8217;elle doit être multiple de 10.<br />
Un numéro siret comporte 14 chiffre.</p>
<p>Voici le code du validator: sfValidatorSiret.class.php</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1159code113'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1159113"><td class="code" id="p1159code113"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> sfValidatorSiret <span style="color: #000000; font-weight: bold;">extends</span> sfValidatorBase 
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> doClean<span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$siret</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/trim"><span style="color: #990000;">trim</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/empty"><span style="color: #990000;">empty</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$siret</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <a href="http://www.php.net/strlen"><span style="color: #990000;">strlen</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$siret</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">14</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorError<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Le numéro siret est invalide'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$sum</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">&lt;</span><span style="color: #cc66cc;">14</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">%</span><span style="color:#800080;">2</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$tmp</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$siret</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$tmp</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$tmp</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">9</span> ? <span style="color: #000088;">$tmp</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">9</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$tmp</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
      <span style="color: #b1b100;">else</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$tmp</span><span style="color: #339933;">=</span> <span style="color: #000088;">$siret</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
      <span style="color: #000088;">$sum</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$tmp</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sum</span><span style="color: #339933;">%</span><span style="color:#800080;">10</span> <span style="color: #339933;">!==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorError<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Le numéro siret est invalide'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$siret</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Pour expliquer rapidement:<br />
1. si la valeur est vide ou de longueur différente de 14 on retourne une exception.<br />
2. on parcours les 14 chiffres, si le chiffre est paire alors on le multiplie par 2 et si ce résultat est supérieur à  9 alors on retranche 9.<br />
ex: 7 =&gt; 7&#215;2 = 14 =&gt; 14 &#8211; 9 = 5.<br />
faire 14 -9  reviens à additionner les 2 chiffres: 1 + 4 = 5.<br />
3. On additionne tous les chiffres paires x2 et les chiffres impaires.<br />
4. si le résultat est divisible par 10 alors c&#8217;est un numéro siret.</p>
<p>Attention ceci indique que le numéro fourni peut être un numéro siret, MAIS PAS que ce numéro est réellement un numéro siret inscrit à L&#8217;INSEE, actif et correspond à une société.</p>
<p><a href="http://www.lexik.fr/blog/symfony/wp-content/uploads/2010/05/sfValidatorSiret.tar.gz">Vous pouvez télécharger le validator ici.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/1-4-x/validation-dun-numero-siret-sfvalidatorsiret-1159/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tips : Conversions de devises</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/tips-conversions-de-devises-1137</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/tips-conversions-de-devises-1137#comments</comments>
		<pubDate>Mon, 17 May 2010 12:29:10 +0000</pubDate>
		<dc:creator>Nikaw</dc:creator>
				<category><![CDATA[1.0.x]]></category>
		<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[1.3.x]]></category>
		<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[astuce]]></category>
		<category><![CDATA[helper]]></category>
		<category><![CDATA[taux de change]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1137</guid>
		<description><![CDATA[Aujourd&#8217;hui je vous montre juste une petite astuce pour avoir les taux de conversion de l&#8217;Euro vers d&#8217;autres devises. Le site de la banque centrale Européenne publie tous les jours un fichier XML contenant les taux de conversion à jour. &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/tips-conversions-de-devises-1137">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Aujourd&#8217;hui je vous montre juste une petite astuce pour avoir les taux de conversion de l&#8217;Euro vers d&#8217;autres devises.</p>
<p>Le site de la banque centrale Européenne publie tous les jours un fichier XML contenant les taux de conversion à jour.</p>
<p>Il fournit également un morceau de code donnant un exemple de manipulation<br />
<span id="more-1137"></span><br />
<a href="http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml">http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml</a></p>
<p>Voici le code fourni par le site lui-même pour les développeurs :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1137code117'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1137117"><td class="code" id="p1137code117"><pre class="php" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">//This is a PHP (4/5) script example on how eurofxref-daily.xml can be parsed </span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Read eurofxref-daily.xml file in memory </span>
<span style="color: #000088;">$XMLContent</span><span style="color: #339933;">=</span> <a href="http://www.php.net/file"><span style="color: #990000;">file</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//the file is updated daily between 2.15 p.m. and 3.00 p.m. CET</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$XMLContent</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><a href="http://www.php.net/ereg"><span style="color: #990000;">ereg</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;currency='([[:alpha:]]+)'&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$line</span><span style="color: #339933;">,</span><span style="color: #000088;">$currencyCode</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><a href="http://www.php.net/ereg"><span style="color: #990000;">ereg</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;rate='([[:graph:]]+)'&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$line</span><span style="color: #339933;">,</span><span style="color: #000088;">$rate</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #666666; font-style: italic;">//Output the value of 1 EUR for a currency code </span>
                    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'1 &amp;euro; = '</span><span style="color: #339933;">.</span><span style="color: #000088;">$rate</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">' '</span><span style="color: #339933;">.</span><span style="color: #000088;">$currencyCode</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;br /&gt;'</span><span style="color: #339933;">;</span>
                    <span style="color: #666666; font-style: italic;">//--------------------------------------------------</span>
                    <span style="color: #666666; font-style: italic;">// Here you can add your code for inserting</span>
                    <span style="color: #666666; font-style: italic;">// $rate[1] and $currencyCode[1] into your database</span>
                    <span style="color: #666666; font-style: italic;">//--------------------------------------------------</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Ce code permet d&#8217;afficher les taux de conversion Euro vers devise pour toutes les devises.<br />
(source : <a href="http://www.ecb.europa.eu/stats/exchange/eurofxref/html/index.en.html">http://www.ecb.europa.eu/stats/exchange/eurofxref/html/index.en.html</a>)</p>
<p>Et voici un helper tout simple permettant de convertir directement de EUR vers une devise, en utilisant la librairie Dom.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1137code118'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1137118"><td class="code" id="p1137code118"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> convertEuroToCurrency<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #000088;">$currency</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #666666; font-style: italic;">//ouverture du doc</span>
  <span style="color: #000088;">$dom_rates</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMDocument<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$dom_rates</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">//récupération de l'ensemble des éléments Cube</span>
  <span style="color: #000088;">$dom_cubes</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom_rates</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Cube'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$j</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$rate_found</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">//tant qu'on a pas trouvé le bon pays, on continue</span>
  <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$rate_found</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$cube</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom_cubes</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$j</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">//tant qu'on a pas trouvé le bon pays, on continue</span>
    <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$rate_found</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$attribute</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$cube</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">attributes</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$j</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//si on est en train de lire le noeud &quot;temps&quot; on stocke la date</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$attribute</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'time'</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$date</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$attribute</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">//si l'attribut et &quot;currency&quot; on est en train de lire le code pays, on vérifie aussi que c'est le bon</span>
      <span style="color: #000088;">$rate_found</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$attribute</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'currency'</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$attribute</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$currency</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$j</span><span style="color: #339933;">++;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$i</span><span style="color: #339933;">++;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//si le pays a été trouvé, on affiche le résultat de la conversion</span>
  <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rate_found</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">&quot;le &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$date</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot; &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$value</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot; EUR = &quot;</span><span style="color: #339933;">.</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cube</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">attributes</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$j</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span><span style="color: #339933;">*</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">' '</span><span style="color: #339933;">.</span><span style="color: #000088;">$cube</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">attributes</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$j</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">value</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">&quot;cette devise n'existe pas&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Pour tester :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1137code119'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1137119"><td class="code" id="p1137code119"><pre class="php" style="font-family:monospace;">use_helper<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Converter'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> convertEurToCurrency<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">125</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'USD'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Et voilà !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/tips-conversions-de-devises-1137/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Valider un numéro de TVA intracommunautaire</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/un-validator-tva-bien-pratique-1123</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/un-validator-tva-bien-pratique-1123#comments</comments>
		<pubDate>Mon, 03 May 2010 08:23:01 +0000</pubDate>
		<dc:creator>Nikaw</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[1.3.x]]></category>
		<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[formulaire]]></category>
		<category><![CDATA[TVA]]></category>
		<category><![CDATA[validator]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1123</guid>
		<description><![CDATA[Aujourd&#8217;hui il est courant d&#8217;avoir à développer des sites avec abonnement, mise à disposition de service payant en ligne et autre, à l&#8217;échelle internationale et à des professionnels. Or il se trouve que dans une situation pareille intervient la notion &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/un-validator-tva-bien-pratique-1123">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Aujourd&#8217;hui il est courant d&#8217;avoir à développer des sites avec abonnement, mise à disposition de service payant en ligne et autre, à l&#8217;échelle internationale et à des professionnels.</p>
<p>Or il se trouve que dans une situation pareille intervient la notion de TVA, où la responsabilité du développeur (ou de son employeur) peut être mise en jeu (ainsi que celle du client, mais ça&#8230;).</p>
<p>Lors du paiement, un client professionnel (une société, entreprise, personne morale quoi) devra saisir son numéro de TVA ainsi que son pays pour que le montant de la TVA correspondant soit calculé puisqu&#8217;il change d&#8217;un pays à l&#8217;autre.<br />
Le site http://ec.europa.eu/ propose un webService permettant de vérifier cela.</p>
<p>Moi, je vous propose un validator personnalisé pour valider le numéro de TVA entré dès la validation du formulaire, basé sur ce webService.<br />
<span id="more-1123"></span><br />
Voici l&#8217;adresse du wsdl : <a href="http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl" target="_blank" >http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl</a>.</p>
<h2>Le validator</h2>
<p>Je pars du principe que l&#8217;utilisateur saisit son numéro de TVA et son code pays dans 2 champs différents. Le validator devra alors faire un contrôle en prenant en compte les 2 champs, à l&#8217;instar du validator Doctrine qui vérifie la concordance entre le username et le password au login. Donc il héritera de la classe sfValidatorSchema.</p>
<p>Commençons par voir la méthode __construct :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1123code125'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1123125"><td class="code" id="p1123code125"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$vat_number</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'vat_number'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$country</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'country'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$options</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$messages</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'vat_number'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$vat_number</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'country'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$country</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'throw_global_error'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">messages</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array_merge"><span style="color: #990000;">array_merge</span></a><span style="color: #009900;">&#40;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">messages</span><span style="color: #339933;">,</span>
    <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'invalid_syntax'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'Your VAT Number syntax is not correct. You should have something like this: BE805670816B01'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'invalid_country'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'Your VAT Number is not valid for the selected country.'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'invalid'</span><span style="color: #339933;">=&gt;</span>sprintf<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Invalid VAT Number. Check the validity on the customer VAT Number via &lt;a href=&quot;%s&quot;&gt;Europa VAT Number validation webservice&lt;/a&gt;'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'http://ec.europa.eu/taxation_customs/vies/lang.do?fromWhichPage=vieshome'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$options</span><span style="color: #339933;">,</span> <span style="color: #000088;">$messages</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Ici on définit l&#8217;intitulé par défaut des champs contenant le numéro de TVA (vat_number) et le code du pays (country).<br />
Puis on définit les messages des différentes erreurs pouvant être générées :<br />
- mauvaise syntaxe<br />
- pays qui ne correspond pas<br />
- numéro invalide.</p>
<p>Voyons maintenant le doClean et la méthode appelant le webService :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1123code126'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1123126"><td class="code" id="p1123code126"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> doClean<span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$values</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><a href="http://www.php.net/is_array"><span style="color: #990000;">is_array</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> InvalidArgumentException<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'You must pass an array parameter to the clean() method'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$vatnumber</span>  <span style="color: #339933;">=</span> <a href="http://www.php.net/isset"><span style="color: #990000;">isset</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'vat_number'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'vat_number'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$country</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/isset"><span style="color: #990000;">isset</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'country'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'country'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//on récupère la validité du numéro de TVA via le webService</span>
    <span style="color: #000088;">$valid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">haleValidateVAT</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'vatnumber'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$vatnumber</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'country'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$country</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//si le résultat n'est pas valide, on throw l'erreur correspondante</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$valid</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'result'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorError<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #000088;">$valid</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'error'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'value'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$vatnumber</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'throw_global_error'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">throw</span> <span style="color: #000088;">$error</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">//l'erreur s'applique sur le champ vat_number</span>
      <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorErrorSchema<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'vat_number'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$error</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//si valide, on retourne les valeurs</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$values</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * vérifie la validité du numéro de TVA en prenant en compte le pays donné
   *
   * @param array $args
   * @return array
   */</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> haleValidateVAT<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">''</span> <span style="color: #339933;">!=</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'vatnumber'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">// on sérialize le numéro TVA</span>
      <span style="color: #000088;">$vat_number</span> 	<span style="color: #339933;">=</span> <a href="http://www.php.net/str_replace"><span style="color: #990000;">str_replace</span></a><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">' '</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'.'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'-'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">', '</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'vatnumber'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #666666; font-style: italic;">// on récupère le code pays</span>
      <span style="color: #000088;">$countryCode</span> 	<span style="color: #339933;">=</span> <a href="http://www.php.net/substr"><span style="color: #990000;">substr</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$vat_number</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #666666; font-style: italic;">//on récupère le numéro TVA</span>
      <span style="color: #000088;">$vatNumber</span> 		<span style="color: #339933;">=</span> <a href="http://www.php.net/substr"><span style="color: #990000;">substr</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$vat_number</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">//on vérifie la syntaxe du numéro</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><a href="http://www.php.net/strlen"><span style="color: #990000;">strlen</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$countryCode</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">||</span> <a href="http://www.php.net/is_numeric"><span style="color: #990000;">is_numeric</span></a><span style="color: #009900;">&#40;</span><a href="http://www.php.net/substr"><span style="color: #990000;">substr</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$countryCode</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <a href="http://www.php.net/is_numeric"><span style="color: #990000;">is_numeric</span></a><span style="color: #009900;">&#40;</span><a href="http://www.php.net/substr"><span style="color: #990000;">substr</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$countryCode</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$error</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'result'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'error'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'invalid_syntax'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$error</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">//on vérifie que le pays correspond bien au pays indiqué dans le numéro de TVA</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'country'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> <span style="color: #000088;">$countryCode</span> <span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$error</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'result'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'error'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'invalid_country'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$error</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">//appelle le webservice</span>
      <span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SoapClient<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$params</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'countryCode'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$countryCode</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'vatNumber'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$vatNumber</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">checkVat</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">//vérifie la validité et renvoie l'erreyr correspondante</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #000088;">$result</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">valid</span> <span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$error</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'result'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'error'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'invalid'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$error</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'result'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'result'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'error'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'required'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>Testons</h2>
<p>Pour tester tout simplement, voici un petit formulaire contenant uniquement les champs pays et numéro de TVA :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1123code127'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1123127"><td class="code" id="p1123code127"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> TestVATForm <span style="color: #000000; font-weight: bold;">extends</span> sfForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'vat_number'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormInput<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'country'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormInput<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'vat_number'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'country'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setPostValidator</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> sfValidatorVAT<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setNameFormat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'tva_form[%s]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Voici l&#8217;action :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1123code128'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1123128"><td class="code" id="p1123code128"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> defaultActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeTestTVA<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> TestVATForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isMethod</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'post'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isValid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'notice'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'TVA ok'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'default/testTVA'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'error'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'TVA ko'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Et pour finir, voici la vue (toute bête) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1123code129'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1123129"><td class="code" id="p1123code129"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>form action<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo url_for('default/testTVA') ?&gt;&quot;</span> method<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;post&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>table<span style="color: #339933;">&gt;</span>
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$form</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #339933;">&lt;</span>tr<span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;&lt;/</span>td<span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;</span>input type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;submit&quot;</span> value<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;Tester&quot;</span> <span style="color: #339933;">/&gt;</span>
      <span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;/</span>tr<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;/</span>table<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>form<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Et voilà !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/un-validator-tva-bien-pratique-1123/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Doctrine_Collection et hydration hiérarchisée.</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/doctrine_collection-et-hydration-hierarchisee-1109</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/doctrine_collection-et-hydration-hierarchisee-1109#comments</comments>
		<pubDate>Wed, 07 Apr 2010 07:51:10 +0000</pubDate>
		<dc:creator>yoye</dc:creator>
				<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Doctrine_Collection]]></category>
		<category><![CDATA[Doctrine_Hydrator]]></category>
		<category><![CDATA[helper]]></category>
		<category><![CDATA[nestedset]]></category>
		<category><![CDATA[toHierarchy]]></category>
		<category><![CDATA[treeTable]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1109</guid>
		<description><![CDATA[En ce moment nous sommes en train de travailler sur un site de collectionneurs et nous avons le plaisir de tomber sur quelques cas intéressants au niveau développement ce qui n&#8217;est pas pour nous déplaire. Ce site contient une grosse &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/doctrine_collection-et-hydration-hierarchisee-1109">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>En ce moment nous sommes en train de travailler sur un site de collectionneurs et nous avons le plaisir de tomber sur quelques cas intéressants au niveau développement ce qui n&#8217;est pas pour nous déplaire. Ce site contient une grosse partie sur la gestion des zones géographiques, on a décidé d&#8217;utiliser le behavior Nestedset ce qui nous permet de gérer facilement les différentes arborescences : &laquo;&nbsp;Continent > Pays > état&nbsp;&raquo; ou &laquo;&nbsp;Continent > Pays > Région&nbsp;&raquo; ou encore &laquo;&nbsp;Continent > Pays / Ancien Pays&nbsp;&raquo;.<br />
<span id="more-1109"></span><br />
Je ne vais pas faire un point sur le nested, la <a href="http://www.lexik.fr/blog/symfony/symfony/nested-set-doctrine-135">gestion par arborescence</a> a déjà été abordée sur ce blog. En revanche je vais vous faire part d&#8217;une découverte récente. La possibilité d&#8217;hydrater directement une collection sous sa forme d&#8217;arbre.</p>
<p>Pour le listing de ces zones j&#8217;ai donc choisi d&#8217;utiliser un plugin jQuery : <a href="http://blog.cubicphuse.nl/2008/11/12/jquery-treetable-2-0">treeTable</a>. Comme son nom l&#8217;indique ce plugin va nous permettre une organisation d&#8217;un arbre dans une table HTML. Il faut indiquer en &laquo;&nbsp;id&nbsp;&raquo; de la balise<br />
<tr> de notre tableau un identifiant de notre objet (ex: id=&nbsp;&raquo;node-1&#8243;) et à l&#8217;attribut &laquo;&nbsp;class&nbsp;&raquo; on signale de qui le noeud est l&#8217;enfant (ex: child-of-node-1 sera le fils du noeud 1).</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1109code134'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1109134"><td class="code" id="p1109code134"><pre class="php" style="font-family:monospace;">  <span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;content-box-content&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>table id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;tree&quot;</span><span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;</span>tbody<span style="color: #339933;">&gt;</span>
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$areas</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$area</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #000088;">$parent</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParent</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
        <span style="color: #339933;">&lt;</span>tr id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;node-&lt;?php echo <span style="color: #006699; font-weight: bold;">$area-&gt;getId</span>() ?&gt;&quot;</span> <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$parent</span> ? <span style="color: #0000ff;">'class=&quot;child-of-node-'</span><span style="color: #339933;">.</span><span style="color: #000088;">$parent</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;'</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&gt;</span>
          <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;</span>
          <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;</span>
            <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> link_to<span style="color: #009900;">&#40;</span>__<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'module_area_list_action_add_children'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'area_new'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'query_string'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'parent_id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          <span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;</span>
          <span style="color: #339933;">&lt;</span>td<span style="color: #339933;">&gt;</span>
            <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> link_to<span style="color: #009900;">&#40;</span>__<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'text_action_delete'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'@area_delete?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'method'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'delete'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'confirm'</span> <span style="color: #339933;">=&gt;</span> __<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'text_action_delete_confirm'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          <span style="color: #339933;">&lt;/</span>td<span style="color: #339933;">&gt;</span>
        <span style="color: #339933;">&lt;/</span>tr<span style="color: #339933;">&gt;</span>
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
      <span style="color: #339933;">&lt;/</span>tbody<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;/</span>table<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Voici le résultat : </p>
<p><img src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2010/04/treeTableArea1.png" alt="treeTableArea" title="treeTableArea" width="975" height="528" class="alignnone size-full wp-image-1115" /></p>
<p>Le rendu correspond à ce que souhaite mon client, lorsque l&#8217;on clique sur une branche, par exemple Afrique ou Europe les lignes suivantes se déplient et laissent apparaitre les enfants. Tout va pour le mieux dans le meilleur des mondes, simplement quand on regarde de plus près on s&#8217;aperçoit que pour un listing de simplement 12 zones je fais 29 requêtes, que va t&#8217;il se passer lorsque je vais avoir toutes mes zones renseignées, la réponse est : +700 requêtes. Le souci vient de la méthode <a href="http://www.doctrine-project.org/Doctrine_Node_NestedSet/1_2#method_getparent">getNode()->getParent()</a> qui exécute une nouvelle requête à chaque appel. En effet pour lier une ligne à son parent j&#8217;ai besoin de connaître l&#8217;ID du père.</p>
<p>Pour remédier à cela je vais donc utiliser l&#8217;Hydratation hiérarchisée, que l&#8217;on peut créer à l&#8217;aide d&#8217;une Doctrine_Query qu&#8217;on exécutera comme suit :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1109code135'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1109135"><td class="code" id="p1109code135"><pre class="php" style="font-family:monospace;">Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Area'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span>
   <span style="color: #004000;">createQuery</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'a'</span><span style="color: #009900;">&#41;</span>
  execute<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">HYDRATE_RECORD_HIERARCHY</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Sinon on peut directement utiliser la méthode toHierarchy() sur notre collection, qui nous hydratera directement cette dernière. Chaque élément contenant alors des enfants aura une clé __children, qui n&#8217;est autre qu&#8217;un tableau des éléments enfants.</p>
<p>Je vais donc remplacer mon code et utiliser un helper pour le rendu d&#8217;une ligne ce qui permettra de faire de la récursivité plus facilement dans mon code.</p>
<p>Je crée donc l&#8217;helper suivant :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1109code136'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1109136"><td class="code" id="p1109code136"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// apps/backend/lib/helper/AreaHierarchyHelper.php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Permet l'affichage en arbre dans le listing des zones
 *
 * @param Area $area
 * @param int $parent
 * @return string
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> render_row<span style="color: #009900;">&#40;</span><span style="color: #000088;">$area</span><span style="color: #339933;">,</span> <span style="color: #000088;">$parent</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Formatage du HTML</span>
  <span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/sprintf"><span style="color: #990000;">sprintf</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'
&lt;tr id=&quot;node-%s&quot;%s&gt;
  &lt;td&gt;%s&lt;/td&gt;
  &lt;td&gt;%s&lt;/td&gt;
  &lt;td&gt;%s&lt;/td&gt;
  &lt;td&gt;%s&lt;/td&gt;
  &lt;td&gt;%s&lt;/td&gt;
&lt;/tr&gt;'</span><span style="color: #339933;">,</span>
      <span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$parent</span> ? <span style="color: #0000ff;">''</span> <span style="color: #339933;">:</span> <a href="http://www.php.net/sprintf"><span style="color: #990000;">sprintf</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">' class=&quot;child-of-node-%s&quot;'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$parent</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'ID : '</span><span style="color: #339933;">.</span><span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      link_to<span style="color: #009900;">&#40;</span>__<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'module_area_list_action_add_children'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'area_new'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'query_string'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'parent_id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      link_to<span style="color: #009900;">&#40;</span>__<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'text_action_edit'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'area_edit'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$area</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'class'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'area-edit'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      link_to<span style="color: #009900;">&#40;</span>__<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'text_action_delete'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'@area_delete?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'method'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'delete'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'confirm'</span> <span style="color: #339933;">=&gt;</span> __<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'text_action_delete_confirm'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Récursivité pour créer les lignes des fils</span>
  <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'__children'</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$child</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$html</span> <span style="color: #339933;">.=</span> render_row<span style="color: #009900;">&#40;</span><span style="color: #000088;">$child</span><span style="color: #339933;">,</span> <span style="color: #000088;">$area</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #000088;">$html</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Désormais sur ma page, il me suffit de charger mon helper et d&#8217;écrire le code suivant :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1109code137'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1109137"><td class="code" id="p1109code137"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> use_helper<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'AreaHierarchy'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;content-box&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;content-box-header&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;content-box-content&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>table id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;tree&quot;</span><span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;</span>tbody<span style="color: #339933;">&gt;</span>
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$areas</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toHierarchy</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$area</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> render_row<span style="color: #009900;">&#40;</span><span style="color: #000088;">$area</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
      <span style="color: #339933;">&lt;/</span>tbody<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;/</span>table<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Le résultat est exactement le même au niveau de l&#8217;affichage en revanche je passe désormais à 5 requêtes et sur les données définitives,  j&#8217;obtiens toujours 5 requêtes et ce quelque soit le nombre de résultat dans ma collection. J&#8217;ai donc bénéficié des avantages de Doctrine et surtout des Doctrine_Hydrator pour diminuer le nombre de requêtes. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/doctrine_collection-et-hydration-hierarchisee-1109/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Retour sur le plugin Commentaires, partie administration</title>
		<link>http://www.lexik.fr/blog/symfony/non-classe/retour-sur-le-plugin-commentaires-partie-administration-1087</link>
		<comments>http://www.lexik.fr/blog/symfony/non-classe/retour-sur-le-plugin-commentaires-partie-administration-1087#comments</comments>
		<pubDate>Wed, 31 Mar 2010 08:39:13 +0000</pubDate>
		<dc:creator>Nikaw</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[1.3.x]]></category>
		<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[Admingenerator 1.2.x]]></category>
		<category><![CDATA[Admingenerator 1.3.x]]></category>
		<category><![CDATA[Admingenerator 1.4.x]]></category>
		<category><![CDATA[Non classé]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[commentable]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1087</guid>
		<description><![CDATA[J&#8217;espère que vous vous souvenez du post concernant le plugin / behavior sfLexikDoctrineActAsCommentablePlugin. Je vous avais promis une deuxième partie sur l&#8217;administration des commentaires, et bien après quelques mois d&#8217;absence me revoilà pour tenir ma promesse. Tout d&#8217;abord un peu &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/non-classe/retour-sur-le-plugin-commentaires-partie-administration-1087">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>J&#8217;espère que vous vous souvenez du <a href="http://www.lexik.fr/blog/symfony/symfony/sflexikdoctrineactascommentableplugin-ou-comment-rendre-des-objets-commentables-via-un-behavior-plugin-1002">post concernant le plugin / behavior sfLexikDoctrineActAsCommentablePlugin</a>.<br />
Je vous avais promis une deuxième partie sur l&#8217;administration des commentaires, et bien après quelques mois d&#8217;absence me revoilà pour tenir ma promesse.<br />
<span id="more-1087"></span><br />
Tout d&#8217;abord un peu de configuration, puis nous verront quelles sont l&#8217;utilité et la problématique principales de cette partie.<br />
Nous verrons l&#8217;administration des commentaires dans leur ensemble, puis la gestion des commentaires depuis l&#8217;objet porteur.</p>
<p><strong><em>Configuration</em></strong><br />
Tout d&#8217;abord il ne faut pas oublier de charger le module dans les settings.<br />
apps/backend/config/settings.yml :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code152'); return false;">View Code</a> YAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087152"><td class="code" id="p1087code152"><pre class="yaml" style="font-family:monospace;">all:
  .settings:
    enabled_modules: [..., comment]</pre></td></tr></table></div>

<p><strong><em>Problématique</em></strong></p>
<p>On veut ici pouvoir gérer facilement et rapidement les commentaires déposés par les utilisateurs.<br />
Une des problématiques sera donc la façon de lister les commentaires sur l&#8217;index.<br />
J&#8217;ai choisi par défaut de regrouper les commentaires par type d&#8217;objet, puis par objet, puis par date de modification.</p>
<p>Exemple : je liste tous les commentaires déposé sur les objets Message, je les regroupe par message, et je les classe par date de modification (la plupart du temps, un commentaire ne pouvant être modifié, on aura une concordance entre la date d&#8217;ajout et la date de modification).</p>
<p>Pour ceci, je spécifie dans le fichier de génération la méthode utilisée pour récupérer les commentaires :<br />
plugins/sfLexikDoctrineActAsCommentablePlugin/module/comment/config/generator.yml :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code153'); return false;">View Code</a> YAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087153"><td class="code" id="p1087code153"><pre class="yaml" style="font-family:monospace;">generator:
  config:
    list:
      table_method: retrieveBackendCommentList</pre></td></tr></table></div>

<p>La méthode en question :<br />
plugins/sfLexikDoctrineActAsCommentablePlugin/lib/model/doctrine/PluginCommentTable.class.php :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code154'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087154"><td class="code" id="p1087code154"><pre class="php" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> retrieveBackendCommentList<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">createQuery</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'c'</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">orderBy</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'c.parent_class_name ASC'</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">addOrderBy</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'c.parent_id ASC'</span><span style="color: #009900;">&#41;</span>
            <span style="color: #339933;">-&gt;</span><span style="color: #004000;">addOrderBy</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'c.updated_at DESC'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$query</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Nous allons maintenant nous pencher sur les différents traitements que je propose.<br />
Il s&#8217;agit ici de publier / censurer, marquer comme spam / non spam, nettoyer les spams, et bien sûr supprimer des commentaires.</p>
<p>Tout d&#8217;abord je vous donne la configuration que j&#8217;ai choisie pour l&#8217;index, évidemment vous pouvez choisir de la changer, elle représente mes préférences rapportées au projet pour lequel j&#8217;ai créé ce plugin.<br />
plugins/sfLexikDoctrineActAsCommentablePlugin/module/comment/config/generator.yml :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code155'); return false;">View Code</a> YAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087155"><td class="code" id="p1087code155"><pre class="yaml" style="font-family:monospace;">generator:
  class: sfDoctrineGenerator
  param:
    model_class:           Comment
    theme:                 admin
    non_verbose_templates: true
    with_show:             false
    singular:              ~
    plural:                ~
    route_prefix:          comment
    with_doctrine_route:     1
&nbsp;
    config:
      actions: ~
      fields:
      list:
        table_method: retrieveBackendCommentList
        display: [author_name, author_mail, text, is_published, is_spam]
        fields:
          author_name: {label: 'Nom auteur'}
        actions:
          _delete: ~
          CleanSpam: {label: 'Nettoyer les spams'}
        object_actions:
          Publish: {label: 'Publier'}
          UnPublish: {label: 'Censurer'}
          MakeSpam: {label: 'Spam !'}
          UnmakeSpam: {label: 'Pas spam'}
          _delete: ~
        batch_actions:
          _delete: ~
          Publish: {label: 'Publier'}
          UnPublish: {label: 'Censurer'}
          MakeSpam: {label: 'Marquer comme spams'}
          UnmakeSpam: {label: 'Retirer des spams'}
      filter: ~
      form: ~
      edit: ~
      new:     ~</pre></td></tr></table></div>

<p>Laissez moi maintenant vous décrire rapidement chaque méthode :<br />
<strong>Publish: {label: &#8216;Publier&#8217;}</strong><br />
permet d&#8217;afficher un commentaire</p>
<p><strong>UnPublish: {label: &#8216;Censurer&#8217;}</strong><br />
permet de censurer un commentaire, c&#8217;est à dire de bloquer sa publication</p>
<p><strong>MakeSpam: {label: &#8216;Spam !&#8217;}</strong><br />
permet de marquer un commentaire en tant que spam</p>
<p><strong>UnmakeSpam: {label: &#8216;Pas spam&#8217;}</strong><br />
permet de marquer un commentaire en tant que non spam</p>
<p>Ces méthodes dans la &laquo;&nbsp;list&nbsp;&raquo; s&#8217;appliquent sur un seul commentaire, et dans le &laquo;&nbsp;batch&nbsp;&raquo; sur un groupe de commentaires sélectionnés.</p>
<p>La méthode <strong>CleanSpam: {label: &#8216;Nettoyer les spams&#8217;}</strong> quant à elle permet de supprimer d&#8217;un coup tous les commentaires notifiés comme étant des spams.</p>
<p>Voici le code des méthodes ci-dessus :<br />
plugins/sfLexikDoctrineActAsCommentablePlugin/modules/comment/actions/actions.class.php :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code156'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087156"><td class="code" id="p1087code156"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeListCleanSpam<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$nb</span> <span style="color: #339933;">=</span> Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">cleanSpam</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$nb</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'notice'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/sprintf"><span style="color: #990000;">sprintf</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'%d spam'</span><span style="color: #339933;">.</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nb</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span> ? <span style="color: #0000ff;">'s'</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">' supprimé'</span><span style="color: #339933;">.</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nb</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span> ? <span style="color: #0000ff;">'s'</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$nb</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'notice'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Pas de spams.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeListPublish<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$page</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsPublished</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@comment?page='</span><span style="color: #339933;">.</span><span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeListUnPublish<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$page</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsPublished</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@comment?page='</span><span style="color: #339933;">.</span><span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeListMakeSpam<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$page</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsSpam</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@comment?page='</span><span style="color: #339933;">.</span><span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeListUnmakeSpam<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$page</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsSpam</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@comment?page='</span><span style="color: #339933;">.</span><span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeBatchPublish<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$page</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$ids</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ids'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ids</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsPublished</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@comment?page='</span><span style="color: #339933;">.</span><span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeBatchUnPublish<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$page</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$ids</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ids'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ids</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsPublished</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@comment?page='</span><span style="color: #339933;">.</span><span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeBatchMakeSpam<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$page</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$ids</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ids'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ids</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsSpam</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@comment?page='</span><span style="color: #339933;">.</span><span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeBatchUnmakeSpam<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$page</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$ids</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ids'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ids</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsSpam</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@comment?page='</span><span style="color: #339933;">.</span><span style="color: #000088;">$page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>et la méthode cleanSpam() dans le modèle :<br />
plugins/sfLexikDoctrineActAsCommentablePlugin/lib/model/doctrine/PluginCommentTable.class.php :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code157'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087157"><td class="code" id="p1087code157"><pre class="php" style="font-family:monospace;">  <span style="color: #009933; font-style: italic;">/**
   * supprime tous les commentaires classifiés comme spam et retourne le nombre d'enregistrements supprimés
   *
   * @return int
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> cleanSpam<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$q</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">createQuery</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'c'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">where</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'c.is_spam = ?'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Je n&#8217;ai pas touché au filtre, mais chacun peut décider que tel ou tel champ sera utile ou pas, ça dépendra très souvent du projet.</p>
<p>Donc voilà pour la première étape. Jusque là on peut afficher et traiter les commentaires un par un ou par lots, directement depuis leur index.</p>
<p>Voyons maintenant comment ajouter la gestion des commentaires depuis les objets porteurs.<br />
Attention, cette partie est une nouveauté par rapport au premier post, voici les nouvelles sources : plugin.</p>
<p>Tout d&#8217;abord il faut ajouter dans l&#8217;édition de l&#8217;objet porteur le partial qui permettra de gérer les commentaires.<br />
Pour éviter de devoir dupliquer le même template pour chaque type d&#8217;objet, on va créer un partial dans le module comment du plugin puis l&#8217;appeler dans le partial de l&#8217;objet porteur :<br />
/home/lexik/sfprojects/kelsms/plugins/sfLexikDoctrineActAsCommentablePlugin/modules/comment/templates/_backend_comments_list.php :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code158'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087158"><td class="code" id="p1087code158"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;container_16&quot;</span><span style="color: #339933;">&gt;</span>
  Commentaires <span style="color: #339933;">:</span>
<span style="color: #339933;">&lt;</span>ul <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;order&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
	<span style="color: #339933;">&lt;</span>li id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo <span style="color: #006699; font-weight: bold;">$comment-&gt;getId</span>() ?&gt;&quot;</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;row_&lt;?php echo <span style="color: #006699; font-weight: bold;">$key</span>%2 ?&gt;&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>div id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;show_&lt;?php echo <span style="color: #006699; font-weight: bold;">$comment-&gt;getId</span>() ?&gt;&quot;</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;grid_10&quot;</span><span style="color: #339933;">&gt;</span>
          <span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;grid_4&quot;</span><span style="color: #339933;">&gt;</span>
          <span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;&lt;/</span>li<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>ul<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;&lt;!--</span>mce<span style="color: #339933;">:</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">--&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Il sera appelé de la manière suivant dans le partial de notre objet, par exemple ici un Message, grâce à la configuration du generator.yml :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code159'); return false;">View Code</a> YAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087159"><td class="code" id="p1087code159"><pre class="yaml" style="font-family:monospace;">generator:
  config:
      edit:
        display: [..., _handle_comments]</pre></td></tr></table></div>

<p>apps/backend/modules/message/template/_handle_comments.php :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code160'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087160"><td class="code" id="p1087code160"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">findComments</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Bref.<br />
Dans le partial _backend_comments_list.php on remarque 3 choses :<br />
1) l&#8217;appel du partial backend_show<br />
2) l&#8217;appel du partial backend_comment_actions<br />
3) les fonctions javascript</p>
<p>1) le partial backend_show affiche tout simplement le contenu du commentaire :<br />
_backend_show.php</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code161'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087161"><td class="code" id="p1087code161"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;show_comment_class&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;infos_class&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;author_name_class&quot;</span><span style="color: #339933;">&gt;</span>
      getAuthorName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #339933;">&lt;/</span>span<span style="color: #339933;">&gt;</span>
&nbsp;
    <span style="color: #339933;">&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;time_and_date_class&quot;</span><span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">-</span> le <span style="color: #339933;">&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;date_class&quot;</span><span style="color: #339933;">&gt;</span>getCreatedAt<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'d/MM/yyyy'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'fr'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>span<span style="color: #339933;">&gt;</span>
      à <span style="color: #339933;">&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;time_class&quot;</span><span style="color: #339933;">&gt;</span>getCreatedAt<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'hh:mm'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'fr'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>span<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;/</span>span<span style="color: #339933;">&gt;&lt;/</span>div<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>hr <span style="color: #339933;">/&gt;</span>
<span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;text_class&quot;</span><span style="color: #339933;">&gt;</span>
    <a href="http://www.php.net/gettext"><span style="color: #990000;">getText</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>2) le partial _backend_comment_actions.php contient les actions pouvant être effectuées sur un commentaire :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code162'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087162"><td class="code" id="p1087code162"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>a onclick<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;publishComment(&lt;?php echo <span style="color: #006699; font-weight: bold;">$comment-&gt;getId</span>()?&gt;)&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;#&quot;</span><span style="color: #339933;">&gt;</span>publier<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span> <span style="color: #339933;">|</span>
<span style="color: #339933;">&lt;</span>a onclick<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;unPublishComment(&lt;?php echo <span style="color: #006699; font-weight: bold;">$comment-&gt;getId</span>()?&gt;)&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;#&quot;</span><span style="color: #339933;">&gt;</span>censurer<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span> <span style="color: #339933;">|</span>
<span style="color: #339933;">&lt;</span>a onclick<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;makeSpamComment(&lt;?php echo <span style="color: #006699; font-weight: bold;">$comment-&gt;getId</span>()?&gt;)&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;#&quot;</span><span style="color: #339933;">&gt;</span>spam<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span> <span style="color: #339933;">|</span>
<span style="color: #339933;">&lt;</span>a onclick<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;unMakeSpamComment(&lt;?php echo <span style="color: #006699; font-weight: bold;">$comment-&gt;getId</span>()?&gt;)&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;#&quot;</span><span style="color: #339933;">&gt;</span>pas spam<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span> <span style="color: #339933;">|</span>
<span style="color: #339933;">&lt;</span>a onclick<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;deleteComment(&lt;?php echo <span style="color: #006699; font-weight: bold;">$comment-&gt;getId</span>()?&gt;)&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;#&quot;</span><span style="color: #339933;">&gt;</span>supprimer<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span> <span style="color: #339933;">|</span>
<span style="color: #339933;">&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo url_for('@comment_edit?id='.<span style="color: #006699; font-weight: bold;">$comment-&gt;getId</span>()) ?&gt;&quot;</span><span style="color: #339933;">&gt;</span>editer<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>3) les fonctions javascript : elles permettent d&#8217;appeler respectivement les méthodes permettant d&#8217;effectuer les actions correspondante, tout ça en AJAX.</p>
<p>Ces différentes actions vont effectuer le même travail que les ListAction, à la différence près qu&#8217;elle sont appelée en Ajax, et n&#8217;ont donc pas le même template de retour.</p>
<p>Voilà d&#8217;abord le routing, puis les actions :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code163'); return false;">View Code</a> YAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087163"><td class="code" id="p1087code163"><pre class="yaml" style="font-family:monospace;">comment_ajax_publish:
  url:   /comment_ajax_publish
  params: {module: comment, action: ajaxPublish}
comment_ajax_unpublish:
  url:   /comment_ajax_unpublish
  params: {module: comment, action: ajaxUnPublish}
comment_ajax_makespam:
  url:   /comment_ajax_markspam
  params: {module: comment, action: ajaxMakeSpam}
comment_ajax_unmakespam:
  url:   /comment_ajax_unmarkspam
  params: {module: comment, action: ajaxUnMakeSpam}
comment_ajax_delete:
  url:   /comment_ajax_delete
  params: {module: comment, action: ajaxDelete}</pre></td></tr></table></div>

<p>actions :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code164'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087164"><td class="code" id="p1087code164"><pre class="php" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeAjaxPublish<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">publish</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setTemplate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ajaxAction'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeAjaxUnPublish<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">unpublish</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setTemplate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ajaxAction'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeAjaxMakeSpam<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">makespam</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setTemplate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ajaxAction'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeAjaxUnMakeSpam<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">unmakespam</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setTemplate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ajaxAction'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeAjaxDelete<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span> <span style="color: #339933;">=</span> Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> publish<span style="color: #009900;">&#40;</span><span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsPublished</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> unpublish<span style="color: #009900;">&#40;</span><span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsPublished</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> makespam<span style="color: #009900;">&#40;</span><span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsSpam</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> unmakespam<span style="color: #009900;">&#40;</span><span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setIsSpam</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><em>On remarque une certaine redondance de code dans le actions.class.php,c&#8217;est pour ça que j&#8217;ai factorisé. Pensez à corriger les autres actions (elles sont ok si vous récupérez les sources).</em></p>
<p>Et pour finir, dans les templates correspondant à ces actions, on reload la ligne du commentaire en cours, ce qui permettra de mette à jour ses état de publication et spam dans la liste des commentaires.</p>
<p>ajaxActionSuccess.php :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1087code165'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1087165"><td class="code" id="p1087code165"><pre class="php" style="font-family:monospace;">include_partial<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'comment/backend_show'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'comment'</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>Voilà, si vous avez des questions ou des incompréhensions, n&#8217;hésitez pas !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/non-classe/retour-sur-le-plugin-commentaires-partie-administration-1087/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Utilisation de sfUser et de ses &#171;&#160;namespace&#160;&#187;(s)</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-sfuser-et-de-ses-namespaces-1053</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-sfuser-et-de-ses-namespaces-1053#comments</comments>
		<pubDate>Mon, 08 Feb 2010 15:06:29 +0000</pubDate>
		<dc:creator>yoye</dc:creator>
				<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[méthode magique]]></category>
		<category><![CDATA[sfUser]]></category>
		<category><![CDATA[__call]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1053</guid>
		<description><![CDATA[Récemment j&#8217;ai du développer un outil permettant de créer des tournois, cet outil a la particularité d&#8217;être accessible par les personnes connectés ou non. Je devais conserver d&#8217;une page à l&#8217;autre les informations saisies par mon utilisateur, pour quelqu&#8217;un de &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/utilisation-de-sfuser-et-de-ses-namespaces-1053">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Récemment j&#8217;ai du développer un outil permettant de créer des tournois, cet outil a la particularité d&#8217;être accessible par les personnes connectés ou non. Je devais conserver d&#8217;une page à l&#8217;autre les informations saisies par mon utilisateur, pour quelqu&#8217;un de connecté on peut toujours passer par la base de donnée mais pour les autres on doit jouer avec la classe sfUser.<br />
<span id="more-1053"></span><br />
Le scénario est le suivant :<br />
- Etape 1 : je saisis des informations dans un formulaire<br />
- Etape 2 : je saisis de nouvelles informations en fonction des précédentes</p>
<p>En réalité il y a bien plus d&#8217;étapes que cela mais ce scénario me permet de poser les bases de mon article. </p>
<p>Pour rester dans la simplicité voici le schéma que nous allons utiliser :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1053code170'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1053170"><td class="code" id="p1053code170"><pre class="yml" style="font-family:monospace;">ModelA:
  columns:
    id:         { type: integer(4), autoincrement: true, unsigned: true, primary: true }
    title:      { type: string(255), notnull: true }
    body:       { type: clob, notnull: true }
&nbsp;
ModelB:
  columns:
    id:         { type: integer(4), autoincrement: true, unsigned: true, primary: true }
    title:      { type: string(255), notnull: true }
    body:       { type: clob, notnull: true }</pre></td></tr></table></div>

<p>Tout d&#8217;abord j&#8217;ai un formulaire lié à un modèle, je dois conserver cet objet dans ma session pour me permettre d&#8217;y accéder lors des étapes suivantes. Voilà comment j&#8217;ai procédé au niveau de ma class myUser :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1053code171'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1053171"><td class="code" id="p1053code171"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> myUser <span style="color: #000000; font-weight: bold;">extends</span> sfBasicSecurityUser
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">const</span>
  MY_NAMESPACE <span style="color: #339933;">=</span> <span style="color: #0000ff;">'mynamespace'</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * __call
   *
   * @param string $method
   * @param Array $arguments
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __call<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$arguments</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">case</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'set'</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$prefix</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/substr"><span style="color: #990000;">substr</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
          <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">isValidModelClass</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/substr"><span style="color: #990000;">substr</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_set<span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #339933;">,</span> <span style="color: #000088;">$arguments</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">case</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'getInstance'</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$prefix</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/substr"><span style="color: #990000;">substr</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">11</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
          <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">isValidModelClass</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/substr"><span style="color: #990000;">substr</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">11</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getModelInstance</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">default</span><span style="color: #339933;">:</span>
        <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span>__call<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$arguments</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * Model storage
   *
   * @param string $class
   * @param Doctrine_Record $argument
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> _set<span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #339933;">,</span> <span style="color: #000088;">$argument</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$argument</span> instanceof <span style="color: #000088;">$class</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><a href="http://www.php.net/sprintf"><span style="color: #990000;">sprintf</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'You must specify a valid %s'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$class</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #339933;">,</span> <span style="color: #000088;">$argument</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">MY_NAMESPACE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * Return model
   *
   * @param string $modelName
   * @return Doctrine_Record
   */</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> getModelInstance<span style="color: #009900;">&#40;</span><span style="color: #000088;">$modelName</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$modelName</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">MY_NAMESPACE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Ayant surchargé ma méthode __call(), je peux désormais appeler les méthodes suivantes :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1053code172'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1053172"><td class="code" id="p1053code172"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setModelA</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> ModelA<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getInstanceModelA</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Pour être sûr de ne passer que des objets définis au niveau de mon schéma j&#8217;utilise la méthode &laquo;&nbsp;Doctrine_Core::isValidModelClass&nbsp;&raquo;, ce code me permet également de ne conserver qu&#8217;une seule fois un objet au niveau de mon objet myUser. De plus, je regroupe toutes ces données dans un &laquo;&nbsp;namespace&nbsp;&raquo; ce qui me permettra de les effacer très simplement par exemple si mon utilisateur souhaite retourner sur la première étape.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1053code173'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1053173"><td class="code" id="p1053code173"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// apps/MON_APPS/modules/MON_MODULE/actions/action.class.php</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeStep1<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">cleanMyNameSpace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// apps/MON_APPS/lin/myUser.class.php</span>
  <span style="color: #009933; font-style: italic;">/**
   * Clean Mynamespace
   *
   * @param $exception Valeur à ne pas enlever
   * @return void
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> cleanMyNameSpace<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttributeHolder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">removeNamespace</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">MY_NAMESPACE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Ce code m&#8217;a permis de conserver une flexibilité lorsque je passe d&#8217;une étape à l&#8217;autre, en effet, j&#8217;aurai pu choisir de passer simplement les attributs que je souhaite conserver.  Depuis la mise en production les paramètres nécessaires d&#8217;une étape à l&#8217;autre ont changé en conservant un objet entier je n&#8217;ai pas eu à m&#8217;en soucier, de plus je ne suis pas obligé de stocker ces objets en base de donnée.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-sfuser-et-de-ses-namespaces-1053/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tips : Symfony 1.3/1.4 orderBy des relations</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/tips-symfony-1-31-4-orderby-des-relations-1026</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/tips-symfony-1-31-4-orderby-des-relations-1026#comments</comments>
		<pubDate>Thu, 14 Jan 2010 13:11:27 +0000</pubDate>
		<dc:creator>Samuel Breton</dc:creator>
				<category><![CDATA[1.3.x]]></category>
		<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[orderBy]]></category>
		<category><![CDATA[relation]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1026</guid>
		<description><![CDATA[Depuis la branche 1.3/1.4 la gestion des relations a été bien enrichie. Au niveau des formulaire l'apparition du EmbedRelation a vraiment facilité l'implémentation des embedForm. Petit problème, l'ordre de retour de la Doctrine_Collection ...<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/tips-symfony-1-31-4-orderby-des-relations-1026">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Depuis la branche 1.3/1.4 la gestion des relations a été bien enrichie.</p>
<p>Au niveau des formulaire l&#8217;apparition du EmbedRelation a vraiment facilité l&#8217;implémentation des embedForm. Je ne vais pas reprendre l&#8217;explication de cette fonctionnalité dans cet article et vous renvoie donc vers le très bon article de NiKo <a href="http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine" target="_blank">sur son blog</a> (En anglais).</p>
<p>Petit problème, l&#8217;ordre de tri de la Doctrine_Collection retrounée qui est &#8230;<span id="more-1026"></span> en vrac ^^ J&#8217;en ai fait l&#8217;expérience sur une base postGre ou l&#8217;ordre de retour est en fonction de la dernière modification alors que sur une base mySql c&#8217;est l&#8217;ordre des IDs (déjà moins gênant). Dans les 2 cas ça n&#8217;est pas très satisfaisant, et on aimerais pouvoir maitriser l&#8217;ordre de tri de cette relation.</p>
<p>Un bout de schema.yml pour pouvoir illustrer mon explication  :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1026code174'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1026174"><td class="code" id="p1026code174"><pre class="yml" style="font-family:monospace;">...
Produit:
  columns:
    id:                 { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    name:               { type: string(128), notnull: true }
&nbsp;
Photo:
  columns:
    id:                 { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    file_name:          { type: string(128), notnull: true }
    id_produit:         { type: integer(4), unsigned: true }
    ordre:              { type: integer(4), unsigned: true }
  relations:
    Produit:
      local:            id_produit
      foreign:          id
      foreignAlias:     Photos
      onDelete:         CASCADE
...</pre></td></tr></table></div>

<p>Dans ce contexte on peut imaginer faire un EmbedRelation des Photos dans la classe ProduitForm.</p>
<p>Le fonctionnement du EmbedRelation est qu&#8217;il utilise l&#8217;accesseur magique getPhotos() qui elle même fait un findByIdProduit() dans la classe PhotoTable et retourne une Doctrine_Collection d&#8217;objects Photo. Seul problème comme je l&#8217;ai dit plus haut, c&#8217;est que la requête n&#8217;est pas trié.</p>
<p>Vous allez me dire &laquo;&nbsp;c&#8217;est facile, il n&#8217;y a qu&#8217;à surcharger getPhotos() de Produit.class.php&nbsp;&raquo;. C&#8217;est ce que j&#8217;avais fait au début, et ça marche. Seul problème, c&#8217;est que lorsque l&#8217;on redéfini un accesseur magique (ici le getteur) l&#8217;autre (le setteur) ne fonctionne plus&#8230; est ce que c&#8217;est voulu ou est ce que c&#8217;est un bug? Je n&#8217;en sais rien ^^ Toujours est-il que je me servais du setteur et donc cette solution ne m&#8217;a pas convenu et j&#8217;ai cherché une alternative.</p>
<p>L&#8217;alternative est prévue par Doctrine qui depuis la 1.2 qui implémente la possibilité de spécifier le orderBy sur une relation directement lors de sa définition dans le schema.yml. Seul problème le foreinOrderBy n&#8217;existe pas et donc la définition de la relation ne peut plus se faire comme je l&#8217;avais écrite plus haut, il faut la définir des deux cotés.</p>
<p>Tréve de blabla, ca ressemble à quelque chose comme ca :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1026code175'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1026175"><td class="code" id="p1026code175"><pre class="yml" style="font-family:monospace;">...
Produit:
  columns:
    id:                 { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    name:               { type: string(128), notnull: true }
  relations:
    Photos:
      type:             many
      class:            Photo
      local:            id
      foreign:          id_produit
      orderBy:          ordre ASC
      onDelete:         CASCADE
&nbsp;
Photo:
  columns:
    id:                 { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    file_name:          { type: string(128), notnull: true }
    id_produit:         { type: integer(4), unsigned: true }
    ordre:              { type: integer(4), unsigned: true }
  relations:
    Produit:
      local:            id_produit
      foreign:          id
      onDelete:         CASCADE
...</pre></td></tr></table></div>

<p>J&#8217;espère que cette petite astuce vous aidera.<br />
@bientôt</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/tips-symfony-1-31-4-orderby-des-relations-1026/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>sfLexikDoctrineActAsCommentablePlugin ou comment rendre des objets commentables via un behavior / plugin</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/sflexikdoctrineactascommentableplugin-ou-comment-rendre-des-objets-commentables-via-un-behavior-plugin-1002</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/sflexikdoctrineactascommentableplugin-ou-comment-rendre-des-objets-commentables-via-un-behavior-plugin-1002#comments</comments>
		<pubDate>Mon, 09 Nov 2009 10:39:52 +0000</pubDate>
		<dc:creator>Nikaw</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[behavior]]></category>
		<category><![CDATA[commentable]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=1002</guid>
		<description><![CDATA[Aujourd&#8217;hui je vais vous montrer comment rendre des objets commentables grâce à un behavior Doctrine que j&#8217;ai créé, et le plugin qui permet de l&#8217;exploiter. Le behavior donne les fonctionnalités, le plugin donne le modèle et l&#8217;affichage ainsi que les &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/sflexikdoctrineactascommentableplugin-ou-comment-rendre-des-objets-commentables-via-un-behavior-plugin-1002">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Aujourd&#8217;hui je vais vous montrer comment rendre des objets commentables grâce à un behavior Doctrine que j&#8217;ai créé, et le plugin qui permet de l&#8217;exploiter.</p>
<p>Le behavior donne les fonctionnalités, le plugin donne le modèle et l&#8217;affichage ainsi que les actions (listing des commentaires, formulaire d&#8217;ajout de commentaire, &#8230;)</p>
<p>Je me suis basé sur le behavior Doctrine Taggable fourni à l&#8217;origine pour réaliser ceci.</p>
<p>Le behavior et le plugin ne sont pas utilisable l&#8217;un sans l&#8217;autre.</p>
<p><span id="more-1002"></span><br />
télécharger les <a href='http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/11/sfLexikDoctrineActAsCommentablePlugin.tar1.gz'>sources</a></p>
<p><strong>Fourni par le behavior :</strong></p>
<p>Le listener :</p>
<p>void postDelete(event) //supprime tous les commentaires liés lors de la suppression de l&#8217;objet les portant</p>
<p>Le template et ses méthodes :</p>
<p>void addComment(Comment) //ajoute le commentaire à l&#8217;objet</p>
<p>void deleteComments() //supprime tous les commentaires reliés à l&#8217;objet</p>
<p>Doctrine_Collection findComments(array $params, array $orders) //retourne tous les commentaires liés à l&#8217;objet, respectant les paramètres du tableau params, et classés successivement dans les ordres donnés par le tableau orders</p>
<p>int getNbComments() //retourne le nombre de commentaires liés à l&#8217;objet</p>
<p>CommentForm getCommentForm()</p>
<p><strong>Fourni par le plugin :</strong></p>
<p>La classe Comment :</p>
<p>getParent() pour récupérer l&#8217;objet porteur du commentaire</p>
<p>La classe CommentTable :</p>
<p>getCommentsFilteredQuery($params, $orders) pour récupérer une requête permettant de retrouver une collection de commentaires selon certains paramètres, et en respectant une suite d&#8217;ordres</p>
<p>getUnmoderatedCommentsQuery() pour récupérer une requête permettant de retrouver la collection des commentaires non modérés</p>
<p>getSpamCommentsQuery() pour récupérer la collection des commentaires classés spam<br />
Le modèle de données :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1002code180'); return false;">View Code</a> YAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1002180"><td class="code" id="p1002code180"><pre class="yaml" style="font-family:monospace;">Comment:
  tableName: sf_comment
&nbsp;
  actAs: [Timestampable]
&nbsp;
  columns:
    user_id:
      type: integer(4)
&nbsp;
    #nom de l'auteur
    author_name:
      type: string(255)
      default: Anonyme
    #email de l'auter
    author_mail:
      type: string(255)
    #site web de l'auteur
    author_website:
      type: string(255)
&nbsp;
    #texte du commentaire
    text:
      type: clob
&nbsp;
    #id de l'objet porteur du commentaire
    parent_id:
      type: integer
    #classe de l'objet porteur du commentaire
    parent_class_name:
      type: string(255)
&nbsp;
    #publié ?
    is_published:
      type: boolean
      notnull: true
      default: true
    #modéré ?
    is_moderated:
      type: boolean
      notnull: true
      default: false
    #est un spam ?
    is_spam:
      type: boolean
      notnull: true
      default: false
&nbsp;
  relations:
    sfGuardUser:
      type: one
      foreignType: many
      local: user_id
      foreign: id
      foreignAlias: Comments</pre></td></tr></table></div>

<p>La technique pour relier un objet à cette table Comment est d&#8217;utiliser 2 champs spéciaux : parent_class_name et parent_id qui contiennent le nom de la classe ainsi que l&#8217;identifiant en base de l&#8217;objet porteur du commentaire.</p>
<p>De cette manière, on perd en partie l&#8217;aspect relationnel de la base, mais on allège énormément les requêtes de listing (derniers commentaires toutes catégories confondues, commentaires reliés à un objet, reliés à un type d&#8217;objet, &#8230;).<br />
Comment ça marche :</p>
<p>télécharger les <a href='http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/11/sfLexikDoctrineActAsCommentablePlugin.tar1.gz'>sources</a><br />
Avant de commencer, il faut évidemment copié les sources du plugin dans le répertoire plugin/ de votre projet, puis :</p>
<p>php symfony plugin:publish-assets</p>
<p>Tout d&#8217;abord, il faut activer le module dans les settings, en l&#8217;ajoutant comme ceci :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1002code181'); return false;">View Code</a> YAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1002181"><td class="code" id="p1002code181"><pre class="yaml" style="font-family:monospace;">all:
  .settings:
    enabled_modules: [default, sfGuardAuth, sfGuardUser, comment]</pre></td></tr></table></div>

<p>Ensuite dans le schema.yml du projet, il faut spécifier le behavior sur l&#8217;objet :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1002code182'); return false;">View Code</a> YAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1002182"><td class="code" id="p1002code182"><pre class="yaml" style="font-family:monospace;">Message:
  actAs:
    Timestampable: ~
    Commentable: ~
  columns:
    …</pre></td></tr></table></div>

<p>A partir de là, on utilisera les fonctions et méthodes vues plus haut (fournies par le template).</p>
<p>Le plugin fournit des partials pour l&#8217;affichage par défaut, personnalisable via les noms de classes et id passables en paramètres (toutes les classes et id sont définies par défaut si pas d&#8217;options) :</p>
<p>Partial show_comment, paramètres :<br />
  $comment : le message à afficher<br />
  $options : les options spécifiques pour css personnalisé<br />
    show_comment_class → conteneur global<br />
    infos_class → entete (auteur, date et heure)<br />
    author_name_class → auteur<br />
    time_and_date_class → date et heure<br />
    date_class → date<br />
    time_class → heure<br />
    text_class → corps du commentaire</p>
<p>Partial comments_list, paramètres : (boucle sur le partial show_comment, donc passer en parametre les options pour le show_comment)<br />
  $comments : la liste des messages à afficher<br />
  $options : les options spécifiques pour css personnalisé<br />
    list_comment_class : classe de la div conteneur<br />
    list_comment_id : id de la div conteneur</p>
<p>Partial form_comment, paramètres :<br />
  $form : le formulaire<br />
  $action : l&#8217;action du formulaire, définie par défaut<br />
  $options : les options spécifiques pour css personnalisé<br />
    id → id du formulaire<br />
    class → classe du formulaire</p>
<p>Partial ajax_script, paramètres : script jquery permettant de valider le formulaire en ajax<br />
  $form : le formulaire</p>
<p>Partial ajax_form_comment, paramètres : le formulaire et le script ajax</p>
<p>Exemple d&#8217;utilisation :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1002code183'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1002183"><td class="code" id="p1002code183"><pre class="php" style="font-family:monospace;">  <span style="color: #339933;">&lt;!--</span> <span style="color: #666666; font-style: italic;">// liste des commentaires du message --&gt;</span>
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> include_partial<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'comment/comments_list'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'comments'</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$message</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">findComments</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'created_at DESC'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'options'</span><span style="color: #339933;">=&gt;</span>array<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
  <span style="color: #339933;">&lt;!--</span> <span style="color: #666666; font-style: italic;">// formulaire d'ajout de commentaire --&gt;</span>
  <span style="color: #339933;">&lt;</span>div id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;form&lt;?php echo <span style="color: #006699; font-weight: bold;">$message-&gt;getId</span>() ?&gt;&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>h2<span style="color: #339933;">&gt;</span>Postez votre commentaire <span style="color: #339933;">:&lt;/</span>h2<span style="color: #339933;">&gt;</span>
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> include_partial<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'comment/ajax_form_comment'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'form'</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$message</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCommentForm</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Vous aurez noté qu&#8217;on ne parle pas encore de l&#8217;administration dans ce post, dans les publications à venir je vous parlerai d&#8217;abord du backend pour les commentaires, puis de la réalisation d&#8217;un behavior étape par étape.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/sflexikdoctrineactascommentableplugin-ou-comment-rendre-des-objets-commentables-via-un-behavior-plugin-1002/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Snippet sfValidatorEmailList</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/12x/snippet-sfvalidatoremaillist-979</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/12x/snippet-sfvalidatoremaillist-979#comments</comments>
		<pubDate>Wed, 14 Oct 2009 07:55:38 +0000</pubDate>
		<dc:creator>yoye</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[sfMailer]]></category>
		<category><![CDATA[sfValidator]]></category>
		<category><![CDATA[sfValidatorEmail]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Symfony 1.3]]></category>
		<category><![CDATA[validator]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/blog/symfony/?p=979</guid>
		<description><![CDATA[La version de Symfony 1.3 vient de passer en ALPHA2. Etant en cours de développement d&#8217;un projet sur cette version j&#8217;en profite pour tester les nouvelles fonctionnalités. Parmi celles-ci, il y a le sfMailer. Je ne vais pas m&#8217;étendre sur &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/12x/snippet-sfvalidatoremaillist-979">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>La version de Symfony 1.3 vient de passer en ALPHA2. Etant en cours de développement d&#8217;un projet sur cette version j&#8217;en profite pour tester les nouvelles fonctionnalités. Parmi celles-ci, il y a le sfMailer. Je ne vais pas m&#8217;étendre sur le sujet car on peut déjà trouver pas mal de posts sur internet concernant cette classe notamment dans les jobeet : <a href="http://www.symfony-project.org/jobeet/1_3/Doctrine/en/16">Day 16 The Mailer</a> .</p>
<p>Je me suis par contre amusé à coder un petit validator, qui il me semble, se couple bien avec le sfMailer : sfValidatorEmailList. Son nom est assez explicite mais pourquoi tester des listes de mails ? Tout simplement parceque sfMailer permet d&#8217;envoyer des mails groupés !<br />
  <span id="more-979"></span>
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p979code187'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p979187"><td class="code" id="p979code187"><pre class="php" style="font-family:monospace;">  <span style="color: #009933; font-style: italic;">/**
   * Creates a new message.
   *
   * @param string|array $from    The from address
   * @param string|array $to      The recipient(s)
   * @param string       $subject The subject
   * @param string       $body    The body
   *
   * @return Swift_Message A Swift_Message instance
   */</span></pre></td></tr></table></div>

<p>Dans les commentaires de la fonction compose() on peut voir que l&#8217;on a la possibilité de passer un string ou un tableau. sfValidatorEmailList va ainsi nous permettre de valider une liste de mails séparés par un caractère quelconque.</p>
<p>Tout d&#8217;abord je vais créer un formulaire classique qui me permettra de saisir les adresses emails, le sujet et le corps de mon email.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p979code188'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p979188"><td class="code" id="p979code188"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> lkInvitationForm <span style="color: #000000; font-weight: bold;">extends</span> sfForm
<span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setup<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mailer'</span><span style="color: #009900;">&#41;</span> instanceof sfMailer <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> RuntimeException<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'A valid mailer option is required to send an email from this form'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setWidgets</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'email'</span>         <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormInputText<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'label'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Adresse(s) email'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'title'</span>         <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormInputText<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'label'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'titre du mail'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'body'</span>          <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormTextarea<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'label'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Corps du mail'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setValidators</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'email'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorEmailList<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'invalid'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&quot;%value%&quot; invalide'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'title'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorString<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'invalid'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&quot;%value%&quot; invalide'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'body'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorString<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'invalid'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&quot;%value%&quot; invalide'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setNameFormat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'invitation[%s]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">errorSchema</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorErrorSchema<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Bind form and send mail
     *
     * @param sfWebRequest $request
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> bindAndSend<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a> <span style="color: #000088;">$taintedValues</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$taintedValues</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isValid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$mailer</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mailer'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #000088;">$mailer</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">composeAndSend</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'contact@lexik.fr'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'email'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'body'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>J&#8217;utilise donc pour mon email le sfValidatorEmailList dont voici le code :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p979code189'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p979189"><td class="code" id="p979code189"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> sfValidatorEmailList <span style="color: #000000; font-weight: bold;">extends</span> sfValidatorEmail
<span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * @see sfValidatorEmail
   */</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$messages</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        parent<span style="color: #339933;">::</span><span style="color: #004000;">configure</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #339933;">,</span> <span style="color: #000088;">$messages</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'separator'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">','</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * @see sfValidatorString
   */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> doClean<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$retVal</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$valueError</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$mails</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/explode"><span style="color: #990000;">explode</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'separator'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$mails</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$mail</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            try
            <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$retVal</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">doClean</span><span style="color: #009900;">&#40;</span><a href="http://www.php.net/trim"><span style="color: #990000;">trim</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mail</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            catch <span style="color: #009900;">&#40;</span>sfValidatorError <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$valueError</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <a href="http://www.php.net/empty"><span style="color: #990000;">empty</span></a> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$valueError</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorError<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'invalid'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'value'</span> <span style="color: #339933;">=&gt;</span> <a href="http://www.php.net/implode"><span style="color: #990000;">implode</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">', '</span><span style="color: #339933;">,</span> <span style="color: #000088;">$valueError</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$retVal</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h4>Quelques explications :</h4>
<p>Au niveau de la configuration on peut indiquer quel sera le caractère de séparation. Ensuite, la fonction doClean() qui se charge de tester la validité d&#8217;une valeur va transformer le string que l&#8217;on récupère en tableau et va appeler le doClean de sfEmailValidator. Afin de permettre un rendu plus propre du message d&#8217;erreur, j&#8217;utilise un try-catch qui me permet de lister tous les emails invalides. Une fois la boucle terminée, je n&#8217;ai plus qu&#8217;a créer mon exception avec toutes les valeurs catchées.<br />
Je peux par la suite passer le $this->getValue(&#8216;email&#8217;) à ma fonction composeAndSend() puisque le validator me retourne un tableau.</p>
<h4>Exemple d&#8217;une erreur dans un seul email</h4>
<p><img class="alignnone size-full wp-image-982" title="simple_erreur" src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/10/simple_erreur.png" alt="simple_erreur" width="323" height="75" /></p>
<h4>Exemple d&#8217;une erreur dans plusieurs emails</h4>
<p><img class="alignnone size-full wp-image-981" title="double_erreur" src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/10/double_erreur.png" alt="double_erreur" width="311" height="79" /></p>
<p>Maintenant lorsque j&#8217;affiche mon formulaire, les utilisateurs pourront saisir des adresses emails séparées d&#8217;une virgule pour envoyer à plusieurs contacts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/12x/snippet-sfvalidatoremaillist-979/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Réflexions sur l&#8217;élaboration d&#8217;un bon backend</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/12x/reflexions-sur-lelaboration-dun-bon-backend-958</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/12x/reflexions-sur-lelaboration-dun-bon-backend-958#comments</comments>
		<pubDate>Wed, 30 Sep 2009 08:00:20 +0000</pubDate>
		<dc:creator>Calu</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[Admingenerator 1.2.x]]></category>
		<category><![CDATA[Méthodologie]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[methode]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=958</guid>
		<description><![CDATA[Lors de la réalisation de vos projets, l&#8217;étape de la construction du backend est devenue un passage obligatoire. Que cela soit un souhait initial du client ou une envie de pouvoir proposer une prise en main du site via une &#8230;<p class="more aright"><a href="http://www.lexik.fr/blog/symfony/symfony/12x/reflexions-sur-lelaboration-dun-bon-backend-958">...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Lors de la réalisation de vos projets, l&#8217;étape de la construction du backend est devenue un passage obligatoire. Que cela soit un souhait initial du client ou une envie de  pouvoir proposer une prise en main du site via une interface, le backoffice justifie pleinement sa présence et son importance. Cette philosophie est très largement soutenue par Symfony avec son générateur CRUD d&#8217;admin, ses filters, l&#8217;extensibilité de ses templates, l&#8217;internationalisation&#8230;</p>
<p>Le but de cet article est de chercher plus loin dans les fonctionnalités de base proposées par Symfony pour l&#8217;élaboration de notre backend.</p>
<h3><span id="more-958"></span>La Homepage</h3>
<p>Proposer à l&#8217;administrateur l&#8217;affichage d&#8217;une page de listing d&#8217;un modèle, dès le login effectué,  est bien sûr une mauvaise idée. Une page d&#8217;accueil doit être présente et peut présenter les différentes informations pertinentes et vitales pour l&#8217;administrateur :</p>
<div id="attachment_960" class="wp-caption alignnone" style="width: 310px"><a href="http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/09/Capture-1.png"><img class="size-medium wp-image-960" title="Accueil" src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/09/Capture-1-300x91.png" alt="Accueil du backoffice : Statistiques et accés" width="300" height="91" /></a><p class="wp-caption-text">Accueil du backoffice : Statistiques et accés</p></div>
<p>Dans cette capture, l&#8217;accueil permet dès l&#8217;authentification, de connaitre les différentes statistiques du site et d&#8217;avoir un accés direct aux actions redondantes mais nécessaires : Utilisateurs en attente de validation, Visualisation de messages suspects etc&#8230;</p>
<p>Pour aller plus loin, vous pouvez afficher certaines indications propres à la fréquentation sur votre site. Si vous possédez un compte <a title="Google Analytics" href="www.Google.com/Analytics">Google Analytics</a>, c&#8217;est l&#8217;occasion d&#8217;en profiter ! En effet, une API pour accéder à ses statistiques est disponible depuis peu, et devinez quoi ? Il existe un plugin Symfony pour l&#8217;utiliser : <a title="sfGoogleAnalyticsPlugin : Un plugin Symfony pour Google Analytics" href="http://www.symfony-project.org/plugins/sfGoogleAnalyticsPlugin">sfGoogleAnalyticsPlugin</a>. Alors plus d&#8217;excuses pour ne plus proposer une page d&#8217;accueil efficace à votre client.</p>
<h3>Un listing précis et concis</h3>
<p>Par défault, Symfony propose un listing complet des différents champs de votre modèle. Cela est souvent beaucoup trop confus et non adapté pour les besoins d&#8217;un client :</p>
<p><a href="http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/09/mauvais-listing.png"><img class="alignnone size-medium wp-image-963" title="Mauvais listing" src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/09/mauvais-listing-300x19.png" alt="Mauvais listing" width="300" height="19" /></a></p>
<p>Il apparait comme  essentiel de sélectionner et de renommer  les différentes colonnes de votre modèle que vous souhaitez afficher. De même, selon la complexité de votre objet, il peut être intéressant de fournir des informations &laquo;&nbsp;associées&nbsp;&raquo; : Pour un objet <em>Article de Blog</em>, il est pertinent d&#8217;afficher le nombre de <em>Commentaire</em>s associés. Dans mon cas, j&#8217;affiche le nombre d&#8217;utilisateurs associés à un projet :</p>
<p><a href="http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/09/listing.png"><img class="alignnone size-medium wp-image-967" title="listing" src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/09/listing-300x54.png" alt="listing" width="300" height="54" /></a></p>
<p>Concernant les valeurs, il est déconseillé d&#8217;utiliser des IDs. Ils apportent aucune information quantitative ou qualitative pour l&#8217;administrateur. De plus, il est préférable de créer une action pour les tâches répétitives. Cela simplifie grandement l&#8217;administration pour un client et on évite ainsi de l&#8217;envoyer directement sur les pages d&#8217;éditions.</p>
<p>La <a href="http://www.symfony-project.org/book/1_2/14-Generators#chapter_14_generator_configuration">documentation</a> de Symfony étant très complète sur ce sujet, nous allons continuer notre tour d&#8217;horizon avec les filters.</p>
<h3>Les filtres au service de la navigation</h3>
<p>Symfony permet à l&#8217;aide du générateur d&#8217;administration, de trier vos modèles en fonction de filtres spécifiques. Mais comme pour la partie précédente, les problèmes sont similaires : Trop de champs renseignables, souvent complexes et non traduits. Outre la documentation de Symfony qui vient encore une fois à notre aide, il faudra faire un tour sur <a href="http://www.zen-in-progress.com/post/symfony-traduction-des-filtres-de-l-admin-generateur" target="_blank">cet article</a> pour compléter la traduction des filtres sur le backend.</p>
<p>Mais la véritable force des filtres, c&#8217;est leur utilisation de manière transparente par le client. En effet, si on reprend l&#8217;exemple de notre page d&#8217;accueil, on propose un lien &laquo;&nbsp;<em>3 projets en attente&nbsp;&raquo;</em> sensé rediriger sur les projets concernés.</p>
<h4>Comment cela est-il possible ?</h4>
<p>Tout simplement en créant le filtre qui nous permet de trier nos projets, dès le chargement de la page. La manière la plus simple est de passer nos filtres dans l&#8217;URL.</p>
<h4>Mise en place</h4>
<p>Il faut d&#8217;abord surcharger notre action index du module concerné :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p958code197'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p958197"><td class="code" id="p958code197"><pre class="php" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getParameter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'filter'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>setFilters<span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getParameter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'filter'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        parent<span style="color: #339933;">::</span><span style="color: #004000;">executeIndex</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>On vérifie si l&#8217;on passe un paramètre &laquo;&nbsp;filter&nbsp;&raquo; lors du chargement de la page. Le cas échéant, on applique les filtres renseignés.</p>
<p>Mon lien permettant de voir seulement les utilisateurs en attente de validation aura le routing :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p958code198'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p958198"><td class="code" id="p958code198"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">@</span>user_user?filter<span style="color: #009900;">&#91;</span>is_active<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span></pre></td></tr></table></div>

<p>Pour mes projets en attente de validation, c&#8217;est la pratiquement la même chose, on indique en plus le type de l&#8217;argument.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p958code199'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p958199"><td class="code" id="p958code199"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">@</span>project_project?filter<span style="color: #009900;">&#91;</span>state<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>text<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">1</span></pre></td></tr></table></div>

<p>Pensez à bien regarder la structure de vos filtres en cas d&#8217;erreur.</p>
<h4>Allez plus loin</h4>
<p>Maintenant que vous savez filtrer directement à partir d&#8217;un lien, vous allez pouvoir vous servir de cette astuce autre part que sur la page d&#8217;accueil. Revenons sur nos listing. Nous avons vu qu&#8217;il était pratique pour le client d&#8217;afficher par exemple le nombre d&#8217;objet <em>Commentaire</em> associés à un objet <em>Article</em>. Nous sommes maintenant capables de rediriger directement vers les objets associés.</p>
<p>On ajoute une méthode d&#8217;affichage sur notre objet <em>Article</em> :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p958code200'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p958200"><td class="code" id="p958code200"><pre class="php" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getCountPositioning<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> link_to<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getComments<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>count<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'@comment_comment?filter[article_id]='</span><span style="color: #339933;">.</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>Id<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>On retourne ainsi le lien contenant le filtre permettant de trier les commentaires en fonction de l&#8217;ID de l&#8217;article. Il suffit de modifer notre action index afin de correctement afficher notre entité HTML :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p958code201'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p958201"><td class="code" id="p958code201"><pre class="php" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sf_escaping_strategy'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getParameter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'filter'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>setFilters<span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getParameter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'filter'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        parent<span style="color: #339933;">::</span><span style="color: #004000;">executeIndex</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Voilà pour nos petites idées pour vous aider à parfaire votre back office. N&#8217;hésitez pas à parlez de vos astuces dans les commentaires.</p>
<h3>Mise à jour</h3>
<p lang="php">La désactivation de la stratégie d&#8217;échappement des caractères (<em>sfConfig::set(&#8216;sf_escaping_strategy&#8217;, false)) </em>est utilisée pour éviter l&#8217;affichage des balises &lt;a&gt; obtenues depuis notre modèle. Cette méthode à deux limites : D&#8217;une part, elle est inhérente à certaines failles de sécurité provoquées par une injection de code malicieux (cf commentaire de @Niko) ; D&#8217;autre part, on perd l&#8217;avantage lié à notre MVC en faisant parvenir le lien directement depuis le modèle.</p>
<p>Il est alors conseillé de déclarer dans notre <em>generator.yml </em>l&#8217;utilisation des partials pour afficher nos liens filtrants :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p958code202'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p958202"><td class="code" id="p958code202"><pre class="php" style="font-family:monospace;">display<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>_countComments<span style="color: #009900;">&#93;</span></pre></td></tr></table></div>

<p>Il suffit alors de créer notre partial <em>_countComments.php</em> dans le dossier <em>templates</em>/ de notre module :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p958code203'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p958203"><td class="code" id="p958code203"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>?php <span style="color: #b1b100;">echo</span> link_to<span style="color: #009900;">&#40;</span><span style="color: #000088;">$article</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getComments<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>count<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'@comments_comments?filter[article_id]='</span><span style="color: #339933;">.</span><span style="color: #000088;">$article</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>?<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/12x/reflexions-sur-lelaboration-dun-bon-backend-958/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

