<?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>Amicalement Web - Astuces et Bons plans dans le développement web &#187; propel</title>
	<atom:link href="http://www.amicalement-web.net/tag/propel/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.amicalement-web.net</link>
	<description>Astuces et bons plans d&#039;un web developpeur</description>
	<lastBuildDate>Wed, 04 Jan 2012 14:54:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Développement Web: les bons plans de la semaine #22</title>
		<link>http://www.amicalement-web.net/developpement-web-les-bons-plans-de-la-semaine-22/2009/11/09/</link>
		<comments>http://www.amicalement-web.net/developpement-web-les-bons-plans-de-la-semaine-22/2009/11/09/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 10:00:47 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Bons plans]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.amicalement-web.net/?p=950</guid>
		<description><![CDATA[De la chair fraîche pour cette semaine! Vous devriez avoir un autre billet que celui-ci cette semaine encore si vous êtes sage. On m&#8217;a soufflé que ca pourrait parler de WordPress! Un sujet un peu oublié depuis la V2 mais qui m&#8217;intéresse toujours autant. Wait and see mais en attendant voici la sélection de la [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.amicalement-web.net/wp-content/uploads/enveloppe.png" alt="enveloppe" title="enveloppe" width="614" height="100" class="alignnone size-full wp-image-956" /> De la chair fraîche pour cette semaine! Vous devriez avoir un autre billet que celui-ci cette semaine encore si vous êtes sage. On m&#8217;a soufflé que ca pourrait parler de WordPress! Un sujet un peu oublié depuis la V2 mais qui m&#8217;intéresse toujours autant.</p>
<p>Wait and see mais en attendant voici la sélection de la semaine.<br />
<span id="more-950"></span></p>
<ul>
<li><a  href="http://propel.posterous.com/propel-140-stable-is-there">Propel 1.4 stable</a><br />
C&#8217;est un peu l&#8217;annonce de la semaine. Propel 1.4 stable est sortie! Pas mal de nouveautés dont certaines reprises des bonnes idées de Doctrine, mais également quelques exclus. Peut-être un futur billet plus complet à ce sujet ;)</li>
<li><a  href="http://wordpress.digitalnature.ro/mystique/">Un joli thème wordpress</a><br />
Une fois n&#8217;est pas coutume, croisé au détour d&#8217;un clic, assez sobre mais bourré de petits détails.</li>
<li><a  href="http://demo.kreativethemes.com/furvious/?kreativestyle=02">Un autre joli thème wordpress</a><br />
Comme quoi ya des semaines comme ça. Celui-ci est plus poussé graphiquement mais a un vrai potentiel je pense</li>
<li><a  href="http://davidwalsh.name/text-selection-ajax">Event jquery sur la sélection de texte</a><br />
Fonctionnalité qui pourrait ouvrir la porte à quelques nouvelles possibilités sympa</li>
<li><a  href="http://validatious.org/">Un nouveau script de validation de formulaire</a><br />
Oui encore un. Ca faisait longtemps. Mais celui-ci est vraiment bien fini et permet de définir ses validations avec très peu de ligne js, tout étant calibré depuis le code html</li>
<li><a  href="http://papermashup.com/using-memcache-with-php/">Memcache et le PHP</a><br />
Une petite explication sur Memcache et ses bienfaits pour le PHP</li>
<li><a  href="http://webdeveloperplus.com/jquery/quick-easy-way-to-implement-drag-n-share-with-jquery/">Drag and share avec jQuery</a><br />
Une façon originale de penser le drag and drop et le partage sur les medias sociaux.</li>
<li><a  href="http://www.alsacreations.com/actu/lire/899-optimiser-les-javascripts-avec-google-closure-tools-et-closure-compiler.html">Un compilateur javascript par Google</a><br />
C&#8217;est le lien qui a fait le tour du web, cette semaine. Le voilà décrit par dew, même s&#8217;il s&#8217;avère très compliqué d&#8217;être utilisé avec jquery, ca reste un outil assez novateur.</li>
<li><a  href="http://www.phpactiverecord.org/">Un nouvel ORM PHP</a><br />
Basé sur l&#8217;ORM de Ruby, voici un ORM dont on pourrait bien entendre parler prochainement.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.amicalement-web.net/developpement-web-les-bons-plans-de-la-semaine-22/2009/11/09/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Actualité Symfony, Doctrine et Propel</title>
		<link>http://www.amicalement-web.net/actualite-symfony-doctrine-et-propel/2009/09/21/</link>
		<comments>http://www.amicalement-web.net/actualite-symfony-doctrine-et-propel/2009/09/21/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 09:00:32 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Actualité]]></category>
		<category><![CDATA[behavior]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.amicalement-web.net/?p=659</guid>
		<description><![CDATA[Comme souvent après la rentrée, on assiste au débarquement des nouvelles versions en tout genre, comme Apple avec Snow Leopard ou Karmic Koala chez Canonical (bon ok eux c&#8217;est tous les mois d&#8217;octobre :p). Et forcément, chez les développeurs Symfony, ca frétille d&#8217;impatience car chaque jour nous rapproche de la sortie de la version 1.3 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.amicalement-web.net/wp-content/uploads/journal-cafe-netbook.png" alt="journal-cafe-netbook" title="journal-cafe-netbook" width="614" height="100" class="alignnone size-full wp-image-745" /> Comme souvent après la rentrée, on assiste au débarquement des nouvelles versions en tout genre, comme Apple avec Snow Leopard ou Karmic Koala chez Canonical (bon ok eux c&#8217;est tous les mois d&#8217;octobre :p). </p>
<p>Et forcément, chez les développeurs Symfony, ca frétille d&#8217;impatience car chaque jour nous rapproche de la sortie de la version 1.3 de notre framework PHP préféré, dernière release majeure avant le passage en 2.0 (oué pour le coup, ils sont pas encore à la mode).</p>
<p>Je me suis dis que ca valait le coup de faire un petit tour d&#8217;horizon des nouveautés attendues (au moins par moi) que se soit Symfony, Doctrine et même Propel:<br />
<span id="more-659"></span></p>
<h3>Propel</h3>
<p>On commence avec le feuilleton de l&#8217;été. Propel, mourra, mourra pas?</p>
<p>L&#8217;info a très vite circulé, et Propel a été enterré très vite après <a  href="http://groups.google.com/group/propel-development/msg/829895b081ec7873">l&#8217;annonce de son créateur Hans Lellelid</a> d&#8217;arrêter là les frais. </p>
<p>Mais dans son message,<strong> il y avait bien un appel au passage de relai</strong>, appel auquel François Zaninotto (himself, ex de la core team Symfony) et Sven Teitje ont répondu. Le premier prenant en charge l&#8217;évolution de la branche 1.x et le second le développement de la nouvelle branche 2.x.</p>
<p>D&#8217;ailleurs ils n&#8217;ont pas trainé car <strong>on parle déjà de Propel 1.4</strong>! On suivra bien sûr ça de très près.</p>
<h3>Doctrine</h3>
<p>Avec la mode 2.0, Mister Wage prépare lui aussi une version 2.0 de son ORM Doctrine. Peu d&#8217;infos encore si ce n&#8217;est qu&#8217;il sera plus beau, plus fort et surtout plus rapide! Grâce à PHP 5.3 en particulier.<br />
Mais on pourra également retrouver <strong>des messages d&#8217;erreurs localisés</strong>! Et ça c&#8217;est la classe.</p>
<p>Mais ceci reste du futur pas proche. Et on va s&#8217;intéresser plutôt à la version 1.2, celle qui accompagnera la version 1.3 de Symfony (oui j&#8217;avoue, ils auraient pu se mettre d&#8217;accord sur les numéros de version, ça aurait été plus simple).</p>
<p>Et la nouveauté majeure pour moi, c&#8217;est la<strong> possibilité d&#8217;étendre les classe de Doctrine</strong> facilement et en particulier Doctrine_Query et Doctrine_Collection. On pourra alors généraliser certains comportements et ajouter de nouvelles fonctionnalités comme des tri personnalisés dans les collections ou adapter <a  href="http://prendreuncafe.com/blog/post/Optimize-your-Doctrine-Workflow-with-Specialized-Queries">l&#8217;idée de NiKo</a> pour les query.</p>
<p>On notera également, l&#8217;ajout d&#8217;un<strong> système d&#8217;extension</strong> directement via doctrine qui sont en fait des behaviors. Vous retrouverez <a  href="http://www.doctrine-project.org/extensions">la liste sur le site lui même</a>. J&#8217;ai d&#8217;ailleurs de mon côté, une petite idée d&#8217;extension, mais on en reparlera le moment voulu ;)</p>
<h3>Symfony</h3>
<p>Gros programme pour cette dernière release (comme annoncée, la 1.4 ne sera qu&#8217;une 1.3 débarrassé des méthodes/classes dépréciées). Beaucoup de choses, mais voici un résumé de celles que j&#8217;attends vraiment:</p>
<ul>
<li>La vrai nouveauté, un<strong> Mailer de série</strong>! Basé sur Swift, très bonne librairie, cela fera toujours un plugin de moins à utiliser</li>
<li>Le système de formulaire pluggué sur le système d&#8217;évènement avec <strong>4 nouveaux évènements</strong> qui va permettre enfin de généraliser des comportements pour certains formulaires très facilement.</li>
<li>Pouvoir <strong>ne pas générer les formulaires ou filtres d&#8217;un modèle</strong> lors de sa définition dans le schema.yml (seulement doctrine). Nan parce que, c&#8217;est vrai que des fois, on en a vraiment pas besoin.</li>
<li>Petit détail enfin corrigé, les <strong>pager intègrent enfin les interfaces Countable et Iterator</strong>.</li>
<li>Autre détail, à la génération automatique d&#8217;un label d&#8217;un champ de formulaire, <strong>les _id seront supprimés</strong>! Ca permettra d&#8217;avoir quelque chose de présentable plus facilement, pcq les _id nous on les voit pas, mais les clients, ca leur saute toujours aux yeux ;)</li>
<li>Petite révolution dans les définitions de formulaire. Actuellement, il faut retirer du formulaire les champs qu&#8217;on ne souhaite pas voir s&#8217;afficher. Mais le coup classique du &laquo;&nbsp;je rajoute un champ et il apparait automatiquement alors que je voulais pas&nbsp;&raquo; ça agace. Dans la 1.3, ca sera donc l&#8217;inverse,<strong> il faudra spécifier les champs qu&#8217;on voudra afficher</strong> grâce à la nouvelle méthode useFields</li>
<li>Niveau CLI aussi beaucoup de nouveautés, dont une assez formidable, la possibilité de <strong>rejouer seulement les tests qui auront échoué</strong>! Il suffira de rajouter l&#8217;option &#8211;only-failed.</li>
<li>Pour Doctrine aussi, beaucoup de rajouts bien pratiques, comme la possibilité de regénérer/supprimer les fichiers liés à un model donné. Et même de <strong>resynchroniser tous les modèles avec le schema.yml</strong> (entendre par là qu&#8217;il supprimera ceux qui n&#8217;existe plus). Des petits gains de temps qui ne sont pas de refus, surtout dans les débuts d&#8217;un nouveau projet.</li>
<li>Et bien sûr, la plus attendue pour la fin. <a  href="http://www.symfony-project.org/blog/2009/06/10/new-in-symfony-1-3-project-creation-customization">Fabien en avait déjà parlé sur le blog</a>, la <strong>possibilité de créer un installer</strong> pour la génération de nouveau projet qui fera automatiquement toutes les tâches de personnalisation que vous faisiez avant à la main ou en maintenant votre skeleton de projet.</li>
</ul>
<p>En tout cas, ça fait envie, et ca va dans le bon sens selon moi. Pour tous les détails:</p>
<ul>
<li><a  href="http://www.slideshare.net/jwage/symfony-13-doctrine-12">Slides de Jonathan Wage  sur Symfony 1.3 et Doctrine 1.2</a></li>
<li><a  href="http://www.symfony-project.org/tutorial/1_3/en/whats-new">Page officielle des nouveautés de la v1.3</a></li>
</ul>
<p><small>Crédit photo: http://www.flickr.com/photos/mfobrien</small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.amicalement-web.net/actualite-symfony-doctrine-et-propel/2009/09/21/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Symfony: Relation many-to-many sur la meme table avec Propel</title>
		<link>http://www.amicalement-web.net/symfony-relation-many-to-many-sur-la-meme-table-avec-propel/2009/06/24/</link>
		<comments>http://www.amicalement-web.net/symfony-relation-many-to-many-sur-la-meme-table-avec-propel/2009/06/24/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 10:36:51 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Astuces]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.amicalement-web.net/?p=375</guid>
		<description><![CDATA[Beaucoup de boulot pour cette courte semaine (je suis en week end, ce soir :D) du coup, je n&#8217;ai pas eu le temps de faire le billet Symfony du mardi! Ca tombait bien en même temps, car je n&#8217;avais pas énormément d&#8217;idées. Finalement, j&#8217;ai trouvé un petit quelque chose pour subvenir à vos besoins de [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.amicalement-web.net/wp-content/uploads/system-search.png" alt="system-search" title="system-search" width="48" height="48" class="alignleft size-full wp-image-39" /> Beaucoup de boulot pour cette courte semaine (je suis en week end, ce soir :D) du coup, je n&#8217;ai pas eu le temps de faire le billet Symfony du mardi! Ca tombait bien en même temps, car je n&#8217;avais pas énormément d&#8217;idées.<br />
Finalement, j&#8217;ai trouvé un petit quelque chose pour subvenir à vos besoins de nouveautés permanents. On va parler d&#8217;une petite faiblesse dans Propel, que je n&#8217;ai pas encore pris le temps d&#8217;analyser dans toute sa profondeur mais qui reste assez gênant: La gestion des relations many-to-many sur une même table.<br />
<span id="more-375"></span><br />
En gros, une table d&#8217;association dont le couple serait deux clé étrangères sur la même table du genre:</p>

<div class="wp_syntax"><div class="code"><pre class="yaml" style="font-family:monospace;">  cross_selling:
    _attributes: { phpName: CrossSelling }
    pid: { type: SMALLINT, size: '5', primaryKey: true, required: true, foreignTable: produits, foreignReference: pid, onDelete: CASCADE, onUpdate: CASCADE }
    csid: { type: SMALLINT, size: '5', primaryKey: true, required: true, foreignTable: produits, foreignReference: pid, onDelete: CASCADE, onUpdate: CASCADE }</pre></div></div>

<p>Autant dans la partie model, aucun souci, on est capable de récupérer chacun des éléments par la table &laquo;&nbsp;Produits&nbsp;&raquo; (la table où pointe les 2 clés étrangères pour ceux qui se sont perdus en route), autant dans la partie form, aucune trace du widget pour matérialiser cette relation, rien, nada. Alors qu&#8217;au départ, si on définie notre relation, c&#8217;est qu&#8217;on en a un peu besoin en fait.</p>
<p>On va donc tâcher de combler ce vide, en rajoutant ce dont a besoin notre formulaire pour reproduire notre relation dans le fichier <code>lib/form/ProduitsForm.class.php</code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> ProduitsForm <span style="color: #000000; font-weight: bold;">extends</span> BaseProduitsForm
<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>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">configure</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// Ajout Cross Selling</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;">'cross_selling_list'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormPropelChoiceMany<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    	<span style="color: #0000ff;">'model'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Produits'</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;">validatorSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'cross_selling_list'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorPropelChoiceMany<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'model'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Produits'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</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></div></div>

<p>On crée ensuite la méthode qui va permettre d&#8217;enregistrer le résultat de notre choix dans notre widget de liste (en fait, il suffit d&#8217;adapter le code généré pour une relation many-to-many qui fonctionne):</p>

<div class="wp_syntax"><div class="code"><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> saveCrossSellingList<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">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: #b1b100;">throw</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getErrorSchema</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: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</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;">'cross_selling_list'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">// somebody has unset this widget</span>
      <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_null</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</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> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getConnection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$c</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span>CrossSellingPeer<span style="color: #339933;">::</span><span style="color: #004000;">PID</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">object</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPrimaryKey</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    CrossSellingPeer<span style="color: #339933;">::</span><span style="color: #004000;">doDelete</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #339933;">,</span> <span style="color: #000088;">$con</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: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cross_selling_list'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$obj</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CrossSelling<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setPid</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">object</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPrimaryKey</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;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setCsid</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: #000088;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Puis on surcharge le doSave pour ajouter cette fonction:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> doSave<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">doSave</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;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">saveCrossSellingList</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: #009900;">&#125;</span></pre></div></div>

<p>et pour finir on surcharge la méthode  updateDefaultsFromObject pour charger le résultat une fois sauvegardé:</p>

<div class="wp_syntax"><div class="code"><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> updateDefaultsFromObject<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">updateDefaultsFromObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</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;">'cross_selling_list'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <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: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">object</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCrossSellingsRelatedByPid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$obj</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCsid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setDefault</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cross_selling_list'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$values</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></div></div>

<p>Et voilà, Propel n&#8217;a qu&#8217;a bien se tenir, on peut se passer de lui! Je pense qu&#8217;avec un peu plus de temps, je me plongerai bien dans le détail pour voir où ça coince, à moins que j&#8217;ai loupé encore une fois un épisode.</p>
<p>Moralité, Doctrine vaincra?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.amicalement-web.net/symfony-relation-many-to-many-sur-la-meme-table-avec-propel/2009/06/24/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mysql, Propel et l&#8217;UTF8 sont dans un bateau</title>
		<link>http://www.amicalement-web.net/mysql-propel-utf8/2009/05/21/</link>
		<comments>http://www.amicalement-web.net/mysql-propel-utf8/2009/05/21/#comments</comments>
		<pubDate>Thu, 21 May 2009 13:35:37 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Astuces]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://www.amicalement-web.net/?p=254</guid>
		<description><![CDATA[Un gros souci que j&#8217;ai toujours eu lors de mes projets symfony c&#8217;est la capacité de dire à Propel que je veux ma base en UTF8, j&#8217;ai beau mettre UTF8 un peu partout, database.yml, schema.yml, propel.ini rien n&#8217;y fait, mon build-all créé mes tables en ISO. D&#8217;ailleurs un peu déçu que Jobeet chapitre 3 n&#8217;aborde [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.amicalement-web.net/wp-content/uploads/edit-cut.png" alt="edit-cut" title="edit-cut" width="48" height="48" class="alignleft size-full wp-image-34" /> Un gros souci que j&#8217;ai toujours eu lors de mes projets symfony c&#8217;est la capacité de dire à Propel que je veux ma base en UTF8, j&#8217;ai beau mettre UTF8 un peu partout, database.yml, schema.yml, propel.ini rien n&#8217;y fait, mon build-all créé mes tables en ISO. D&#8217;ailleurs un peu déçu que <a  href="http://www.symfony-project.org/jobeet/1_2/Propel/en/03" class="extern">Jobeet chapitre 3</a> n&#8217;aborde pas le sujet.</p>
<p>J&#8217;ai donc tenté de voir du côté de Mysql, pour mettre ce dernier par défaut en utf8, mais là aussi, on a beau remplir le my.cnf de utf8 dans toutes les options, rien de concret ne se produit.</p>
<p>J&#8217;en été donc resté à devoir rajouter à la main, dans mon .sql généré par symfony, le fameux &laquo;&nbsp;DEFAUT CHARSET=UTF8&#8243;. Mais devoir le rajouter à chaque modification de mon schema, cela peut devenir pénible dans des projets de tests.</p>
<p>Et puis par hasard au détour d&#8217;une conversation sur mysql dans une mailing-list (mea culpa j&#8217;ai pas noté l&#8217;adresse) je suis enfin tombé sur quelque chose qui fonctionne! A la création de la table, écrire:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">CREATE</span> <span style="color: #990099; font-weight: bold;">DATABASE</span> mydb CHARACTER <span style="color: #990099; font-weight: bold;">SET</span> utf8 <span style="color: #CC0099; font-weight: bold;">COLLATE</span> utf8_general_ci</pre></div></div>

<p>Voilà, toutes les tables créés maintenant dans cette base seront en UTF8 par défaut.</p>
<p>Il y a sans doute mieux, mais pour l&#8217;instant je me contente de ça. Mais peut-être que quelqu&#8217;un a une meilleur solution? Comment gérez-vous vos tables en UTF8?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.amicalement-web.net/mysql-propel-utf8/2009/05/21/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>How-to Symfony: Gestion d’un arbre en Propel via les NestedSet &#8211; Part 2</title>
		<link>http://www.amicalement-web.net/how-to-symfony-gestion-d%e2%80%99un-arbre-en-propel-via-les-nestedset-part-2/2009/05/19/</link>
		<comments>http://www.amicalement-web.net/how-to-symfony-gestion-d%e2%80%99un-arbre-en-propel-via-les-nestedset-part-2/2009/05/19/#comments</comments>
		<pubDate>Tue, 19 May 2009 11:31:07 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[nestedset]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.amicalement-web.net/?p=246</guid>
		<description><![CDATA[La dernière fois, on avait vu comment construire l&#8217;aspect graphique de notre gestion de catégorie via Symfony et Propel. On va voir maintenant comme lui associer les actions symfony qui vont bien. Au programme donc dans l&#8217;ordre: la remise en état des liens modifier/supprimer l&#8217;ajout d&#8217;un lien pour ajouter un enfant à une catégorie la [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.amicalement-web.net/wp-content/uploads/system-run.png" alt="system-run" title="system-run" width="48" height="48" class="alignleft size-full wp-image-38" /> La dernière fois, on avait vu comment construire l&#8217;aspect graphique de notre <a  href="/symfony-gestion-d-un-arbre-en-propel-via-les-nestedset-part-1/2009/05/12/">gestion de catégorie</a> via <a  href="http://www.symfony-project.org" class="extern">Symfony</a> et Propel. On va voir maintenant comme lui associer les actions symfony qui vont bien.<br />
Au programme donc dans l&#8217;ordre:</p>
<ul>
<li>la remise en état des liens modifier/supprimer</li>
<li>l&#8217;ajout d&#8217;un lien pour ajouter un enfant à une catégorie</li>
<li>la sauvegarde de l&#8217;ordre de l&#8217;arbre</li>
</ul>
<p>Ya du boulot, alors on se lance.<br />
<span id="more-246"></span><br />
Le seul problème à la remise des liens modifier/supprimer c&#8217;est leur structure HTML, en ul/li qui pose souci avec le plugin NestedSortable. On va donc revoir la chose en les mettant dans un &laquo;&nbsp;p&nbsp;&raquo; avec de simples liens. Pour cela on va éditer dans notre module le fichier <code>lib/categoriesGeneratorHelper.class.php</code> (qui doit être vierge pour l&#8217;instant) et on va surcharger les méthodes, linkToEdit et linkToDelete:</p>

<div class="wp_syntax"><div class="code"><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> linkToEdit<span style="color: #009900;">&#40;</span><span style="color: #000088;">$object</span><span style="color: #339933;">,</span> <span style="color: #000088;">$params</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'&lt;span class=&quot;sf_admin_action_edit&quot;&gt;'</span><span style="color: #339933;">.</span>link_to<span style="color: #009900;">&#40;</span>__<span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'label'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'sf_admin'</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;">getUrlForAction</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'edit'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$object</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/span&gt;'</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> linkToDelete<span style="color: #009900;">&#40;</span><span style="color: #000088;">$object</span><span style="color: #339933;">,</span> <span style="color: #000088;">$params</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;">$object</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isNew</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'&lt;span class=&quot;sf_admin_action_delete&quot;&gt;'</span><span style="color: #339933;">.</span>link_to<span style="color: #009900;">&#40;</span>__<span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'label'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'sf_admin'</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;">getUrlForAction</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'delete'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$object</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'method'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'delete'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'confirm'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'confirm'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> ? __<span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'confirm'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'sf_admin'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'confirm'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/span&gt;'</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Les seules modifications concernant le changement d&#8217;un li par un span.</p>
<p>Maintenant on va modifier le partial <code>_list_td_actions.php</code> et donc le rajouter dans notre répertoire templates de notre module:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;p class=&quot;sf_admin_td_actions list_action&quot;&gt;
  &lt;span class=&quot;sf_admin_action_new&quot;&gt;
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> link_to<span style="color: #009900;">&#40;</span>__<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Ajout Enfant'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'categories/addChild?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$categories</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'messages'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  &lt;/span&gt;
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$helper</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">linkToEdit</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$categories</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>  <span style="color: #0000ff;">'params'</span> <span style="color: #339933;">=&gt;</span>   <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>  <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>  <span style="color: #0000ff;">'class_suffix'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'edit'</span><span style="color: #339933;">,</span>  <span style="color: #0000ff;">'label'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Edit'</span><span style="color: #339933;">,</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: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$helper</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">linkToDelete</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$categories</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>  <span style="color: #0000ff;">'params'</span> <span style="color: #339933;">=&gt;</span>   <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>  <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>  <span style="color: #0000ff;">'confirm'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Are you sure?'</span><span style="color: #339933;">,</span>  <span style="color: #0000ff;">'class_suffix'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'delete'</span><span style="color: #339933;">,</span>  <span style="color: #0000ff;">'label'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Delete'</span><span style="color: #339933;">,</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;/p&gt;</pre></div></div>

<p>A noter qu&#8217;on a ajouté au passage l&#8217;action Ajout d&#8217;enfant.<br />
Il nous reste plus qu&#8217;à rajouter l&#8217;appel à ce partial dans notre <code>_tree.php</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">[...]
&lt;div class=&quot;sort-handle&quot;&gt;
   <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$node</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>
&lt;/div&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> include_partial<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'categories/list_td_actions'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'categories'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$node</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'helper'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$helper</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
[...]</pre></div></div>

<p>Le résultat nous donne ceci:<br />
<a  href="http://www.amicalement-web.net/wp-content/uploads/image-311.png"><img src="http://www.amicalement-web.net/wp-content/uploads/image-311-300x134.png" alt="image-311" title="image-311" width="300" height="134" class="alignnone size-medium wp-image-247" /></a></p>
<p>Alors oui c&#8217;est moche, mais ca fonctionne! Maintenant, on passe un petit coup de CSS comme d&#8217;habitude:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #6666ff;">.list_action</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">absolute</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">right</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">:</span><span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">350px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #6666ff;">.list_action</span> span <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">10px</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #6666ff;">.current-nesting</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#FFE</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#sf_admin_container</span> <span style="color: #cc00cc;">#sf_admin_content</span> p span<span style="color: #6666ff;">.sf_admin_action_new</span> a <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span><span style="color: #993333;">transparent</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000; font-style: italic;">/sfPropelPlugin/images/new.png</span><span style="color: #00AA00;">&#41;</span> <span style="color: #993333;">no-repeat</span> <span style="color: #993333;">scroll</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #cc00cc;">#sf_admin_container</span> <span style="color: #cc00cc;">#sf_admin_content</span> p span<span style="color: #6666ff;">.sf_admin_action_edit</span> a <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span><span style="color: #993333;">transparent</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000; font-style: italic;">/sfPropelPlugin/images/edit.png</span><span style="color: #00AA00;">&#41;</span> <span style="color: #993333;">no-repeat</span> <span style="color: #993333;">scroll</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #cc00cc;">#sf_admin_container</span> <span style="color: #cc00cc;">#sf_admin_content</span> p span<span style="color: #6666ff;">.sf_admin_action_delete</span> a<span style="color: #00AA00;">,</span><span style="color: #6666ff;">.link_delete</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span><span style="color: #993333;">transparent</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000; font-style: italic;">/sfPropelPlugin/images/delete.png</span><span style="color: #00AA00;">&#41;</span> <span style="color: #993333;">no-repeat</span> <span style="color: #993333;">scroll</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>Et la magie opère de nouveau:<br />
<a  href="http://www.amicalement-web.net/wp-content/uploads/image-331.png"><img src="http://www.amicalement-web.net/wp-content/uploads/image-331-300x90.png" alt="image-331" title="image-331" width="300" height="90" class="alignnone size-medium wp-image-249" /></a></p>
<p>On va maintenant créer les actions liées à cette nouvelle action dans notre fichier d&#8217;actions de notre module:</p>

<div class="wp_syntax"><div class="code"><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> executeAddChild<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;">categories</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: #666666; font-style: italic;">// On récupère le parent pour insérer la nouvelle catégorie sous ce parent et on le fait transiter via session </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;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'categories.addChild'</span><span style="color: #339933;">,</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">categories</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPrimaryKey</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'admin_module'</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: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">configuration</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getForm</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;">setTemplate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'new'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * On surcharge le processForm pour récupérer le parent de la catégorie à ajouter s'il existe
   *
   * @param sfWebRequest $request
   * @param sfForm $form
   */</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> processForm<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #339933;">,</span> sfForm <span style="color: #000088;">$form</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;">$parent</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;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'categories.addChild'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'admin_module'</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;">getAttributeHolder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">remove</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'categories.addChild'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'admin_module'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$root</span> <span style="color: #339933;">=</span> CategoriesPeer<span style="color: #339933;">::</span><span style="color: #004000;">retrieveByPk</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$parent</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</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;">insertAsLastChildOf</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$root</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    parent<span style="color: #339933;">::</span><span style="color: #004000;">processForm</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">,</span><span style="color: #000088;">$form</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Si vous cliquez maintenant sur &laquo;&nbsp;Ajouter un enfant&#8217; d&#8217;une des catégories déjà présente vous obtenez alors:<br />
<a  href="http://www.amicalement-web.net/wp-content/uploads/image-34.png"><img src="http://www.amicalement-web.net/wp-content/uploads/image-34-300x180.png" alt="image-34" title="image-34" width="300" height="180" class="alignnone size-medium wp-image-258" /></a></p>
<p>Vu que les tree left et tree right sont définis par Propel, on va les supprimer du formulaire.<br />
Dans notre <code>CategoriesForm.class.php</code> on rajoute:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #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;">'tree_left'</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;">'tree_right'</span><span style="color: #009900;">&#93;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Maintenant, il ne manque plus qu&#8217;à pouvoir sauvegarder les modifications d&#8217;ordre effectuées via javascript. Pour cela on va rajouter une batch actions (elles soumettent un formulaire, il sera ainsi plus facile de faire passer les modifications faites à l&#8217;arbre).<br />
Dans notre <code>generator.yml</code> on rajoute dans l&#8217;entrée list:</p>

<div class="wp_syntax"><div class="code"><pre class="yaml" style="font-family:monospace;">  batch_actions:
    saveOrder:
      label: Sauvegarder ordre
      action: saveOrder</pre></div></div>

<p>Et dans notre partial <code>_list.php</code>, juste avant le javascript:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;div&gt;
	&lt;input type=&quot;hidden&quot; id=&quot;hashValue&quot; name=&quot;hashValue&quot; value=&quot;&quot; /&gt;
	&lt;input type=&quot;hidden&quot; name=&quot;ids&quot; value=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$item</span><span style="color: #009900;">&#41;</span>?<span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPrimaryKey</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">'1'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; /&gt;
&lt;/div&gt;</pre></div></div>

<p>Le premier pour récupérer la sérialisation de la nestedlist en javascript, le deuxième pour passer outre le système de batch qui demande de sélectionner au moins un ids pour lancer l&#8217;action ensuite.</p>
<p>On obtient donc:<br />
<a  href="http://www.amicalement-web.net/wp-content/uploads/image-351.png"><img src="http://www.amicalement-web.net/wp-content/uploads/image-351.png" alt="image-351" title="image-351" width="278" height="100" class="alignnone size-full wp-image-262" /></a></p>
<p>Il ne reste plus qu&#8217;à faire l&#8217;action correspondante dans notre fichier d&#8217;actions:</p>

<div class="wp_syntax"><div class="code"><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> executeBatchSaveOrder<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;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'hashValue'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">parse_str</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$hash</span><span style="color: #339933;">,</span> <span style="color: #000088;">$list</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    CategoriesPeer<span style="color: #339933;">::</span><span style="color: #004000;">saveOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$list</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;">setFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'notice'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Ordre mis à jour'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Et les fonctions de sauvegarde dans notre modèle. La fonction mère dans le <code>CategoriesPeer.php</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> saveOrder<span style="color: #009900;">&#40;</span><span style="color: #000088;">$hash</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$root</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">retrieveRoot</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$hash</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'main_list'</span><span style="color: #009900;">&#93;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$categorie</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span> 
      <span style="color: #000088;">$u</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">retrieveByPk</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$categorie</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$categorie</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'children'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$u</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">saveChildren</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$categorie</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'children'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #000088;">$u</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">moveToLastChildOf</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$root</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$u</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Qui gère les &laquo;&nbsp;racines&nbsp;&raquo; et son équivalent récursif dans le model <code>Categories.php</code>:</p>

<div class="wp_syntax"><div class="code"><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> saveChildren<span style="color: #009900;">&#40;</span><span style="color: #000088;">$children</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
	  <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$children</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$child</span><span style="color: #009900;">&#41;</span>
	  <span style="color: #009900;">&#123;</span>
	    <span style="color: #000088;">$item</span> <span style="color: #339933;">=</span> CategoriesPeer<span style="color: #339933;">::</span><span style="color: #004000;">retrieveByPk</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$child</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$child</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'children'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	    <span style="color: #009900;">&#123;</span>
	      <span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">saveChildren</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$child</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'children'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    <span style="color: #009900;">&#125;</span>
	    <span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">moveToLastChildOf</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	  <span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Et voilà! Vous pouvez maintenant déplacer vos catégories et sauvegarder leur position dans l&#8217;arbre.</p>
<p>Evidemment toute question, suggestion sont bien sûr les bienvenues. Je pense mettre les source et une démo en ligne très bientôt, voir en faire un plugin si jamais je rencontre un réel intérêt pour ce genre de gadget.</p>
<p>En attendant, une petit illustration en vidéo:<br />
<object id='stUE1TSkxIR11dR15eX1taVV5V' width='425' height='344' type='application/x-shockwave-flash' data='http://www.screentoaster.com/swf/STPlayer.swf'  codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0'><param name='movie' value='http://www.screentoaster.com/swf/STPlayer.swf'/><param name='allowFullScreen' value='true'/><param name='allowScriptAccess' value='always'/><param name='flashvars' value='video=stUE1TSkxIR11dR15eX1taVV5V'/></object>
<div style='width: 425px; text-align: right;'><a  href="http://www.screentoaster.com/">Screencasts and videos online</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.amicalement-web.net/how-to-symfony-gestion-d%e2%80%99un-arbre-en-propel-via-les-nestedset-part-2/2009/05/19/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>How-to Symfony: Gestion d&#8217;un arbre en Propel via les NestedSet &#8211; Part 1</title>
		<link>http://www.amicalement-web.net/symfony-gestion-d-un-arbre-en-propel-via-les-nestedset-part-1/2009/05/12/</link>
		<comments>http://www.amicalement-web.net/symfony-gestion-d-un-arbre-en-propel-via-les-nestedset-part-1/2009/05/12/#comments</comments>
		<pubDate>Tue, 12 May 2009 16:34:01 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[nestedset]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.amicalement-web.net/?p=203</guid>
		<description><![CDATA[Les arbres en informatique c&#8217;est un peu le sujet qui fait rêver mais qui embête souvent, moi le premier. Car qui dit arbre, dit récursivité et là en général on commence à se prendre la tête dans les mains. Bah oui gérer quelque chose dont on ne connait pas la fin, ca fait toujours un [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.amicalement-web.net/wp-content/uploads/accessories-text-editor.png" alt="accessories-text-editor" title="accessories-text-editor" width="48" height="48" class="alignleft size-full wp-image-28" /> Les arbres en informatique c&#8217;est un peu le sujet qui fait rêver mais qui embête souvent, moi le premier. Car qui dit arbre, dit <a  href="http://fr.wikipedia.org/wiki/Algorithme_r%C3%A9cursif" class="extern">récursivité</a> et là en général on commence à se prendre la tête dans les mains. Bah oui gérer quelque chose dont on ne connait pas la fin, ca fait toujours un peu peur.</p>
<p>Ici, le principe va être justement de gérer un arbre de catégories, un cas qui peut revenir assez régulièrement. A noter que le concept reprend la version doctrine de <a  href="http://redotheoffice.com/?p=74" class="extern">redotheoffice</a> avec une modification quant au plugin jquery utilisé. En effet, on essaiera ici de gérer l&#8217;ordre des catégories également par drag and drop.<br />
<span id="more-203"></span><br />
En général, quand on part la tête dans le guidon, on crée une table categories, et pour créer la notion de parent, on applique une clé étrangère sur cette même table. Oui mais voilà, autant pour les opérations de suppression et d&#8217;ajout, voir même de déplacement dans l&#8217;arbre cette démarche est très performante, autant quand il s&#8217;agit d&#8217;afficher l&#8217;arbre, la galère commence.<br />
Et pourtant, c&#8217;est bien cette deuxième qu&#8217;on fait à chaque affichage de page!</p>
<p>Il existe pourtant une alternative à cette clé étrangère: les Nested Set. En français, les représentations intervallaires. Le but n&#8217;étant pas d&#8217;expliquer dans le détail ce que c&#8217;est, je vous invite à faire un tour sur développez.com où on retrouve <a  href="http://sqlpro.developpez.com/cours/arborescence/" class="extern">un très bon article illustré à ce sujet</a>.</p>
<p>Brièvement, cette méthode consiste à rajouter des champs en base, left, right et scope permettant de retrouver ses petits. Le diagramme de developpez.com résume bien:<br />
<a  href="http://www.amicalement-web.net/wp-content/uploads/sqltree3.gif"><img src="http://www.amicalement-web.net/wp-content/uploads/sqltree3-300x194.gif" alt="Nested set" title="sqltree3" width="300" height="194" class="size-medium wp-image-204" /></a></p>
<p>Ok, c&#8217;est bien, mais appliquer tout ça à symfony ca doit être lourd! Et bien nan, Propel dans sa dernière version (1.3) intègre déjà cet algorithme en tant que behavior. (Cela sous entend qu&#8217;il faut utiliser symfony 1.2)</p>
<p>Pour se faire, on va donc créer un project vierge en 1.2 histoire d&#8217;éviter tout parasitage qu&#8217;on mènera en 2 parties. La première pour la partie visuel, la deuxième pour la partie code admin generator.</p>
<p>Voici le résultat attendu à la fin de cette première partie:<br />
<a  href="http://www.amicalement-web.net/wp-content/uploads/image-301.png"><img src="http://www.amicalement-web.net/wp-content/uploads/image-301-300x109.png" alt="image-301" title="image-301" width="300" height="109" class="alignnone size-medium wp-image-237" /></a></p>
<p>On se lance donc, notre beau projet est créé, on ouvre le schema.yml que l&#8217;on modifie comme ceci:</p>

<div class="wp_syntax"><div class="code"><pre class="yaml" style="font-family:monospace;">propel:
  categories:
    _attributes: { phpName: Categories, treeMode: NestedSet }
    id: ~
    titre: { type: VARCHAR, size: '50', required: true }
    tree_left: { type: INTEGER, size: '11', required: true, nestedSetLeftKey: true }
    tree_right: { type: INTEGER, size: '11', required: true, nestedSetRightKey: true }
    tree_parent: { type: INTEGER, size: '11', required: true }</pre></div></div>

<p>Vous noterez donc l&#8217;ajout du treeMode et la définition des nesetSetLeftKey et nestedSetRightKey, le tree_parent, n&#8217;est là que pour un certain confort à l&#8217;affichage, mais pas indispensable.</p>
<p>Votre schema ainsi terminé (vous pouvez y rajouter d&#8217;autres tables, même pas peur), on construit la base correspondante (en ayant au préalable configuré notre database.yml évidemment:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php symfony propel:build-all</pre></div></div>

<p>Et là on constate dans notre dossier lib, deux nouvelles classes que vous n&#8217;avez sans doute jamais vu:<br />
<img src="http://www.amicalement-web.net/wp-content/uploads/image-25.png" alt="image-25" title="image-25" width="304" height="218" class="alignnone size-full wp-image-220" /><br />
- BaseCategoriesNestedSet<br />
- BaseCategoriesNestedSetPeer<br />
qui viennent se placer entre entre les classes classiques et les classes &laquo;&nbsp;Base&nbsp;&raquo;</p>
<p>Afin de jouer rapidement, on va ajouter quelques valeurs test dans data/fixtures/fixtures.yml comme suit:</p>

<div class="wp_syntax"><div class="code"><pre class="yaml" style="font-family:monospace;">Categories:
  cat_1:
    titre: root
    tree_left: 1
    tree_right: 10
  cat_2:
    titre: Hi-Tech
    tree_left: 2
    tree_right: 7
  cat_3:
    titre: Developpement
    tree_left: 3
    tree_right: 4
  cat_4:
    titre: Internet
    tree_left: 5
    tree_right: 6
  cat_5:
    titre: Culture
    tree_left: 8
    tree_right: 9</pre></div></div>

<p>que l&#8217;on va charger dès à présent:</p>

<div class="wp_syntax"><div class="code"><pre class="yaml" style="font-family:monospace;">php symfony propel:data-load</pre></div></div>

<p>A noter que la notion de root est ici très importante. En effet, j&#8217;ai choisi délibérément de travailler avec un seul scope (une seule racine) pour la simple et bonne raison que les manipulations entre scope sont très limitées et l&#8217;intérêt et de pouvoir y faire tout et n&#8217;importe quoi. Il nous faut donc un élément parent de tous, que l&#8217;on ne modifiera jamais, que l&#8217;on n&#8217;affichera jamais.</p>
<p>Maintenant, les choses sérieuses commencent. On va commencer par générer un module admin generator:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php symfony generate:app main
php symfony propel:generate-admin main Categories</pre></div></div>

<p>Et vous devriez arriver via http://monlocal/categories sur quelque chose d&#8217;assez classique:<br />
<a  href="http://www.amicalement-web.net/wp-content/uploads/image-26.png"><img src="http://www.amicalement-web.net/wp-content/uploads/image-26-300x218.png" alt="image-26" title="image-26" width="300" height="218" class="alignnone size-medium wp-image-221" /></a></p>
<p>L&#8217;idée est maintenant d&#8217;inclure un plugin jquery qui va matérialiser notre arbre, propel ne s&#8217;occupant évidemment que de la logique métier.<br />
J&#8217;ai choisi le très bon <a  href="http://code.google.com/p/nestedsortables/wiki/NestedSortableDocumentation" class="extern">NestedSortable</a> qui répond très bien en terme de performance et très flexible à configurer. Vous pouvez donc télécharger <a  href="http://code.google.com/p/nestedsortables/downloads/list" class="extern">la dernière version</a>. Seul bémol, il nécessite <a  href="http://interface.eyecon.ro" class="extern">Interface</a>, un équivalent à jquery UI, que l&#8217;on va donc <a  href="http://interface.eyecon.ro/download" class="extern">télécharger également</a>.<br />
Pour jQuery, on laissera google faire.</p>
<p>On a donc nos js comme ceci:<br />
<img src="http://www.amicalement-web.net/wp-content/uploads/image-281.png" alt="image-281" title="image-281" width="250" height="111" class="alignnone size-full wp-image-222" /></p>
<p>et on les intègre à notre projet via notre view.yml (la notation en ligne étant plus claire à mon goût):</p>

<div class="wp_syntax"><div class="code"><pre class="yaml" style="font-family:monospace;">  javascripts: 
    - http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js
    - interface.js
    - inestedsortable-1.0.1.pack.js</pre></div></div>

<p>On va devoir maintenant modifier un peu quelques partials car le plugin jquery nécessite une imbrication de tag html, ici on utilisera ce qui semble être le plus apte sémantiquement parlant, des couples ul/li.</p>
<p>L&#8217;idée est donc d&#8217;afficher tout l&#8217;arbre quelque soit le nombre d&#8217;élément et de n&#8217;afficher que l&#8217;info qui nous interesse, en l&#8217;occurrence le titre. Première chose, voici la modification sur le generator.yml:</p>

<div class="wp_syntax"><div class="code"><pre class="yaml" style="font-family:monospace;">      list:
        peer_method: retrieveTree
        max_per_page: 99999
        display: [titre]</pre></div></div>

<p>Vous n&#8217;avez maintenant plus qu&#8217;un seul élément affiché dans votre tableau, l&#8217;élément root et c&#8217;est normal. </p>
<p>La suite se passe dans le partial _list.php. Rapide brief pour ceux qui n&#8217;ont jamais modifier un partial de l&#8217;admin generator. On récupère la version qui est dans le dossier <code>cache/[APP]/[ENV]/modules/auto[MODULE]/templates</code> et on la copie dans notre dossier templates de notre module généré.</p>
<p>Une fois cette opération effectuée, rien n&#8217;a du changer, mais maintenant on a la possibilité de modifier le partial, et voici un extrait de ce qu&#8217;il faut modifier dans la balise tbody:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">     &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;container_main_list&quot; colspan=&quot;3&quot;&gt;
              <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pager</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResults</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$item</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> include_partial<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'categories/tree'</span><span style="color: #339933;">,</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'tree'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$item</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'helper'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$helper</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: #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>
            &lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;</pre></div></div>

<p>Puis dans la partie script tout en base (vous pouvez retirer l&#8217;ancienne fonction checkAll, on ne pourra plus s&#8217;en servir:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #009966; font-style: italic;">/* &lt;![CDATA[ */</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;">'#main_list'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">NestedSortable</span><span style="color: #009900;">&#40;</span>
    <span style="color: #009900;">&#123;</span>
      accept<span style="color: #339933;">:</span> <span style="color: #3366CC;">'item_list'</span><span style="color: #339933;">,</span>
      opacity<span style="color: #339933;">:</span> <span style="color: #CC0000;">0.6</span><span style="color: #339933;">,</span>
      autoScroll<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
      revert<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
      nestingPxSpace<span style="color: #339933;">:</span> <span style="color: #3366CC;">'15'</span><span style="color: #339933;">,</span>
      handle<span style="color: #339933;">:</span> <span style="color: #3366CC;">'.sort-handle'</span><span style="color: #339933;">,</span>
      currentNestingClass<span style="color: #339933;">:</span> <span style="color: #3366CC;">'current-nesting'</span><span style="color: #339933;">,</span>
      noNestingClass<span style="color: #339933;">:</span> <span style="color: #3366CC;">'sf_admin_td_actions'</span><span style="color: #339933;">,</span>
      onChange<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>serialized<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#hashValue'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span>serialized<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">hash</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>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009966; font-style: italic;">/* ]]&gt; */</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>Bon si vous avez suivi, vous vous doutez que si vous actualisez, symfony vous dira gentiment qu&#8217;il manque le partial _tree.php. Et bien créons le! C&#8217;est la base même du tuto, car c&#8217;est un partial récursif, qui va donc s&#8217;auto inclure:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;ul <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#41;</span>?<span style="color: #0000ff;">'id=&quot;main_list&quot; '</span><span style="color: #339933;">:</span><span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #000000; font-weight: bold;">?&gt;</span>class=&quot;page-list&quot;&gt;
  <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;">$tree</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getChildren</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    &lt;li class=&quot;item_list clear-element&quot; id=&quot;ele-<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPrimaryKey</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
      &lt;div class=&quot;sort-handle&quot;&gt;
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$node</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>
			&lt;/div&gt;
      <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;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">hasChildren</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
            <span style="color: #000000; font-weight: bold;">&lt;?php</span> include_partial<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'categories/tree'</span><span style="color: #339933;">,</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'tree'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$node</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'helper'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$helper</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: #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>
    &lt;/li&gt;
  <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>
&lt;/ul&gt;</pre></div></div>

<p>Et là, un petit coup de F5 et la magie comment à opérer. Vous pouvez maintenant déplacer les éléments de branche en branche tel un hibou&#8230; bref, ca fonctionne!</p>
<p>Un petit coup de css s&#8217;impose pour que ca se rapproche le plus possible des autres modules classiques:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #cc00cc;">#sf_admin_container</span> table tr<span style="color: #3333ff;">:hover </span><span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#FFF</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
ul<span style="color: #cc00cc;">#menu</span> li<span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">list-style</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">inline</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">10px</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span> <span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#admin_content</span> ul <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">list-style-position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">inside</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#admin_content</span> ul<span style="color: #cc00cc;">#list-container</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">margin-left</span><span style="color: #00AA00;">:</span> <span style="color: #933;">1em</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#FFF</span> <span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span> <span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#admin_content</span> ul li <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">list-style-position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">inside</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
li img <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">vertical-align</span><span style="color: #00AA00;">:</span> text-<span style="color: #000000; font-weight: bold;">bottom</span> <span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#list-container</span> li span <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">cursor</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">pointer</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#sortHelper</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#FFE</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#dragHelper</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#EEE</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
div<span style="color: #6666ff;">.wrap</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">border</span><span style="color: #00AA00;">:</span><span style="color: #933;">1px</span> <span style="color: #993333;">solid</span> <span style="color: #cc00cc;">#BBBBBB</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #933;">1em</span> <span style="color: #933;">1em</span> <span style="color: #933;">1em</span> <span style="color: #933;">1em</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #cc00cc;">#main_list</span><span style="color: #00AA00;">,</span><span style="color: #cc00cc;">#contenu_list</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">700px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#main_list</span> li <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">list-style-type</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">list-style-position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #6666ff;">.page-list</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">list-style</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #6666ff;">.clear-element</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">clear</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">both</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">relative</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #6666ff;">.sort-handle</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">cursor</span><span style="color: #00AA00;">:</span>move<span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #933;">0.25em</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #933;">2px</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">2px</span> <span style="color: #933;">18px</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#f3F3F3</span> <span style="color: #000000; font-weight: bold;">left</span> <span style="color: #993333;">center</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000; font-style: italic;">../images/toggleexpanddark.png</span><span style="color: #00AA00;">&#41;</span> <span style="color: #993333;">no-repeat</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
div<span style="color: #6666ff;">.item-title</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#DDD</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #933;">0.25em</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #933;">2px</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">2px</span> <span style="color: #933;">18px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #6666ff;">.list-action</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #808080; font-style: italic;">/*background-color: #f3F3F3;*/</span>
	<span style="color: #000000; font-weight: bold;">position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">absolute</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">right</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">:</span><span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">350px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>Et l&#8217;image qui va bien (récupéré de redotheoffice):<br />
<img src="http://www.amicalement-web.net/wp-content/uploads/toggleexpanddark.png" alt="toggleexpanddark" title="toggleexpanddark" width="16" height="16" class="alignnone size-full wp-image-229" /></p>
<p>Et voilà, la première étape s&#8217;achève ici, on peut s&#8217;amuser à déplacer ces éléments. La suite très prochainement, pour remettre les actions et ajouter une action pour sauvegarder l&#8217;arbre.</p>
<p>A noter que je ne détaille pas forcément toutes les étapes de création d&#8217;un projet symfony, <a  href="http://www.symfony-project.org/jobeet/1_2/Propel/en/" class="extern">Jobeet</a> le fais si bien.</p>
<p>Évidemment, toutes remarques, questions, propositions, meilleurs solutions sont les bienvenues! Je suis aussi là pour apprendre : )</p>
]]></content:encoded>
			<wfw:commentRss>http://www.amicalement-web.net/symfony-gestion-d-un-arbre-en-propel-via-les-nestedset-part-1/2009/05/12/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
