<?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; olivier</title>
	<atom:link href="http://www.lexik.fr/blog/symfony/author/olivier/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>Tips : Symfony 1.3/1.4 orderBy des relations</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/tips-symfony-1-31-4-orderby-des-relations-1026</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/tips-symfony-1-31-4-orderby-des-relations-1026#comments</comments>
		<pubDate>Thu, 14 Jan 2010 14:11:27 +0000</pubDate>
		<dc:creator>olivier</dc:creator>
				<category><![CDATA[1.3.x]]></category>
		<category><![CDATA[1.4.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[orderBy]]></category>
		<category><![CDATA[relation]]></category>

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

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

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

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

<p>J&#8217;espère que cette petite astuce vous aidera.<br />
@bientôt</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/tips-symfony-1-31-4-orderby-des-relations-1026/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Gestion d&#8217;une galerie photo avec swfUpload dans l&#8217;admin</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/gestion-dune-galerie-photo-avec-swfupload-dans-ladmin-918</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/gestion-dune-galerie-photo-avec-swfupload-dans-ladmin-918#comments</comments>
		<pubDate>Wed, 16 Sep 2009 09:49:18 +0000</pubDate>
		<dc:creator>olivier</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[Admingenerator 1.2.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[admin generator]]></category>
		<category><![CDATA[swfUpload]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=918</guid>
		<description><![CDATA[Je vous propose de voir une gestion de galerie photo pour l'administration, telle que je l'ai abordée dans un de mes derniers projets.
C'est à dire avec swfUpload et en ajax dans l'admin generator.]]></description>
			<content:encoded><![CDATA[<p>Je vous propose de voir une gestion de galerie photo pour l&#8217;administration, telle que je l&#8217;ai abordée dans un de mes derniers projets.</p>
<p>Pour vous situer, il s&#8217;agit d&#8217;un site de vente en ligne.<br />
Qui dit vente dit produits, et qui dit produits dit photos <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /><br />
<span id="more-918"></span><br />
L&#8217;idée est de gérer les photos d&#8217;un produit directement depuis sa page d&#8217;édition de l&#8217;admin générator.</p>
<p><img src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/09/upload1-300x99.png" alt="upload1" title="upload1" width="300" height="99" class="alignnone size-medium wp-image-921" /></p>
<p><img src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/09/upload2-300x184.png" alt="upload2" title="upload2" width="300" height="184" class="alignnone size-medium wp-image-922" /></p>
<p><img src="http://www.lexik.fr/blog/symfony/wp-content/uploads/2009/09/upload3-300x178.png" alt="upload3" title="upload3" width="300" height="178" class="alignnone size-medium wp-image-923" /></p>
<p>On a choisi de gérer l&#8217;upload avec swfUpload qui gére un liste d&#8217;attente pour l&#8217;upload de plusieurs fichiers. Et l&#8217;upload en background qui ne gèle pas la page, ca fait plus web2.0 :p<br />
(<a href="http://code.google.com/p/swfupload/" tager="_blank">http://code.google.com/p/swfupload/</a>)</p>
<p>J&#8217;ai téléchargé le <a href="http://swfupload.googlecode.com/files/SWFUpload%20v2.2.0.1%20Samples.zip" target="_blank">SWFUpload v2.2.0.1 Samples.zip</a> et j&#8217;ai utilisé les fichiers du répertoire &laquo;&nbsp;simpledemo&nbsp;&raquo; que j&#8217;ai réparties comme suis.<br />
(Le fichier css d&#8217;origine s&#8217;appelait default.css, je l&#8217;ai renommé pour des raisons évidentes.)</p>
<ul>
<li>/web/swf/swfupload.swf</li>
<li>/web/css/swfUpload.css</li>
<li>/web/js/swfupload.js</li>
<li>/web/js/swfupload.queue.js</li>
<li>/web/js/fileprogress.js</li>
<li>/web/js/handlers.js</li>
<li>/web/images/XPButtonUploadText_61x22.png</li>
</ul>
<p>Un coup d&#8217;oeil rapide à la partie du schema.yml qui nous intéresse. Rien de transcendant, un objet Produit avec quelques champs types et l&#8217;objet ProduitPhoto qui lui est lié. Sur l&#8217;objet ProduitPhoto, un filename et un booléen pour définir l&#8217;image  par défaut du produit.</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('p918code3'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p9183"><td class="code" id="p918code3"><pre class="yml" style="font-family:monospace;">...
Produit:
  tableName:        monprojet_produit
  actAs:
    Timestampable:  ~
  columns:
    id:             { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    nom:            { type: string(255), notnull: true }
    description:    { type: clob }
    prix:           { type: decimal, scale: 2 }
&nbsp;
ProduitPhoto:
  tableName:        monprojet_produit_photo
  columns:
    id:             { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    produit_id:     { type: integer(4), unsigned: true }
    filename:       { type: string(255), notnull: true }
    is_default:     { type: boolean, default: false }
  relations:
    Produit:
      local:        produit_id
      foreign:      id
      foreignAlias: Photos
      onDelete:     CASCADE
...</pre></td></tr></table></div>

<p>On génére l&#8217;admin-generator pour l&#8217;objet produit.</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('p918code4'); return false;">View Code</a> CONSOLE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p9184"><td class="code" id="p918code4"><pre class="console" style="font-family:monospace;">./symfony doctrine:generate-admin backend Produit</pre></td></tr></table></div>

<p>Et c&#8217;est partie !</p>
<p>Pour rajouter cette gestion des images dans l&#8217;ecran d&#8217;édition des produits il faut rajouter un partial à la vue edit.<br />
(On la rajoute uniquement sur l&#8217;edit, car sur l&#8217;écran create, l&#8217;objet n&#8217;est pas encore persisté en base et donc on ne peut pas lui rattacher des objets ProduitPhoto)</p>
<p>Le fonctionnement est le suivant. Le partial général où est inclus et configuré swfUpload (_photoUpload.php). Un parial _photoListe.php inclus dans _photoUpload.php qui servira pour raffraichir la liste en ajax (avec jQuery). Et un dernier partial _ajaxPhotoDelete.php qui ne sert qu&#8217;a retourner l&#8217;animation à faire lors de la suppression d&#8217;une photo.</p>
<p>On commence par positionner le partial _photoUpload.php dans le generator.yml en contexte edit.</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('p918code5'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p9185"><td class="code" id="p918code5"><pre class="yml" style="font-family:monospace;">generator:
  class: sfDoctrineGenerator
  param:
    model_class:           Produit
    theme:                 admin
    non_verbose_templates: true
    with_show:             false
    singular:              ~
    plural:                ~
    route_prefix:          produit_produit
    with_doctrine_route:     1
&nbsp;
    config:
      actions: ~
      fields:
        created_at:        { label: Date de création, date_format: dd/MM/yyyy }
        updated_at:        { label: Date de modification, date_format: dd/MM/yyyy }
        nom:               { label: Nom }
        description:       { label: Déscription }
      list:
        title:             Liste des produits
        display:           [=id, =nom]
      filter: ~
      form: ~
      edit:
        title:             Modifier un produit
        display:
          &quot;Produit&quot;:       [id, nom, description]
          &quot;Photos&quot;:        [_photoUpload]
          &quot;Dates&quot;:         [created_at, updated_at]
      new:
        title:             Ajouter un produit
        display:
          &quot;Produit&quot;:       [id, nom, description]
          &quot;Dates&quot;:         [created_at, updated_at]</pre></td></tr></table></div>

<p>Et on va se pencher plus en détail sur ce partial _photoUpload.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('p918code6'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p9186"><td class="code" id="p918code6"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> use_stylesheet<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'swfUpload.css'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> use_javascript<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery.js'</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> use_javascript<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery-ui.js'</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> use_javascript<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'swfupload.js'</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> use_javascript<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'swfupload.queue.js'</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> use_javascript<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'fileprogress.js'</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> use_javascript<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'handlers.js'</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;pictures_list&quot;</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;sf_admin_form_row&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> include_partial<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'produit/photoListe'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'photos'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPhotos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>div id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;picture_upload&quot;</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;sf_admin_form_row&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;fieldset flash&quot;</span> id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;fsUploadProgress&quot;</span><span style="color: #339933;">&gt;&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;legend&quot;</span><span style="color: #339933;">&gt;</span>File d<span style="color: #0000ff;">'attente.&lt;/span&gt;&lt;/div&gt;
  &lt;div id=&quot;divStatus&quot;&gt;0 fichier uploadé.&lt;/div&gt;
  &lt;div&gt;
    &lt;span id=&quot;spanButtonPlaceHolder&quot;&gt;&lt;/span&gt;
    &lt;input id=&quot;btnCancel&quot; type=&quot;button&quot; value=&quot;Cancel All Uploads&quot; onclick=&quot;$.swfUpload.cancelQueue();&quot; disabled=&quot;disabled&quot; style=&quot;margin-left: 2px; font-size: 8pt; height: 29px;&quot; /&gt;
  &lt;/div&gt;
&lt;/div&gt;
&nbsp;
&lt;script type=&quot;text/javascript&quot;&gt;
&nbsp;
(function($) {
&nbsp;
  $('</span>div<span style="color: #339933;">.</span>actions a<span style="color: #339933;">.</span><span style="color: #000000; font-weight: bold;">default</span><span style="color: #0000ff;">').live('</span>click<span style="color: #0000ff;">', function(event) {
    event.preventDefault();
    $.post(
      $(this).attr('</span>href<span style="color: #0000ff;">'),
      { },
      function(data) {
        $('</span><span style="color: #666666; font-style: italic;">#pictures_list').html(data);</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  $<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'div.actions a.delete'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>live<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'click'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    event<span style="color: #339933;">.</span>preventDefault<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>confirm<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Etes vous sur de vouloir supprimer cette photo ?'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      $<span style="color: #339933;">.</span>post<span style="color: #009900;">&#40;</span>
        $<span style="color: #009900;">&#40;</span>this<span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>attr<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #990000;">eval</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  myQueueComplete <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>numFilesUploaded<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">var</span> status <span style="color: #339933;">=</span> document<span style="color: #339933;">.</span>getElementById<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;divStatus&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    status<span style="color: #339933;">.</span>innerHTML <span style="color: #339933;">=</span> numFilesUploaded <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot; fichier&quot;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>numFilesUploaded <span style="color: #339933;">===</span> <span style="color: #cc66cc;">1</span> ? <span style="color: #0000ff;">&quot;&quot;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;s&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot; uploadé&quot;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>numFilesUploaded <span style="color: #339933;">===</span> <span style="color: #cc66cc;">1</span> ? <span style="color: #0000ff;">&quot;&quot;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;s&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;.&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    $<span style="color: #339933;">.</span>post<span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'&lt;?php echo url_for('</span>produit_ajax_photo_liste<span style="color: #0000ff;">', $form-&gt;getObject()) ?&gt;'</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        $<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'#pictures_list'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>html<span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
  jQuery<span style="color: #339933;">.</span>swfUpload <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SWFUpload<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    flash_url<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;/swf/swfupload.swf&quot;</span><span style="color: #339933;">,</span>
    upload_url<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;&lt;?php echo url_for('produit_photo', <span style="color: #006699; font-weight: bold;">$form-&gt;getObject</span>()) ?&gt;&quot;</span><span style="color: #339933;">,</span>
    post_params<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;&lt;?php echo ini_get('session.name') ?&gt;&quot;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;&lt;?php echo session_id(); ?&gt;&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    file_size_limit<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;100 MB&quot;</span><span style="color: #339933;">,</span>
    file_types<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;*.jpg;*.gif;*.png&quot;</span><span style="color: #339933;">,</span>
    file_types_description<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;Fichiers image&quot;</span><span style="color: #339933;">,</span>
    file_upload_limit<span style="color: #339933;">:</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span>
    file_queue_limit<span style="color: #339933;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
    file_post_name<span style="color: #339933;">:</span> <span style="color: #0000ff;">'photo'</span><span style="color: #339933;">,</span>
    custom_settings<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
      progressTarget<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;fsUploadProgress&quot;</span><span style="color: #339933;">,</span>
      cancelButtonId<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;btnCancel&quot;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    debug<span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">false</span><span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">// Button settings</span>
    button_image_url<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;/images/XPButtonUploadText_61x22.png&quot;</span><span style="color: #339933;">,</span>
    button_width<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;61&quot;</span><span style="color: #339933;">,</span>
    button_height<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;22&quot;</span><span style="color: #339933;">,</span>
    button_placeholder_id<span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;spanButtonPlaceHolder&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">// The event handler functions are defined in handlers.js</span>
    file_queued_handler<span style="color: #339933;">:</span> fileQueued<span style="color: #339933;">,</span>
    file_queue_error_handler<span style="color: #339933;">:</span> fileQueueError<span style="color: #339933;">,</span>
    file_dialog_complete_handler<span style="color: #339933;">:</span> fileDialogComplete<span style="color: #339933;">,</span>
    upload_start_handler<span style="color: #339933;">:</span> uploadStart<span style="color: #339933;">,</span>
    upload_progress_handler<span style="color: #339933;">:</span> uploadProgress<span style="color: #339933;">,</span>
    upload_error_handler<span style="color: #339933;">:</span> uploadError<span style="color: #339933;">,</span>
    upload_success_handler<span style="color: #339933;">:</span> uploadSuccess<span style="color: #339933;">,</span>
    upload_complete_handler<span style="color: #339933;">:</span> uploadComplete<span style="color: #339933;">,</span>
    queue_complete_handler<span style="color: #339933;">:</span> myQueueComplete
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>jQuery<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></pre></td></tr></table></div>

<p>Il faut penser à inclure les différents éléments nécessaires le css et les tout les js. Je les ai inclus ici pour bien les mettre en évidence.<br />
Après il suffit de positionner les différents éléments html nécessaires au fonctionnement de swfUpload.<br />
Et enfin le javascript pour initialiser swfUpload. J&#8217;utilise jQuery pour gérer l&#8217;ajax, j&#8217;ai donc adapté l&#8217;initialisation de swfUpload pour la rendre &laquo;&nbsp;jQuery friendly&nbsp;&raquo; :p</p>
<p>L&#8217;initialisation de swfUpload est assez standard, avec toute une tripoté de paramètres pour définir : le type de fichier accepté, configurer l&#8217;apparence du bouton et configurer tous les retour d&#8217;événements qu&#8217;il est possible d&#8217;utiliser.<br />
J&#8217;ai laissé les gestionnaires d&#8217;événements par défaut à l&#8217;exception de l&#8217;événement de fin d&#8217;upload (myQueueComplete) que j&#8217;ai redéfini pour faire un appel ajax et recharger le partial _photoListe.php.<br />
J&#8217;attire votre attention sur le parametre post_params auquel on passe le session name et le session_id, on verra un peu plus bas le pourquoi du comment <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Le partial _photoListe.php, rien de spécial. Un listing des photos du produit avec 2 liens pour supprimer ou définir comme image par défaut, les 2 faisant appel à une action en ajax.<br />
(NB: On retrouve <a href="http://www.lexik.fr/blog/symfony/symfony/generer-des-thumbs-lors-de-laffichage-dune-image-781" target="_blank">le Helper Thumb de thomas</a> pour les miniatures des photos)</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('p918code7'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p9187"><td class="code" id="p918code7"><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;">'Thumb'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$photos</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$photos</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$photo</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;</span>div id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;photo-&lt;?php echo <span style="color: #006699; font-weight: bold;">$photo-&gt;getId</span>()?&gt;&quot;</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;picture&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #990000;">echo</span> showThumb<span style="color: #009900;">&#40;</span>
  <span style="color: #000088;">$photo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getFilename</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'produits'</span><span style="color: #339933;">,</span>
  <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'height'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">120</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'width'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">120</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'alt'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$photo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getProduit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNom</span><span style="color: #009900;">&#40;</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: #000088;">$photo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getProduit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNom</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'border'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'center'</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'produit-defaut.jpg'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;actions&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$photo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #339933;">&lt;</span>strong<span style="color: #339933;">&gt;&lt;</span>img src<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;/images/backend/star.png&quot;</span> align<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;left&quot;</span> <span style="color: #339933;">/&gt;</span> Par défaut<span style="color: #339933;">&lt;/</span>strong<span style="color: #339933;">&gt;</span>
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">else</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #339933;">&lt;</span>ul<span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;</span>li<span style="color: #339933;">&gt;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo url_for('produit_photo_ajax_default', <span style="color: #006699; font-weight: bold;">$photo</span>) ?&gt;&quot;</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;default&quot;</span><span style="color: #339933;">&gt;&lt;</span>img src<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;/images/backend/star.png&quot;</span> align<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;left&quot;</span> <span style="color: #339933;">/&gt;</span> Par défaut<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;&lt;/</span>li<span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;</span>li<span style="color: #339933;">&gt;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo url_for('produit_photo_ajax_delete', <span style="color: #006699; font-weight: bold;">$photo</span>) ?&gt;&quot;</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;delete&quot;</span><span style="color: #339933;">&gt;&lt;</span>img src<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;/images/backend/cross.png&quot;</span> align<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;left&quot;</span> <span style="color: #339933;">/&gt;</span> Supprimer<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;&lt;/</span>li<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;/</span>ul<span style="color: #339933;">&gt;</span>
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;clear&quot;</span><span style="color: #339933;">&gt;&lt;/</span>div<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">else</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;</span>p<span style="color: #339933;">&gt;</span>Aucune photo pour l<span style="color: #0000ff;">'instant.&lt;/p&gt;
&lt;?php endif; ?&gt;</span></pre></td></tr></table></div>

<p>Le partial _ajaxPhotoDelete.php, c&#8217;est juste l&#8217;effet jQuery-ui pour faire disparaitre la div de la photo qui viens d&#8217;être supprimé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('p918code8'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p9188"><td class="code" id="p918code8"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#photo-&lt;?php echo $photo_id ?&gt;'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">effect</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'drop'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Un petit tour sur le routing.yml pour défnir les différentes routes utilisées.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p918code9'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p9189"><td class="code" id="p918code9"><pre class="yml" style="font-family:monospace;">...
produit_photo:
  url:     /produit/:id/upload
  class:   sfDoctrineRoute
  options: { model: Produit, type: object }
  param:   { module: produit, action: upload }
  requirements:
    sf_method: [get, post]
&nbsp;
produit_photo_ajax_default:
  url:     /produit_photo/:id/default
  class:   sfDoctrineRoute
  options: { model: ProduitPhoto, type: object }
  param:   { module: produit, action: ajaxPhotoDefault }
  requirements:
    sf_method: [post]
&nbsp;
produit_photo_ajax_delete:
  url:     /produit_photo/:id/delete
  class:   sfDoctrineRoute
  options: { model: ProduitPhoto, type: object }
  param:   { module: produit, action: ajaxPhotoDelete }
  requirements:
    sf_method: [post]
&nbsp;
produit_ajax_photo_liste:
  url:     /produit_photo/:id/list
  class:   sfDoctrineRoute
  options: { model: Produit, type: object }
  param:   { module: produit, action: ajaxPhotoListe }
  requirements:
    sf_method: [post]
...</pre></td></tr></table></div>

<p>On utilise la classe formulaire qui va gérer l&#8217;upload.<br />
Il faut désactiver le csrf car l&#8217;envoie n&#8217;est pas effectué par le formulaire mais par l&#8217;animation flash.</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('p918code10'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p91810"><td class="code" id="p918code10"><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> ProduitPhotoForm <span style="color: #000000; font-weight: bold;">extends</span> BaseProduitPhotoForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'produit_id'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormInputHidden<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'is_default'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormInputHidden<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'filename'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormInputFile<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: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'filename'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorFile<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: #339933;">,</span>
      <span style="color: #0000ff;">'path'</span>       <span style="color: #339933;">=&gt;</span> sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sf_upload_dir'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/produits/source'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'mime_types'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'web_images'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'max_size'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">10485760</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;">'max_size'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Fichier trop gros (10Mo maximum).'</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;">disableCSRFProtection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Et enfin l&#8217;action.class.php qui orchestre tout ca.<br />
Au niveau de l&#8217;action executeUpload il faut créer &laquo;&nbsp;à la main&nbsp;&raquo; le tableau des paramètres à passer au bind.</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('p918code11'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p91811"><td class="code" id="p918code11"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <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;">'/../lib/produitGeneratorConfiguration.class.php'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</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;">'/../lib/produitGeneratorHelper.class.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * produit actions.
 *
 * @package    
 * @subpackage produit
 * @author     
 * @version    SVN: $Id: actions.class.php 12474 2008-10-31 10:41:27Z fabien $
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> produitActions <span style="color: #000000; font-weight: bold;">extends</span> autoProduitActions
<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> executeUpload<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;">produit</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">produit</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;">form</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ProduitPhotoForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$values</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'produit_id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">produit</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;">'is_default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">produit</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPhotos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000000; font-weight: bold;">false</span> <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'filename'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getFiles</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'photo'</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;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #339933;">,</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isValid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$photo</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;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$return</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'ok'</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;">$return</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'ko'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderText</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$return</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * ajax pour definir une photo par defaut
   *
   * @param sfWebRequest $request
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeAjaxPhotoDefault<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isXmlHttpRequest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$photo</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$produit</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$photo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getProduit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$old_default</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$produit</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPhotoDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$produit</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setPhotoDefaut</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$photo</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>
&nbsp;
      <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderPartial</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'produit/photoListe'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'photos'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$produit</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPhotos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect404</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;
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * ajax pour effacer une photo
   *
   * @param sfWebRequest $request
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeAjaxPhotoDelete<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isXmlHttpRequest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$photo</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$photo_id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$photo</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: #000088;">$photo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderPartial</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'produit/ajaxPhotoDelete'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'photo_id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$photo_id</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect404</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;
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * ajax pour avoir la liste des photos
   *
   * @param sfWebRequest $request
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeAjaxPhotoListe<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isXmlHttpRequest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$produit</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderPartial</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'produit/photoListe'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'photos'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$produit</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPhotos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect404</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;
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Produit.class.php</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p918code12'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p91812"><td class="code" id="p918code12"><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> Produit <span style="color: #000000; font-weight: bold;">extends</span> BaseProduit
<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> setPhotoDefaut<span style="color: #009900;">&#40;</span><span style="color: #000088;">$photoId</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    Doctrine_Query<span style="color: #339933;">::</span><span style="color: #004000;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">-&gt;</span><span style="color: #004000;">update</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ProduitPhoto p'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'p.is_default'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'?'</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;">-&gt;</span><span style="color: #004000;">where</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'p.produit_id = ?'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</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;">-&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>
&nbsp;
    Doctrine_Query<span style="color: #339933;">::</span><span style="color: #004000;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">-&gt;</span><span style="color: #004000;">update</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ProduitPhoto p'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'p.is_default'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'?'</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;">-&gt;</span><span style="color: #004000;">andWhere</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'p.id = ?'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$photoId</span><span style="color: #009900;">&#41;</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>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getPhotoDefault<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ProduitPhoto'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDefault</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</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: #009900;">&#125;</span></pre></td></tr></table></div>

<p>ProduitPhotoTable.class.php</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p918code13'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p91813"><td class="code" id="p918code13"><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> ProduitPhotoTable <span style="color: #000000; font-weight: bold;">extends</span> Doctrine_Table
<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> getDefault<span style="color: #009900;">&#40;</span><span style="color: #000088;">$produit_id</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;">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.produit_id = ?'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$produit_id</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.is_default = ?'</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;">-&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>
  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>ProduitPhoto.class.php</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p918code14'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p91814"><td class="code" id="p918code14"><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> ProduitPhoto <span style="color: #000000; font-weight: bold;">extends</span> BaseProduitPhoto
<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> isDefault<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>bool<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getIsDefault</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: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>Le problème !</h2>
<p>A ce stade, tout est fini et en place pour que ca marche. Hors ca ne marche pas&#8230; Pourquoi ? Je rapelle le contexte, on est dans l&#8217;admin donc on est identifié et c&#8217;est là le problème. En effet swfUpload est une animation flash contenu dans le page mais qui va initialiser des requêtes http parallèles à celle utilisée par le navigateur. Et donc lorsque swfUpload se pointe à l&#8217;url &laquo;&nbsp;produit_photo&nbsp;&raquo; pour initialisé son upload, il se prend une belle erreur 403&#8230;</p>
<p>Le problème est connu des concepteurs de swfUpload et la solutions qu&#8217;ils préconisent est de forcé l&#8217;identifiant de session dans le script d&#8217;upload en faisant un session_id($session_id). C&#8217;est pourquoi on le fait passer dans la variable &laquo;&nbsp;post_params&nbsp;&raquo; à l&#8217;initialisation de swfUpload.</p>
<p>Pour faire la même chose dans symfony on ne peut pas le faire dans une action, car la session est déjà initialisée à ce niveau. On est obligé d&#8217;aller modifié le factories.yml et la calsse la classe sfSessionStorage pour aller forcer l&#8217;identifiant de session dans le cas ou on fait appel à l&#8217;action upload.</p>
<p>C&#8217;est un tip que j&#8217;ai trouvé sur le <a href="http://forum.symfony-project.org/index.php/m/42999/" target="_blank">forum symfony</a> qui était pour la version 1.0, et qui fonctionne toujours à la différence que le contexte n&#8217;est plus passé en paramètre dans la 1.2 et donc il faut aller le charger.</p>
<p>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('p918code15'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p91815"><td class="code" id="p918code15"><pre class="yml" style="font-family:monospace;">...
all:
...
  storage:
    class: mySessionStorage
    param:
      session_name: weezobackend
...</pre></td></tr></table></div>

<p>mySessionStorage.calss.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('p918code16'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p91816"><td class="code" id="p918code16"><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> mySessionStorage <span style="color: #000000; font-weight: bold;">extends</span> sfSessionStorage
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> initialize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</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>
    <span style="color: #000088;">$context</span> <span style="color: #339933;">=</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;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//Shitty work-around for swfuploader</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$context</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getActionName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">&quot;upload&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$sessionName</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$parameters</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;session_name&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</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;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sessionName</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #990000;">session_name</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sessionName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">session_id</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</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;
    parent<span style="color: #339933;">::</span><span style="color: #004000;">initialize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</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>Ça y est, cette fois ça marche !<br />
Et vous avez une gestion d&#8217;images directement dans la fiche du produit qui est assez user-friendly <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Merci d&#8217;avoir lu jusqu&#8217;au bout :p<br />
Je reste à votre disposition pour toute questions ou suggestions <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
@bientôt !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/gestion-dune-galerie-photo-avec-swfupload-dans-ladmin-918/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Du Javascript dynamique dans une vue en utilisant sf_format</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/du-javascript-dynamique-dans-une-vue-en-utilisant-sf_format-746</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/du-javascript-dynamique-dans-une-vue-en-utilisant-sf_format-746#comments</comments>
		<pubDate>Wed, 08 Jul 2009 08:13:32 +0000</pubDate>
		<dc:creator>olivier</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[sf_format]]></category>
		<category><![CDATA[vue]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=746</guid>
		<description><![CDATA[Il arrive que l&#8217;on ai besoin d&#8217;utiliser un script javascript spécifique dans une vue. Un script dynamique qui nécessite d&#8217;être renseigné par des informations de php (utiliser des variables ou des méthodes de nos objets). Dans mon précédent post j&#8217;évoquais les différentes possibilités d&#8217;inclure le javascript dans les vues. Mettre des balises &#60;script&#62; directement au [...]]]></description>
			<content:encoded><![CDATA[<p>Il arrive que l&#8217;on ai besoin d&#8217;utiliser un script javascript spécifique dans une vue. Un script dynamique qui nécessite d&#8217;être renseigné par des informations de php (utiliser des variables ou des méthodes de nos objets).</p>
<p>Dans mon précédent post j&#8217;évoquais les différentes possibilités d&#8217;inclure le javascript dans les vues.</p>
<ul>
<li>Mettre des balises &lt;script&gt; directement au milieu du html (un peu crade mais efficace)</li>
<li>Faire un fichier .js &laquo;&nbsp;en dur&nbsp;&raquo; dans le dossier /web/js (mais là on perd la possibilité d&#8217;utiliser du php)</li>
<li>Utiliser un slot dans le &lt;head&gt; du template</li>
<li>Utiliser une vue</li>
</ul>
<p>C&#8217;est ce dernier point que je vous propose de voir aujourd&#8217;hui.</p>
<p><span id="more-746"></span></p>
<p>Pour se dessiner un petit background on va prendre l&#8217;exemple d&#8217;une vue index dans un module d&#8217;actualités.<br />
Dans cette vue on veut faire un appel ajax sur un lien et on veut utiliser le routing pour définir l&#8217;url du script à appeler.</p>
<p>On va donc utiliser une action et deux vues, une pour la page html et une pour le javascript qui sera inclus dans la vue html. On utilise des sf_format différents.
<p>On créé la route qui servira pour les deux vues (/app/frontend/config/routing.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('p746code24'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p74624"><td class="code" id="p746code24"><pre class="yml" style="font-family:monospace;">...
actu_index:
  url:   /actualites/index.:sf_format
  param: { module: actu, action: index, sf_format: html }
...</pre></td></tr></table></div>

<p>Dans notre action on récupère juste les dernières actualités à afficher dans la page html (/app/frontend/modules/actu/actions/actions.class.php).</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p746code25'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p74625"><td class="code" id="p746code25"><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> actuActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<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> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">actus</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;">'Actu'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLast</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: #009900;">&#125;</span></pre></td></tr></table></div>

<p>La vue Html. C&#8217;est la que ca se passe ! On fais un use_javascript() auquel on passe le url_for() de la même vue en spécifiant juste le sf_format à &#8216;js&#8217; (/app/frontend/modules/actu/templates/indexSuccess.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('p746code26'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p74626"><td class="code" id="p746code26"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> use_javascript<span style="color: #009900;">&#40;</span>url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@actu_index?sf_format=js'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;liste_actus&quot;</span><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;">$actus</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$actu</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;actu&quot;</span><span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;</span>h3<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;">$actu</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getTitre</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>h3<span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;</span>p<span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #990000;">echo</span> <span style="color: #000088;">$actu</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getTexteCourt</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>p<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;action&quot;</span><span style="color: #339933;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;?</span>php <span style="color: #990000;">echo</span> link_to<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Lire la suite'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'@actu_detail'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;</span>div<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span>
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Et donc la vue js sera inclue par la vue html qui rajoute dans le head l&#8217;appel au 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('p746code27'); return false;">View Code</a> HTML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p74627"><td class="code" id="p746code27"><pre class="html" style="font-family:monospace;">&lt;script type=&quot;text/javascript&quot; src=&quot;/actualites/index.js&quot;&gt;&lt;/script&gt;</pre></td></tr></table></div>

<p>Il ne reste plus qu&#8217;a faire la script javascript dans la vue /app/frontend/modules/actu/templates/indexSuccess.js.php ou on peut avoir accès  à tous les éléments de symfony que l&#8217;on désire.</p>
<p>Par exemple là un peut appel ajax en jQuery ou je récupère l&#8217;url du script appelé grâce au routing.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p746code28'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p74628"><td class="code" id="p746code28"><pre class="javascript" style="font-family:monospace;">jQuery<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div.action a'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    event.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    $.<span style="color: #660066;">post</span><span style="color: #009900;">&#40;</span>
      <span style="color: #3366CC;">'&lt;?php echo url_for('</span><span style="color: #339933;">@</span>actu_detail<span style="color: #3366CC;">') ?&gt;'</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span> url<span style="color: #339933;">:</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'href'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">'script'</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Il se peut que dans la vue javascript on n&#8217;ait pas besoin d&#8217;exécuter toute l&#8217;action.<br />
Par exemple ici, dans ma vue javascript, je n&#8217;ai pas besoin des dernières actualités, il est donc possible de filtrer pour alléger l&#8217;action grâce au sf_format.</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('p746code29'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p74629"><td class="code" id="p746code29"><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> actuActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<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> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sf_format'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">'js'</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;">actus</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;">'Actu'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLast</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: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Après, libre a chacun de voir si on doit utiliser la même action que la vue html ou si la vue javascript nécessite sa propre action.</p>
<p>En utilisant une action séparée pour la vue javascript on peut s&#8217;amuser à pousser le vice du camouflage en utilisant un routing qui fasse croire que l&#8217;on appelle un fichier .js (Attention si jamais un fichier avec le même nom existe réellement dans le répertoire /web/js c&#8217;est ce dernier qui sera inclus).</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('p746code30'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p74630"><td class="code" id="p746code30"><pre class="yml" style="font-family:monospace;">...
actu_index_js:
  url:   /js/actu.:sf_format
  param: { module: actu, action: index, sf_format: js }
...</pre></td></tr></table></div>

<p><b>Avantage de cette technique :</b></p>
<ul>
<li>Un code source html super &laquo;&nbsp;clean&nbsp;&raquo;</li>
</ul>
<p><b>Inconvéniant :</b></p>
<ul>
<li>Pour une page html, on fait deux appels à symfony.<br />
A utiliser avec parcimonie et bien optimiser les actions pour ne pas faire des requêtes inutiles sur la base de donnée.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/du-javascript-dynamique-dans-une-vue-en-utilisant-sf_format-746/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Listes déroulantes mises à jours en Ajax avec jQuery</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/listes-deroulantes-mises-a-jours-en-ajax-avec-jquery-704</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/listes-deroulantes-mises-a-jours-en-ajax-avec-jquery-704#comments</comments>
		<pubDate>Wed, 17 Jun 2009 08:49:39 +0000</pubDate>
		<dc:creator>olivier</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Liste déroulante]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=704</guid>
		<description><![CDATA[Un petit TIPS pour faire des listes déroulantes liées qui s&#8217;enrichissent en fonction de la valeur choisie sur l&#8217;une d&#8217;entre elles. (J&#8217;ai l&#8217;impression que la phrase est très compliqué pour pas grand chose ^^) Le tout en Ajax en utilisant jQuery. Dans mon exemple, ça sera tout simplement un formulaire Lambda avec des listes déroulante [...]]]></description>
			<content:encoded><![CDATA[<p>Un petit TIPS pour faire des listes déroulantes liées qui s&#8217;enrichissent en fonction de la valeur choisie sur l&#8217;une d&#8217;entre elles.<br />
(J&#8217;ai l&#8217;impression que la phrase est très compliqué pour pas grand chose ^^)<br />
Le tout en Ajax en utilisant jQuery.<br />
<span id="more-704"></span><br />
Dans mon exemple, ça sera tout simplement un formulaire Lambda avec des listes déroulante pour les Régions et les Départements.<br />
Le fonctionnement est le suivant. Par défaut les listes déroulantes sont initialisées avec toutes les valeurs. Dés que l&#8217;on choisi une valeur pour la région, la liste déroulante des département affine sa liste pour ne proposer que les départements de la région saisie.</p>
<p>Vite fait, le schéma utilisé :</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('p704code36'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p70436"><td class="code" id="p704code36"><pre class="yml" style="font-family:monospace;">...
Region:
  tableName:  region
  actAs:
    Sluggable:
      unique: true
      fields: [nom]
  columns:
    id:       { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    nom:      { type: string(255), notnull: true }
&nbsp;
Departement:
  tableName: departement
  actAs:
    Sluggable:
      unique: true
      fields: [nom]
  columns:
    id:        { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    nom:       { type: string(255), notnull: true }
    region_id: { type: integer(4), unsigned: true }
  relations:
    Region:
      local:        region_id
      foreign:      id
      foreignAlias: Departements
      onDelete:     CASCADE
...</pre></td></tr></table></div>

<p>Juste pour mettre en évidence la relation entre le Département et la Région, avec le très important le foreignAlias que j&#8217;aime tant <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Pour faire fonctionner tout ça on va avoir besoin de :<br />
 &#8211; 1 route<br />
 &#8211; 1 action minuscule<br />
 &#8211; 1 partial de 4 lignes<br />
 &#8211; 1 tout petit bout de javascript</p>
<p>La route :</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('p704code37'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p70437"><td class="code" id="p704code37"><pre class="javascript" style="font-family:monospace;"># routing.<span style="color: #660066;">yml</span>
...
<span style="color: #660066;">ajax_departement</span><span style="color: #339933;">:</span>
  url<span style="color: #339933;">:</span>   <span style="color: #339933;">/</span>ajax<span style="color: #339933;">/</span>departement
  param<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> module<span style="color: #339933;">:</span> lambda<span style="color: #339933;">,</span> action<span style="color: #339933;">:</span> ajaxDepartement <span style="color: #009900;">&#125;</span>
...</pre></td></tr></table></div>

<p>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('p704code38'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p70438"><td class="code" id="p704code38"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// actions.class.php</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * requete ajax pour avoir la liste des déparements de la région
   *
   * @param sfWebRequest $request
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeAjaxDepartement<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;">$region</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;">'Region'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">findOneById</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'region'</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;">renderPartial</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'lambda/selectDepartement'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'region'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$region</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Le partial :</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('p704code39'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p70439"><td class="code" id="p704code39"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// _selectDepartement.php</span>
<span style="color: #339933;">&lt;</span>option value<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">&gt;&lt;/</span>option<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;">$region</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDepartements</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$departement</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;</span>option value<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo <span style="color: #006699; font-weight: bold;">$departement-&gt;getId</span>() ?&gt;&quot;</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;">$departement</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNom</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>option<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Et enfin le petit bout de code jQuery à rajouter au formulaire :</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('p704code40'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p70440"><td class="code" id="p704code40"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script language<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;javascript&quot;</span><span style="color: #339933;">&gt;</span>
$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#mon_formulaire_lambda_region_id&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">change</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    $.<span style="color: #660066;">post</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;/ajax/departement&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> region<span style="color: #339933;">:</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#mon_formulaire_lambda_departement_id&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Pour le javascript plusieurs solutions. Soit l&#8217;inclure directement dans la vue avec les balises <script></script> comme je l&#8217;ai fait ici.<br />
Soit faire un fichier .js que l&#8217;on met dans /web/js/mon_fichier.js (bien mais pas top <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ).</p>
<p>Le plus &laquo;&nbsp;propre&nbsp;&raquo; est de faire une vue et d&#8217;utiliser le sf_format et d&#8217;inclure le fichier via une route.<br />
On verra ça lors d&#8217;un prochain post <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>@bientôt !</p>
<p>NB : Bien entendu il faut que jQuery soi inclus :<br />
 &#8211; Soit il est inclus dans le view.yml<br />
 &#8211; Soit directement dans la vue avec un use_javascript(&#8216;jQuery.js&#8217;)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/listes-deroulantes-mises-a-jours-en-ajax-avec-jquery-704/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Utilisation de sfDoctrineGuardPlugin pour la gestion des utilisateurs</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-sfdoctrineguardplugin-pour-la-gestion-des-utilisateurs-634</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-sfdoctrineguardplugin-pour-la-gestion-des-utilisateurs-634#comments</comments>
		<pubDate>Wed, 27 May 2009 12:01:50 +0000</pubDate>
		<dc:creator>olivier</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[sfguard]]></category>
		<category><![CDATA[utilisateur]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=634</guid>
		<description><![CDATA[sfDoctrineGuardPlugin comme son nom l&#8217;indique est la version Doctrine de sfGuardPlugin qui est THE plugin de gestion des utilisateurs de Symfony. Il comporte des formulaires d&#8217;identification et d&#8217;inscription très basique, mais son principal point fort est la gestion des droits associés aux utilisateurs, la possibilité de gérer des groupes le tout générant automatiquement les crédentials [...]]]></description>
			<content:encoded><![CDATA[<p>sfDoctrineGuardPlugin comme son nom l&#8217;indique est la version Doctrine de sfGuardPlugin qui est <strong>THE plugin</strong> de gestion des utilisateurs de Symfony.</p>
<p>Il comporte des formulaires d&#8217;identification et d&#8217;inscription très basique, mais son principal point fort est la gestion des droits associés aux utilisateurs, la possibilité de gérer des groupes le tout générant automatiquement les crédentials qui va permettre de sécuriser l&#8217;application de manière très simple.</p>
<p><span id="more-634"></span></p>
<p>Je ne reviendrai pas sur la gestion des crédentials qui est très bien expliquée dans le <a href="http://www.symfony-project.org/jobeet/1_2/Doctrine/en/13#chapter_13_application_security" target="_blank">Jobeet #13</a>.</p>
<p>De même pour l&#8217;installation. <a href="http://www.symfony-project.org/plugins/sfDoctrineGuardPlugin" targer="_blank">Le readme</a> est très bien fait et explique très clairement comment faire.</p>
<h2>Le modèle de données</h2>
<p>Le modèle de données du plugin comporte la table des Utilisateurs, des Groupes et des Permissions ainsi que les tables d&#8217;associations entre Utilisateurs/Permissions, Groupes/Permissions et Utilsateurs/Groupes.</p>
<p>Ce sont les permissions attribuées à un utilisateur (directement ou par ses groupes) qui déterminent les crédentials qu&#8217;il aura une fois logué (C&#8217;est le nom de la permission qui sera le nom du crédential).</p>
<p>Pour illustrer tout ca, on va voir un petit exemple.</p>
<p>On prends une structure simple, avec 2 groupes et 3 permissions.<br />
Les permissions de Lecture, Ecriture et Téléchargement (même si la loi Hadopie a été votée ^^).<br />
Les groupes Admin qui a tous les droits et Membre qui n&#8217;a que le droit de lecture.</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('p634code49'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63449"><td class="code" id="p634code49"><pre class="yml" style="font-family:monospace;">&nbsp;
sfGuardPermission:
  pLecture:
    name: lecture
  pEcriture:
    name: ecriture
  pTelegargement:
    name: telechargement
&nbsp;
sfGuardGroup:
  gAdmin:
    name: admin
  gMembre:
    name: membre
&nbsp;
sfGuardGroupPermission:
  gp1:
    sfGuardGroup:      gAdmin
    sfGuardPermission: pLecture
  gp2:
    sfGuardGroup:      gAdmin
    sfGuardPermission: pEcriture
  gp3:
    sfGuardGroup:      gAdmin
    sfGuardPermission: pTelegargement
  gp4:
    sfGuardGroup:      gMembre
    sfGuardPermission: pLecture</pre></td></tr></table></div>

<p>Et 3 utilisateurs : Toto, Titi et Tata à qui on va définir des droits différents.</p>
<p>- Toto sera dans le groupe admin, il aura ainsi tout les droits.<br />
- Titi et Tata seront dans le groupe Membre et auront ainsi seulement le droit de Lecture.<br />
- Titi a en plus le droit de téléchargement.</p>
<p>Ce qui se traduit en fixture comme ceci :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p634code50'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63450"><td class="code" id="p634code50"><pre class="yml" style="font-family:monospace;">&nbsp;
sfGuardUser:
  Toto:
    username: toto
    password: t0t0
  Titi:
    username: titi
    password: t1t1
  Tata:
    username: tata
    password: t4t4
&nbsp;
sfGuardUserGroup:
  ug1:
    sfGuardUser:  Toto
    sfGuardGroup: gAdmin
  ug2:
    sfGuardUser:  Titi
    sfGuardGroup: gMembre
  ug3:
    sfGuardUser:  Tata
    sfGuardGroup: gMembre
&nbsp;
sfGuardUserPermission:
  up1:
    sfGuardUser:       Titi
    sfGuardPermission: pTelegargement</pre></td></tr></table></div>

<p>Dans un module lambda, on peut donc très facilement sécuriser nos pages comme suit.</p>
<p>/module/config/security.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('p634code51'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63451"><td class="code" id="p634code51"><pre class="yml" style="font-family:monospace;">secure:
  is_secure:   on
&nbsp;
telechargement:
  is_secure:   on
  credentials: [lecture, telechargement]
&nbsp;
default:
  is_secure:   off</pre></td></tr></table></div>

<p>La page secure nécessite que l&#8217;utilisateur soit connecté mais il n&#8217;y a aucune restriction de crédential. Les 3 utilisateur, une fois logés, pourront y accéder.</p>
<p>La page téléchargement nécessite 2 permissions lecture et téléchargement. Seuls Toto et Titi y auront accès. Tata sera redirigé automatiquement vers la page d&#8217;erreur de permissions.</p>
<h2>La redirection après l&#8217;authentification.</h2>
<p>L&#8217;authentification est gérée par le plugin, il suffit d&#8217;envoyer l&#8217;utilisateur vers la route @sf_guard_signin.</p>
<p>Une fois l&#8217;authentification effectuée, le script redirige l&#8217;utilisateur. Par défaut l&#8217;utilisateur est redirigé vers le HTTP_REFERER.</p>
<p>Heureusement on peut aussi déterminer une route vers laquelle on veut être redirigé après l&#8217;authentification de plusieurs manières.</p>
<p>Premièrement via des variable du app.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('p634code52'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63452"><td class="code" id="p634code52"><pre class="yml" style="font-family:monospace;">all:
  sf_guard_plugin:
    success_signin_url:      @my_route?param=value
    success_signout_url:     module/action</pre></td></tr></table></div>

<p>Autre méthode qui consiste à utiliser le comportement par défaut de redirection vers le referer, mais en utilisant la méthode setReferer() de la classe sfGuardSecurityUser.</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('p634code53'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63453"><td class="code" id="p634code53"><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> moduleActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<span style="color: #009900;">&#123;</span>
  <span style="color: #339933;">...</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeAction<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #339933;">...</span>
    <span style="color: #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;">setReferer</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@my_route'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@sf_guard_signin'</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>L&#8217;ordre de priorité est :<br />
- la variable du fichier app.yml<br />
- le getReferer() du GuardUser<br />
- le HTTP_REFERER</p>
<h2>Connecter automatiquement un utilisateur</h2>
<p>Il est possible de connecter automatiquement un utilisateur grâce à la méthode signin() à la quelle on doit passer une instance de sfGuardUser.</p>
<p>Par exemple dans une action quelconque :</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('p634code54'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63454"><td class="code" id="p634code54"><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> moduleActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<span style="color: #009900;">&#123;</span>
  <span style="color: #339933;">...</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeAction<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #339933;">...</span>
    <span style="color: #000088;">$utilisateur</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;">'sfGuardUser'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">findOneByUsername</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'toto'</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;">signin</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$utilisateur</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #339933;">...</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>Associer un ou plusieurs groupes à un utilisateur</h2>
<p>On a vu au début de l&#8217;article comment associer des groupes aux utilisateurs par le fixture.</p>
<p>On va voir ici comment le faire en php.</p>
<p>Par exemple si on avait à le faire dans le script d&#8217;inscription et qu&#8217;on veulait associer automatiquement le groupe membre aux utilisateurs qui s&#8217;inscrivent.</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('p634code55'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63455"><td class="code" id="p634code55"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeInscription<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfGuardUserFormRegister<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">// la classe de formulaire sfGuardUserFormRegister n'existe pas dans le plugin par defaut</span>
  <span style="color: #666666; font-style: italic;">// je la mets en annexe à la fin de l'article</span>
&nbsp;
  <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isMethod</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'post'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isValid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$permission</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;">'sfGuardGroup'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">findOneByName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'membre'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$utilisateur</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;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$utilisateur</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'permissions'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$permission</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$utilisateur</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">signIn</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$utilisateur</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@homepage'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>Annexe</h2>

<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('p634code56'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p63456"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
</pre></td><td class="code" id="p634code56"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * formulaire d'inscription
 *
 * @package    form
 * @subpackage sfGuardUser
 * @author     Lexik
 * @version    SVN: $Id: sfDoctrineFormTemplate.php 6174 2007-11-27 06:22:40Z fabien $
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> sfGuardUserFormRegister <span style="color: #000000; font-weight: bold;">extends</span> PluginsfGuardUserForm
<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> configure<span style="color: #009900;">&#40;</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;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'groups_list'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'permissions_list'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'algorithm'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'salt'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'is_active'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'is_super_admin'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'last_login'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'created_at'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'updated_at'</span><span style="color: #009900;">&#93;</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: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span>     <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormInputPassword<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password_bis'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormInputPassword<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLabels</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'username'</span>     <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Email* :'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'password'</span>     <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Mot de passe* :'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'password_bis'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Confirmation* :'</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;">validatorSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'username'</span><span style="color: #009900;">&#93;</span>     <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorEmail<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;">'Cet email n\'</span>est pas valide<span style="color: #339933;">.</span><span style="color: #0000ff;">', '</span>required<span style="color: #0000ff;">' =&gt; '</span>Champ obligatoire<span style="color: #339933;">.</span><span style="color: #0000ff;">'));
    $this-&gt;validatorSchema['</span>password<span style="color: #0000ff;">']     = new sfValidatorString(array('</span>required<span style="color: #0000ff;">' =&gt; true, '</span>min_length<span style="color: #0000ff;">' =&gt; 6), array('</span>min_length<span style="color: #0000ff;">' =&gt; '</span><span style="color: #0000ff;">&quot;%value%&quot;</span> est trop court <span style="color: #009900;">&#40;</span><span style="color: #339933;">%</span>min_length<span style="color: #339933;">%</span> lettres minimum<span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">', '</span>required<span style="color: #0000ff;">' =&gt; '</span>Champ obligatoire<span style="color: #339933;">.</span><span style="color: #0000ff;">'));
    $this-&gt;validatorSchema['</span>password_bis<span style="color: #0000ff;">'] = new sfValidatorString(array('</span>required<span style="color: #0000ff;">' =&gt; true, '</span>min_length<span style="color: #0000ff;">' =&gt; 6), array('</span>min_length<span style="color: #0000ff;">' =&gt; '</span><span style="color: #0000ff;">&quot;%value%&quot;</span> est trop court <span style="color: #009900;">&#40;</span><span style="color: #339933;">%</span>min_length<span style="color: #339933;">%</span> lettres minimum<span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">', '</span>required<span style="color: #0000ff;">' =&gt; '</span>Champ obligatoire<span style="color: #339933;">.</span><span style="color: #0000ff;">'));
&nbsp;
    $this-&gt;mergePostValidator(new sfValidatorSchemaCompare(
      '</span>password<span style="color: #0000ff;">',
      sfValidatorSchemaCompare::EQUAL,
      '</span>password_bis<span style="color: #0000ff;">',
      array(),
      array('</span>invalid<span style="color: #0000ff;">' =&gt; '</span>Les champs doivent être identiques<span style="color: #339933;">.</span><span style="color: #0000ff;">')
    ));
  }
&nbsp;
}</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/utilisation-de-sfdoctrineguardplugin-pour-la-gestion-des-utilisateurs-634/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Schema.yml Doctrine, Bonnes pratiques, Convention de nommage et fonctions magiques</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/schemayml-doctrine-bonnes-pratiques-convention-de-nommage-et-fonctions-magiques-508</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/schemayml-doctrine-bonnes-pratiques-convention-de-nommage-et-fonctions-magiques-508#comments</comments>
		<pubDate>Tue, 21 Apr 2009 13:14:33 +0000</pubDate>
		<dc:creator>olivier</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[doctrine]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=508</guid>
		<description><![CDATA[On c'est rendu compte ici qu'il y avait pas mal de questions en rapport avec le schema.yml qui ressortaient régulièrement.

Le schema.yml est généralement trop vite oublié. C'est facile à faire, ça génère la base sans trop se poser de questions, et puis on l'oublie... Alors que le schema.yml est certainement le fichier le plus important d'une application Symfony.

Je vais donc essayer de regrouper dans ce post les questions auxquelles on réponds généralement par "Regardes dans ton schema.yml" où "Comment est ce que tu l'as défini dans ton schema.yml ?". Notamment au niveau des définitions des relations et les méthodes magiques qui en découlent.]]></description>
			<content:encoded><![CDATA[<p>On s&#8217;est rendu compte ici qu&#8217;il y avait pas mal de questions en rapport avec le schema.yml qui ressortaient régulièrement.</p>
<p>Le schema.yml est généralement trop vite oublié. C&#8217;est facile à faire, ça génère la base sans trop se poser de questions, et puis on l&#8217;oublie&#8230; Alors que le schema.yml est certainement <strong>le fichier le plus important</strong> d&#8217;une application Symfony.  </p>
<p>Je vais donc essayer de regrouper dans ce post les questions auxquelles on répond généralement par &laquo;&nbsp;Regardes dans ton schema.yml&nbsp;&raquo; où &laquo;&nbsp;Comment est ce que tu l&#8217;as défini dans ton schema.yml ?&nbsp;&raquo;. </p>
<p>Notamment au niveau des définitions des relations et les méthodes magiques qui en découlent.</p>
<p><span id="more-508"></span></p>
<p>Tout d&#8217;abord un petit bookmark des pages à lire et à relire de la documentation doctrine. </p>
<ul>
<li><a href="http://www.doctrine-project.org/documentation/manual/1_1/en/defining-models#columns">Les types de colonnes</a></li>
<li><a href="http://www.doctrine-project.org/documentation/manual/1_1/en/defining-models#relationships">Les relations</a></li>
<li><a href="http://www.doctrine-project.org/documentation/manual/1_1/en/data-validation#introduction">Les data validations</a></li>
<li><a href="http://www.doctrine-project.org/documentation/manual/1_1/en/behaviors#introduction">Les behaviors</a></li>
</ul>
<p>(Personnellement je trouve que la documentation Doctrine est très bien faite. Les exemples omniprésent et la rendent très explicite, même pour un anglophobe.)</p>
<p>
Pour ce post j&#8217;ai fait le schema.yml d&#8217;une application lambda. On a des utilisateurs, des groupes, la relation n:n entre les deux. Et pour rajouter une petite relation 1:n les utilisateurs ont des photos. (original non?)</p>
<p>
J&#8217;ai utilisé des behaviors Timestampable et Sluggable.<br />
Dans les types j&#8217;en ai profité pour tester le Enum que je n&#8217;utilisais pas jusqu&#8217;à présent, mais je pense que dans un avenir proche je vais m&#8217;en servir beaucoup plus <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  <br />
Pareil dans les data validation le &laquo;&nbsp;email: true&nbsp;&raquo; sur le champ email et le &laquo;&nbsp;past: true&nbsp;&raquo; sur la date de naissance sont assez énormes et permettent d&#8217;avoir déjà les validators adéquats dans les classes formulaires.</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="left2">Download <a href="http://www.lexik.fr/blog/symfony/wp-content/plugins/wp-codebox/wp-codebox.php?p=508&amp;download=schema.yml">schema.yml</a></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50857"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
</pre></td><td class="code" id="p508code57"><pre class="yml" style="font-family:monospace;">Utilisateur:
  tableName:        test_utilisateur
  actAs:
    Timestampable:  ~
    Sluggable:
      unique:       true
      fields:       [nom,prenom]
      canUpdate:    true
  columns:
    id:             { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    sexe:           { type: enum, values: ['','Homme','Femme'], default: 'Homme' }
    nom:            { type: string(255) }
    prenom:         { type: string(255) }
    date_naissance: { type: date, past: true }
    email:          { type: string(255), notnull: true, unique: true, email: true }
  relations:
    Groupes:
      class:        Groupe
      refClass:     Membre
      local:        utilisateur_id
      foreign:      groupe_id
&nbsp;
&nbsp;
Photo:
  tableName:        test_photo
  actAs:
    Timestampable:  ~
  columns:
    id:             { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    fichier:        { type: string(255), notnull: true }
    utilisateur_id: { type: integer(4), unsigned: true, primary: true }
  relations:
    Utilisateur:
      local:        utilisateur_id
      foreign:      id
      foreignAlias: Photos
      onDelete:     CASCADE
&nbsp;
&nbsp;
Membre:
  tableName:        test_membre
  columns:
    utilisateur_id: { type: integer(4), unsigned: true, primary: true }
    groupe_id:      { type: integer(4), unsigned: true, primary: true }
  relations:
    Utilisateur:
      local:        utilisateur_id
      foreign:      id
      foreignAlias: Membres
      onDelete:     CASCADE
    Groupe:
      local:        groupe_id
      foreign:      id
      foreignAlias: Membres
      onDelete:     CASCADE
&nbsp;
&nbsp;
Groupe:
  tableName:        test_groupe
  columns:
    id:             { type: integer(4), unsigned: true, primary: true, autoincrement: true }
    nom:            { type: string(255), notnull: true }
  relations:
    Utilisateurs:
&nbsp;
      class:        Utilisateur
      refClass:     Membre
      local:        groupe_id
      foreign:      utilisateur_id</pre></td></tr></table></div>

<h2>La convention de nommage</h2>
<p><b>Le nom des objets :</b> Le plus court et le plus explicite possible. En CamelCase avec la première lettre en majuscule et au singulier. Pourquoi la 1er lettre en majuscule. Si la table a le même nom, ça permet de les dissocier facilement pour éviter les ambiguïté, notamment dans la construction des requête en DQL.</p>
<p><b>Le nom des relations :</b> Si possible, je donne le même nom que l&#8217;objet cible. Au singulier si on est sur une relation N:1 ou 1:1 et au pluriel quand on est sur une relation 1:N ou N:N (généralement les foreignAlias). La aussi la 1er lettre en majuscule est importante, car elle permet de conserver une syntaxe camelCase sur les accessers magiques.</p>
<p>  Par exemple sur l&#8217;objet Photo : </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('p508code58'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50858"><td class="code" id="p508code58"><pre class="yml" style="font-family:monospace;">Photo:
  ...
  relations:
    Utilisateur:
      local:        utilisateur_id
      foreign:      id</pre></td></tr></table></div>

<p>L&#8217;accesseur magique sera :</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('p508code59'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50859"><td class="code" id="p508code59"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$ma_photo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUtilisateur</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Alors que si on appelle la relation en minuscule :</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('p508code60'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50860"><td class="code" id="p508code60"><pre class="yml" style="font-family:monospace;">Photo:
  ...
  relations:
    utilisateur:
      local:        utilisateur_id
      foreign:      id</pre></td></tr></table></div>

<p>L&#8217;accesseur magique sera</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('p508code61'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50861"><td class="code" id="p508code61"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$ma_photo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getutilisateur</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>Et du coup on perd la syntaxe camelCase qui est généralisée dans tout le framework.<br />
C&#8217;est du chipotage mais ca peut être source d&#8217;erreur bête qui fait perdre du temps.</p>
<h2>Les TOC (Troubles Obsessionnels de Codage :p) ou Bonnes pratiques</h2>
<p>Sur les relations 1:N et 1:1, je définie toute la relation dans l&#8217;objet qui possède la clé étrangère. Pour essayer de ne pas alourdir trop mon schema.yml et aussi par faignantise.</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('p508code62'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50862"><td class="code" id="p508code62"><pre class="yml" style="font-family:monospace;">Photo:
  ...
  relations:
    Utilisateur:
      local:        utilisateur_id
      foreign:      id
      foreignAlias: Photos
      onDelete:     CASCADE</pre></td></tr></table></div>

<p>Cette relation défini 2 méthodes magiques Photo::getUtilisateur() qui va retourner l&#8217;objet Utilisateur lié à la photo et Utilisateur::getPhotos() qui retourne une collection d&#8217;objets Photo liés à utilisateur.</p>
<p>Cette même relation peut se décrire aussi en la décomposant en 2 parties.</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('p508code63'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50863"><td class="code" id="p508code63"><pre class="yml" style="font-family:monospace;">Utilisateur:
  ...
  relations:
    Photos:
      local:        id
      foreign:      utilisateur_id
      onDelete:     CASCADE
&nbsp;
Photo:
  ...
  relations:
    Utilisateur:
      local:        utilisateur_id
      foreign:      id
      onDelete:     CASCADE</pre></td></tr></table></div>

<p>Les 2 méthodes marchent parfaitement et ont leurs avantages et leurs inconvénients.</p>
<p>Sur les relations N:N, je définie toute la relation dans la Classe de liaison, et sur les objets externes seulement la partie qui les concernent. Pour éviter les multiples redéfinitions.</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('p508code64'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50864"><td class="code" id="p508code64"><pre class="yml" style="font-family:monospace;">Membre:
  ...
  relations:
    Utilisateur:
      local:        utilisateur_id
      foreign:      id
      foreignAlias: Membres
      onDelete:     CASCADE
    Groupe:
      local:        groupe_id
      foreign:      id
      foreignAlias: Membres
      onDelete:     CASCADE
&nbsp;
&nbsp;
Utilisateur:
  ...
  relations:
    Groupes:
      class:        Groupe
      refClass:     Membre
      local:        utilisateur_id
      foreign:      groupe_id
&nbsp;
&nbsp;
Groupe:
  ...
  relations:
    Utilisateurs:
      class:        Utilisateur
      refClass:     Membre
      local:        groupe_id
      foreign:      utilisateur_id</pre></td></tr></table></div>

<p>Sur les objets, j&#8217;aime bien avoir des noms simples et explicites mais paradoxalement, j&#8217;aime bien préfixer mes tables dans la base de donnée. C&#8217;est pourquoi je redéfinie systématiquement le tableName des objets dans le schema.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('p508code65'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50865"><td class="code" id="p508code65"><pre class="yml" style="font-family:monospace;">Utilisateur:
  tableName:        test_utilisateur
  ...</pre></td></tr></table></div>

<p>Sur les objets l&#8217;id est généré automatiquement mais il est de type bigint(20) signé. Et là aussi, comme je suis un gros maniaque et que je n&#8217;aime pas avoir des id signé qui plus est en bigint. Je redéfini l&#8217;id en int signé.</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('p508code66'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50866"><td class="code" id="p508code66"><pre class="yml" style="font-family:monospace;">Utilisateur:
  ...
  columns:
    id:             { type: integer(4), unsigned: true, primary: true, autoincrement: true }</pre></td></tr></table></div>

<p>Attention, il est possible de définir les relations à plusieurs endroits et de plusieurs manières différentes. Il faut essayer de se tenir à une méthodologie la plus stricte possible pour éviter des redéfinitions de relations.<br />
Si il y a des redéfinitions, Symfony ne va pas forcement les détecter lors de la re-génération des classes et ça risque de ne pas fonctionner correctement.</p>
<h2>Créer des relations avec les objets d&#8217;un plugin</h2>
<p>On va prendre le cas de sfGuard qui est un des plugins les plus utilisés.</p>
<p>Petite chose à savoir. Quand on utilise sfGuard, l&#8217;id de l&#8217;objet sfGuardUser est un int signé. Si vous avez besoin de faire des jointures pensez bien à utiliser un integer(4).</p>
<p>(Le type des clé étrangère est très important et source de pas mal de problèmes.)</p>
<p>Si on voulait lier l&#8217;objet Photo à sfGuardUser il faudrait écrire quelque-chose comme :</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('p508code67'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50867"><td class="code" id="p508code67"><pre class="yml" style="font-family:monospace;">Photo:
  ...
  columns:
    ...
    user_id: { type: integer(4) }
  relations:
    User:
      class:            sfGuardUser
      local:            user_id
      foreign:          id
      foreignAlias:     Photos
      onDelete:         CASCADE</pre></td></tr></table></div>

<p>Toujours dans l&#8217;hypothèse de l&#8217;intégration de sfGuard à la place de mon objet Utilisateur.<br />
Pour les relations N:N, étant donné que l&#8217;on a pas accès au schema.yml de l&#8217;objet sfGuarduser avec lequel on va se lier. Il faut définir toutes les relations de manière externe.</p>
<p>Pour la relation avec les groupes ça donnerais :</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('p508code68'); return false;">View Code</a> YML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50868"><td class="code" id="p508code68"><pre class="yml" style="font-family:monospace;">Membre:
  ...
  relations:
    Utilisateur:
      class:        sfGuardUser
      local:        utilisateur_id
      foreign:      id
      foreignAlias: Membres
      onDelete:     CASCADE
    Groupe:
      local:        groupe_id
      foreign:      id
      foreignAlias: Membres
      onDelete:     CASCADE
&nbsp;
&nbsp;
Groupe:
  ...
  relations:
    Utilisateurs:
      class:        sfGuardUser
      refClass:     Membre
      local:        groupe_id
      foreign:      utilisateur_id
      foreignAlias: Groupes</pre></td></tr></table></div>

<h2>Méthodes magiques dans les objets</h2>
<p>On a vu que les nom des relations et les foreignAlias engendraient des méthodes magiques qui permettent de remonter facilement les objets de la relation.<br />
Si on reprends le schema.yml du début, la liste des méthodes magiques est la suivante :</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('p508code69'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50869"><td class="code" id="p508code69"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #666666; font-style: italic;">//methodes magiques su l'objet Utilisateur</span>
<span style="color: #000088;">$utilisateur</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>
&nbsp;
<span style="color: #000088;">$utilisateur</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPhotos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$utilisateur</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getGroupes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$utilisateur</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMembres</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//methodes magiques su l'objet Photo</span>
<span style="color: #000088;">$photo</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Photo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$photo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUtilisateur</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//methodes magiques su l'objet Membre</span>
<span style="color: #000088;">$membre</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Membre<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$membre</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUtilisateur</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$membre</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getGroupe</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//methodes magiques su l'objet Groupe</span>
<span style="color: #000088;">$groupe</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Groupe<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$groupe</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMembres</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$groupe</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUtilisateurs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Les getters et les setters sont aussi des méthodes magiques.</p>
<p>Il y a un petit piège à éviter si on veut surcharger un getter ou un setter.</p>
<p>Par exemple si on vaut surcharger le getter Nom de l&#8217;objet Utilisateur, on a tendance a vouloir écrire :</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('p508code70'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50870"><td class="code" id="p508code70"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> UtilisateurTable <span style="color: #000000; font-weight: bold;">extends</span> Doctrine_Table
<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> getNom<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">getNom</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;
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Et bien il ne faut pas ! Ça fait en fait une boucle infinie.<br />
Il faut écrire :</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('p508code71'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50871"><td class="code" id="p508code71"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> UtilisateurTable <span style="color: #000000; font-weight: bold;">extends</span> Doctrine_Table
<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> getNom<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span>_get<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'nom'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>Finders magiques dans les classes Table</h2>
<p>Comme pour les getters, il y a deux finders magiques par champ dans la classe Table.<br />
Un findBy<em>Lechamp</em> et un findOneBy<em>Lechamp</em>. Le premier qui retourne une collection d&#8217;objets (même s&#8217;il n&#8217;y en a qu&#8217;un) et le second qui renvoie un objet seul.</p>
<p>Par exemple:</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('p508code72'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50872"><td class="code" id="p508code72"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000088;">$utilisateur</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;">findOneByNom</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Toto'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h2>Le nombre de requêtes</h2>
<p>Le nombre de requêtes effectuer en base peut rapidement devenir impressionnant.</p>
<p>Mais si on y regarde de plus prés ce sont souvent de petites requêtes.<br />
On va voir comment jouer sur le nombre de requêtes générées avec un petit exemple.</p>
<p>Une action toute simple ou je récupère un objet Utilisateur par son slug.</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('p508code73'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50873"><td class="code" id="p508code73"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//actions.class.php</span>
<span style="color: #000000; font-weight: bold;">class</span> userActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<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> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">test_utilisateur</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;">findOneBySlug</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'teta-toto'</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></pre></td></tr></table></div>

<p>Et la vue qui correspond</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('p508code74'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50874"><td class="code" id="p508code74"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//indexSuccess.php</span>
<span style="color: #339933;">&lt;</span>p<span style="color: #339933;">&gt;</span>Utilisateur <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #990000;">echo</span> <span style="color: #000088;">$test_utilisateur</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPrenom</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>p<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>p<span style="color: #339933;">&gt;</span>Photos <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #990000;">echo</span> <span style="color: #000088;">$test_utilisateur</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getGroupes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">count</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>p<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>ul<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;">$test_utilisateur</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPhotos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$photo</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #339933;">&lt;</span>li<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;">$photo</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getFichier</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>li<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;/</span>ul<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>p<span style="color: #339933;">&gt;</span>Groupes <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #990000;">echo</span> <span style="color: #000088;">$test_utilisateur</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getGroupes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">count</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>p<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>ul<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;">$test_utilisateur</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getGroupes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$groupe</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #339933;">&lt;</span>li<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;">$groupe</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNom</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>li<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;/</span>ul<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>On vois que 3 requetes sont effectuées.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p508code75'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50875"><td class="code" id="p508code75"><pre class="sql" style="font-family:monospace;">&nbsp;
1<span style="color: #66cc66;">.</span> <span style="color: #993333; font-weight: bold;">SELECT</span> t<span style="color: #66cc66;">.</span>id <span style="color: #993333; font-weight: bold;">AS</span> t__id<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>sexe <span style="color: #993333; font-weight: bold;">AS</span> t__sexe<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>nom <span style="color: #993333; font-weight: bold;">AS</span> t__nom<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>prenom <span style="color: #993333; font-weight: bold;">AS</span> t__prenom<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>date_naissance <span style="color: #993333; font-weight: bold;">AS</span> t__date_naissance<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>email <span style="color: #993333; font-weight: bold;">AS</span> t__email<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>created_at <span style="color: #993333; font-weight: bold;">AS</span> t__created_at<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>updated_at <span style="color: #993333; font-weight: bold;">AS</span> t__updated_at<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>slug <span style="color: #993333; font-weight: bold;">AS</span> t__slug <span style="color: #993333; font-weight: bold;">FROM</span> test_utilisateur t <span style="color: #993333; font-weight: bold;">WHERE</span> t<span style="color: #66cc66;">.</span>slug <span style="color: #66cc66;">=</span> ? <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">-</span> <span style="color: #66cc66;">&#40;</span>teta<span style="color: #66cc66;">-</span>toto <span style="color: #66cc66;">&#41;</span>
&nbsp;
2<span style="color: #66cc66;">.</span> <span style="color: #993333; font-weight: bold;">SELECT</span> t<span style="color: #66cc66;">.</span>id <span style="color: #993333; font-weight: bold;">AS</span> t__id<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>nom <span style="color: #993333; font-weight: bold;">AS</span> t__nom<span style="color: #66cc66;">,</span> t2<span style="color: #66cc66;">.</span>utilisateur_id <span style="color: #993333; font-weight: bold;">AS</span> t2__utilisateur_id<span style="color: #66cc66;">,</span> t2<span style="color: #66cc66;">.</span>groupe_id <span style="color: #993333; font-weight: bold;">AS</span> t2__groupe_id <span style="color: #993333; font-weight: bold;">FROM</span> test_groupe t <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> test_membre t2 <span style="color: #993333; font-weight: bold;">ON</span> t<span style="color: #66cc66;">.</span>id <span style="color: #66cc66;">=</span> t2<span style="color: #66cc66;">.</span>groupe_id <span style="color: #993333; font-weight: bold;">WHERE</span> t2<span style="color: #66cc66;">.</span>utilisateur_id <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span>?<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span>
&nbsp;
3<span style="color: #66cc66;">.</span> <span style="color: #993333; font-weight: bold;">SELECT</span> t<span style="color: #66cc66;">.</span>id <span style="color: #993333; font-weight: bold;">AS</span> t__id<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>utilisateur_id <span style="color: #993333; font-weight: bold;">AS</span> t__utilisateur_id<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>fichier <span style="color: #993333; font-weight: bold;">AS</span> t__fichier<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>created_at <span style="color: #993333; font-weight: bold;">AS</span> t__created_at<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>updated_at <span style="color: #993333; font-weight: bold;">AS</span> t__updated_at <span style="color: #993333; font-weight: bold;">FROM</span> test_photo t <span style="color: #993333; font-weight: bold;">WHERE</span> t<span style="color: #66cc66;">.</span>utilisateur_id <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span>?<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>La 1er requête est effectuée lors du findOneBySlug() dans l&#8217;action.<br />
La seconde lors du getPhotos() dans la vue.<br />
Et la derniere lors du getGroupes() dans la vue également.</p>
<p>On peut obtimiser le nombre de requete en forceant les jointures.</p>
<p>Pour le même code si on surcharge le finder findOneBySlug() en y rajoutant toutes les jointures</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('p508code76'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50876"><td class="code" id="p508code76"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
 * /lib/model/doctrine/UtilisateurTable.class.php
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> UtilisateurTable <span style="color: #000000; font-weight: bold;">extends</span> Doctrine_Table
<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> findOneBySlug<span style="color: #009900;">&#40;</span><span style="color: #000088;">$slug</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$q</span> <span style="color: #339933;">=</span> Doctrine_Query<span style="color: #339933;">::</span><span style="color: #004000;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #339933;">-&gt;</span><span style="color: #004000;">from</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Utilisateur u'</span><span style="color: #009900;">&#41;</span>
      <span style="color: #339933;">-&gt;</span><span style="color: #004000;">leftJoin</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'u.Photos'</span><span style="color: #009900;">&#41;</span>
      <span style="color: #339933;">-&gt;</span><span style="color: #004000;">leftJoin</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'u.Groupes'</span><span style="color: #009900;">&#41;</span>
      <span style="color: #339933;">-&gt;</span><span style="color: #004000;">where</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'u.slug = ?'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$slug</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$q</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchOne</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: #009900;">&#125;</span></pre></td></tr></table></div>

<p>On obtiens le même résultat avec une seule requète</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p508code77'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p50877"><td class="code" id="p508code77"><pre class="sql" style="font-family:monospace;">&nbsp;
<span style="color: #993333; font-weight: bold;">SELECT</span>  t<span style="color: #66cc66;">.</span>id <span style="color: #993333; font-weight: bold;">AS</span>  t__id<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>sexe <span style="color: #993333; font-weight: bold;">AS</span>  t__sexe<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>nom <span style="color: #993333; font-weight: bold;">AS</span>  t__nom<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>prenom <span style="color: #993333; font-weight: bold;">AS</span>  t__prenom<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>date_naissance <span style="color: #993333; font-weight: bold;">AS</span>  t__date_naissance<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>email <span style="color: #993333; font-weight: bold;">AS</span>  t__email<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>created_at <span style="color: #993333; font-weight: bold;">AS</span>  t__created_at<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>updated_at <span style="color: #993333; font-weight: bold;">AS</span>  t__updated_at<span style="color: #66cc66;">,</span> t<span style="color: #66cc66;">.</span>slug <span style="color: #993333; font-weight: bold;">AS</span>  t__slug<span style="color: #66cc66;">,</span> t2<span style="color: #66cc66;">.</span>id <span style="color: #993333; font-weight: bold;">AS</span>  t2__id<span style="color: #66cc66;">,</span> t2<span style="color: #66cc66;">.</span>utilisateur_id <span style="color: #993333; font-weight: bold;">AS</span>  t2__utilisateur_id<span style="color: #66cc66;">,</span> t2<span style="color: #66cc66;">.</span>fichier <span style="color: #993333; font-weight: bold;">AS</span>  t2__fichier<span style="color: #66cc66;">,</span> t2<span style="color: #66cc66;">.</span>created_at <span style="color: #993333; font-weight: bold;">AS</span>  t2__created_at<span style="color: #66cc66;">,</span> t2<span style="color: #66cc66;">.</span>updated_at <span style="color: #993333; font-weight: bold;">AS</span>  t2__updated_at<span style="color: #66cc66;">,</span> t3<span style="color: #66cc66;">.</span>id <span style="color: #993333; font-weight: bold;">AS</span>  t3__id<span style="color: #66cc66;">,</span> t3<span style="color: #66cc66;">.</span>nom <span style="color: #993333; font-weight: bold;">AS</span>  t3__nom <span style="color: #993333; font-weight: bold;">FROM</span> test_utilisateur t <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> test_photo t2 <span style="color: #993333; font-weight: bold;">ON</span> t<span style="color: #66cc66;">.</span>id <span style="color: #66cc66;">=</span> t2<span style="color: #66cc66;">.</span>utilisateur_id <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> test_membre t4 <span style="color: #993333; font-weight: bold;">ON</span> t<span style="color: #66cc66;">.</span>id <span style="color: #66cc66;">=</span> t4<span style="color: #66cc66;">.</span>utilisateur_id <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> test_groupe t3 <span style="color: #993333; font-weight: bold;">ON</span> t3<span style="color: #66cc66;">.</span>id <span style="color: #66cc66;">=</span> t4<span style="color: #66cc66;">.</span>groupe_id <span style="color: #993333; font-weight: bold;">WHERE</span> t<span style="color: #66cc66;">.</span>slug <span style="color: #66cc66;">=</span> ? <span style="color: #66cc66;">-</span> <span style="color: #66cc66;">&#40;</span>teta<span style="color: #66cc66;">-</span>toto <span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>Il ne faut pas nonplus s&#8217;amuser a remonter la moitié de la base de donnée dans chaque requête, mais ça permet de mieu gérer la charge générée par les scripts.</p>
<h2>Supprimer ou renommer un objet</h2>
<p>Si on supprime ou qu&#8217;on renomme une classe, les classes générés ne sont pas nettoyées et il faut le faire &laquo;&nbsp;a la main&nbsp;&raquo; sinon, les objets sont toujours regénéré et les tables toujours présentes en base.</p>
<p>Par exemple si ou voulais supprimer l&#8217;objet Utilisateur parcequ&#8217;on a décidé de se servir de sfGuard pour gérer les utilisateurs.</p>
<p>Il faut supprimer :</p>
<ul>
<li>/lib/filter/doctrine/UtilisateurFormFilter.class</li>
<li>/lib/filter/doctrine/base/BaseUtilisateurFormFilter.class.php</li>
<li>/lib/form/doctrine/UtilisateurForm.class.php</li>
<li>/lib/form/doctrine/base/BaseUtilisateurForm.class.php</li>
<li>/lib/model/doctrine/Utilisateur.class.php</li>
<li>/lib/model/doctrine/UtilisateurTable.class.php</li>
<li>/lib/model/doctrine/base/Utilisateur.class.php</li>
</ul>
<p>Merci a ceux qui ont eu le courage d&#8217;aller jusqu&#8217;au bout. J&#8217;avoue que je ne pensais pas faire un post aussi long à la base.<br />
J&#8217;ai un peu tapé au kilomètre et je pense que je le remanierai d&#8217;ici quelques temps avec plus d&#8217;explications et beaucoup moins de fautes <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/schemayml-doctrine-bonnes-pratiques-convention-de-nommage-et-fonctions-magiques-508/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Configurer Ubuntu pour envoyer des mails PHP à la sauce sendmail sans sendmail !</title>
		<link>http://www.lexik.fr/blog/symfony/ubuntu/configurer-ubuntu-pour-envoyer-des-mails-php-a-la-sauce-sendmail-sans-sendmail-237</link>
		<comments>http://www.lexik.fr/blog/symfony/ubuntu/configurer-ubuntu-pour-envoyer-des-mails-php-a-la-sauce-sendmail-sans-sendmail-237#comments</comments>
		<pubDate>Fri, 13 Mar 2009 18:03:14 +0000</pubDate>
		<dc:creator>olivier</dc:creator>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[ubuntu php email]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=237</guid>
		<description><![CDATA[Sur windows la fonction mail() de php est configurée pour fonctionner via SMTP que l&#8217;on peut configurer dans le php.ini Sur les systèmes Linux, ça n&#8217;est pas le cas. Php est configuré pour transmettre les mails via un vrai service de transport de mail du style sendmail ou postfix. Le problème de ces programmes (demon), [...]]]></description>
			<content:encoded><![CDATA[<p>Sur windows la fonction mail() de php est configurée pour fonctionner via SMTP que l&#8217;on peut configurer dans le php.ini</p>
<p>Sur les systèmes Linux, ça n&#8217;est pas le cas. Php est configuré pour transmettre les mails via un vrai service de transport de mail du style sendmail ou postfix.<br />
Le problème de ces programmes (demon), c&#8217;est qu&#8217;ils ne sont pas évidents à installer et configurer correctement pour tout les développeurs qui ne sont pas admin système.<span id="more-237"></span></p>
<p>Heureusement ESMTP est là pour nous sauver, nous autres simples développeurs.</p>
<blockquote><p><strong>Esmtp is a send-only sendmail emulator</strong></p></blockquote>
<p>Pour les anglophobes, ESMTP est un émulateur de sendmail pour l&#8217;envoi seulement des mails.<br />
C&#8217;est à dire que c&#8217;est un programme qui comprend les commandes sendmail, les traduit en requêtes smtp et les transmet à un serveur smtp.</p>
<h2>Installation et configuration de ESMTP</h2>

<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('p237code82'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p23782"><td class="code" id="p237code82"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> esmtp</pre></td></tr></table></div>

<p>Ou alors, vous le trouverez dans Synaptic.</p>
<p>Aprés quoi un petit coup de</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p237code83'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p23783"><td class="code" id="p237code83"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">nano</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>esmtprc</pre></td></tr></table></div>

<p>pour aller modifier la configuration et mettre le stmp que l&#8217;on veut utiliser (celui de votre provider).</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('p237code84'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p23784"><td class="code" id="p237code84"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Config file for ESMTP sendmail</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># The SMTP host and service (port)</span>
<span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">hostname</span></span>=smtp.orange.fr:<span style="color: #000000;">25</span></pre></td></tr></table></div>

<p>Dernier petit point à voir, faire un lien symbolique de sendmail vers esmtp pour faire croire à php que sendmail est installé.</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('p237code85'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p23785"><td class="code" id="p237code85"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>esmtp <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">sendmail</span></pre></td></tr></table></div>

<p>Et voila ! Vous pouvez coder des envois de mails, dans des conditions de production, avec la méthode sendmail sans avoir eu à passer des heures à configurer votre serveur de mail <img src='http://www.lexik.fr/blog/symfony/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Source : <a href="http://esmtp.sourceforge.net/">http://esmtp.sourceforge.net/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/ubuntu/configurer-ubuntu-pour-envoyer-des-mails-php-a-la-sauce-sendmail-sans-sendmail-237/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Formulaire multiples</title>
		<link>http://www.lexik.fr/blog/symfony/symfony/formulaire-multiples-7</link>
		<comments>http://www.lexik.fr/blog/symfony/symfony/formulaire-multiples-7#comments</comments>
		<pubDate>Mon, 16 Feb 2009 09:29:12 +0000</pubDate>
		<dc:creator>olivier</dc:creator>
				<category><![CDATA[1.2.x]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.lexik.fr/sfblog/?p=7</guid>
		<description><![CDATA[Depuis la 1.1, les formulaires imbriqués sont gérés grace à la méthode embedForm de la classe sfForm Un exemple avec le module sfDoctrineGuard que l&#8217;on veut éttendre avec un profil. La classe du formulaire principal : ?View Code PHPclass sfGuardUserForm extends PluginsfGuardUserForm &#123; public function configure&#40;&#41; &#123; unset&#40; $this&#91;'is_active'&#93;, ... $this&#91;'permissions_list'&#93; &#41;; &#160; $profile = [...]]]></description>
			<content:encoded><![CDATA[<p>Depuis la 1.1, les formulaires imbriqués sont gérés grace à la méthode embedForm de la classe sfForm</p>
<p>Un exemple avec le module sfDoctrineGuard que l&#8217;on veut éttendre avec un profil.</p>
<p><span id="more-7"></span>La classe du formulaire principal :</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('p7code90'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p790"><td class="code" id="p7code90"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> sfGuardUserForm <span style="color: #000000; font-weight: bold;">extends</span> PluginsfGuardUserForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span>
      <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'is_active'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #339933;">...</span>
      <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'permissions_list'</span><span style="color: #009900;">&#93;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$profile</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ProfileForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span>
      <span style="color: #000088;">$profile</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'sf_guard_user_id'</span><span style="color: #009900;">&#93;</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;">embedForm</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Profile'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$profile</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>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('p7code91'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p791"><td class="code" id="p7code91"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #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> sfGuardUserForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isMethod</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'post'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<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;">-&gt;</span><span style="color: #004000;">bindAndSave</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'notice'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Utilisateur enregistré.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'utilisateur/index'</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>Le problème c&#8217;est que le de bindAndSave() sur le formulaire principal provoque 2 save sur le formulaire embarqué.</p>
<p>Du coup si il y a des champs unique dans le formulaire embarqué et surtout un notnull sur la clé de jointure, ca plante.</p>
<p>La méthode alternative pour arriver au même résultat :</p>
<p>Pas la peine de redéfinir la classe formulaire.</p>
<p>Tout se passe dans la classe action ou on va définir les 2 formulaires à utiliser dans la vue et le traitement associé.</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('p7code92'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p792"><td class="code" id="p7code92"><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> executeInscription<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;">formUser</span>    <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfGuardUserFormInscription<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;">formProfile</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> UtilisateurFormInscription<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isMethod</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'post'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">formUser</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sf_guard_user'</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;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">formProfile</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'utilisateur'</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;">&#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;">formUser</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: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">formProfile</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;">$con</span> <span style="color: #339933;">=</span> Doctrine_Manager<span style="color: #339933;">::</span><span style="color: #004000;">connection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        try
        <span style="color: #009900;">&#123;</span>
          <span style="color: #000088;">$con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">beginTransaction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
          <span style="color: #000088;">$newUser</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">formUser</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          <span style="color: #000088;">$newProfil</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">formProfile</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
          <span style="color: #000088;">$newProfil</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setUserId</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$newUser</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: #000088;">$newProfil</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
          <span style="color: #000088;">$con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">commit</span><span style="color: #009900;">&#40;</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>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
          <span style="color: #000088;">$con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">rollback</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
          throw <span style="color: #000088;">$e</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;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'notice'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Votre inscription a bien été prise en compte.<span style="color: #000099; font-weight: bold;">\n</span>Vous allez recevoir un email dans quelques minutes pour valider votre inscription.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'utilisateur/index'</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>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Pour garantir l&#8217;intégrité des données il faut passer par une transaction que l&#8217;on est obligé de gérer à la main. (avec embedForm elle est gérée automatiquement)</p>
<p>Le code html avec les deux formulaires :</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('p7code93'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p793"><td class="code" id="p7code93"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>form action<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo url_for('utilisateur/inscription'); ?&gt;&quot;</span> method<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;post&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>table<span style="color: #339933;">&gt;</span>
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #990000;">echo</span> <span style="color: #000088;">$formUser</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> <span style="color: #000088;">$formProfile</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #339933;">&lt;</span>tr<span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;</span>td colspan<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;2&quot;</span><span style="color: #339933;">&gt;&lt;</span>input type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;submit&quot;</span> value<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo __('Signin') ?&gt;&quot;</span> <span style="color: #339933;">/&gt;&lt;/</span>td<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;/</span>tr<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;/</span>table<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>form<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.lexik.fr/blog/symfony/symfony/formulaire-multiples-7/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
