<?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 Symfony - Lexik Montpellier &#187; yoye</title>
	<atom:link href="http://www.lexik.fr/blog/symfony/author/yoye/feed" rel="self" type="application/rss+xml" />
	<link>http://www.lexik.fr/blog/symfony</link>
	<description>Blog sur le développement Web PHP</description>
	<lastBuildDate>Tue, 20 Jul 2010 08:35:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<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[Symfony]]></category>
		<category><![CDATA[doctrine]]></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 partie sur la gestion des zones géographiques, on a décidé d&#8217;utiliser le behavior Nestedset ce [...]]]></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('p1109code5'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p11095"><td class="code" id="p1109code5"><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: #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: #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: #990000;">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: #990000;">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: #990000;">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> <span style="color: #990000;">array</span><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: #990000;">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> <span style="color: #990000;">array</span><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('p1109code6'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p11096"><td class="code" id="p1109code6"><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><span style="color: #990000;">array</span><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('p1109code7'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p11097"><td class="code" id="p1109code7"><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: #000000; 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> <span style="color: #990000;">sprintf</span><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: #000000; 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> <span style="color: #990000;">sprintf</span><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> <span style="color: #990000;">array</span><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> <span style="color: #990000;">array</span><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> <span style="color: #990000;">array</span><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('p1109code8'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p11098"><td class="code" id="p1109code8"><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: #009900;">&#40;</span><span style="color: #009900;">&#41;</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: #990000;">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>2</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 connecté on peut toujours passer par la base de donnée mais pour les autres on [...]]]></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('p1053code13'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p105313"><td class="code" id="p1053code13"><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('p1053code14'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p105314"><td class="code" id="p1053code14"><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: #000000; 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> <span style="color: #990000;">substr</span><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> <span style="color: #990000;">substr</span><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> <span style="color: #990000;">substr</span><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> <span style="color: #990000;">substr</span><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: #000000; font-weight: bold;">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>
      throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #990000;">sprintf</span><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>
  protected <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> <span style="color: #990000;">array</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;">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('p1053code15'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p105315"><td class="code" id="p1053code15"><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('p1053code16'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p105316"><td class="code" id="p1053code16"><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>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 le sujet car on peut déjà trouver pas mal de posts sur internet concernant cette [...]]]></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('p979code20'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p97920"><td class="code" id="p979code20"><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('p979code21'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p97921"><td class="code" id="p979code21"><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>
            throw <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><span style="color: #990000;">array</span><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><span style="color: #990000;">array</span><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><span style="color: #990000;">array</span><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><span style="color: #990000;">array</span><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><span style="color: #990000;">array</span><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><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><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><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><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><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><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><span style="color: #990000;">array</span> <span style="color: #000088;">$taintedValues</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</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;">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('p979code22'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p97922"><td class="code" id="p979code22"><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>
    protected <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> <span style="color: #990000;">array</span><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> <span style="color: #990000;">array</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>
        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> <span style="color: #990000;">array</span><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> <span style="color: #990000;">array</span><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> <span style="color: #990000;">explode</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;">'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><span style="color: #990000;">trim</span><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> <span style="color: #990000;">empty</span> <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>
            throw <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> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'value'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">implode</span><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>Utilisation de sfSessionStorage dans Symfony</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-sfsessionstorage-dans-symfony-901</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-sfsessionstorage-dans-symfony-901#comments</comments>
		<pubDate>Mon, 24 Aug 2009 07:10:29 +0000</pubDate>
		<dc:creator>yoye</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[cookies]]></category>
		<category><![CDATA[environnement]]></category>
		<category><![CDATA[factories]]></category>
		<category><![CDATA[sfSessionStorage]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=901</guid>
		<description><![CDATA[sfSessionStorage fait partie des fonctionnalités du Framework qui restent un brin obscures lorsqu&#8217;on commence avec Symfony. Mais il s&#8217;avère par la suite très utile, que ce soit dans le cadre de la production ou même du développement. A quoi ça sert ? Tout simplement à la gestion des cookies de session. pourquoi l&#8217;utiliser ? Récemment [...]]]></description>
			<content:encoded><![CDATA[<p>sfSessionStorage fait partie des fonctionnalités du Framework qui restent un brin obscures lorsqu&#8217;on commence avec Symfony. Mais il s&#8217;avère par la suite très utile, que ce soit dans le cadre de la production ou même du développement.<br />
<span id="more-901"></span></p>
<h4>A quoi ça sert ?</h4>
<p>Tout simplement à la gestion des cookies de session.</p>
<h4>pourquoi l&#8217;utiliser ?</h4>
<p>Récemment j&#8217;ai du développer un projet qui contenait plusieurs applications, 3 pour commencer et elles peuvent se multiplier par la suite. Cela n&#8217;a rien de choquant tous les projets on généralement un minimum de 2 applications, un backend et un frontend.<br />
Ce qui peut s&#8217;avérer très vite ennuyeux, en effet pour peu que l&#8217;on souhaite être connecté en tant qu&#8217;admin sur notre backend et en tant qu&#8217;utilisateur lamda sur notre frontend, il va falloir se déconnecter assez souvent, ce qui a la longue devient fastidieux.</p>
<p><strong>C&#8217;est là qu&#8217;intervient notre sfSessionStorage.</strong></p>
<h4>Comment le configurer ?</h4>
<p>Ce qui est intéressant dans l&#8217;utilisation des cookies de session c&#8217;est leur simplicité d&#8217;utilisation grâce au framework. Pour cela il va falloir modifier le fichier factories.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('p901code26'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p90126"><td class="code" id="p901code26"><pre class="yml" style="font-family:monospace;"># apps/frontend/config/factories.yml
&nbsp;
all:
#début de ma config
  storage:
    class: sfSessionStorage
    param:
      session_name: frontend
&nbsp;
# apps/backend/config/factories.yml
&nbsp;
all:
#début de ma config
  storage:
    class: sfSessionStorage
    param:
      session_name: backend</pre></td></tr></table></div>

<p>Je me retrouve désormais avec des cookies différents pour chaque application ce qui va me permettre de me connecter sur chacune de mes applications avec des utilisateurs différents.</p>
<h4>Autres cas pratiques</h4>
<p>On peut bien évidemment étendre cette solution sur les environnements. En effet on peut avoir besoin d&#8217;être connecté sur une même application avec deux types d&#8217;utilisateurs. Imaginons que j&#8217;ai besoin de tester sur mon frontend les différents crédentials que j&#8217;ai ajouté à mon application. Je peux me créer des environnements pour chacun de ces crédentials comme par ex : rédacteur et administrateur.<br />
Je vais de nouveau modifier mon fichier factories.yml et le champs d&#8217;application ne va plus se faire sur toute l&#8217;application mais sur un environnement.</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('p901code27'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p90127"><td class="code" id="p901code27"><pre class="yml" style="font-family:monospace;">redac:
  storage:
    class: sfSessionStorage
    param:
      session_name: redacteur
admin:
  storage:
    class: sfSessionStorage
    param:
      session_name: administrateur</pre></td></tr></table></div>

<p>Dans un soucis de simplicité j&#8217;ai raccourci le nom des environnements. Il me faut pour terminer créer mes deux environnements. Je vais pour cela créer les fichiers frontend_redac.php et frontend_admin.php dans le dossier web qui contiendront :</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('p901code28'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p90128"><td class="code" id="p901code28"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// environnement redac</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/../config/ProjectConfiguration.class.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;">'redac'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #009900;">&#41;</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;">-&amp;</span>gt<span style="color: #339933;">;</span>dispatch<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;">// environnement admin</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/../config/ProjectConfiguration.class.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;">'admin'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #009900;">&#41;</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;">-&amp;</span>gt<span style="color: #339933;">;</span>dispatch<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Je pourrai maintenant être connecté sur mon application avec 2 comptes différents.</p>
<p>L&#8217;utilisation de la classe sfSessionStorage peut donc s&#8217;avérer très utile comme je l&#8217;ai dis plus tôt dans un cadre de développement pour faciliter la navigation entre les différentes configuration que l&#8217;on peut retrouver sur notre application quant à son utilisation en production chacun fera en fonction de ses besoins bien évidemment.</p>
<p>Mais quand on voit la simplicité de la mise en place il serait dommage de s&#8217;en passer.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-sfsessionstorage-dans-symfony-901/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Symfony : Utilisation de la classe sfFilter</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/symfony-utilisation-de-la-classe-sffilter-792</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/symfony-utilisation-de-la-classe-sffilter-792#comments</comments>
		<pubDate>Thu, 16 Jul 2009 09:48:23 +0000</pubDate>
		<dc:creator>yoye</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[sfFilter]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=792</guid>
		<description><![CDATA[Nous allons voir l&#8217;utilisation de la classe sfFilter. Attention à ne pas confondre sfFilter et les classes auto-générés lors du build de l&#8217;application qui sont des classes principalement utilisées dans le backend pour faire le tri sur les colonnes. Mais concentrons nous d&#8217;abord sur sfFilter. Comme on peut le voir en parcourant rapidement le code [...]]]></description>
			<content:encoded><![CDATA[<p>Nous allons voir l&#8217;utilisation de la classe sfFilter. Attention à ne pas confondre sfFilter et les classes auto-générés lors du build de l&#8217;application qui sont des classes principalement utilisées dans le backend pour faire le tri sur les colonnes.</p>
<p>Mais concentrons nous d&#8217;abord sur <a href="http://www.symfony-project.org/api/1_2/sfFilter">sfFilter</a>. Comme on peut le voir en parcourant rapidement le code c&#8217;est une classe abstraite on ne pourra donc l&#8217;utiliser que part héritage.<br />
Les filters sont en fait une couche du Framework qui permet d&#8217;effectuer des actions avant ou après l&#8217;affichage d&#8217;une page, ce qui peut s&#8217;avérer très pratique.<br />
<span id="more-792"></span><br />
On va donc partir d&#8217;un exemple simple :<br />
Imaginons deux sites internet, un site A qui va faire une redirection vers mon site B. Sur mon site B les utilisateurs peuvent s&#8217;inscrire et j&#8217;ai besoin de stocker le site de provenance, ce qui va se faire à l&#8217;aide d&#8217;un cookie.<br />
Une méthode primaire pourrait consister à faire une page qui va poser le cookie et faire la redirection. Seulement le jour ou je souhaite que mon site A redirige vers une page précise de mon site B il va falloir que je vienne changer le code.<br />
<strong>Heureusement sfFilter est là !</strong></p>
<p>Grâce à cette couche du framework je vais pouvoir créer une classe que je vais appeler TrackerFilter et qui va me faire tout le traitement nécessaire. 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('p792code33'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p79233"><td class="code" id="p792code33"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> TrackerFilter <span style="color: #000000; font-weight: bold;">extends</span> sfFilter <span style="color: #009900;">&#123;</span>
     <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><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>
&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;">isFirstCall</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</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;">'r'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$context</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>
&nbsp;
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCookie</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'reservation'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$time</span> <span style="color: #339933;">=</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #cc66cc;">60</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">60</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">24</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">7</span><span style="color: #339933;">;</span>
                <span style="color: #000088;">$context</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;">setCookie</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'reservation'</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;">'r'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$time</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: #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>

<dl>
<dt>Que se passe t&#8217;il dans ces quelques lignes de code ?</dt>
<dd>Notre classe va hériter de sfFilter (obligatoire)</dd>
<dd>On va créer une function execute avec en paramètre $filterchain qui va nous permettre d&#8217;exécuter le code souhaité (obligatoire)</dd>
<dd>On récupère le &laquo;&nbsp;context&nbsp;&raquo; et le &laquo;&nbsp;request&nbsp;&raquo; ce qui va nous permettre de vérifier si le cookie existe déjà et de le poser dans le cas contraire</dd>
<dd>On exécute le filter (obligatoire)</dd>
</dl>
<p>Quelques précisions supplémentaires :<br />
La fonction isFirstCall() permet de vérifier si c&#8217;est la première exécution du filter.<br />
Le placement de la ligne</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('p792code34'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p79234"><td class="code" id="p792code34"><pre class="php" style="font-family:monospace;"><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></pre></td></tr></table></div>

<p>a son importance puisqu&#8217;elle permet de signifier si l&#8217;on souhaite que le filter s&#8217;exécute avant ou après l&#8217;action.</p>
<p>Maintenant il ne nous reste plus qu&#8217;à configurer notre filter, pour cela il faut modifier le fichier apps/APPLICATION/config/filters.yml qui d&#8217;origine contient :</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('p792code35'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p79235"><td class="code" id="p792code35"><pre class="yml" style="font-family:monospace;">rendering: ~
security:  ~
&nbsp;
# insert your own filters here
&nbsp;
cache:     ~
common:    ~
execution: ~</pre></td></tr></table></div>

<p>Ce qui semble assez explicite pour savoir ou écrire notre configuration. On va donc compléter ce fichier 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('p792code36'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p79236"><td class="code" id="p792code36"><pre class="yml" style="font-family:monospace;">rendering: ~
security:  ~
&nbsp;
TrackerFilter:
  class:  TrackerFilter
&nbsp;
cache:     ~
common:    ~
execution: ~</pre></td></tr></table></div>

<p>Nous avons donc vu comment utiliser les filters avec un cas pratique simple mais qui est un cas qu&#8217;un développeur web va rencontrer souvent. Cette façon de faire laisse donc une certaine flexibilité et permet une fois de plus d&#8217;avoir un code simple, clair et factorisé.<br />
On trouve là tout la puissance de Symfony.</p>
<p>Pour ceux qui sont intéressés par d&#8217;autres cas d&#8217;utilisation de sfFilter vous pouvez bien sûr vous reportez sur le <a href="http://www.symfony-project.org/book/1_2/06-Inside-the-Controller-Layer#chapter_06_filters">livre</a>. Vous y verrez qu&#8217;il est possible grâce aux filters de faire des redirection, ou encore d&#8217;ajouter du code sur notre page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/symfony-utilisation-de-la-classe-sffilter-792/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Faisons un peu de référencement avec symfony</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/faisons-un-peu-de-referencement-avec-symfony-637</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/faisons-un-peu-de-referencement-avec-symfony-637#comments</comments>
		<pubDate>Thu, 07 May 2009 16:13:09 +0000</pubDate>
		<dc:creator>yoye</dc:creator>
				<category><![CDATA[Symfony]]></category>
		<category><![CDATA[factories.yml]]></category>
		<category><![CDATA[meta]]></category>
		<category><![CDATA[référencement]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[sfWebResponse]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=637</guid>
		<description><![CDATA[Tout site internet qui se respecte et qui veut atteindre un trafic correct doit effectuer un travail sur son SERP. Symfony étant un Framework et non un CMS on ne trouve pas énormément d&#8217;informations concernant le SEO. Cependant pour quelques sites que Lexik a lancé récemment nous nous sommes penché un peu sur l&#8217;optimisation de [...]]]></description>
			<content:encoded><![CDATA[<p>Tout site internet qui se respecte et qui veut atteindre un trafic correct doit effectuer un travail sur son SERP.</p>
<p>Symfony étant un Framework et non un CMS on ne trouve pas énormément d&#8217;informations concernant le SEO. Cependant pour quelques sites que Lexik a lancé récemment nous nous sommes penché un peu sur l&#8217;optimisation de notre référencement. </p>
<p><!</p>
<p align="center">Attention il ne s&#8217;agit la que de quelques conseils primaires rien de bien révolutionnaire. Prétendre ressortir premier sur Google en quelques lignes et serait un pure escroquerie.  </p>
<p><span id="more-637"></span></p>
<p>Pour commencer j&#8217;ai voulu éclaircir quelques chose qui me perturbe depuis que je travaille sur Symfony. La balise META title. Elle est présente dans un projet Symfony mais je ne l&#8217;avais vu quasiment nulle part auparavant. <br />
Un exemple simple tapez des mots extrèmement concurrentiel sur votre moteur de recherche préféré : &laquo;&nbsp;Jeux d&#8217;argent&nbsp;&raquo;, &laquo;&nbsp;Location immobilière&nbsp;&raquo;. Sur la première page des résultats si on regarde la source des pages on peut voir que la majorité ont la balise &lt;title&gt;&lt;/title&gt; en première position dans leur header et que la <del datetime="2009-05-07T13:47:04+00:00">quasi</del> totalité n&#8217;ont pas de balise META title.</p>
<p>L&#8217;explication qui semble la plus plausible et que ces deux balises ont la même fonction et que les moteurs de recherche pourraient interpréter la présence des deux balises comme du spam, en gros on essaye de caser nos mots clés en quantité anormale.<br />
  <br />
  J&#8217;ai donc cherché comment régler ce problème et je suis tombé sur un post qui correspondait exactement à ce que je voulais : <a href="http://theseomantra.com/2008/07/20/removing-meta-nametitle-tag-in-symfony-for-seo/" target="_blank">Removing META name=title tag in Symfony for SEO</a> Simplement il y a une petite retouche à faire dans le code fourni, ce qui donne : </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('p637code42'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63742"><td class="code" id="p637code42"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">class</span> myWebResponse <span style="color: #000000; font-weight: bold;">extends</span> sfWebResponse
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getMetas<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$meta_tags</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">metas</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'title'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$meta_tags</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$meta_tags</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#93;</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;">$meta_tags</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Il nous faut ensuite modifier notre fichier factories.yml pour lui indiquer quelle classe 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('p637code43'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63743"><td class="code" id="p637code43"><pre class="yml" style="font-family:monospace;">prod:
  response:
    class: myWebResponse</pre></td></tr></table></div>

<p>Et voilà le tour est joué. On se retrouve maintenant avec uniquement la balise <title></title></p>
<p>Pour rester dans les META je vous conseille de modifier votre fichier view.yml dans votre application afin d&#8217;être sur d&#8217;avoir des META sur toutes les pages.</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('p637code44'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63744"><td class="code" id="p637code44"><pre class="yml" style="font-family:monospace;">default:
  metas:
    title:        Le titre de mon site
    description:  la description de mon site
    keywords:     site, symfony</pre></td></tr></table></div>

<p>Maintenant google et les autres moteurs de recherche, oui oui il en existe d&#8217;autres, n&#8217;aiment pas que l&#8217;on est des META en double en gros ils n&#8217;aiment pas retrouver les mêmes descriptions ou titre d&#8217;une page à l&#8217;autre. Donc de manière générale je définis les META pour chaque page à partir de 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('p637code45'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63745"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p637code45"><pre class="php" style="font-family:monospace;"><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;">-&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;">addMeta</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'description'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'La description de mon site'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Ensuite de manière à ce que le moteur de recherche tombe en premier sur mes mots clés j&#8217;ai tendance à modifier un peu mon layout.php et l&#8217;ordre des includes, je précise que ce n&#8217;est en rien une vérité :</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('p637code46'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63746"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p637code46"><pre class="php" style="font-family:monospace;">    <span style="color: #339933;">&lt;</span>head<span style="color: #339933;">&gt;</span>
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> include_title<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_metas<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_http_metas<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>link rel<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;shortcut icon&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;/favicon.ico&quot;</span> <span style="color: #339933;">/&gt;</span>
    <span style="color: #339933;">&lt;/</span>head<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Une fois encore je précise que ce ne sont là pas des vérités absolus, juste des mise en pratique d&#8217;observations.</p>
<p>De plus cette semaine j&#8217;ai vu qu&#8217;un plugin spécial SEO venait de sortir <a href="http://www.symfony-project.org/plugins/csSEOToolkitPlugin" target="_blank">csSEOToolkitPlugin</a> je n&#8217;ai pas eu le temps de le tester mais je compte bientôt le faire, peut être ce sera le sujet d&#8217;un prochain post, en attentant si certains ont des feed-back à partager sur ce plugin, ils peuvent les partager via les commentaires.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/faisons-un-peu-de-referencement-avec-symfony-637/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Simuler un loader pendant l&#8217;exécution d&#8217;une tâche</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/simuler-un-loader-pendant-lexecution-dune-tache-495</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/simuler-un-loader-pendant-lexecution-dune-tache-495#comments</comments>
		<pubDate>Thu, 16 Apr 2009 11:29:07 +0000</pubDate>
		<dc:creator>yoye</dc:creator>
				<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[loader]]></category>
		<category><![CDATA[périodique]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=495</guid>
		<description><![CDATA[J&#8217;ai parlé il y a deux semaines de la méthode que l&#8217;on pouvait utiliser pour créer des tâches dans symfony et la façon de les alimenter dynamiquement : créer des tâches avec symfony. Il serait maintenant intéressant de pouvoir l&#8217;utiliser dans une application et également de pouvoir suivre l&#8217;évolution de notre tâche. Pour lancer la [...]]]></description>
			<content:encoded><![CDATA[<p>J&#8217;ai parlé il y a deux semaines de la méthode que l&#8217;on pouvait utiliser pour créer des tâches dans symfony et la façon de les alimenter dynamiquement : <a href="http://www.lexik.fr/blog/symfony/symfony/12x/symfony-et-les-taches-436">créer des tâches avec symfony</a>. </p>
<p>Il serait maintenant intéressant de pouvoir l&#8217;utiliser dans une application et également de pouvoir suivre l&#8217;évolution de notre tâche.<br />
<span id="more-495"></span><br />
Pour lancer la tâche nous avions dans un premier penser la lancer grâce à la fonction <strong>proc_open()</strong> de PHP qui inclut une gestion des logs assez intéressante. Nos premiers tests en local se sont déroulés sans problèmes mais une fois en production il semble que la configuration du serveur ne permette pas d&#8217;utiliser cette commande.<br />
On s&#8217;est donc rabattus sur la façon qui semble la plus utilisée :</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('p495code57'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p49557"><td class="code" id="p495code57"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #990000;">chdir</span><span style="color: #009900;">&#40;</span>sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sf_root_dir'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
<span style="color: #000088;">$myTask</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> importExecuteTask<span style="color: #009900;">&#40;</span>sfContext<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</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: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> sfFormatter<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;">$myTask</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">run</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</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>Il est important de ne pas oublier le <strong>chdir()</strong> pour permettre l&#8217;exécution de notre tâche.</p>
<p>La première étape est donc terminée, on a pu lancer notre tâche depuis notre application, on va maintenant s&#8217;intéresser à suivre l&#8217;évolution de celle-ci.<br />
Pour cela je vais créer un fichier que j&#8217;appelerai lock.txt dans mon répertoire d&#8217;import et je vais même l&#8217;utiliser comme compteur. Pour des raisons que nous verrons un peu plus bas, je vais créer une constante dans la classe de ma tâche qui correspondra au nom du fichier.</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('p495code58'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p49558"><td class="code" id="p495code58"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">const</span> LOCK_FILE <span style="color: #339933;">=</span> <span style="color: #0000ff;">'lock.txt'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Au début de ma boucle je donc avoir 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('p495code59'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p49559"><td class="code" id="p495code59"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000088;">$handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'file'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'r'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arguments</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'import_dir'</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: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">LOCK_FILE</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'x'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fgetcsv</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">5000</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;;&quot;</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;">false</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
 <span style="color: #666666; font-style: italic;">/* Mon code d'insertion */</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Bon ok on a notre fichier mais à quoi nous sert-il ?<br />
On peut dès à présent l&#8217;utiliser pour faire un redirect dans notre action pour empêcher de lancer plusieurs tâches en même temps :</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('p495code60'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p49560"><td class="code" id="p495code60"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirectIf</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_file</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'chemin/de/mon/dossier/import'</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/'</span><span style="color: #339933;">.</span>importExecuteTask<span style="color: #339933;">::</span><span style="color: #004000;">LOCK_FILE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'import/loading'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Ici je redirige vers une page &laquo;&nbsp;loading&nbsp;&raquo; qui permettra de faire &laquo;&nbsp;patienter&nbsp;&raquo; notre utilisateur.</p>
<p>On vient de voir la première utilisation de notre fichier lock on va maitenant l&#8217;utiliser pour suivre l&#8217;évolution de la tâche. Pour cela je vais utiliser un compteur dans la boucle de ma tâche et l&#8217;écrire dans mon fichier. Il me faut tout d&#8217;abord obtenir le nombre maximum de mon fichier CSV.</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('p495code61'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p49561"><td class="code" id="p495code61"><pre class="php" style="font-family:monospace;">&nbsp;
            <span style="color: #000088;">$handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arguments</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'import_dir'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #000088;">$file</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'r'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$contenu_fichier</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fread</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #990000;">filesize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arguments</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'import_dir'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$max</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr_count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$contenu_fichier</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Dans ma boucle je vais maintenant incrémenter mon compteur et mettre tout ça dans notre fichier lock :</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('p495code62'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p49562"><td class="code" id="p495code62"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fgetcsv</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">5000</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;;&quot;</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;">false</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #666666; font-style: italic;">//- Début de mon code</span>
&nbsp;
file_put_contents<span style="color: #009900;">&#40;</span><span style="color: #000088;">$arguments</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'import_dir'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">LOCK_FILE</span><span style="color: #339933;">,</span> <span style="color: #000088;">$count</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/'</span><span style="color: #339933;">.</span><span style="color: #000088;">$max</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$count</span><span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Maintenant que mon fichier contient les informations nécessaires je vais les utiliser dans 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('p495code63'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p49563"><td class="code" id="p495code63"><pre class="php" style="font-family:monospace;">&nbsp;
        <span style="color: #000088;">$filename</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_chemin_import'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/'</span><span style="color: #339933;">.</span>importExecuteTask<span style="color: #339933;">::</span><span style="color: #004000;">LOCK_FILE</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span> <span style="color: #339933;">,</span> <span style="color: #0000ff;">'r'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000088;">$moyenne</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fread</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #990000;">filesize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000088;">$a</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$moyenne</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;">content</span> <span style="color: #339933;">=</span> <span style="color: #990000;">floor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$a</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #000088;">$a</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Voilà maintenant lorsque l&#8217;utilisateur sera redirigé vers notre page d&#8217;attente. On pourra lui afficher le pourcentage de l&#8217;évolution de la tâche. Petit problème si l&#8217;on veut suivre en direct cette évolution on va recharger la page indéfiniment ? Non pour cela on va utiliser un Helper Javascript : periodically_call_remote()</p>
<p>On va donc créer une action page progess qui ne sera appeler que par le javacript et qui sera inclut dans notre page &laquo;&nbsp;loading&nbsp;&raquo; par l&#8217;appel d&#8217;un component ce qui nous donnera :</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('p495code64'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p49564"><td class="code" id="p495code64"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// actions.class.php</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeProgress<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000088;">$filename</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_chemin_import'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/lock.txt'</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span> <span style="color: #339933;">,</span> <span style="color: #0000ff;">'r'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000088;">$moyenne</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fread</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #990000;">filesize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000088;">$a</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$moyenne</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;">content</span> <span style="color: #339933;">=</span> <span style="color: #990000;">floor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$a</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #000088;">$a</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Notre template :</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('p495code65'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p49565"><td class="code" id="p495code65"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #339933;">&lt;</span>div style<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;width: 220px;&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>div style<span style="color: #339933;">=</span><span style="color: #0000ff;">'width:&lt;?php echo $content ?&gt;%; background-image: url(/images/progress.gif); float: left;'</span><span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #990000;">echo</span> <span style="color: #000088;">$content</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>Une div qui contiendra une image gif que l&#8217;on fera grandir au fur et à mesure tel une barre de progression.<br />
Et pour terminer notre page d&#8217;attente :</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('p495code66'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p49566"><td class="code" id="p495code66"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> use_helper<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>
&nbsp;
<span style="color: #339933;">&lt;</span>div id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;progress&quot;</span><span style="color: #339933;">&gt;&lt;/</span>div<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #990000;">echo</span> periodically_call_remote<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
   <span style="color: #0000ff;">'frequency'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'1'</span><span style="color: #339933;">,</span>
   <span style="color: #0000ff;">'update'</span>     <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'progress'</span><span style="color: #339933;">,</span>
   <span style="color: #0000ff;">'url'</span>        <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'import/progress'</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>Tout les secondes la div va donc être rafraîchie en appelant notre page progress ce qui simulera l&#8217;évolution de notre tâche.</p>
<p>Pour terminer, il ne faudra surtout pas oublier de supprimer le fichier lock à l&#8217;aide d&#8217;un petit unlink().</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/simuler-un-loader-pendant-lexecution-dune-tache-495/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Symfony et les tâches</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/12x/symfony-et-les-taches-436</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/12x/symfony-et-les-taches-436#comments</comments>
		<pubDate>Wed, 01 Apr 2009 10:42:53 +0000</pubDate>
		<dc:creator>yoye</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[méthode magique]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Task]]></category>
		<category><![CDATA[YAML]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=436</guid>
		<description><![CDATA[Pour un projet récent j&#8217;ai du implémenter un script qui devait insérer des utilisateurs dans la base d&#8217;un projet symfony. Afin de conserver l&#8217;avantage des objets et de leur validator je n&#8217;ai pas effectué un script à base de &#8216;INSERT INTO&#8217; mais j&#8217;ai bel et bien créé ma propre tâche. Je ne vais pas dans [...]]]></description>
			<content:encoded><![CDATA[<p>Pour un projet récent j&#8217;ai du implémenter un script qui devait insérer des utilisateurs dans la base d&#8217;un projet symfony. Afin de conserver l&#8217;avantage des objets et de leur validator je n&#8217;ai pas effectué un script à base de &#8216;INSERT INTO&#8217; mais j&#8217;ai bel et bien créé ma propre tâche.<br />
Je ne vais pas dans cette article vous parler de la façon de créer les tâches pour cela je vous renvoie vers <a href="http://www.symfony-project.org/cookbook/1_2/fr/tasks">le cookbook</a> aucune excuse pour ne pas le lire, il a été traduit en français mais je vais vous parler de la façon dont je l&#8217;ai implémenté dans mon application.</p>
<p>Il s&#8217;agit donc d&#8217;un projet très simple listant des profils d&#8217;utilisateur pour lesquels on spécifie des dates d&#8217;inscription à une option.<br />
<span id="more-436"></span><br />
Voici donc le schéma que l&#8217;on obtient :</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('p436code80'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43680"><td class="code" id="p436code80"><pre class="yml" style="font-family:monospace;">Utilisateur:
actAs:
Timestampable:  ~
columns:
civilite:         { type: string(5)}
nom:              { type: string(150)}
prenom:           { type: string(150)}
email:            { type: string(255), unique: true}
profession:       { type: string(255)}
adresse:          { type: string(255)}
code_postal:      { type: string(10)}
ville:            { type: string(100)}
pays:             { type: string(5)}
date_naissance:   { type: date}
telephone:        { type: string(30)}
site_inscription: { type: string(255)}
option1:         { type: Date}
option2:         { type: Date}
option3:         { type: Date}
option4:         { type: Date}</pre></td></tr></table></div>

<p>On a vu plus compliqué comme schéma. Le but de ma tâche est donc de récupérer des fichiers CSV et de les insérer dans ma base de données. On va commencer par créer notre 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('p436code81'); return false;">View Code</a> BATCH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43681"><td class="code" id="p436code81"><pre class="batch" style="font-family:monospace;">./symfony generate:task import:execute</pre></td></tr></table></div>

<p>On se retrouve donc avec notre class <em>importExecuteTask</em> dans le dossier : <em>/lib/task</em><br />
Dans la partie configure je vais d&#8217;abord définir l&#8217;option file qui va définir le fichier CSV que je veux importer :</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('p436code82'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43682"><td class="code" id="p436code82"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">new</span> sfCommandOption<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'file'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">null</span><span style="color: #339933;">,</span> sfCommandOption<span style="color: #339933;">::</span><span style="color: #004000;">PARAMETER_REQUIRED</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Nom du fichier a traiter'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>Maintenant passons à la partir qui va se charger de l&#8217;import. Dans un premier temps création de ma boucle</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('p436code83'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43683"><td class="code" id="p436code83"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'file'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'r'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fgetcsv</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">5000</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;;&quot;</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;">false</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
 <span style="color: #666666; font-style: italic;">/* Mon code d'insertion */</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Je veux que les utilisateurs déjà existant soit juste mis à jour pour les autres ils seront créé.</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('p436code84'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43684"><td class="code" id="p436code84"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$user</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;">'Utilisateur'</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;">'c'</span><span style="color: #009900;">&#41;</span>
<span style="color: #339933;">-&gt;</span><span style="color: #004000;">andWhere</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'c.email = ? '</span><span style="color: #339933;">,</span> <span style="color: #000088;">$data</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;">-&gt;</span><span style="color: #004000;">fetchOne</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: #339933;">!</span><span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$user</span> <span style="color: #339933;">=</span><span style="color: #000000; font-weight: bold;">new</span> Utilisateur<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: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setEmail</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</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: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setPrenom</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</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;">/* Etc pour chaque champs */</span></pre></td></tr></table></div>

<p>Je veux maintenant préciser les options et pouvoir en ajouter dans le futur assez facilement. Pour cela je vais mettre dans mon fichier <em>apps/monApplication/modules/monModule/config/app.yml</em> la liste de mes options :</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('p436code85'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43685"><td class="code" id="p436code85"><pre class="yml" style="font-family:monospace;">all:
  option: [option1, option2, option3, option4]</pre></td></tr></table></div>

<p>Je vais ensuite définir un attribut dans ma tâche, n&#8217;oublions pas que c&#8217;est une classe et que symfony ou pas il n&#8217;en reste pas moins qu&#8217;on peut lui définir des attributs, j&#8217;insiste sur ce point car je pense que c&#8217;est une des difficultés quand on débute avec symfony, ne pas oublier que l&#8217;on est dans du 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('p436code86'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43686"><td class="code" id="p436code86"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #990000;">static</span> <span style="color: #000088;">$app_yml</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Maitenant que l&#8217;attribut est crée on va lui attribuer la valeur contenu dans le fichier app.yml graĉe à la classe <em>sfYaml()</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('p436code87'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43687"><td class="code" id="p436code87"><pre class="php" style="font-family:monospace;">    protected <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: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$app_yml</span> <span style="color: #339933;">=</span> sfYaml<span style="color: #339933;">::</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span>sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sf_root_dir'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/apps/backend/config/app.yml'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// suite du code ...</span></pre></td></tr></table></div>

<p>Mais à quoi cela peut-il servir ? Et bien par exemple à créer des options à la volée :</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('p436code88'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43688"><td class="code" id="p436code88"><pre class="php" style="font-family:monospace;">protected <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: #666666; font-style: italic;">// Début du code</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$app_yml</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'all'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'option'</span><span style="color: #009900;">&#93;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$option</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: #000088;">$option</span><span style="color: #339933;">,</span><span style="color: #000000; font-weight: bold;">null</span><span style="color: #339933;">,</span>sfCommandOption<span style="color: #339933;">::</span><span style="color: #004000;">PARAMETER_OPTIONAL</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Valeur pour '</span><span style="color: #339933;">.</span><span style="color: #000088;">$option</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">false</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;">// Suite du code</span></pre></td></tr></table></div>

<p>Je me retrouve maintenant avec 4 options supplémentaires que l&#8217;on peut vérifier en tapant 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('p436code89'); return false;">View Code</a> BATCH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43689"><td class="code" id="p436code89"><pre class="batch" style="font-family:monospace;">./symfony help import:execute</pre></td></tr></table></div>

<p>Maintenant que nous avons créé ces options autant les utiliser mais il faut que cela soit dynamique pour cela on va utiliser les méthodes magiques dans ma boucle qui insère les utilisateurs :</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('p436code90'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43690"><td class="code" id="p436code90"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// debut du code</span>
 <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$app_yml</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'all'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'option'</span><span style="color: #009900;">&#93;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$option</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;">$options</span><span style="color: #009900;">&#91;</span>option<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span>__get<span style="color: #009900;">&#40;</span><span style="color: #000088;">$option</span><span style="color: #339933;">,</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Y-m-d'</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: #666666; font-style: italic;">// fin du code</span></pre></td></tr></table></div>

<p>Maintenant lorsque que je vais appeler ma tâche je peux préciser les options auxquelles correspond mon fichier CSV.</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('p436code91'); return false;">View Code</a> BATCH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43691"><td class="code" id="p436code91"><pre class="batch" style="font-family:monospace;">./symfony import:execute --option1=&quot;true&quot;</pre></td></tr></table></div>

<p>Pour terminer voilà un petit conseil pour le traitement de masse et la création multiple d&#8217;objet. En fin de boucle une fois que votre objet ne sera plus utiliser ajouté :</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('p436code92'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p43692"><td class="code" id="p436code92"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// debut du code</span>
<span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">free</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// fin de ma boucle</span></pre></td></tr></table></div>

<p>Ceci évitera certains problèmes de mémoire.</p>
<p>En conclusion :</p>
<p>Dans le futur si des options supplémentaires sont nécessaires je pourrais simplement rajouter une colonne dans ma base de données et compléter mon fichier app.YML. Il est bien évident que l&#8217;on pourrait faire cette gestion dans la base de données directement avec une table lié et une relation 1-1. Mais ici le but été de voir également la possibilité de charger un fichier YML depuis un autre module voir même d&#8217;ailleurs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/12x/symfony-et-les-taches-436/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Internationalisation et formulaire avec Symfony</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/12x/internationalisation-et-formulaire-399</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/12x/internationalisation-et-formulaire-399#comments</comments>
		<pubDate>Wed, 18 Mar 2009 18:18:44 +0000</pubDate>
		<dc:creator>yoye</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[formulaire]]></category>
		<category><![CDATA[I18N]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=399</guid>
		<description><![CDATA[Aujourd&#8217;hui on va traiter des formulaires et de l&#8217;internationalisation. Une des grandes fiert&#233; de Symfony 1.2 est l&#8217;internationalisation et les formulaires.&#160; Vous avez&#160; eu droit &#224; leur chapitre dans les jobeet. En revanche lorsque l&#8217;on veut&#160; coupler les deux, les choses se compliquent un peu et c&#8217;est bien l&#224; l&#8217;int&#233;r&#234;t de notre m&#233;tier. Le but [...]]]></description>
			<content:encoded><![CDATA[<p>Aujourd&#8217;hui on va traiter des formulaires et de l&#8217;internationalisation.  Une des grandes fiert&eacute; de Symfony 1.2 est l&#8217;internationalisation et les formulaires.&nbsp; Vous avez&nbsp; eu droit &agrave; leur chapitre dans les jobeet. En revanche lorsque l&#8217;on veut&nbsp; coupler les deux, les choses se compliquent un peu et c&#8217;est bien l&agrave; l&#8217;int&eacute;r&ecirc;t de notre m&eacute;tier.  Le but de cet article n&#8217;&eacute;tant pas d&#8217;expliquer une nouvelle fois le fonctionnement des formulaires ou de l&#8217;I18N, vous comprendrez que je survole certains points. Je vous renverrez simplement <a href="http://www.symfony-project.org/jobeet/1_2/Doctrine/en/10">ici pour les formulaires</a> et <a href="http://www.symfony-project.org/jobeet/1_2/Doctrine/en/19">ici pour l&#8217;I18N</a> .</p>
<p><span id="more-399"></span></p>
<p>Le but est d&#8217;obtenir un site (un bout de site) qui nous permette de faire un listing de recettes et cela dans diff&eacute;rentes langues, on va se contenter du fran&ccedil;ais et de l&#8217;anglais.  Il faut d&#8217;abord commencer par le sch&eacute;ma :</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('p399code98'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39998"><td class="code" id="p399code98"><pre class="yml" style="font-family:monospace;"> Recipe:
  actAs:
    I18n:
      fields: [name, body, is_activated]
    actAs:
      Sluggable: { fields: [name], uniqueBy: [lang, name] }
  columns:
    name: { type: string(255)}
    body: { type: clob}
    is_activated: { type:boolean, notnull: true, default: 0}</pre></td></tr></table></div>

<p>Le schema est tr&egrave;s simple il n&#8217;y aucune relation avec d&#8217;autres tables, ce qui nous int&eacute;ressent ici c&#8217;est le traitement I18N et les formulaires.  <strong>Petite remarque :</strong>  &#8211; Je passe le is_activated, qui indique si la recette est active ou non, dans le actAs I18N ainsi les recettes par langue seront totalement ind&eacute;pendantes.  &#8211; Le sluggable est pass&eacute; &eacute;galement en deuxi&egrave;me niveau d&#8217;actAs pour permettre &agrave; chaque langue d&#8217;avoir son propre slug.  &#8211; Dernier point, il ne faut surtout pas mettre de unique : true dans la partie columns de notre schema, sinon on va se retrouver &agrave; ne pas pouvoir mettre &agrave; jour une langue ind&eacute;pendament de l&#8217;autre.  Maintenant que l&#8217;on visualise le sch&eacute;ma et donc les classes qui en d&eacute;coulent on va parler code. Comme on en a l&#8217;habitude on va g&eacute;n&eacute;rer nos mod&egrave;les, notre CRUD&nbsp;de recettes.  On va maintenant s&#8217;attaquer &agrave; notre classe RecipeForm.class.php, on veut que l&#8217;utilisateur n&#8217;ai pas &agrave; rentrer les recettes dans les deux langues mais uniquement dans la sienne. Pour cela il faut lui afficher uniquement le formulaire rattach&eacute; &agrave; sa culture.  <strong>Modifions notre classe:</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('p399code99'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39999"><td class="code" id="p399code99"><pre class="php" style="font-family:monospace;"> <span style="color: #000000; font-weight: bold;">class</span> RecipeForm <span style="color: #000000; font-weight: bold;">extends</span> BaseRecipeForm
 <span style="color: #009900;">&#123;</span>
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$lang</span><span style="color: #339933;">;</span> 
&nbsp;
   <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;">$lang</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'fr'</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;">lang</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$lang</span><span style="color: #339933;">;</span> 
&nbsp;
      parent<span style="color: #339933;">::</span>__construct<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>La premi&egrave;re &eacute;tape est donc de red&eacute;finir le constructeur de notre classe auquel on va soumettre une langue par d&eacute;faut et de cr&eacute;er un attribut priv&eacute; pour d&eacute;finir la langue ($lang).  On va maintenant d&eacute;finir l&#8217;affichage de notre formulaire en modifiant la fonction configure()</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('p399code100'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p399100"><td class="code" id="p399code100"><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> configure<span style="color: #009900;">&#40;</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: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lang</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$cultures</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lang</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;">$cultures</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lang</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> 
&nbsp;
  <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$cultures</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$culture</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$i18nObject</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">object</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Translation</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$culture</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$i18n</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RecipeTranslationForm<span style="color: #009900;">&#40;</span><span style="color: #000088;">$i18nObject</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i18n</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$i18n</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'lang'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$i18n</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'is_activated'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$i18n</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</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: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'size'</span><span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">60</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$i18n</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'body'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormTextarea<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cols'</span><span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">58</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'rows'</span><span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">12</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;">embedForm</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$culture</span><span style="color: #339933;">,</span> <span style="color: #000088;">$i18n</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>Dans notre action on va appeler ce formulaire 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('p399code101'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p399101"><td class="code" id="p399code101"><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> executeNew<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;">culture</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;">getCulture</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;">form</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RecipeForm<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">culture</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Vous noterez que l&#8217;on passe la culture en attribut ainsi on peut le r&eacute;cup&eacute;rer dans le template :</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('p399code102'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p399102"><td class="code" id="p399code102"><pre class="php" style="font-family:monospace;">render<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>Il vous suffit de mettre d&eacute;sormais tout les champs et les label &agrave; afficher et le tour est jou&eacute;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/12x/internationalisation-et-formulaire-399/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
