<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://prendreuncafe.com/blog/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Prendre un Café - Tag - symfony</title>
  <link>http://prendreuncafe.com/blog/</link>
  <atom:link href="http://prendreuncafe.com/blog/feed/tag/symfony/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>fr</language>
  <pubDate>Wed, 17 Mar 2010 07:45:27 +0100</pubDate>
  <copyright>Contenus sous licence Creative Commons BY-SA</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>User Dependent Forms with Symfony</title>
    <link>http://prendreuncafe.com/blog/post/2010/02/17/User-Dependant-Forms-with-Symfony</link>
    <guid isPermaLink="false">urn:md5:afa96fedd9e7bc61404cdf6e257005b0</guid>
    <pubDate>Wed, 17 Feb 2010 09:04:00 +0100</pubDate>
    <dc:creator>NiKo</dc:creator>
        <category>Dev</category>
        <category>best practices</category><category>credentials</category><category>forms</category><category>php</category><category>security</category><category>session</category><category>symfony</category>    
    <description>    &lt;p&gt;While sadly not being at &lt;a href=&quot;http://www.symfony-live.com/&quot;&gt;Symfony Live 2010&lt;/a&gt; with pals, I&amp;#8217;m drowning my sorrow into tech tutorials writing.&lt;/p&gt;


&lt;p&gt;Sometimes you want to design forms and contextualize them regarding the current user session. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manage the display of some fields regarding the user authentication status and credentials;&lt;/li&gt;
&lt;li&gt;Filter some queries used to get the values available in a &lt;code&gt;&amp;lt;select/&amp;gt;&lt;/code&gt; tag;&lt;/li&gt;
&lt;li&gt;Allow multiple steps form validation with step state persistence (wizzard);&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So how can we achieve this without using an evilish &lt;code&gt;sfContext::getInstance()-&amp;gt;getUser()&lt;/code&gt; call in the &lt;code&gt;configure()&lt;/code&gt; method of the form?&lt;/p&gt;


&lt;p&gt;Symfony &lt;del&gt;1.2&lt;/del&gt; &lt;strong&gt;1.3 and 1.4&lt;/strong&gt; introduced the generation of a project-wide &lt;code&gt;BaseForm&lt;/code&gt; class we can use here to setup some convenient methods to allow user setters and getters:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; BaseForm extends sfFormSymfony
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;a href=&quot;http://www.php.net/static&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;static&lt;/span&gt;&lt;/a&gt; protected &lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;null&lt;/span&gt;;
&amp;nbsp;
  &lt;a href=&quot;http://www.php.net/static&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;static&lt;/span&gt;&lt;/a&gt; public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; getUser&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt; 
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; self::&lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  &lt;a href=&quot;http://www.php.net/static&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;static&lt;/span&gt;&lt;/a&gt; public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; getValidUser&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;!self::&lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt; instanceof sfBasicSecurityUser&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      throw &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; RuntimeException&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'No valid user instance available'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
    
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; self::&lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  &lt;a href=&quot;http://www.php.net/static&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;static&lt;/span&gt;&lt;/a&gt; public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; setUser&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;sfBasicSecurityUser &lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    self::&lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt; = &lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Okay, we now can set a user instance as a static property of all available forms within the project, nice. Wait, how the hell will we set the instance, and when?&lt;/p&gt;


&lt;p&gt;Symfony dispatch a very useful &lt;code&gt;context.load_factories&lt;/code&gt; event when all the factories - including the &lt;code&gt;user&lt;/code&gt; one - are instanciated and available in the context. So we can listen to this event and set the user instance to the forms when it&amp;#8217;s ready. We&amp;#8217;ll do this in the &lt;code&gt;ProjectConfiguration.class.php&lt;/code&gt;:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; ProjectConfiguration extends sfProjectConfiguration
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; setup&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// ...&lt;/span&gt;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;dispatcher&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;connect&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'context.load_factories'&lt;/span&gt;, &lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;'listenToLoadFactoriesEvent'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; listenToLoadFactoriesEvent&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;sfEvent &lt;span style=&quot;color: #0000ff;&quot;&gt;$event&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    BaseForm::&lt;span style=&quot;color: #006600;&quot;&gt;setUser&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$event&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getSubject&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getUser&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;So now we&amp;#8217;ve set a static user instance in every form at project configuration time, we can use it in any form.&lt;/p&gt;


&lt;p&gt;For example, imagine a form where only authenticated users having an &lt;code&gt;admin&lt;/code&gt; credential can see, fill and submit an hypothetic &lt;code&gt;is_published&lt;/code&gt; field:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; myForm extends BaseForm
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; configure&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// will throw an exception if no user is available&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt; = self::&lt;span style=&quot;color: #006600;&quot;&gt;getValidUser&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setWidgets&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
      &lt;span style=&quot;color: #ff0000;&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfWidgetFormInputText&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
      &lt;span style=&quot;color: #ff0000;&quot;&gt;'body'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfWidgetFormTextarea&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setValidators&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
      &lt;span style=&quot;color: #ff0000;&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfValidatorString&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'min_length'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #cc66cc;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
      &lt;span style=&quot;color: #ff0000;&quot;&gt;'body'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfValidatorString&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'min_length'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #cc66cc;&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;isAuthenticated&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;hasCredential&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'admin'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;widgetSchema&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'is_published'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfWidgetFormInputCheckbox&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
      &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;validatorSchema&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'is_published'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfValidatorBoolean&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
        &lt;span style=&quot;color: #ff0000;&quot;&gt;'required'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;false&lt;/span&gt;,
      &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
    
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// ...&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Here a basic user won&amp;#8217;t see and won&amp;#8217;t be able to submit any value for the &lt;code&gt;is_published&lt;/code&gt; field. Note that all those changes won&amp;#8217;t ever affect the controllers or the model, and the forms will still be easily testable because the forms and the user instance are not tightly coupled.&lt;/p&gt;


&lt;p&gt;As a side note, you can also use the form options to eventually pass a user instance and fallback on the static instance in case it&amp;#8217;s not available:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; myForm extends BaseForm
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; configure&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// will throw an exception if no user is available&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt; = &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getOption&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'user'&lt;/span&gt;, self::&lt;span style=&quot;color: #006600;&quot;&gt;getValidUser&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// ...&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;In a controller, you would use it this way:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; 
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; fooActions extends sfActions
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; executeBar&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;sfWebRequest &lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;form&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; myForm&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'user'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getUser&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// ...&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;A typical unit test suite of the form would be:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$t&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; lime_test&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;2&lt;/span&gt;, &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; lime_output_color&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfBasicSecurityUser&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfEventDispatcher&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfSessionTestStorage&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
  &lt;span style=&quot;color: #ff0000;&quot;&gt;'session_path'&lt;/span&gt; =&amp;gt; sys_get_temp_dir&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; myForm&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'user'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span style=&quot;color: #0000ff;&quot;&gt;$t&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;is&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/count&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;count&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getWidgetSchema&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span style=&quot;color: #cc66cc;&quot;&gt;2&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;'-&amp;gt;configure() displays 2 fields when user is not authenticated'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setAuthenticated&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addCredential&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'admin'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span style=&quot;color: #0000ff;&quot;&gt;$t&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;is&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/count&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;count&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getWidgetSchema&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span style=&quot;color: #cc66cc;&quot;&gt;3&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;'-&amp;gt;configure() displays 3 fields when user is authenticated and is an admin'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// ... I'll let you complete the suite by yourself &lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Now imagine we want to filter the choices offered by a one to many relationship field of a Doctrine form regarding user credentials:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; ArticleForm extends BaseArticleForm
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; configure&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// will throw an exception if no user is available&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt; = &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getOption&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'user'&lt;/span&gt;, self::&lt;span style=&quot;color: #006600;&quot;&gt;getValidUser&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// ...&lt;/span&gt;
    
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// Category choices&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$categoryQuery&lt;/span&gt; = &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getUserCategoryQuery&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;widgetSchema&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'category_id'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfWidgetFormDoctrineChoice&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
      &lt;span style=&quot;color: #ff0000;&quot;&gt;'model'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;'Category'&lt;/span&gt;,
      &lt;span style=&quot;color: #ff0000;&quot;&gt;'query'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$categoryQuery&lt;/span&gt;,
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;validatorSchema&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'community_id'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfValidatorDoctrineChoice&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
      &lt;span style=&quot;color: #ff0000;&quot;&gt;'model'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;'Category'&lt;/span&gt;,
      &lt;span style=&quot;color: #ff0000;&quot;&gt;'query'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$categoryQuery&lt;/span&gt;,
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  
  &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/**
   * Please note that this method would naturally better fit in the model, in the 
   * ArticleTable class; We put this here for conciseness
   */&lt;/span&gt;
  protected &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; getUserCategoryQuery&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;sfBasicSecurityUser &lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$query&lt;/span&gt; = Doctrine:getTable&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Category'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;createQuery&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'c'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// If user is not an admin, only allow choice of published categories&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;!&lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;hasCredential&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'admin'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;span style=&quot;color: #0000ff;&quot;&gt;$query&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;where&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'c.is_published = 1'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
    
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$query&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;There are many more cool things you can achieve by offering user session access to a form, while keeping all the stuff easy to test.&lt;/p&gt;


&lt;p&gt;As usual, if you have a better way, feel free to tell us about it in the comments.&lt;/p&gt;&lt;hr/&gt;&lt;p style=&quot;margin:.5em 0;padding:.5em;border:1px solid #333;background:#eee;color:#222&quot;&gt;&lt;small&gt;Ce billet intitulé &lt;a href=&quot;http://prendreuncafe.com/blog/post/2010/02/17/User-Dependant-Forms-with-Symfony&quot;&gt;User Dependent Forms with Symfony&lt;/a&gt; a été rédigé par &lt;a href=&quot;http://prendreuncafe.com/cv&quot;&gt;Nicolas Perriault&lt;/a&gt; et publié sur le blog &lt;a href=&quot;http://prendreuncafe.com/blog/&quot;&gt;Prendre un Café&lt;/a&gt; sous licence &lt;a href=&quot;http://creativecommons.org/licenses/by-nc-sa/2.5/&quot;&gt;Creative Commons BY-NC-SA&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Symfony Development using Textmate</title>
    <link>http://prendreuncafe.com/blog/post/2009/12/16/Symfony-Development-using-Textmate</link>
    <guid isPermaLink="false">urn:md5:bd4ca88c19a951de03a540798feb7467</guid>
    <pubDate>Wed, 16 Dec 2009 08:45:00 +0100</pubDate>
    <dc:creator>NiKo</dc:creator>
        <category>Dev</category>
        <category>osx</category><category>symfony</category><category>textmate</category>    
    <description>    &lt;p&gt;When I do consulting, a lot of people are really surprised that I use &lt;a href=&quot;http://macromates.com/&quot; hreflang=&quot;en&quot;&gt;Texmate&lt;/a&gt;, a popular text editor for OS X, to develop on &lt;a href=&quot;http://www.symfony-project.org/&quot; hreflang=&quot;en&quot;&gt;Symfony&lt;/a&gt; projects. Indeed, Textmate is a bit rough around the edge compared to &lt;del&gt;bloated&lt;/del&gt; full featured &lt;acronym title=&quot;Integrated Development Environment&quot;&gt;IDE&lt;/acronym&gt; like &lt;a href=&quot;http://www.eclipse.org/pdt/&quot; hreflang=&quot;en&quot;&gt;Eclipse PDT&lt;/a&gt; or &lt;a href=&quot;http://netbeans.org/&quot; hreflang=&quot;en&quot;&gt;Netbeans&lt;/a&gt;, which are both Java based by the way.&lt;/p&gt;


&lt;p&gt;So why using Textmate? No intelligent autocompletion, very basic project management, poor &lt;acronym title=&quot;Version Control System&quot;&gt;VCS&lt;/acronym&gt; native support, limited index search capabilities&amp;#8230; First and while it&amp;#8217;s mainly a matter of taste, I mainly use Texmate because it&amp;#8217;s &lt;em&gt;fast&lt;/em&gt;. Compared to PDT with which you often have to wait a bunch of seconds for the UI to respond on some action you make, &lt;em&gt;mate&lt;/em&gt; will react quite instantaneously, and &lt;strong&gt;that&lt;/strong&gt; is making big difference to me. Because when I&amp;#8217;m concentrated, focused on some complex problem to solve, I demand my text editor to &lt;strong&gt;not make me wait&lt;/strong&gt; &lt;sup&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/12/16/Symfony-Development-using-Textmate#pnote-1131-1&quot; id=&quot;rev-pnote-1131-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;Oppositely, not having full code introspection and autocompletion makes mate &lt;strong&gt;making me think&lt;/strong&gt; about the code I write, instead of just consuming some API passively. I&amp;#8217;ve been using &lt;a href=&quot;http://www.phpeclipse.com/&quot; hreflang=&quot;en&quot;&gt;phpeclipse&lt;/a&gt; and PDT for some years with Symfony, but I think I really began to understand the framework architecture when I switched to mate as my primary editor. Because every time you need to do something with the Symfony API, you &lt;em&gt;have&lt;/em&gt; to open the file and read the code: then you learn a lot. And by the time, you end by knowing the core very well, and it&amp;#8217;s incredibly efficient. One more time, this is just matter of taste.&lt;/p&gt;


&lt;h3&gt;Textmate quick tips&lt;/h3&gt;


&lt;p&gt;So whereas mate can be somewhat limited at first glance, a second look shows it provides some really effective commands to enhance your productivity. Let&amp;#8217;s examine some of them.&lt;/p&gt;


&lt;h4&gt;Searching for a file within the project codebase&lt;/h4&gt;


&lt;p&gt;Just by pressing &lt;code&gt;⌘ + t&lt;/code&gt;, a snappy filename search window will pop up and allow you to search a file interactively by its name pattern. If you&amp;#8217;re using the incredible &lt;a href=&quot;http://docs.blacktree.com/quicksilver/what_is_quicksilver&quot; hreflang=&quot;en&quot;&gt;Quicksilver app&lt;/a&gt; for osx, you got the picture.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/ScreenShots/Textmate/interactive-filename-search.png&quot; alt=&quot;interactive-filename-search.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;interactive-filename-search.png, déc. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;As Symfony names php files against the class name they contain, finding a class file is just easy as typing the class name in the search field!&lt;/p&gt;


&lt;h4&gt;Browsing the available functions, classes and methods within a php file&lt;/h4&gt;


&lt;p&gt;When a php file is opened, the &lt;code&gt;⌘ + shift + t&lt;/code&gt; command will show up the available sections of the document, with a search box you can use to filter their names, still interactively.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/ScreenShots/Textmate/interactive-method-name-search.png&quot; alt=&quot;interactive-method-name-search.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;interactive-method-name-search.png, déc. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Note that this will also work for other file types (like CSS for instance).&lt;/p&gt;


&lt;h4&gt;Obtening help on native php functions&lt;/h4&gt;


&lt;p&gt;Move the carret onto some php native function and press &lt;code&gt;ctrl + h&lt;/code&gt; and you&amp;#8217;ll get the &lt;a href=&quot;http://php.net/&quot; hreflang=&quot;en&quot;&gt;php.net&lt;/a&gt; related page in a pop up.&lt;/p&gt;


&lt;p&gt;Want the function signature definition in a tooltip, like in PDT or Netbeans? Hit &lt;code&gt;⌥ + F1&lt;/code&gt; and you&amp;#8217;re done.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/ScreenShots/Textmate/signature-tooltip.png&quot; alt=&quot;signature-tooltip.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;signature-tooltip.png, déc. 2009&quot; /&gt;&lt;/p&gt;


&lt;h4&gt;Using the &lt;code&gt;mate&lt;/code&gt; command line utility&lt;/h4&gt;


&lt;p&gt;Textmate ships with a native command line interface executable called &lt;code&gt;mate&lt;/code&gt; you can use from your term:&lt;/p&gt;

&lt;pre&gt;
$ cd /path/to/project
$ mate .
&lt;/pre&gt;


&lt;p&gt;You can also &lt;em&gt;pipe&lt;/em&gt; some command to &lt;code&gt;mate&lt;/code&gt; to open the output in it:&lt;/p&gt;

&lt;pre&gt;
$ svn diff|mate
&lt;/pre&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/ScreenShots/Textmate/diff-mate.png&quot; alt=&quot;diff-mate.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;diff-mate.png, déc. 2009&quot; /&gt;&lt;/p&gt;


&lt;h4&gt;Taking part of Mate&amp;#8217;s url-scheme capabilities with Symfony&lt;/h4&gt;


&lt;p&gt;I already blogged about this &lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/10/12/A-Symfony-1.3-Gem:-Open-Files-Listed-in-Exceptions-with-the-Editor-of-your-Choice&quot; hreflang=&quot;en&quot;&gt;awesome feature&lt;/a&gt; available since Symfony 1.3, one more I won&amp;#8217;t ever be able to live without.&lt;/p&gt;


&lt;h3&gt;Improve your productivity using bundles&lt;/h3&gt;


&lt;h4&gt;The &lt;a href=&quot;http://github.com/protocool/ack-tmbundle&quot; hreflang=&quot;en&quot;&gt;Ack in project&lt;/a&gt; bundle&lt;/h4&gt;


&lt;p&gt;One of the most annoying lack of mate is its internal search engine. It&amp;#8217;s really damn slow. The best way to get something decent is to install the &lt;a href=&quot;http://github.com/protocool/ack-tmbundle&quot; hreflang=&quot;en&quot;&gt;Ack in project&lt;/a&gt; bundle. You&amp;#8217;ll then be able to access a fast and convenient fulltext search engine by pressing the &lt;code&gt;⌘ + shift + a&lt;/code&gt; command.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/ScreenShots/Textmate/ack-in-project.png&quot; alt=&quot;ack-in-project.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;ack-in-project.png, déc. 2009&quot; /&gt;&lt;/p&gt;


&lt;h4&gt;The &lt;a href=&quot;http://ciaranwal.sh/2008/08/05/textmate-plug-in-projectplus&quot; hreflang=&quot;en&quot;&gt;ProjectPlus&lt;/a&gt; bundle&lt;/h4&gt;


&lt;p&gt;If you&amp;#8217;re looking after a better project browser and some VCS support in mate, you&amp;#8217;ll love the &lt;a href=&quot;http://ciaranwal.sh/2008/08/05/textmate-plug-in-projectplus&quot; hreflang=&quot;en&quot;&gt;ProjectPlus bundle&lt;/a&gt;. It will replace the default project drawer by a new one with finder label colors support, file sorting options and VCS icons integration. Give it a try, you won&amp;#8217;t be able to live without it.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/ScreenShots/Textmate/project-plus-drawer.png&quot; alt=&quot;project-plus-drawer.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;project-plus-drawer.png, déc. 2009&quot; /&gt;&lt;/p&gt;


&lt;h4&gt;The &lt;a href=&quot;http://github.com/denderello/symfony-tmbundle&quot; hreflang=&quot;en&quot;&gt;Symfony&lt;/a&gt; bundle&lt;/h4&gt;


&lt;p&gt;How could I write a blog post on Textmate and Symfony without mentioning the &lt;a href=&quot;http://github.com/denderello/symfony-tmbundle&quot; hreflang=&quot;en&quot;&gt;Symfony bundle&lt;/a&gt;? &lt;a href=&quot;http://www.denderello.com/&quot; hreflang=&quot;en&quot;&gt;Denderello&lt;/a&gt; and contributors did a really good job taking over the original tool, which provides very convenient and effective shortcuts to write Symfony snippets of code quickly.&lt;/p&gt;


&lt;h4&gt;The &lt;a href=&quot;http://github.com/textmate/getbundle.tmbundle&quot; hreflang=&quot;en&quot;&gt;GetBundle&lt;/a&gt; bundle&lt;/h4&gt;


&lt;p&gt;Last, if you didn&amp;#8217;t find anything new or useful reading this blog entry, you might then be interested by installing the &lt;a href=&quot;http://github.com/textmate/getbundle.tmbundle&quot; hreflang=&quot;en&quot;&gt;GetBundle&lt;/a&gt; bundle which will allow you to browse all available bundles and install any of them in one click!&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/ScreenShots/Textmate/GetBundle.png&quot; alt=&quot;GetBundle.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;GetBundle.png, déc. 2009&quot; /&gt;&lt;/p&gt;


&lt;h3&gt;Conclusion&lt;/h3&gt;


&lt;p&gt;So these are some of the reasons why I&amp;#8217;m using Textmate when developing with Symfony (and other languages too). &lt;strong&gt;What are yours?&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/12/16/Symfony-Development-using-Textmate#rev-pnote-1131-1&quot; id=&quot;pnote-1131-1&quot;&gt;1&lt;/a&gt;] You know the &lt;q&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Don't_Make_Me_Think&quot; hreflang=&quot;en&quot;&gt;don&amp;#8217;t make me think&lt;/a&gt;&lt;/q&gt; mantra? Well, now you got another one &lt;img src=&quot;/blog/themes/battlestar/smilies/wink.gif&quot; alt=&quot;;)&quot; class=&quot;smiley&quot; /&gt;&lt;/p&gt;&lt;/div&gt;&lt;hr/&gt;&lt;p style=&quot;margin:.5em 0;padding:.5em;border:1px solid #333;background:#eee;color:#222&quot;&gt;&lt;small&gt;Ce billet intitulé &lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/12/16/Symfony-Development-using-Textmate&quot;&gt;Symfony Development using Textmate&lt;/a&gt; a été rédigé par &lt;a href=&quot;http://prendreuncafe.com/cv&quot;&gt;Nicolas Perriault&lt;/a&gt; et publié sur le blog &lt;a href=&quot;http://prendreuncafe.com/blog/&quot;&gt;Prendre un Café&lt;/a&gt; sous licence &lt;a href=&quot;http://creativecommons.org/licenses/by-nc-sa/2.5/&quot;&gt;Creative Commons BY-NC-SA&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Saving Search Filters in Symfony's Doctrine Admin Generator</title>
    <link>http://prendreuncafe.com/blog/post/2009/12/02/Saving-Search-Filters-in-Symfony-s-Doctrine-Admin-Generator</link>
    <guid isPermaLink="false">urn:md5:fb2139dab5ae20977bb758adc85805d7</guid>
    <pubDate>Wed, 02 Dec 2009 11:43:00 +0100</pubDate>
    <dc:creator>NiKo</dc:creator>
        <category>Dev</category>
        <category>admin-generator</category><category>doctrine</category><category>filters</category><category>search</category><category>symfony</category>    
    <description>    &lt;p&gt;Yesterday I made some consulting in a company where people asked me if it was possible/hard to setup some kind of search filtering persistence in a &lt;em&gt;doctrine-admin-generated&lt;/em&gt; module in &lt;a href=&quot;http://www.symfony-project.org/&quot; hreflang=&quot;en&quot;&gt;Symfony&lt;/a&gt;. I told them:&lt;/p&gt;


&lt;blockquote&gt;&lt;p&gt;Well, it&amp;#8217;s a twenty minutes job.&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;They logically answered me:&lt;/p&gt;


&lt;blockquote&gt;&lt;p&gt;Haha, prove it.&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;Challenge and stress then started.&lt;/p&gt;


&lt;p&gt;The examples below are based on the simple model I took for my previous blog post about &lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine&quot; hreflang=&quot;en&quot;&gt;embedding relations in Doctrine forms&lt;/a&gt;, which I will add fancy bookmarks tagging facilities to:&lt;/p&gt;

&lt;pre&gt;# in ./config/doctrine/schema.yml
User:
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    name:
      type: string(255)
      notnull: true
  relations:
    Bookmarks:
      type: many
      class: Bookmark
      local: id
      foreign: user_id
      onDelete: CASCADE
&amp;nbsp;
Bookmark:
  actAs:
    I18n:
      fields: [name]
      actAs:
        Sluggable:
          fields: [name]
          uniqueBy: [name, lang]
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    name:
      type: string(255)
      notnull: true
    url:
      type: string(255)
      notnull: true
    user_id:
      type: integer(4)
      notnull: true
  relations:
    User:
      type: one
      local: user_id
      foreign: id
    Tags:
      class: Tag
      refClass: BookmarkTag
      local: bookmark_id
      foreign: tag_id
      foreignAlias: Bookmarks
&amp;nbsp;
Tag:
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    name:
      type: string(255)
      notnull: true
&amp;nbsp;
BookmarkTag:
  columns:
    bookmark_id:
      type: integer(4)
      primary: true
      notnull: true
    tag_id:
      type: integer(4)
      primary: true
      notnull: true&lt;/pre&gt;


&lt;p&gt;No need to say you should rebuild your model, right?&lt;/p&gt;


&lt;p&gt;Updated fixtures file:&lt;/p&gt;

&lt;pre&gt;# in ./data/fixtures/fixtures.yml
User:
  niko:
    name: niko
&amp;nbsp;
Bookmark:
  niko_bookmark1:
    User: niko
    name: Slashdot
    url: http://slashdot.org/
    Tags: [geek_tag, tech_tag, php_tag]
  niko_bookmark2:
    User: niko
    name: Delicious
    url: http://delicious.com/
    Tags: [geek_tag, tech_tag]
  niko_bookmark3:
    User: niko
    name: Digg
    url: http://digg.com/
    Tags: [geek_tag, php_tag]
&amp;nbsp;
Tag:
  geek_tag:
    name: geek
  php_tag:
    name: php
  tech_tag:
    name: tech&lt;/pre&gt;


&lt;h3&gt;Generate the &lt;code&gt;Bookmark&lt;/code&gt; admin&lt;/h3&gt;


&lt;p&gt;Let&amp;#8217;s generate a &lt;code&gt;backend&lt;/code&gt; app and a &lt;code&gt;Bookmark&lt;/code&gt; admin module:&lt;/p&gt;

&lt;pre&gt;
$ ./symfony generate:app backend
$ ./symfony doctrine:generate-admin backend Bookmark
&lt;/pre&gt;


&lt;p&gt;Now let&amp;#8217;s enhance a bit our admin by modifying the &lt;code&gt;generator.yml&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;generator:
  class: sfDoctrineGenerator
  param:
    model_class:           Bookmark
    theme:                 admin
    non_verbose_templates: true
    with_show:             false
    singular:              Bookmark
    plural:                Bookmarks
    route_prefix:          bookmark
    with_doctrine_route:   true
    actions_base_class:    sfActions
&amp;nbsp;
    config:
      actions: ~
      fields:  ~
      list:
        display: [=name, url, User]
      filter:  ~
      form:    ~
      edit:    ~
      new:     ~&lt;/pre&gt;


&lt;p&gt;You should be able to browse the generated bookmarks admin interface:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/symfony/savedFilters/basic.png&quot; alt=&quot;basic.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;basic.png, déc. 2009&quot; /&gt;&lt;/p&gt;


&lt;h3&gt;Storing filters in a dedicated Doctrine table, and managing them from the controller&lt;/h3&gt;


&lt;p&gt;We&amp;#8217;ll use Doctrine to store saved filters, so let&amp;#8217;s define a new Doctrine table definition in our &lt;code&gt;schema.yml&lt;/code&gt; file to store stored filters:&lt;/p&gt;

&lt;pre&gt;SavedFilter:
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    name:
      type: string(255)
    type:
      type: enum
      values: [Bookmark, User]
      notnull: true
    filter:
      type: string()&lt;/pre&gt;


&lt;p&gt;Of course, still no need to say that you have to rebuild your model, right?&lt;/p&gt;


&lt;p&gt;Okay, now we&amp;#8217;re going to save the serialized filter values in the &lt;code&gt;filter&lt;/code&gt; column, the &lt;code&gt;name&lt;/code&gt; one will provide a convenient way to reference a filter set. The &lt;code&gt;type&lt;/code&gt; column will reference the Doctrine table familly of the filtered object. Nothing difficult here.&lt;/p&gt;


&lt;p&gt;In the admin generator module, the filters are storedin the &lt;code&gt;tableName.filters&lt;/code&gt; attribute of the user session (where &lt;code&gt;tableName&lt;/code&gt; is the name of the admin module where the filter parameters are operated&lt;sup&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/12/02/Saving-Search-Filters-in-Symfony-s-Doctrine-Admin-Generator#pnote-1130-1&quot; id=&quot;rev-pnote-1130-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;).&lt;/p&gt;


&lt;p&gt;So let&amp;#8217;s add a new &lt;code&gt;executeSaveFilter()&lt;/code&gt; method in the &lt;code&gt;bookmarkActions&lt;/code&gt; controller. And while we&amp;#8217;re at it, let&amp;#8217;s also add &lt;code&gt;executeLoadFilter()&lt;/code&gt; and &lt;code&gt;executeDeleteFilter()&lt;/code&gt; methods as well:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;# in apps/backend/modules/bookmark/actions/actions.class.php&lt;/span&gt;
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; bookmarkActions extends autoBookmarkActions
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; executeDeleteFilter&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;sfWebRequest &lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;forward404Unless&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$filter&lt;/span&gt; = Doctrine::&lt;span style=&quot;color: #006600;&quot;&gt;getTable&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'SavedFilter'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;findOneByTypeAndId&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmark'&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getParameter&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'id'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;a href=&quot;http://www.php.net/sprintf&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;sprintf&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmark filter #%d not found'&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getParameter&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'id'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$filter&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;delete&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getUser&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setFlash&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'notice'&lt;/span&gt;, &lt;a href=&quot;http://www.php.net/sprintf&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;sprintf&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmark saved filters &amp;quot;%s&amp;quot; deleted'&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$filter&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getName&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;redirect&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'bookmark'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; executeLoadFilter&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;sfWebRequest &lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;forward404Unless&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$filter&lt;/span&gt; = Doctrine::&lt;span style=&quot;color: #006600;&quot;&gt;getTable&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'SavedFilter'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;findOneByTypeAndId&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmark'&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getParameter&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'id'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setFilters&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/unserialize&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;unserialize&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$filter&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getFilter&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getUser&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setFlash&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'notice'&lt;/span&gt;, &lt;a href=&quot;http://www.php.net/sprintf&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;sprintf&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmark saved filters &amp;quot;%s&amp;quot; loaded'&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$filter&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getName&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;redirect&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'bookmark'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; executeSaveFilter&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;sfWebRequest &lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$name&lt;/span&gt; = &lt;a href=&quot;http://www.php.net/trim&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;trim&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getGetParameter&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$savedFilter&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; SavedFilter&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$savedFilter&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;fromArray&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
      &lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;   =&amp;gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$name&lt;/span&gt; ? &lt;span style=&quot;color: #0000ff;&quot;&gt;$name&lt;/span&gt; : &lt;span style=&quot;color: #ff0000;&quot;&gt;'Untitled filter'&lt;/span&gt;,
      &lt;span style=&quot;color: #ff0000;&quot;&gt;'type'&lt;/span&gt;   =&amp;gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmark'&lt;/span&gt;,
      &lt;span style=&quot;color: #ff0000;&quot;&gt;'filter'&lt;/span&gt; =&amp;gt; &lt;a href=&quot;http://www.php.net/serialize&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;serialize&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getUser&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'bookmark.filters'&lt;/span&gt;, &lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;'admin_module'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$savedFilter&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getUser&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setFlash&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'notice'&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmark filters saved'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;redirect&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'bookmark'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Of course, we&amp;#8217;ll need to add the corresponding routes to our &lt;code&gt;routing.yml&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;# in apps/backend/config/routing.yml
bookmark_filter_delete:
  url: /bookmark/filter/:id/delete
  param: { module: bookmark, action: deleteFilter }
  requirements:
    id: \d+
&amp;nbsp;
bookmark_filter_load:
  url: /bookmark/filter/:id/load
  param: { module: bookmark, action: loadFilter }
  requirements:
    id: \d+
&amp;nbsp;
bookmark_filter_save:
  url: /bookmark/filter/save
  param: { module: bookmark, action: saveFilter }&lt;/pre&gt;


&lt;p&gt;Wait, we don&amp;#8217;t have any link to save a filter from the admin interface! Let&amp;#8217;s add one next to the &lt;code&gt;Reset&lt;/code&gt; link of the filters column by overriding the &lt;code&gt;_filters.php&lt;/code&gt; generated partial template:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// in apps/backend/modules/bookmark/templates/_filters.php from line 11&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;...&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;
&amp;lt;tfoot&amp;gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;td colspan=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&amp;gt;
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderHiddenFields&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
      &amp;lt;a href=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;&amp;lt;?php echo url_for('@bookmark_filter_save') ?&amp;gt;&amp;quot;&lt;/span&gt; onclick=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;document.location = this.href+'?name='+prompt('Enter a name:');return false&amp;quot;&lt;/span&gt;&amp;gt;
        &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; __&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Save'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
      &amp;lt;/a&amp;gt;
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; link_to&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;__&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Reset'&lt;/span&gt;, &lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;'sf_admin'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;'bookmark_collection'&lt;/span&gt;, &lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'action'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;'filter'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'query_string'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;'_reset'&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;'method'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;'post'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
      &amp;lt;input type=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;submit&amp;quot;&lt;/span&gt; value=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;&amp;lt;?php echo __('Filter', array(), 'sf_admin') ?&amp;gt;&amp;quot;&lt;/span&gt; /&amp;gt;
    &amp;lt;/td&amp;gt;
  &amp;lt;/tr&amp;gt;
&amp;lt;/tfoot&amp;gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;...&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Notice that a javascript prompt will ask you for a name before saving a filter set:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/symfony/savedFilters/prompt.png&quot; alt=&quot;prompt.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;prompt.png, déc. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;So we can now save a filter set in our database. Now, what about listing them below the filters form?&lt;/p&gt;


&lt;h3&gt;Listing existing saved filters&lt;/h3&gt;


&lt;p&gt;To me, the best suited place to retrieve saved filtered searches is the &lt;code&gt;bookmarkGeneratorConfiguration&lt;/code&gt; class, which has been generated in the &lt;code&gt;lib/&lt;/code&gt; subfolder of the &lt;code&gt;bookmark&lt;/code&gt; admin module. Let&amp;#8217;s add a new &lt;code&gt;getSavedFilters()&lt;/code&gt; method to it:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;# in apps/backend/modules/bookmark/lib/bookmarkGeneratorConfiguration.class.php&lt;/span&gt;
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; bookmarkGeneratorConfiguration extends BaseBookmarkGeneratorConfiguration
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; getSavedFilters&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; Doctrine::&lt;span style=&quot;color: #006600;&quot;&gt;getTable&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'SavedFilter'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;createQuery&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;where&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'type = ?'&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmark'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;execute&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    ;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;So in the &lt;code&gt;_filters&lt;/code&gt; partial template, which has already access to a generator configuration instance, we&amp;#8217;re now able to iterate over retrieved saved filter objects to list them:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// in apps/backend/modules/bookmark/templates/_filters.php from line 11&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;...&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;td colspan=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&amp;gt;
      &amp;lt;h3&amp;gt;&amp;lt;?php &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; __&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Saved filters'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ?&amp;gt;&amp;lt;/h3&amp;gt;
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/count&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;count&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$savedFilters&lt;/span&gt; = &lt;span style=&quot;color: #0000ff;&quot;&gt;$configuration&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getSavedFilters&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;: &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
      &amp;lt;ul&amp;gt;
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;foreach&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$savedFilters&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$filter&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;: &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
        &amp;lt;li&amp;gt;
          &amp;lt;a href=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;&amp;lt;?php echo url_for('@bookmark_filter_load?id='.$filter['id']) ?&amp;gt;&amp;quot;&lt;/span&gt;&amp;gt;
            &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$filter&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
          &amp;lt;/a&amp;gt;
          &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&amp;lt;a href=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;&amp;lt;?php echo url_for('@bookmark_filter_delete?id='.$filter['id']) ?&amp;gt;&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/a&amp;gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &amp;lt;/li&amp;gt;
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; endforeach; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
      &amp;lt;/ul&amp;gt;
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;else&lt;/span&gt;: &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
        &amp;lt;p&amp;gt;No filters saved&amp;lt;/p&amp;gt;
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;endif&lt;/span&gt;; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
    &amp;lt;/td&amp;gt;
  &amp;lt;/tr&amp;gt;
&amp;lt;/tbody&amp;gt;&lt;/pre&gt;


&lt;p&gt;So you can now save and list filters, load and run them against your objects list, and delete existing ones. If you thoroughly followed the steps of this tutorial, you should now see something like this below the filters form:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/symfony/savedFilters/withlist.png&quot; alt=&quot;withlist.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;withlist.png, déc. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Twenty minutes, job done. Even if very quick and dirty.&lt;/p&gt;


&lt;h3&gt;Conclusion&lt;/h3&gt;


&lt;p&gt;Yes, I can hear you Symfony nerds, this could be heavily refactored, enhanced and maybe abstracted to provided generic filtering storage accross every generated admin module, but in 20 minutes? Really? &lt;img src=&quot;/blog/themes/battlestar/smilies/wink.gif&quot; alt=&quot;;-)&quot; class=&quot;smiley&quot; /&gt; Then, I&amp;#8217;d say&amp;#8230;&lt;/p&gt;


&lt;blockquote&gt;&lt;p&gt;Haha, prove it &lt;img src=&quot;/blog/themes/battlestar/smilies/smile.gif&quot; alt=&quot;:-)&quot; class=&quot;smiley&quot; /&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/12/02/Saving-Search-Filters-in-Symfony-s-Doctrine-Admin-Generator#rev-pnote-1130-1&quot; id=&quot;pnote-1130-1&quot;&gt;1&lt;/a&gt;] I&amp;#8217;m not definitely sure of this, but who really cares?&lt;/p&gt;&lt;/div&gt;&lt;hr/&gt;&lt;p style=&quot;margin:.5em 0;padding:.5em;border:1px solid #333;background:#eee;color:#222&quot;&gt;&lt;small&gt;Ce billet intitulé &lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/12/02/Saving-Search-Filters-in-Symfony-s-Doctrine-Admin-Generator&quot;&gt;Saving Search Filters in Symfony's Doctrine Admin Generator&lt;/a&gt; a été rédigé par &lt;a href=&quot;http://prendreuncafe.com/cv&quot;&gt;Nicolas Perriault&lt;/a&gt; et publié sur le blog &lt;a href=&quot;http://prendreuncafe.com/blog/&quot;&gt;Prendre un Café&lt;/a&gt; sous licence &lt;a href=&quot;http://creativecommons.org/licenses/by-nc-sa/2.5/&quot;&gt;Creative Commons BY-NC-SA&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Embedding Relations in Forms with Symfony 1.3 and Doctrine</title>
    <link>http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine</link>
    <guid isPermaLink="false">urn:md5:c4b0662b7bed7faf0b568b417597c70e</guid>
    <pubDate>Sun, 29 Nov 2009 18:38:00 +0100</pubDate>
    <dc:creator>NiKo</dc:creator>
        <category>Dev</category>
        <category>doctrine</category><category>forms</category><category>php</category><category>symfony</category>    
    <description>    &lt;p&gt;Symfony 1.3 and 1.4 have been &lt;a href=&quot;http://www.symfony-project.org/blog/2009/11/24/final-release-candidates-for-symfony-1-3-and-1-4&quot; hreflang=&quot;en&quot;&gt;released some days ago in RC2&lt;/a&gt; and you should really take a look at it, because they &lt;a href=&quot;http://www.symfony-project.org/tutorial/1_4/en/whats-new&quot; hreflang=&quot;en&quot;&gt;improve&lt;/a&gt; a lot the way you work with the framework, especially the forms one. It&amp;#8217;s been a couple of days I started to implement a new bookmarks management feature on a project I&amp;#8217;m working on currently, and the new model relationship embedding feature of 1.3&amp;#8217;s forms framework just saved me a lot of days.&lt;/p&gt;


&lt;p&gt;Here&amp;#8217;s a quick and dirty example on how to setup a willingly simplistic bookmarks management system using it&lt;/p&gt;


&lt;h3&gt;The schema&lt;/h3&gt;


&lt;p&gt;Here&amp;#8217;s the naive Doctrine schema I&amp;#8217;ll use for this example:&lt;/p&gt;

&lt;pre&gt;# in config/doctrine/schema.yml
User:
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    name:
      type: string(255)
      notnull: true
  relations:
    Bookmarks:
      type: many
      class: Bookmark
      local: id
      foreign: user_id
      onDelete: CASCADE
&amp;nbsp;
Bookmark:
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    name:
      type: string(255)
      notnull: true
    url:
      type: string(255)
      notnull: true
    user_id:
      type: integer(4)
      notnull: true
  relations:
    User:
      type: one
      local: user_id
      foreign: id&lt;/pre&gt;


&lt;p&gt;As you can see, it&amp;#8217;s really &lt;em&gt;naive&lt;/em&gt;. Anyway.&lt;/p&gt;


&lt;h3&gt;Some fixtures&lt;/h3&gt;


&lt;p&gt;What would be a Doctrine schema without fixtures? Quite nothing I guess, so here we go:&lt;/p&gt;

&lt;pre&gt;# in data/fixtures/fixtures.yml
User:
  niko:
    name: niko
&amp;nbsp;
Bookmark:
  niko_bookmark1:
    User: niko
    name: Slashdot
    url: http://slashdot.org/
  niko_bookmark2:
    User: niko
    name: Delicious
    url: http://delicious.com/
  niko_bookmark3:
    User: niko
    name: Digg
    url: http://digg.com/&lt;/pre&gt;


&lt;h3&gt;Building stuff&lt;/h3&gt;


&lt;p&gt;You guessed it, after having suited the &lt;code&gt;config/databases.yml&lt;/code&gt; file to set up a database of our choice, we can now build the database, all the classes we need and load the previously defined fixtures:&lt;/p&gt;

&lt;pre&gt;
$ ./symfony doctrine:build --all --and-load
&lt;/pre&gt;


&lt;h3&gt;A basic user&amp;#8217;s bookmarks management form&lt;/h3&gt;


&lt;p&gt;What we want do do now is to manage one &lt;code&gt;User&lt;/code&gt;&amp;#8217;s bookmarks in a single form. Let&amp;#8217;s do it now in a new &lt;code&gt;UserBookmarksForm.class.php&lt;/code&gt; file where we&amp;#8217;ll build a form extending the autogenerated &lt;code&gt;UserForm&lt;/code&gt; one:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// lib/form/doctrine/UserBookmarksForm.class.php&lt;/span&gt;
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; UserBookmarksForm extends UserForm
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; configure&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// We don't want to edit the User object&lt;/span&gt;
    &lt;a href=&quot;http://www.php.net/unset&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;unset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// Existing bookmark forms&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;embedRelation&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmarks'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;widgetSchema&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setNameFormat&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'user_bookmarks[%s]'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;All the magic is done by calling the &lt;code&gt;embedRelation()&lt;/code&gt; method here: all &lt;code&gt;BookmarkForm&lt;/code&gt; instances will be embedded and managed automatically in and by our form.&lt;/p&gt;


&lt;p&gt;Let&amp;#8217;s use a simple controller to manage the form&lt;sup&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine#pnote-1129-1&quot; id=&quot;rev-pnote-1129-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; testActions extends sfActions
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; executeBookmarks&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;sfWebRequest &lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;form&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; UserBookmarksForm&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$user&lt;/span&gt; = Doctrine::&lt;span style=&quot;color: #006600;&quot;&gt;getTable&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'User'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;findOneByName&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'niko'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;isMethod&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'post'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;bindAndSave&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getParameter&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'user_bookmarks'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getUser&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setFlash&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'notice'&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmarks list updated'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
      &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;redirect&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'test/index'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;And a basic template:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&amp;lt;form action=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt; method=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;post&amp;quot;&lt;/span&gt;&amp;gt;
  &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderHiddenFields&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderGlobalErrors&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
  &amp;lt;table&amp;gt;
    &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
    &amp;lt;tr&amp;gt;
      &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
      &amp;lt;td&amp;gt;&amp;lt;input type=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;/&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
  &amp;lt;/table&amp;gt;
&amp;lt;/form&amp;gt;&lt;/pre&gt;


&lt;p&gt;You should see something like this:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/symfony/embeddedForms/simple.png&quot; alt=&quot;simple.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;simple.png, nov. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;The form is functional, you can edit several bookmarks at one. Neat? But wait, we can&amp;#8217;t add a new one!&lt;/p&gt;


&lt;h3&gt;Embedding a bookmark creation form&lt;/h3&gt;


&lt;p&gt;Let&amp;#8217;s enhance our form by embedding an empty &lt;code&gt;BookmarkForm&lt;/code&gt; form instance in order to add a new bookmark:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// lib/form/doctrine/UserBookmarksForm.class.php&lt;/span&gt;
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; UserBookmarksForm extends UserForm
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; configure&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;a href=&quot;http://www.php.net/unset&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;unset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// Bookmark creation form&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$newBookmarkForm&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; BookmarkForm&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$newBookmarkForm&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setDefault&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'user_id'&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;object&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;embedForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$newBookmarkForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// Existing bookmark forms&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;embedRelation&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmarks'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;widgetSchema&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setNameFormat&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'user_bookmarks[%s]'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  
  protected &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; doBind&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;''&lt;/span&gt; === &lt;a href=&quot;http://www.php.net/trim&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;trim&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style=&quot;color: #ff0000;&quot;&gt;''&lt;/span&gt; === &lt;a href=&quot;http://www.php.net/trim&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;trim&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'url'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;a href=&quot;http://www.php.net/unset&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;unset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
    
    parent::&lt;span style=&quot;color: #006600;&quot;&gt;doBind&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Here I just override the &lt;code&gt;doBind()&lt;/code&gt; method to remove the bookmark creation embedded form if nothing has been submitted by the user in its fields; that&amp;#8217;s probably because he just wants to edit existing bookmarks&lt;sup&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine#pnote-1129-2&quot; id=&quot;rev-pnote-1129-2&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;By refreshing the page you should now be able to see the new form:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/symfony/embeddedForms/withAdd.png&quot; alt=&quot;withAdd.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;withAdd.png, nov. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;So now you&amp;#8217;re able to add a new &lt;code&gt;Bookmark&lt;/code&gt; and/or edit existing instances within the same simple form. Neat? Wait, we can&amp;#8217;t delete existing bookmarks!&lt;/p&gt;


&lt;h3&gt;Deleting existing bookmarks&lt;/h3&gt;


&lt;p&gt;So you would like to have a checkbox next to every existing bookmark embedded form to schedule its deletion on saving the form? Wow, that&amp;#8217;s getting tricky, I like that.&lt;/p&gt;


&lt;p&gt;The Symfony forms framework has evolved a lot, but what we&amp;#8217;re trying to achieve here will involve some fine-tunning. Don&amp;#8217;t be too much afraid seeing the code &lt;img src=&quot;/blog/themes/battlestar/smilies/wink.gif&quot; alt=&quot;;)&quot; class=&quot;smiley&quot; /&gt;&lt;/p&gt;


&lt;p&gt;First, we&amp;#8217;ll have to add the checkbox widget to the &lt;code&gt;BookmarkForm&lt;/code&gt; form, but only if an existing &lt;code&gt;Bookmark&lt;/code&gt; object has been bound to it:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// lib/form/doctrine/BookmarkForm.class.php&lt;/span&gt;
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; BookmarkForm extends BaseBookmarkForm
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; configure&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;widgetSchema&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'user_id'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfWidgetFormInputHidden&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;validatorSchema&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'url'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfValidatorAnd&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfValidatorString&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'max_length'&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #cc66cc;&quot;&gt;255&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfValidatorUrl&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;object&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;exists&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;widgetSchema&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'delete'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfWidgetFormInputCheckbox&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
      &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;validatorSchema&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'delete'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; sfValidatorPass&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Refreshing the form page should display something like that:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/symfony/embeddedForms/withAddAndDelete.png&quot; alt=&quot;withAddAndDelete.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;withAddAndDelete.png, nov. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;The &lt;code&gt;UserBookmarksForm&lt;/code&gt; now holds this code:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// lib/form/doctrine/UserBookmarksForm.class.php&lt;/span&gt;
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; UserBookmarksForm extends UserForm
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/**
   * Bookmarks scheduled for deletion
   * @var array
   */&lt;/span&gt;
  protected &lt;span style=&quot;color: #0000ff;&quot;&gt;$scheduledForDeletion&lt;/span&gt; = &lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;  
  
  &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/**
   * Configures the form
   *
   */&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; configure&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;a href=&quot;http://www.php.net/unset&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;unset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// Bookmark creation form&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$newBookmarkForm&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; BookmarkForm&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$newBookmarkForm&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setDefault&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'user_id'&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;object&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;embedForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$newBookmarkForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// Existing bookmark forms&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;embedRelation&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmarks'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;widgetSchema&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;setNameFormat&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'user_bookmarks[%s]'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  
  &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/**
   * Here we just drop the bookmark embedded creation form if no value has been 
   * provided for it (it somewhat simulates a non-required embedded form)
   *
   * @see sfForm::doBind()
   */&lt;/span&gt;
  protected &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; doBind&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;''&lt;/span&gt; === &lt;a href=&quot;http://www.php.net/trim&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;trim&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style=&quot;color: #ff0000;&quot;&gt;''&lt;/span&gt; === &lt;a href=&quot;http://www.php.net/trim&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;trim&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'url'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;a href=&quot;http://www.php.net/unset&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;unset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
    
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/isset&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;isset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmarks'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;span style=&quot;color: #b1b100;&quot;&gt;foreach&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmarks'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$i&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$bookmarkValues&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/isset&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;isset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$bookmarkValues&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'delete'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style=&quot;color: #0000ff;&quot;&gt;$bookmarkValues&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'id'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
          &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;scheduledForDeletion&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #0000ff;&quot;&gt;$bookmarkValues&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'id'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;;
        &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
      &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
    
    parent::&lt;span style=&quot;color: #006600;&quot;&gt;doBind&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  
  &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/**
   * Updates object with provided values, dealing with evantual relation deletion
   *
   * @see sfFormDoctrine::doUpdateObject()
   */&lt;/span&gt;
  protected &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; doUpdateObject&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/count&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;count&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;scheduledForDeletion&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;span style=&quot;color: #b1b100;&quot;&gt;foreach&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;scheduledForDeletion&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$index&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;a href=&quot;http://www.php.net/unset&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;unset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmarks'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$index&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
        &lt;a href=&quot;http://www.php.net/unset&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;unset&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmarks'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$index&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
        Doctrine::&lt;span style=&quot;color: #006600;&quot;&gt;getTable&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmark'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;findOneById&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;delete&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
      &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getObject&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;fromArray&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$values&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  
  &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;/**
   * Saves embedded form objects.
   *
   * @param mixed $con   An optional connection object
   * @param array $forms An array of forms
   */&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; saveEmbeddedForms&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$con&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$forms&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;null&lt;/span&gt; === &lt;span style=&quot;color: #0000ff;&quot;&gt;$con&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;span style=&quot;color: #0000ff;&quot;&gt;$con&lt;/span&gt; = &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getConnection&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;null&lt;/span&gt; === &lt;span style=&quot;color: #0000ff;&quot;&gt;$forms&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;span style=&quot;color: #0000ff;&quot;&gt;$forms&lt;/span&gt; = &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;embeddedForms&lt;/span&gt;;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
    
    &lt;span style=&quot;color: #b1b100;&quot;&gt;foreach&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$forms&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt; instanceof sfFormObject&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;!&lt;a href=&quot;http://www.php.net/in_array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;in_array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getObject&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getId&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;scheduledForDeletion&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
          &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;saveEmbeddedForms&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$con&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
          &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getObject&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$con&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
        &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
      &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
      &lt;span style=&quot;color: #b1b100;&quot;&gt;else&lt;/span&gt;
      &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;saveEmbeddedForms&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$con&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getEmbeddedForms&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
      &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
    &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;The code should be self-explanatory&amp;#8230; or not. But anyway, you should now be able to add a new bookmark and delete existing ones as well, in a single form and process, and we&amp;#8217;re still using the very same controller from the beginning!&lt;/p&gt;


&lt;p&gt;Okay, let&amp;#8217;s admit it, we&amp;#8217;re reaching the limits of Symfony and probably those of my knowledge of it as well, but&amp;#8230; IT WORKS.&lt;/p&gt;


&lt;h3&gt;But, what about the templating?&lt;/h3&gt;


&lt;p&gt;As of now we&amp;#8217;ve used the convenient &lt;code&gt;&amp;lt;?php echo $form ?&amp;gt;&lt;/code&gt; trick, but we now want to have full fine-grained control over the way our embedded form fields will look like.&lt;/p&gt;


&lt;p&gt;Let&amp;#8217;s update the form template accordingly:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&amp;lt;form action=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt; method=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;post&amp;quot;&lt;/span&gt;&amp;gt;
  &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderHiddenFields&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderGlobalErrors&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
  &amp;lt;!-- Embedded &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; bookmark form --&amp;gt;
  &amp;lt;fieldset&amp;gt;
    &amp;lt;legend&amp;gt;&amp;lt;?php &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; __&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Create a new bookmark'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ?&amp;gt;&amp;lt;/legend&amp;gt;
    &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderError&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
    &amp;lt;div &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;form-row&amp;quot;&lt;/span&gt;&amp;gt;
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderLabel&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
      &amp;lt;div &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;form-field&amp;quot;&lt;/span&gt;&amp;gt;
        &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;render&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderError&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;form-row&amp;quot;&lt;/span&gt;&amp;gt;
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'url'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderLabel&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
      &amp;lt;div &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;form-field&amp;quot;&lt;/span&gt;&amp;gt;
        &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'url'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;render&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'new'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'url'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderError&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/fieldset&amp;gt;
  &amp;lt;!-- /Embedded &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;new&lt;/span&gt; bookmark form --&amp;gt;
  &amp;lt;!-- Embedded existing bookmark forms --&amp;gt;
  &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;foreach&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$form&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Bookmarks'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$i&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$eForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;: &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
    &amp;lt;fieldset&amp;gt;
      &amp;lt;legend&amp;gt;&amp;lt;?php &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;a href=&quot;http://www.php.net/sprintf&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;sprintf&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;__&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Edit bookmark #%d'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;+1&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ?&amp;gt;&amp;lt;/legend&amp;gt;
      &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$eForm&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderError&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
      &amp;lt;div &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;form-row&amp;quot;&lt;/span&gt;&amp;gt;
        &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$eForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderLabel&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
        &amp;lt;div &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;form-field&amp;quot;&lt;/span&gt;&amp;gt;
          &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$eForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;render&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
          &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$eForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'name'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderError&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;form-row&amp;quot;&lt;/span&gt;&amp;gt;
        &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$eForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'url'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderLabel&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
        &amp;lt;div &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;form-field&amp;quot;&lt;/span&gt;&amp;gt;
          &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$eForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'url'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;render&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
          &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$eForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'url'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderError&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;form-row&amp;quot;&lt;/span&gt;&amp;gt;
        &amp;lt;div &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;form-field&amp;quot;&lt;/span&gt;&amp;gt;
          &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$eForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'delete'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;render&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
          &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$eForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'delete'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderError&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
          &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;a href=&quot;http://www.php.net/echo&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$eForm&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'delete'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;renderLabel&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;__&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'Delete this bookmark'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/fieldset&amp;gt;
  &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; endforeach; &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;?&amp;gt;&lt;/span&gt;
  &amp;lt;!-- /Embedded existing bookmark forms --&amp;gt;
  &amp;lt;input type=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;submit&amp;quot;&lt;/span&gt; value=&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;quot;&amp;lt;?php echo __('Update your bookmarks') ?&amp;gt;&amp;quot;&lt;/span&gt;/&amp;gt;
&amp;lt;/form&amp;gt;&lt;/pre&gt;


&lt;p&gt;Now you can really control the semantics of the HTML code of the form, field by field.&lt;/p&gt;


&lt;p&gt;As always, if you have better solutions in mind, feel free to post them in the comments.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine#rev-pnote-1129-1&quot; id=&quot;pnote-1129-1&quot;&gt;1&lt;/a&gt;] I&amp;#8217;ll leave you to create an app, module and route, okay?&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine#rev-pnote-1129-2&quot; id=&quot;pnote-1129-2&quot;&gt;2&lt;/a&gt;] Of course this can be a lot improved, but the example is kept as simple as possible to ease understanding.&lt;/p&gt;&lt;/div&gt;&lt;hr/&gt;&lt;p style=&quot;margin:.5em 0;padding:.5em;border:1px solid #333;background:#eee;color:#222&quot;&gt;&lt;small&gt;Ce billet intitulé &lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine&quot;&gt;Embedding Relations in Forms with Symfony 1.3 and Doctrine&lt;/a&gt; a été rédigé par &lt;a href=&quot;http://prendreuncafe.com/cv&quot;&gt;Nicolas Perriault&lt;/a&gt; et publié sur le blog &lt;a href=&quot;http://prendreuncafe.com/blog/&quot;&gt;Prendre un Café&lt;/a&gt; sous licence &lt;a href=&quot;http://creativecommons.org/licenses/by-nc-sa/2.5/&quot;&gt;Creative Commons BY-NC-SA&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>An Interactive PHP Shell: phpsh</title>
    <link>http://prendreuncafe.com/blog/post/2009/11/04/An-Interactive-PHP-Shell%3A-PHPSH</link>
    <guid isPermaLink="false">urn:md5:632f3830bb8da94e1293d0cedff337a5</guid>
    <pubDate>Wed, 04 Nov 2009 12:00:00 +0100</pubDate>
    <dc:creator>NiKo</dc:creator>
        <category>Dev</category>
        <category>cli</category><category>php</category><category>shell</category><category>symfony</category>    
    <description>    &lt;p&gt;Just found this nice project contributed by the Facebook team, &lt;a href=&quot;http://www.phpsh.org/&quot; hreflang=&quot;en&quot;&gt;phpsh&lt;/a&gt;. Basically, it&amp;#8217;s an interactive and advanced command line interface to &lt;a href=&quot;http://php.net/&quot;&gt;php&lt;/a&gt;, a kind of super-&lt;code&gt;php -r&lt;/code&gt; similar to what you can find in &lt;a href=&quot;http://python.org/&quot;&gt;Python&lt;/a&gt; or &lt;a href=&quot;http://www.ruby-lang.org/&quot;&gt;Ruby&lt;/a&gt;. Ironically enough, phpsh is mostly written in Python, by the way.&lt;/p&gt;


&lt;p&gt;To install phpsh, just get it from github&lt;sup&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/11/04/An-Interactive-PHP-Shell%3A-PHPSH#pnote-1128-1&quot; id=&quot;rev-pnote-1128-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;:&lt;/p&gt;

&lt;pre&gt;
$ git clone git://github.com/facebook/phpsh.git
$ cd phpsh
$ python setup.py build
$ sudo python setup.py install
&lt;/pre&gt;


&lt;p&gt;To run phpsh:&lt;/p&gt;

&lt;pre&gt;
$ phpsh
Starting php
type 'h' or 'help' to see instructions &amp;amp; features
php&amp;gt; =&amp;quot;hello world&amp;quot;
hello world
php&amp;gt; =2 + 2
4
php&amp;gt; $a = 8

php&amp;gt; =$a
8
&lt;/pre&gt;


&lt;p&gt;Note that you don&amp;#8217;t have to open or close &lt;code&gt;&amp;lt;?php&lt;/code&gt; tags, you can print something just by prepending an &lt;code&gt;=&lt;/code&gt; sign to the command, and no need to type semicolum at the end of a call. Easy&lt;sup&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/11/04/An-Interactive-PHP-Shell%3A-PHPSH#pnote-1128-2&quot; id=&quot;rev-pnote-1128-2&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;You can access a function documentation by just prepending the &lt;code&gt;d&lt;/code&gt; keyword to its name:&lt;/p&gt;

&lt;pre&gt;php&amp;gt; d strlen
&amp;nbsp;
# strlen
&amp;nbsp;
(PHP 4, PHP 5)
&amp;nbsp;
strlen -- Get string length
&amp;nbsp;
### Description
&amp;nbsp;
int strlen ( string $string )
&amp;nbsp;
Returns the length of the given string . 
&amp;nbsp;
### Parameters
&amp;nbsp;
string     
&amp;nbsp;
The [string][1] being measured for length. 
&amp;nbsp;
### Return Values
&amp;nbsp;
The length of the string on success, and 0 if the string is empty. 
&amp;nbsp;
### 
&amp;nbsp;
   [1]: #language.types.string&lt;/pre&gt;


&lt;p&gt;You can define your own classes and functions, and run them:&lt;/p&gt;

&lt;pre&gt;
php&amp;gt; function foo($a){echo $a.'!';}
php&amp;gt; foo('bar')
bar!
&lt;/pre&gt;


&lt;p&gt;Same goes for classes:&lt;/p&gt;

&lt;pre&gt;
php&amp;gt; class Foo {public function bar($a){echo $a.'!';}}
php&amp;gt; $f = new Foo()
php&amp;gt; $f-&amp;gt;bar('baz')
baz!
&lt;/pre&gt;


&lt;p&gt;You can even execute shell command from there:&lt;/p&gt;

&lt;pre&gt;
php&amp;gt; ! ls -la
&lt;/pre&gt;


&lt;p&gt;Of course, you can &lt;del&gt;import&lt;/del&gt; include and require files. As a concrete example, let&amp;#8217;s roughly play with the symfony API:&lt;/p&gt;

&lt;pre&gt;
php&amp;gt; ! symfony -V
symfony version 1.2.2-DEV (/Users/niko/Sites/vendor/symfony12/lib)
php&amp;gt; c /Users/niko/Sites/vendor/symfony12/lib/autoload/sfCoreAutoload.class.php
Extra includes are: ['/Users/niko/Sites/vendor/symfony12/lib/autoload/sfCoreAutoload.class.php']
php&amp;gt; sfCoreAutoload::register()
php&amp;gt; =sfYaml::load('foo: bar')
array(
  &amp;quot;foo&amp;quot; =&amp;gt; &amp;quot;bar&amp;quot;,
)
php&amp;gt; =sfYaml::dump(array('foo' =&amp;gt; array('bar' =&amp;gt; 'baz')))
&amp;quot;foo:\n  bar: baz\n&amp;quot;
&lt;/pre&gt;


&lt;p&gt;Last but not least, when enough playing, type &lt;code&gt;q&lt;/code&gt; or press &lt;code&gt;ctrl + d&lt;/code&gt; to quit phpsh.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/11/04/An-Interactive-PHP-Shell%3A-PHPSH#rev-pnote-1128-1&quot; id=&quot;pnote-1128-1&quot;&gt;1&lt;/a&gt;] So yeah, so you need &lt;a href=&quot;http://git-scm.com/&quot;&gt;git&lt;/a&gt;. And Python, of course.&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/11/04/An-Interactive-PHP-Shell%3A-PHPSH#rev-pnote-1128-2&quot; id=&quot;pnote-1128-2&quot;&gt;2&lt;/a&gt;] Anybody putting &amp;quot;rather use python then&amp;quot; will have serious troubles, even if I strongly agree.&lt;/p&gt;&lt;/div&gt;&lt;hr/&gt;&lt;p style=&quot;margin:.5em 0;padding:.5em;border:1px solid #333;background:#eee;color:#222&quot;&gt;&lt;small&gt;Ce billet intitulé &lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/11/04/An-Interactive-PHP-Shell%3A-PHPSH&quot;&gt;An Interactive PHP Shell: phpsh&lt;/a&gt; a été rédigé par &lt;a href=&quot;http://prendreuncafe.com/cv&quot;&gt;Nicolas Perriault&lt;/a&gt; et publié sur le blog &lt;a href=&quot;http://prendreuncafe.com/blog/&quot;&gt;Prendre un Café&lt;/a&gt; sous licence &lt;a href=&quot;http://creativecommons.org/licenses/by-nc-sa/2.5/&quot;&gt;Creative Commons BY-NC-SA&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>A Symfony 1.3 Gem: Open Files Listed in Exceptions with the Editor of your Choice</title>
    <link>http://prendreuncafe.com/blog/post/2009/10/12/A-Symfony-1.3-Gem%3A-Open-Files-Listed-in-Exceptions-with-the-Editor-of-your-Choice</link>
    <guid isPermaLink="false">urn:md5:6781e6a12d91dda46f4bd533e7f180ac</guid>
    <pubDate>Mon, 12 Oct 2009 18:22:00 +0200</pubDate>
    <dc:creator>NiKo</dc:creator>
        <category>Dev</category>
        <category>editor</category><category>php</category><category>symfony</category><category>textmate</category>    
    <description>    &lt;p&gt;I&amp;#8217;ve just stumbled upon a nice new feature of &lt;a href=&quot;http://www.symfony-project.org/&quot; hreflang=&quot;en&quot;&gt;Symfony&lt;/a&gt; 1.3, the ability to &lt;a href=&quot;http://www.symfony-project.org/tutorial/1_3/en/whats-new#chapter_64a8dd2fac010cece60fe956d341725f_sub_sf_file_link_format&quot; hreflang=&quot;en&quot;&gt;open any linked file within standard exception page with the text editor of your choice&lt;/a&gt;, at least if it provides an url scheme/protocol to open them. &lt;a href=&quot;http://blog.macromates.com/2007/the-textmate-url-scheme/&quot; hreflang=&quot;en&quot;&gt;Texmate provides natively this feature&lt;/a&gt;, so let&amp;#8217;s see how to configure a symfony project to allow its files to be opened directly in textmate when encountering a stack trace.&lt;/p&gt;


&lt;p&gt;In the &lt;code&gt;config/&lt;/code&gt; folder of the project, create a &lt;code&gt;settings.yml&lt;/code&gt; file with this content:&lt;/p&gt;

&lt;pre&gt;dev: #yeah, we never know
  .settings:
    file_link_format: &amp;quot;txmt://open?url=file://%f&amp;amp;line=%l&amp;quot;&lt;/pre&gt;


&lt;p&gt;That&amp;#8217;s it. Now any standard exception page (in &lt;code&gt;dev&lt;/code&gt; environment only, right?) will provide a &lt;code&gt;txmt://&lt;/code&gt; link to every PHP file listed in the stack trace. And at the correct line number. Neat.&lt;/p&gt;&lt;hr/&gt;&lt;p style=&quot;margin:.5em 0;padding:.5em;border:1px solid #333;background:#eee;color:#222&quot;&gt;&lt;small&gt;Ce billet intitulé &lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/10/12/A-Symfony-1.3-Gem%3A-Open-Files-Listed-in-Exceptions-with-the-Editor-of-your-Choice&quot;&gt;A Symfony 1.3 Gem: Open Files Listed in Exceptions with the Editor of your Choice&lt;/a&gt; a été rédigé par &lt;a href=&quot;http://prendreuncafe.com/cv&quot;&gt;Nicolas Perriault&lt;/a&gt; et publié sur le blog &lt;a href=&quot;http://prendreuncafe.com/blog/&quot;&gt;Prendre un Café&lt;/a&gt; sous licence &lt;a href=&quot;http://creativecommons.org/licenses/by-nc-sa/2.5/&quot;&gt;Creative Commons BY-NC-SA&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Simple Continuous Integration of a Symfony Project using Hudson</title>
    <link>http://prendreuncafe.com/blog/post/2009/10/06/Simple-Continuous-Integration-of-a-Symfony-Project-using-Hudson</link>
    <guid isPermaLink="false">urn:md5:48005890d8164cd0a43875105e74d9c0</guid>
    <pubDate>Tue, 06 Oct 2009 15:36:00 +0200</pubDate>
    <dc:creator>NiKo</dc:creator>
        <category>Dev</category>
        <category>continuous integration</category><category>hudson</category><category>php</category><category>symfony</category><category>testing</category>    
    <description>    &lt;p&gt;I love tests, I just cannot program without them anymore, especially with &lt;a href=&quot;http://www.symfony-project.org/&quot; hreflang=&quot;en&quot;&gt;Symfony&lt;/a&gt;. And as I write a lot of them on a daily basis, the full test suite can take a very long time to be executed&amp;#160;; running a &lt;code&gt;symfony test:all&lt;/code&gt; command before every granular commit suppose you have to wait sometimes more than 5, 10 minutes or more for the whole tests to be ran: hardly acceptable. &lt;a href=&quot;http://svnbook.red-bean.com/en/1.4/svn.ref.reposhooks.post-commit.html&quot; hreflang=&quot;en&quot;&gt;Post commit hooks&lt;/a&gt; can be a solution, but what if a lot of devs are working simultaneously on the same project? Added to the previously seen test execution duration, it can become a problem difficult to deal with.&lt;/p&gt;


&lt;p&gt;Here comes &lt;a href=&quot;http://en.wikipedia.org/wiki/Continuous_integration&quot; hreflang=&quot;en&quot;&gt;continuous integration&lt;/a&gt;&amp;#160;: regularly, eg. every hour, the symfony project will be built up and configured from scratch, then the full test suite will be executed and the resulting log will be aggregated. It&amp;#8217;s a very convenient way to keep an eye on the overall code quality and integrity of the project.&lt;/p&gt;


&lt;p&gt;There are several open source continuous integration software available on the market: &lt;a href=&quot;http://cruisecontrol.sourceforge.net/&quot; hreflang=&quot;en&quot;&gt;Cruise Control&lt;/a&gt; (and &lt;a href=&quot;http://phpundercontrol.org/&quot; hreflang=&quot;en&quot;&gt;phpUnderControl&lt;/a&gt;), &lt;a href=&quot;http://continuum.apache.org/&quot; hreflang=&quot;en&quot;&gt;Continuum&lt;/a&gt;, &lt;a href=&quot;http://integrityapp.com/&quot; hreflang=&quot;en&quot;&gt;Integrity&lt;/a&gt;, the uncertain but awesomely looking &lt;a href=&quot;http://sismo-project.org/&quot; hreflang=&quot;en&quot;&gt;Sismo&lt;/a&gt; which powers the &lt;a href=&quot;http://ci.symfony-project.org/&quot; hreflang=&quot;en&quot;&gt;Symfony continous integration server&lt;/a&gt;&amp;#8230; But I recently had the opportunity to test &lt;a href=&quot;https://hudson.dev.java.net&quot; hreflang=&quot;en&quot;&gt;Hudson&lt;/a&gt;, a java based one. It&amp;#8217;s very simple to install, setup and configure, and has tons of plugins. So let&amp;#8217;s see how it can be used to test a Symfony project.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://prendreuncafe.com/blog/public/images/Dev/Hudson/hudson_tests_weather.png&quot;&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/Dev/Hudson/.hudson_tests_weather_m.jpg&quot; alt=&quot;img hudson_tests_weather&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;hudson_tests_weather.png, oct. 2009&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;Hudson Installation&lt;/h3&gt;


&lt;p&gt;That&amp;#8217;s really not the hardest part, because you just need a working &lt;a href=&quot;http://java.sun.com/javase/downloads/index_jdk5.jsp&quot; hreflang=&quot;en&quot;&gt;JRE 1.5&lt;/a&gt; installation on your machine, and to &lt;a href=&quot;http://hudson-ci.org/latest/hudson.war&quot; hreflang=&quot;en&quot;&gt;retrieve the latest version of the program&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;Then, you can launch it directly from a shell prompt:&lt;/p&gt;


&lt;pre&gt;$  java -jar /path/to/hudson.war&lt;/pre&gt;


&lt;p&gt;If you fear to break something or just want to give it a go without the hassle of firing a term, just launch the available &lt;a href=&quot;https://hudson.dev.java.net/hudson.jnlp&quot; hreflang=&quot;en&quot;&gt;Java Web Start version&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;On debian/ubuntu, it&amp;#8217;s just as easy as:&lt;/p&gt;


&lt;pre&gt;$ sudo echo deb http://hudson-ci.org/debian binary/ &amp;gt;&amp;gt; /etc/apt/sources.list
$ sudo apt-get update
$ sudo apt-get install hudson
$ sudo /etc/init.d/hudson start&lt;/pre&gt;


&lt;h3&gt;Configuration and Symfony Project Integration&lt;/h3&gt;


&lt;p&gt;Once Hudson is installed an running, head up to &lt;a href=&quot;http://localhost:8080/&quot; hreflang=&quot;en&quot;&gt;http://localhost:8080/&lt;/a&gt; and start playing with the web based user interface of Hudson. The navigation and configuration forms are quite obvious, and therefore efficient. Creating a project following the provided guidelines is easy and can be achieved within minutes:&lt;/p&gt;


&lt;p&gt;First, create a new Job, choosing the &lt;em&gt;Build a free-style software project&lt;/em&gt; option.&lt;/p&gt;


&lt;p&gt;Then, configure the subversion repository&lt;sup&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/10/06/Simple-Continuous-Integration-of-a-Symfony-Project-using-Hudson#pnote-1125-1&quot; id=&quot;rev-pnote-1125-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt; used by your project by entering its base URL in the &lt;em&gt;Source Code Management&lt;/em&gt; field
You can schedule builds, watch for SCM activity and even trigger builds from remote script using a neat XMLRPC interface&lt;sup&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/10/06/Simple-Continuous-Integration-of-a-Symfony-Project-using-Hudson#pnote-1125-2&quot; id=&quot;rev-pnote-1125-2&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/Dev/Hudson/hudson_svn.png&quot; alt=&quot;img hudson_svn&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;hudson_svn.png, oct. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/Dev/Hudson/hudson_scheduling.png&quot; alt=&quot;img hudson_hudson_scheduling&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;hudson_scheduling.png, oct. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Configuring the building process is as easy as writing down some commands, like the one you&amp;#8217;d execute to setup your project on a new box:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/Dev/Hudson/hudson_build-commands.png&quot; alt=&quot;img hudson_build_commands&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;hudson_build-commands.png, oct. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;As of Symfony 1.3, test result logs can be exported in a jUnit XML file, so Hudson will be able to parse them and provide some useful reports, metrics and charts:&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/Dev/Hudson/.huson_test_results_m.jpg&quot; alt=&quot;huson_test_results.png&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;huson_test_results.png, oct. 2009&quot; /&gt;&lt;/p&gt;


&lt;p&gt;&lt;img src=&quot;http://prendreuncafe.com/blog/public/images/Dev/Hudson/.hudson_tests_charts_m.jpg&quot; alt=&quot;&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Of course, you can configure failure notifications: email, atom feed, there&amp;#8217;s even a &lt;a href=&quot;http://wiki.hudson-ci.org/display/HUDSON/Twitter+Plugin&quot; hreflang=&quot;en&quot;&gt;twitter plugin&lt;/a&gt;!&lt;/p&gt;


&lt;p&gt;As a conclusion, Hudson is a very simple but efficient continous integration tool which can easily be configured to monitor the quality of your Symfony projects&amp;#8230; at least if you write tests &lt;img src=&quot;/blog/themes/battlestar/smilies/wink.gif&quot; alt=&quot;;)&quot; class=&quot;smiley&quot; /&gt;&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/10/06/Simple-Continuous-Integration-of-a-Symfony-Project-using-Hudson#rev-pnote-1125-1&quot; id=&quot;pnote-1125-1&quot;&gt;1&lt;/a&gt;] If you&amp;#8217;re not using Subversion, lot of plugins are available for other SCM in the huge &lt;a href=&quot;http://wiki.hudson-ci.org/display/HUDSON/Plugins#Plugins-Sourcecodemanagement&quot; hreflang=&quot;en&quot;&gt;Hudson plugins repository&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/10/06/Simple-Continuous-Integration-of-a-Symfony-Project-using-Hudson#rev-pnote-1125-2&quot; id=&quot;pnote-1125-2&quot;&gt;2&lt;/a&gt;] Useful if you wish to use post-commit build hook&lt;/p&gt;&lt;/div&gt;&lt;hr/&gt;&lt;p style=&quot;margin:.5em 0;padding:.5em;border:1px solid #333;background:#eee;color:#222&quot;&gt;&lt;small&gt;Ce billet intitulé &lt;a href=&quot;http://prendreuncafe.com/blog/post/2009/10/06/Simple-Continuous-Integration-of-a-Symfony-Project-using-Hudson&quot;&gt;Simple Continuous Integration of a Symfony Project using Hudson&lt;/a&gt; a été rédigé par &lt;a href=&quot;http://prendreuncafe.com/cv&quot;&gt;Nicolas Perriault&lt;/a&gt; et publié sur le blog &lt;a href=&quot;http://prendreuncafe.com/blog/&quot;&gt;Prendre un Café&lt;/a&gt; sous licence &lt;a href=&quot;http://creativecommons.org/licenses/by-nc-sa/2.5/&quot;&gt;Creative Commons BY-NC-SA&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Optimize your Doctrine Workflow with Specialized Queries</title>
    <link>http://prendreuncafe.com/blog/post/Optimize-your-Doctrine-Workflow-with-Specialized-Queries</link>
    <guid isPermaLink="false">urn:md5:07be0ff35e1f2e047f2faca25323c26e</guid>
    <pubDate>Tue, 15 Sep 2009 19:14:00 +0200</pubDate>
    <dc:creator>NiKo</dc:creator>
        <category>Dev</category>
        <category>bestpractices</category><category>doctrine</category><category>php</category><category>query</category><category>sql</category><category>symfony</category><category>tips</category>    
    <description>    &lt;p&gt;I&amp;#8217;m currently working on a big &lt;a href=&quot;http://www.symfony-project.org/&quot; hreflang=&quot;en&quot;&gt;Symfony&lt;/a&gt; project, with a lot of &lt;a href=&quot;http://www.doctrine-project.org/&quot; hreflang=&quot;en&quot;&gt;Doctrine&lt;/a&gt; models and complex queries to write. I found a way to organize all of them in an object-oriented and cleaner way than using the traditionnal &lt;code&gt;addNamedQuery()&lt;/code&gt; and &lt;code&gt;createNamedQuery()&lt;/code&gt; methods workflow&lt;sup&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/Optimize-your-Doctrine-Workflow-with-Specialized-Queries#pnote-1123-1&quot; id=&quot;rev-pnote-1123-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;The idea is to create dedicated &lt;a href=&quot;http://www.doctrine-project.org/Doctrine_Query/1_2&quot; hreflang=&quot;en&quot;&gt;query&lt;/a&gt; classes for a given model&amp;#160;; this way, you can provide useful methods to build the business-related parts of your query.&lt;/p&gt;


&lt;p&gt;As usual, the theory is more understandable with a concrete example. Let&amp;#8217;s consider this simple Doctrine model&lt;sup&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/Optimize-your-Doctrine-Workflow-with-Specialized-Queries#pnote-1123-2&quot; id=&quot;rev-pnote-1123-2&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;&amp;#160;:&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; The provided examples have been written in a hurry, so mistakes might have been not detected by my attentive proof-reading &lt;img src=&quot;/blog/themes/battlestar/smilies/wink.gif&quot; alt=&quot;;)&quot; class=&quot;smiley&quot; /&gt;&lt;/p&gt;

&lt;pre&gt;BlogAuthor:
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true  
    name:
      type: string(255)
  relations:
    Post:
      type: one
      class: BlogPost
      local: id
      foreign: author_id
&amp;nbsp;
BlogPost:
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    author_id:
      type: integer(4)
      notnull: true
    title:
      type: string(255)
    content:
      type: string(65535)
  relations:
    Author:
      type: one
      class: BlogAuthor
      local: author_id
      foreign: id
    Comments:
      type: many
      class: BlogComment
      local: id
      foreign: post_id
&amp;nbsp;
BlogComment:
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    post_id:
      type: integer(4)
      notnull: true
    author:
      type: string(255)
    content:
      type: string(5000)
  relations:
    Post:
      type: one
      class: BlogPost
      local: post_id
      foreign: id&lt;/pre&gt;


&lt;p&gt;Now let&amp;#8217;s imagine a Query class dedicated to query the BlogPost table:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt; 
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; BlogPostQuery extends Doctrine_Query
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;a href=&quot;http://www.php.net/static&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;static&lt;/span&gt;&lt;/a&gt; public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; create&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$conn&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$class&lt;/span&gt; = &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; parent::&lt;span style=&quot;color: #006600;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$conn&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;'BlogPostQuery'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'BlogPost p'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; addPosts&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$fields&lt;/span&gt; = &lt;span style=&quot;color: #ff0000;&quot;&gt;'p.*'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addSelect&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'p.*'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; addComments&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$fields&lt;/span&gt; = &lt;span style=&quot;color: #ff0000;&quot;&gt;'c.*'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addSelect&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$fields&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;leftJoin&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'p.Comments c'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addGroupBy&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'c.id'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; addAuthors&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$fields&lt;/span&gt; = &lt;span style=&quot;color: #ff0000;&quot;&gt;'a.*'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addSelect&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$fields&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;leftJoin&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'p.Author a'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addGroupBy&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'a.id'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; addCommentsCount&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$alias&lt;/span&gt; = &lt;span style=&quot;color: #ff0000;&quot;&gt;'nb_comments'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addSelect&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/sprintf&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;sprintf&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'COUNT(c.id) as %s'&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$alias&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addGroupBy&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'c.id'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
  
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; filterByAuthorName&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$authorName&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;andWhere&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'a.name = ?'&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$authorName&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;So how can we use this query object? Here are some sample uses:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// Retrieve all posts&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;$posts&lt;/span&gt; = BlogPostQuery::&lt;span style=&quot;color: #006600;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addPosts&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;fetchArray&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// Retrieve all posts with comments&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;$posts&lt;/span&gt; = BlogPostQuery::&lt;span style=&quot;color: #006600;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addPosts&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addComments&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;fetchArray&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// Retrieve all posts with comments and their count per post&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;$posts&lt;/span&gt; = BlogPostQuery::&lt;span style=&quot;color: #006600;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addPosts&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addComments&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addCommentsCount&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'yataa'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;fetchArray&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// Retrieve all post with chuck as its author and related comments&lt;/span&gt;
&lt;span style=&quot;color: #0000ff;&quot;&gt;$posts&lt;/span&gt; = BlogPostQuery::&lt;span style=&quot;color: #006600;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addAuthors&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addPosts&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addComments&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;filterByAuthorName&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'chuck'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;fetchArray&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;// and so on... &lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Of course, this example of use is not really relevant as our model is really simple, but when you&amp;#8217;re dealing with dozens of internationalized objects, it can help cleaning your model classes, controllers and improving the organization of your work.&lt;/p&gt;


&lt;h3&gt;Update and important precisions&lt;/h3&gt;


&lt;p&gt;Some people are having negative feedback regarding this technique, claiming it will encourage people using the custom query object directly in the controllers; that&amp;#8217;s absolutely not the case as the queries are to be used only within the model layer, for example in the &lt;code&gt;BlogPostTable&lt;/code&gt; class:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; BlogPostTable extends Doctrine_Table
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;a href=&quot;http://www.php.net/static&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;static&lt;/span&gt;&lt;/a&gt; public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; getPostsWithCommentsByAuthor&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$authorName&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; BlogPostQuery::&lt;span style=&quot;color: #006600;&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addPosts&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;addComments&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;filterByAuthorName&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$authorName&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
      -&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;fetchArray&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
    ;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;And in a controller:&lt;/p&gt;

&lt;pre class=&quot;php&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;class&lt;/span&gt; blogActions extends sfActions
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
  public &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;function&lt;/span&gt; executeListByAuthor&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;sfWebRequest &lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #0000ff;&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;posts&lt;/span&gt; = BlogPostTable::&lt;span style=&quot;color: #006600;&quot;&gt;getPostsWithCommentsByAuthor&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$request&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;getParameter&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;'author'&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;
&lt;div class=&quot;footnotes&quot;&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/Optimize-your-Doctrine-Workflow-with-Specialized-Queries#rev-pnote-1123-1&quot; id=&quot;pnote-1123-1&quot;&gt;1&lt;/a&gt;] &amp;#8230; or raw queries written directly within controllers, but you may know that &lt;a href=&quot;http://www.slideshare.net/nperriault/30-symfony-best-practices&quot; hreflang=&quot;en&quot;&gt;this is really bad&lt;/a&gt; &lt;img src=&quot;/blog/themes/battlestar/smilies/wink.gif&quot; alt=&quot;;)&quot; class=&quot;smiley&quot; /&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href=&quot;http://prendreuncafe.com/blog/post/Optimize-your-Doctrine-Workflow-with-Specialized-Queries#rev-pnote-1123-2&quot; id=&quot;pnote-1123-2&quot;&gt;2&lt;/a&gt;] I&amp;#8217;m using Doctrine 1.2 beta (bundled with upcoming symfony 1.3) in the provided example.&lt;/p&gt;&lt;/div&gt;&lt;hr/&gt;&lt;p style=&quot;margin:.5em 0;padding:.5em;border:1px solid #333;background:#eee;color:#222&quot;&gt;&lt;small&gt;Ce billet intitulé &lt;a href=&quot;http://prendreuncafe.com/blog/post/Optimize-your-Doctrine-Workflow-with-Specialized-Queries&quot;&gt;Optimize your Doctrine Workflow with Specialized Queries&lt;/a&gt; a été rédigé par &lt;a href=&quot;http://prendreuncafe.com/cv&quot;&gt;Nicolas Perriault&lt;/a&gt; et publié sur le blog &lt;a href=&quot;http://prendreuncafe.com/blog/&quot;&gt;Prendre un Café&lt;/a&gt; sous licence &lt;a href=&quot;http://creativecommons.org/licenses/by-nc-sa/2.5/&quot;&gt;Creative Commons BY-NC-SA&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
</channel>
</rss>
