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

<channel>
	<title>Ezzatron</title>
	<atom:link href="http://ezzatron.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://ezzatron.com</link>
	<description>Bringing together the fine arts of programming and death metal.</description>
	<lastBuildDate>Thu, 03 Dec 2009 04:19:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Expanding forms with symfony 1.2 and Doctrine</title>
		<link>http://ezzatron.com/2009/12/03/expanding-forms-with-symfony-1-2-and-doctrine/</link>
		<comments>http://ezzatron.com/2009/12/03/expanding-forms-with-symfony-1-2-and-doctrine/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 04:19:32 +0000</pubDate>
		<dc:creator>Erin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[band]]></category>
		<category><![CDATA[degradation]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[dynamic]]></category>
		<category><![CDATA[enhancement]]></category>
		<category><![CDATA[expanding]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[graceful]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[many]]></category>
		<category><![CDATA[member]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[object]]></category>
		<category><![CDATA[one]]></category>
		<category><![CDATA[oriented]]></category>
		<category><![CDATA[progressive]]></category>
		<category><![CDATA[to]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://ezzatron.com/?p=177</guid>
		<description><![CDATA[
I recently started learning how to use the forms system in symfony 1.2 and for the most part I was impressed with its simplicity and flexibility. Unfortunately I was thrown in the deep end somewhat when a project I was working on had a requirement for an &#8220;expanding&#8221; form &#8211; that is, one where a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.symfony-project.org/"><img class="alignnone" title="symfony" src="http://www.symfony-project.org/downloads/logos/symfony.gif" alt="" width="448" height="122" /></a></p>
<p>I recently started learning how to use the <a title="symfony Forms in Action" href="http://www.symfony-project.org/forms/1_2/en/">forms system</a> in <a title="symfony" href="http://www.symfony-project.org/">symfony</a> 1.2 and for the most part I was impressed with its simplicity and flexibility. Unfortunately I was thrown in the deep end somewhat when a project I was working on had a requirement for an &#8220;expanding&#8221; form &#8211; that is, one where a certain section of a form should be able to be repeated as many times as necessary to accommodate the user&#8217;s needs.</p>
<p>In the case of the project in question, the specific situation was an application form where the user could fill out any number of team members involved in their project. Each team member consisted of a name and a role, both free-form text fields. Team members were to be stored in the database, linked to the application in a one to many relationship.</p>
<p>Circumstances conspired that this must be achieved in a single form, so full of confidence in symfony&#8217;s design decisions regarding the forms system, a bit of light Googling revealed the answer &#8211; symfony&#8217;s <a title="Call the expert: Nested forms - A real implementation" href="http://www.symfony-project.org/blog/2008/11/10/call-the-expert-nested-forms-a-real-implementation">embedded forms</a> system. Great, so you just plonk in a few embedded forms and away you go, right? Wrong.</p>
<p>The good news is, I managed to find a solution that satisfied the requirements, <em>eventually</em>. The bad news is that it is not easy, elegant, or particularly reusable.</p>
<p>What follows is a loose guide to implementing such a system. Being a relative newcomer to symfony I cannot guarantee that this is the best way to do things, so tread with caution, and if you think of a better way to achieve the same outcome, please please let me know! Read on if you dare&#8230;<span id="more-177"></span></p>
<h2>Introduction</h2>
<p>I&#8217;m going to assume the following in this guide:</p>
<ul>
<li>You have a solid working knowledge of <a title="symfony" href="http://www.symfony-project.org/">symfony</a>, <a title="PHP: Hypertext Preprocessor" href="http://php.net/">PHP</a> and <a title="Doctrine - PHP Object Relational Mapper" href="http://www.doctrine-project.org/">Doctrine</a>.</li>
<li>You have a blank symfony 1.2 project, set up to use Doctrine rather than Propel (although I&#8217;m sure the same could be achieved with Propel with a bit of tweaking).</li>
<li>You have the symfony executable in your system path or in the root of your project.</li>
<li>You are using a relational database such as MySQL to store your data.</li>
<li>You have entered your database connection details into your <strong>config/databases.yml</strong> file and set up all the appropriate database permissions.</li>
<li>You have completed any web server setup as required to access the project.</li>
<li>You are aware that you need to clear the symfony cache (by running <code>symfony cc</code>) when new classes are created and when configuration changes are made.</li>
</ul>
<p>I&#8217;m also going to move fairly quickly as there is a lot to cover, so please feel free to ask for any clarification in the comments and I will update as necessary.</p>
<p>For help with installing and setting up symfony 1.2, check out <a title="Getting Started with symfony" href="http://www.symfony-project.org/getting-started/1_2/en/">Getting started with symfony</a>. I chose to use Doctrine 1.1 for this tutorial, however the version that comes with symfony should also be fine. For instructions on upgrading to Doctrine 1.1 see <a title="Using Doctrine 1.1 with Symfony 1.2" href="http://www.brandonturner.net/blog/2009/05/doctrine11-with-symfony12/">Using Doctrine 1.1 with Symfony 1.2</a>.</p>
<p>You can also see a live demo and get an idea of what we are trying to achieve by visiting <a href="http://expandingform.sf.ezzatron.com/">http://expandingform.sf.ezzatron.com/</a>.</p>
<h2>Step 1: Setting up</h2>
<p>Here is the Doctrine schema we will be using. I went for something a bit more cheery than the above situation, namely bands and band members:</p>

<div class="wp_syntax"><div class="code"><pre class="yaml" style="font-family:monospace;">Band:
  columns:
    name:
      type: string(200)
      notnull: true
      notblank: true
    formed: date
&nbsp;
BandMember:
  columns:
    band_id:
      type: integer
      notnull: true
    name:
      type: string(200)
      notnull: true
      notblank: true
    role: string(200)
  relations:
    Band:
      foreignAlias: Members
      onUpdate: cascade
      onDelete: cascade</pre></div></div>

<p>Place this in your <strong>config/doctrine/schema.yml</strong> file, and then create a data fixture so we have some test data to work with:</p>

<div class="wp_syntax"><div class="code"><pre class="yaml" style="font-family:monospace;">Band:
  hnd:
    name: Hesitate &amp; Die
    formed: '2006-06-06'
&nbsp;
BandMember:
  andrew:
    name: Andrew
    role: Guitar
    Band: hnd
  erin:
    name: Erin
    role: Bass
    Band: hnd
  richie:
    name: Richie
    role: Vocals
    Band: hnd
  rowan:
    name: Rowan
    role: Drums
    Band: hnd</pre></div></div>

<p>Place the above in <strong>data/fixtures/fixtures.yml</strong> and run:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ symfony doctrine:build-all-reload --no-confirmation</pre></div></div>

<p>This will generate all the model classes and forms we will need, create the database, and populate it with some test data for us. Next we need to create an application, and we&#8217;ll use the standard symfony app name &#8220;frontend&#8221;:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ symfony generate:app --escaping-strategy=on --csrf-secret=randomstring frontend</pre></div></div>

<p>Replacing &#8220;randomstring&#8221; with whatever you like. Now let&#8217;s generate a module from our model classes as a base to start from:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ symfony doctrine:generate-module --non-verbose-templates frontend band Band</pre></div></div>

<p>Now if you visit <strong>http://&lt;project url&gt;/frontend_dev.php/band/edit/id/1</strong> you should be presented with the following:</p>
<p><img class="alignnone size-full wp-image-190" title="Generated band form" src="http://ezzatron.com/wp-content/uploads/2009/12/end_step_1.png" alt="Generated band form" width="450" height="170" /></p>
<p>We now have a basic form for entering band details. Thus concludes step 1. Moving on to&#8230;</p>
<h2>Step 2: Building the form</h2>
<p>OK let&#8217;s dive right in. We are going to embed forms for editing band members inside of the band form itself. To add a single member form you would simply add:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedForm</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'members'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> BandMemberForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>to our <strong>lib/form/doctrine/BandForm.class.php</strong>&#8217;s <strong>configure()</strong> method. But what we want is to structure the form in such a way that the form data, when posted to the update action, will contain an array of band members. The way to do so in the symfony forms system is to wrap the embedded forms in another form, then embed this wrapper form itself into the main form. Confused? Don&#8217;t worry, everything will become clearer once we actually create the forms.</p>
<p>Firstly, we need to make a small modification to the band member form to allow it to slot into our band form better. The generated form includes a field for the related band ID, which we will not need as all band members will relate to the band represented in the parent band form.</p>
<p>We could modify the <strong>BandMemberForm</strong> class itself, but it&#8217;s possible we may want to use the form outside of a band context, so let&#8217;s harness the power of the forms system and extend the form instead. Create a file at <strong>lib/form/doctrine/EmbeddedBandMemberForm.class.php</strong> with the following class definition (PHP opening tag excluded for brevity):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> EmbeddedBandMemberForm <span style="color: #000000; font-weight: bold;">extends</span> BandMemberForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">configure</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'band_id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Next, let&#8217;s create the &#8220;container&#8221; form. Create a file at <strong>lib/form/doctrine/BandMembersForm.class.php</strong> containing the following class:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> BandMembersForm <span style="color: #000000; font-weight: bold;">extends</span> sfForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedForm</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> EmbeddedBandMemberForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This creates three blank forms for inputting band members. Now to actually embed the container form into our main band form, it&#8217;s actually very simple. Simply edit <strong>lib/form/doctrine/BandForm.class.php</strong> so that it looks like the following:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> BandForm <span style="color: #000000; font-weight: bold;">extends</span> BaseBandForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedForm</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'members'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> BandMembersForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now when we reload our band form (did you remember to clear your cache?), we will see the following:</p>
<p><img class="alignnone size-full wp-image-195" title="Band form with 3 empty member forms" src="http://ezzatron.com/wp-content/uploads/2009/12/band_with_blank_members.png" alt="Band form with 3 empty member forms" width="450" height="348" /></p>
<p>Looks promising, and that wasn&#8217;t <em>too</em> painful so far, right?</p>
<p>There next obvious step would be displaying the existing band members. We want to be able to see and edit the existing band members and still have the option of inputting new members also. To do this we need to pass the <strong>Band</strong> object to our container form so that it can access the existing members. Let&#8217;s update the container form so that it looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> BandMembersForm <span style="color: #000000; font-weight: bold;">extends</span> sfForm
<span style="color: #009900;">&#123;</span>
  protected <span style="color: #000088;">$band</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span>Band <span style="color: #000088;">$band</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">band</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$band</span><span style="color: #339933;">;</span>
&nbsp;
    parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">band</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Members</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$member</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedForm</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> EmbeddedBandMemberForm<span style="color: #009900;">&#40;</span><span style="color: #000088;">$member</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$i</span> <span style="color: #339933;">++;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$j</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$i</span><span style="color: #339933;">;</span> <span style="color: #000088;">$j</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">;</span> <span style="color: #000088;">$j</span> <span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedForm</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$j</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> EmbeddedBandMemberForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now we have to change the main form so that we pass the Band object when we instantiate the container form:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> BandForm <span style="color: #000000; font-weight: bold;">extends</span> BaseBandForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedForm</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'members'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> BandMembersForm<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">object</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Reloading the form should now show the existing members:</p>
<p><img class="alignnone size-full wp-image-198" title="Band form with existing members" src="http://ezzatron.com/wp-content/uploads/2009/12/band_with_existing_members.png" alt="Band form with existing members" width="450" height="581" /></p>
<p>So now we have a form that can display the band with all of its members and still provide room for new ones. Time for the next step.</p>
<h2>Step 3: Getting the form to save</h2>
<p>Try saving the form without making any changes to the data. You should get validation errors because the band member name is a required field:</p>
<p><img class="alignnone size-full wp-image-202" title="Member names incorrectly required" src="http://ezzatron.com/wp-content/uploads/2009/12/member_name_required.png" alt="Member names incorrectly required" width="433" height="379" /></p>
<p>This won&#8217;t do at all because we want to be able to leave a band member blank and have the system ignore it. We also want to be able to delete an existing member by clearing their name and role. So let&#8217;s remove the requirement for now, and we&#8217;ll add it back in later. Edit your <strong>EmbeddedBandMemberForm</strong> class so that it looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> EmbeddedBandMemberForm <span style="color: #000000; font-weight: bold;">extends</span> BandMemberForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">configure</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'band_id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'required'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now when we try to save the form again, we get an exception thrown:</p>
<p><img class="alignnone size-full wp-image-249" title="Database constraint violated" src="http://ezzatron.com/wp-content/uploads/2009/12/constraint_violated.png" alt="Database constraint violated" width="433" height="262" /></p>
<p>As you can see, Doctrine is not happy with us, but why? The answer is that symfony is trying to create new band members from the blank band member forms, but it has no idea which band the new members should belong to. We&#8217;ll deal with this issue shortly, but in the meantime let&#8217;s start by making symfony ignore any band member forms which are left blank.</p>
<p>Firstly, how do we decide if a band member form is &#8220;blank&#8221;? Let&#8217;s write a couple of custom methods in our form classes. Some of this functionality is reusable, so we&#8217;ll place the main body of the code in <strong>lib/form/doctrine/BaseFormDoctrine.class.php</strong> which is the base class for all of our generated forms:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">abstract <span style="color: #000000; font-weight: bold;">class</span> BaseFormDoctrine <span style="color: #000000; font-weight: bold;">extends</span> sfFormDoctrine
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> _formValuesAreBlank<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$fieldNames</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$fieldNames</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$fieldName</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$fieldName</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">formValueIsBlank</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$fieldName</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> formValueIsBlank<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$subValue</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">formValueIsBlank</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$subValue</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span> ? <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #339933;">:</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>These two methods essentially traverse an array recursively looking for any non-blank values, and returns false as soon as one is found. The method needs to be recursive because some fields like dates are passed as an array. Now we can write a simple method in our <strong>EmbeddedBandMemberForm</strong> class to check whether the fields that constitute a band member have been filled out:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> EmbeddedBandMemberForm <span style="color: #000000; font-weight: bold;">extends</span> BandMemberForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> formValuesAreBlank<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$fieldNames</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_diff</span><span style="color: #009900;">&#40;</span>Doctrine<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'BandMember'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getFieldNames</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'id'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'band_id'</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span>_formValuesAreBlank<span style="color: #009900;">&#40;</span><span style="color: #000088;">$fieldNames</span><span style="color: #339933;">,</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>We are simply grabbing the field names directly from our model class, and excluding the ones we don&#8217;t care about. This is more robust that explicitly specifying <em>name</em> and <em>role</em> as the important fields, as it allows for further fields to be added to the band member form as requirements change.</p>
<p>Now we need to actually change the way the form is processed by overriding some methods in our main band form:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> BandForm <span style="color: #000000; font-weight: bold;">extends</span> BaseBandForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> updateObjectEmbeddedForms<span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #339933;">,</span> <span style="color: #000088;">$forms</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$form</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$form</span> instanceof EmbeddedBandMemberForm<span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
          <span style="color: #000088;">$formValues</span> <span style="color: #339933;">=</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
          <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>EmbeddedBandMemberForm<span style="color: #339933;">::</span><span style="color: #004000;">formValuesAreBlank</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$formValues</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">updateObjectEmbeddedForms</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #339933;">,</span> <span style="color: #000088;">$forms</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> saveEmbeddedForms<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$forms</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$form</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$form</span> instanceof EmbeddedBandMemberForm<span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
          <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isModified</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">saveEmbeddedForms</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #339933;">,</span> <span style="color: #000088;">$forms</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>These methods doubtless require some explanation. Firstly let&#8217;s look at <strong>updateObjectEmbeddedForms()</strong>. This method uses the custom method we wrote to check whether the band members passed to the form for processing are blank. If a blank band member is encountered, the related form is removed from the forms array to prevent symfony from attempting to update the related band member object.</p>
<p>The next method, <strong>saveEmbeddedForms()</strong> works in tandem with the above. It runs through each of the forms and checks whether the related object has been modified. If an unmodified object is encountered, the related form is once again removed from the forms array to prevent symfony from attempting to save an unmodified object.</p>
<p>OK so now we should be able to save our form without any validation warnings or exceptions cropping up. If you can&#8217;t, it&#8217;s probably time to double check everything, and perhaps clear your cache. On to the next step&#8230;</p>
<h2>Step 4: Adding and deleting members</h2>
<p>Our form now saves without errors, but what does it actually <em>do</em>? Not much at the moment. Let&#8217;s try adding another band member. Ladies and gentlemen, may I present Steven on second guitar!:</p>
<p><img class="alignnone size-full wp-image-210" title="Attempting to add a member" src="http://ezzatron.com/wp-content/uploads/2009/12/adding_a_member_fail.png" alt="Attempting to add a member" width="433" height="301" /></p>
<p>What happens when we save the form? Ah, it seems we have the same issue we encountered before:</p>
<p><img class="alignnone size-full wp-image-249" title="Database constraint violated" src="http://ezzatron.com/wp-content/uploads/2009/12/constraint_violated.png" alt="Database constraint violated" width="433" height="262" /></p>
<p>As we found out in the previous step, this is caused by symfony not knowing to link our new band member to the band we are editing. We can fix this by making a simple change to our <strong>BandForm</strong> class, in the <strong>saveEmbeddedForms()</strong> method:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> BandForm <span style="color: #000000; font-weight: bold;">extends</span> BaseBandForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> saveEmbeddedForms<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$forms</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$form</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$form</span> instanceof EmbeddedBandMemberForm<span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
          <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isModified</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
          <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Band</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">object</span><span style="color: #339933;">;</span>
          <span style="color: #009900;">&#125;</span>
          <span style="color: #b1b100;">else</span>
          <span style="color: #009900;">&#123;</span>
            <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">saveEmbeddedForms</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #339933;">,</span> <span style="color: #000088;">$forms</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now when we try again, the new member is saved correctly and appears in the list of band members as expected:</p>
<p><img class="alignnone size-full wp-image-212" title="New member successfully saved" src="http://ezzatron.com/wp-content/uploads/2009/12/new_member_saved.png" alt="New member successfully saved" width="450" height="638" /></p>
<p>Awesome! We now have 2 guitarists and all the glory that comes with duelling guitar solos. But wait; oh no! Steven has decided to get married and move to Norway! Well, it&#8217;s time to remove him from the band I guess, so let&#8217;s try setting his name and role to blank and see what happens when we save&#8230;</p>
<p>Oh dear, it seems Steven is not keen on leaving without a fight. He still appears in the list of band members. So what&#8217;s happening here? In short, we simply haven&#8217;t told Doctrine to dispose of the unwanted band member yet! Let&#8217;s go ahead and do that now by modifying the <strong>BandForm</strong> class&#8217; <strong>updateObjectEmbeddedForms()</strong> method:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> BandForm <span style="color: #000000; font-weight: bold;">extends</span> BaseBandForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> updateObjectEmbeddedForms<span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #339933;">,</span> <span style="color: #000088;">$forms</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$form</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$form</span> instanceof EmbeddedBandMemberForm<span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
          <span style="color: #000088;">$formValues</span> <span style="color: #339933;">=</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
          <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>EmbeddedBandMemberForm<span style="color: #339933;">::</span><span style="color: #004000;">formValuesAreBlank</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$formValues</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
          <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
              <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">object</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">unlink</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Members'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
              <span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
&nbsp;
            <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$forms</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">updateObjectEmbeddedForms</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #339933;">,</span> <span style="color: #000088;">$forms</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now we can try again to delete Steven, and it seems to have worked:</p>
<p><img class="alignnone size-full wp-image-224" title="Member successfully deleted" src="http://ezzatron.com/wp-content/uploads/2009/12/member_delete_success.png" alt="Member successfully deleted" width="450" height="580" /></p>
<p>So now we have a fully functional form, which is great! But there are some important things we still need to consider, which leads us to the next step&#8230;</p>
<h2>Step 5: Validation</h2>
<p>That&#8217;s right, you forgot, didn&#8217;t you? Back in step 3 we disabled important validation for the band member form, which means, for example, if you try to enter a band member with a role but no name, you get this nasty validation exception:</p>
<p><img class="alignnone size-full wp-image-225" title="Validation error when saving a band member with only a role" src="http://ezzatron.com/wp-content/uploads/2009/12/validation_error.png" alt="Validation error when saving a band member with only a role" width="433" height="219" /></p>
<p><strong>NOTE:</strong> You may find that you do not encounter this exception, there seems to be a bug somewhere where the &#8220;notblank&#8221; validator we specified in the schema is being ignored. Nevertheless, we still need to prevent blank names from being entered.</p>
<p>We can&#8217;t leave things as they stand, so let&#8217;s create a custom wrapper for the validator schema that we can use to validate band members that have not been left blank. Create a file at <strong>lib/validator/EmbeddedBandMemberValidatorSchema.class.php</strong> and enter this class definition:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> EmbeddedBandMemberValidatorSchema <span style="color: #000000; font-weight: bold;">extends</span> sfValidatorSchema
<span style="color: #009900;">&#123;</span>
  protected <span style="color: #000088;">$validatorSchema</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span>sfValidatorSchema <span style="color: #000088;">$validatorSchema</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$validatorSchema</span><span style="color: #339933;">;</span>
&nbsp;
    parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> doClean<span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>EmbeddedBandMemberForm<span style="color: #339933;">::</span><span style="color: #004000;">formValuesAreBlank</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">doClean</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$values</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>All this class does is check whether the passed values are considered &#8220;blank&#8221; before applying the existing validation rules. This increases robustness by allowing us to keep all of the validation rules defined in the <strong>BandMemberForm</strong> class, and freeing us from having to duplicate their logic in the <strong>EmbeddedBandMemberForm</strong> class.</p>
<p>Now it&#8217;s simply a matter of making a small change to the <strong>EmbeddedBandMemberForm</strong> class&#8217; <strong>configure()</strong> method to allow us to take advantage of our new wrapper class:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> EmbeddedBandMemberForm <span style="color: #000000; font-weight: bold;">extends</span> BandMemberForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">configure</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'band_id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> EmbeddedBandMemberValidatorSchema<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>With those changes made, we can try again to save a band member with only a role and this time we are presented with the appropriate form errors:</p>
<p><img class="alignnone size-full wp-image-226" title="Form validation working correctly" src="http://ezzatron.com/wp-content/uploads/2009/12/form_errors_working.png" alt="Form validation working correctly" width="433" height="236" /></p>
<p>OK, that&#8217;s validation taken care of, let&#8217;s make some usability improvements.</p>
<h2>Step 6: Usability</h2>
<p>We&#8217;re going to add extra functionality to our form for users with JavaScript support, namely the ability to add additional spaces for band members without the need to save the form. What&#8217;s more we&#8217;re going to do it without preventing non-JavaScript enabled users from using the form. This is known as <em>progressive enhancement</em> and is generally considered a best-practice in web development.</p>
<p>The first thing we need to do is set up an action to render the additional band member forms so that we can fetch them via an AJAX call. Open up your <strong>apps/frontend/modules/band/actions/actions.class.php</strong> file and add the following method:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> bandActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeMemberForm<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isXmlHttpRequest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'count'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$form</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> BandForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setNumMembers</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">member</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$form</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'members'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLayout</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The template for this action is very simple. Create a file at <strong>apps/frontend/modules/band/templates/memberFormSuccess.php</strong> with the following contents:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$sf_data</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRaw</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'member'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderRow</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>You may have noticed the call to <strong>BandForm::setNumMembers()</strong> in the above action. We still need to add this method, so let&#8217;s do that now. Edit your <strong>BandForm</strong> class and add the following method definition:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> BandForm <span style="color: #000000; font-weight: bold;">extends</span> BaseBandForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setNumMembers<span style="color: #009900;">&#40;</span><span style="color: #000088;">$numMembers</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedForm</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'members'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> BandMembersForm<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">object</span><span style="color: #339933;">,</span> <span style="color: #000088;">$numMembers</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This in turn means a change to the <strong>BandMembersForm</strong> class, which should be edited to look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> BandMembersForm <span style="color: #000000; font-weight: bold;">extends</span> sfForm
<span style="color: #009900;">&#123;</span>
  protected <span style="color: #000088;">$band</span><span style="color: #339933;">;</span>
&nbsp;
  protected <span style="color: #000088;">$count</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span>Band <span style="color: #000088;">$band</span><span style="color: #339933;">,</span> <span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">band</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$band</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">count</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$count</span><span style="color: #339933;">;</span>
&nbsp;
    parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">band</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Members</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$member</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedForm</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> EmbeddedBandMemberForm<span style="color: #009900;">&#40;</span><span style="color: #000088;">$member</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$i</span> <span style="color: #339933;">++;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #990000;">max</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$j</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$i</span><span style="color: #339933;">;</span> <span style="color: #000088;">$j</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$count</span><span style="color: #339933;">;</span> <span style="color: #000088;">$j</span> <span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedForm</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$j</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> EmbeddedBandMemberForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>What the above changes do are allow us to insert extra blank band members as we please. We then use this to recreate the &#8220;extra&#8221; band member form exactly as it would appear if it were rendered as part of the whole form.</p>
<p>All that is left to do is create the AJAX handler and some unobtrusive JavaScript to fetch and insert the new member form. Open <strong>apps/frontend/modules/band/templates/_form.php</strong> and update the contents to the following:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> use_helper<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Javascript'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> include_stylesheets_for_form<span style="color: #009900;">&#40;</span><span style="color: #000088;">$form</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> include_javascripts_for_form<span style="color: #009900;">&#40;</span><span style="color: #000088;">$form</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
&lt;form action=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'band/'</span><span style="color: #339933;">.</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isNew</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #0000ff;">'create'</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'update'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isNew</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #0000ff;">'?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; method=&quot;post&quot; <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isMultipart</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> and <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">'enctype=&quot;multipart/form-data&quot; '</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isNew</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;input type=&quot;hidden&quot; name=&quot;sf_method&quot; value=&quot;put&quot; /&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  &lt;table id=&quot;band&quot;&gt;
    &lt;tfoot&gt;
      &lt;tr&gt;
        &lt;td colspan=&quot;2&quot;&gt;
          &lt;noscript&gt;&lt;p&gt;
            &lt;strong&gt;NOTE:&lt;/strong&gt; To add more members, please save this form, and more spaces will be presented.
          &lt;/p&gt;&lt;/noscript&gt;
&nbsp;
          &amp;nbsp;&lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'band/index'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;Cancel&lt;/a&gt;
          <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isNew</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
            &amp;nbsp;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> link_to<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Delete'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'band/delete?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'method'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'delete'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'confirm'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Are you sure?'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          &lt;input type=&quot;submit&quot; value=&quot;Save&quot; /&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tfoot&gt;
    &lt;tbody&gt;
      <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$form</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    &lt;/tbody&gt;
  &lt;/table&gt;
&lt;/form&gt;
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> javascript_tag<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  $$('#band table').each(function(e)
  {
    if (e.select('table').length)
    {
      e.select('tbody')[0].id = 'band_members';
&nbsp;
      e.insert('<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> escape_javascript<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;
        &lt;tfoot&gt;&lt;tr&gt;&lt;td colspan=<span style="color: #000099; font-weight: bold;">\&quot;</span>2<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;&quot;</span><span style="color: #339933;">.</span>
          button_to_remote<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Add member'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'url'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'band/memberForm'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'with'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">&quot;'count='+$$('#band_members table').length&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'update'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'band_members'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'position'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'bottom'</span><span style="color: #339933;">,</span>
          <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;&lt;/td&gt;&lt;/tr&gt;&lt;/tfoot&gt;
      &quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>');
    }
  });
<span style="color: #000000; font-weight: bold;">&lt;?php</span> end_javascript_tag<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>It&#8217;s important to note that this code is somewhat ugly because I wanted to avoid manually changing the form&#8217;s layout. In a production situation you could implement a much more elegant solution by customising the form layout or writing a custom form renderer.</p>
<p>This point aside, your form should now look like the image below when JavaScript is enabled (when JavaScript is disabled a message will be displayed informing the user of how to add additional members):</p>
<p><img class="alignnone size-full wp-image-242" title="Form with add member button added" src="http://ezzatron.com/wp-content/uploads/2009/12/form_with_ajax.png" alt="Form with add member button added" width="433" height="608" /></p>
<p>We&#8217;re now able to add additional slots for new members dynamically using the &#8220;Add member&#8221; button. We&#8217;re facing one last hurdle unfortunately; when we add a new member slot and hit the save button we&#8217;re presented with a form error:</p>
<p><img class="alignnone size-full wp-image-245" title="Validation error when adding members dynamically" src="http://ezzatron.com/wp-content/uploads/2009/12/dynamic_validation_error.png" alt="Validation error when adding members dynamically" width="433" height="165" /></p>
<p>Thankfully this is fairly easy to remedy. The issue is that when the update action handles the posted data, it creates a fresh instance of <strong>BandForm</strong> which has no knowledge of our &#8220;extra&#8221; band member form. To fix this we can override the <strong>BandForm</strong> class&#8217; <strong>bind()</strong> method to detect the number of band members passed and expand the form as needed:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> BandForm <span style="color: #000000; font-weight: bold;">extends</span> BaseBandForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> bind<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$taintedValues</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span> <span style="color: #000088;">$taintedFiles</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$taintedValues</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'members'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$taintedValues</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'members'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setNumMembers</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$taintedValues</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'members'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$taintedValues</span><span style="color: #339933;">,</span> <span style="color: #000088;">$taintedFiles</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And hey presto, our form now works perfectly!</p>
<h2>Conclusion</h2>
<p>If you got this far I&#8217;m sure you&#8217;ll agree that this was not by any means an easy exercise. The symfony forms system <em>is </em>powerful and flexible, but it seems like perhaps this type of situation was not really brought into consideration when it was designed. I would love to see the symfony architects consider ways that the implementation of expanding forms could be simplified, or at least better documented.</p>
<p>Once again if you have any suggestions on how to improve this implementation I&#8217;d really love to hear them. I&#8217;m sure there are aspects of the symfony forms system that I don&#8217;t understand fully which could make this whole exercise somewhat simpler, and that would certainly be valuable knowledge.</p>
<p>If you are interested, there is a guide to implementing a similar system <a title="How to Embed AJAX(!) Forms in Symfony 1.2 Admin Generator" href="http://israelwebdev.wordpress.com/2009/05/04/how-to-embed-ajax-forms-in-symfony-12-admin-generator/">here</a>, however it seems to deal with the symfony admin generator specifically, and it also seems to have the disadvantage that the parent object must exist before child objects can be added.</p>
<p>Good luck with your own implementations, let me know how they go!</p>
<h2>Source code</h2>
<ul>
<li><a href="http://expandingform.sf.ezzatron.com/source/_form.phps">_form.php</a></li>
<li><a href="http://expandingform.sf.ezzatron.com/source/actions.class.phps">actions.class.php</a></li>
<li><a href="http://expandingform.sf.ezzatron.com/source/BandForm.class.phps">BandForm.class.php</a></li>
<li><a href="http://expandingform.sf.ezzatron.com/source/BandMembersForm.class.phps">BandMembersForm.class.php</a></li>
<li><a href="http://expandingform.sf.ezzatron.com/source/BaseFormDoctrine.class.phps">BaseFormDoctrine.class.php</a></li>
<li><a href="http://expandingform.sf.ezzatron.com/source/EmbeddedBandMemberForm.class.phps">EmbeddedBandMemberForm.class.php</a></li>
<li><a href="http://expandingform.sf.ezzatron.com/source/EmbeddedBandMemberValidatorSchema.class.phps">EmbeddedBandMemberValidatorSchema.class.php</a></li>
<li><a href="http://expandingform.sf.ezzatron.com/source/fixtures.yml">fixtures.yml</a></li>
<li><a href="http://expandingform.sf.ezzatron.com/source/memberFormSuccess.phps">memberFormSuccess.php</a></li>
<li><a href="http://expandingform.sf.ezzatron.com/source/schema.yml">schema.yml</a></li>
</ul>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fezzatron.com%2F2009%2F12%2F03%2Fexpanding-forms-with-symfony-1-2-and-doctrine%2F';
  addthis_title  = 'Expanding+forms+with+symfony+1.2+and+Doctrine';
  addthis_pub    = 'ezzatron';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://ezzatron.com/2009/12/03/expanding-forms-with-symfony-1-2-and-doctrine/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Automatically signing .jar files in NetBeans</title>
		<link>http://ezzatron.com/2009/09/29/automatically-signing-jar-files-in-netbeans/</link>
		<comments>http://ezzatron.com/2009/09/29/automatically-signing-jar-files-in-netbeans/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 09:03:41 +0000</pubDate>
		<dc:creator>Erin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[applet]]></category>
		<category><![CDATA[automatic]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[netbeans]]></category>
		<category><![CDATA[permissions]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[signing]]></category>

		<guid isPermaLink="false">http://ezzatron.com/?p=143</guid>
		<description><![CDATA[Just a quick article on something I struggled to find a good example for &#8211; configuring NetBeans to sign a .jar file after compilation is complete.
This is very handy, for example, when developing an applet that requires permission to access the file system. This requires the applet to be &#8220;signed&#8221; using the jarsigner utility, and [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick article on something I struggled to find a good example for &#8211; configuring <strong>NetBeans </strong>to sign a .jar file after compilation is complete.</p>
<p>This is very handy, for example, when developing an <strong>applet </strong>that requires permission to access the file system. This requires the applet to be <strong>&#8220;signed&#8221;</strong> using the <strong>jarsigner </strong>utility, and this quickly becomes a tedious step when testing changes made in your applet in the browser itself.</p>
<p><span id="more-143"></span></p>
<p>I&#8217;m assuming that since you&#8217;re reading this article you have basic knowledge of <strong>Java </strong>and the <strong>keytool </strong>and <strong>jarsigner</strong> utilities. If not, there is a good introduction <a title="JAR Signing" href="http://www.cs.princeton.edu/introcs/85application/jar/sign.html">here</a>.</p>
<p>Please note that this how-to is intended for a development environment situation only. Before deploying to a production environment you should read up on the best practices and security implications of the .jar signing process.</p>
<h2>Step 1: Setting up your keystore</h2>
<p>For this step we will be using the <strong>keytool </strong>utility distributed with your <strong><acronym title="Java Development Kit">JDK</acronym></strong>. This will most likely be in the <strong>bin </strong>directory of your <strong><acronym title="Java Development Kit">JDK</acronym></strong> installation.</p>
<p>Assuming <strong>keytool </strong>is in your system path, run the command:</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">keytool -genkey -alias &lt;alias name&gt; -keystore &lt;keystore path&gt; -validity 36500</pre></div></div>

<p>Replacing <em>&lt;alias name&gt;</em> with a suitable alias, and <em>&lt;keystore path&gt;</em> with the filename you&#8217;d like for your <strong>keystore</strong>.</p>
<p>You will then be prompted for a number of inputs. For a test setup, use the following answers:</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">Enter keystore password: &lt;keystore password&gt; &lt;enter&gt;
Re-enter new password: &lt;keystore password&gt; &lt;enter&gt;
What is your first and last name?
  [Unknown]: &lt;enter&gt;
What is the name of your organizational unit?
  [Unknown]: &lt;enter&gt;
What is the name of your organization?
  [Unknown]: &lt;enter&gt;
What is the name of your City or Locality?
  [Unknown]: &lt;enter&gt;
What is the name of your State or Province?
  [Unknown]: &lt;enter&gt;
What is the two-letter country code for this unit?
  [Unknown]: &lt;enter&gt;
Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
  [no]:  y &lt;enter&gt;
&nbsp;
Enter key password for &lt;&lt;alias name&gt;&gt;
        (RETURN if same as keystore password): &lt;key password&gt; &lt;enter&gt;</pre></div></div>

<p>This will create a <strong>keystore</strong> file at <em>&lt;keystore path&gt;</em> which we will use in the next step to sign .jar files. Remember the passwords you used in this step as you&#8217;ll need them very soon.</p>
<p>The <em>-validity 36500</em> section simply specifies that we want this key to last for a very long time (100 years to be exact). This is fine in a <strong>development</strong> environment as you probably don&#8217;t want to have to regenerate new keys all the time, but in a <strong>production</strong> environment this would obviously be much shorter. The <em>-validity</em> value is specified in <strong>days</strong>.</p>
<h2>Step 2: Configuring your NetBeans project</h2>
<p>In this step we will be editing two configuration files from your NetBeans project; <strong>project.properties</strong> and <strong>build.xml</strong>.</p>
<p>The project.properties file should be located in the <strong>nbproject</strong> directory of your NetBeans project, and the build.xml should be in the main project folder itself.</p>
<p>You can edit these files by hand, or you can do so in <strong>NetBeans</strong> itself by switching to the <strong>Files</strong> window.</p>
<p>Add the following lines somewhere in your <strong>project.properties</strong> file, substituting the relevant paths etc. (hint: your <strong>jarsigner</strong> utility should be in the <strong>bin</strong> directory of your <strong><acronym title="Java Development Kit">JDK</acronym></strong> installation):</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">jarsign.jarsigner<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&lt;path to the jarsigner utility&gt;</span>
jarsign.keystore<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&lt;keystore path&gt;</span>
jarsign.storepass<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&lt;keystore password&gt;</span>
jarsign.keypass<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&lt;key password&gt;</span>
jarsign.signedjar<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&lt;path to create signed jar file at&gt;</span>
jarsign.alias<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&lt;alias name&gt;</span></pre></div></div>

<p>Add the following <em>inside</em> the <strong>&lt;project&gt;</strong> block in your <strong>build.xml</strong> file:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;-post-jar&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exec</span> <span style="color: #000066;">executable</span>=<span style="color: #ff0000;">&quot;${jarsign.jarsigner}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">line</span>=<span style="color: #ff0000;">&quot;-keystore&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">file</span>=<span style="color: #ff0000;">&quot;${jarsign.keystore}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">line</span>=<span style="color: #ff0000;">&quot;-storepass ${jarsign.storepass}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">line</span>=<span style="color: #ff0000;">&quot;-keypass ${jarsign.keypass}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">line</span>=<span style="color: #ff0000;">&quot;-signedjar&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">file</span>=<span style="color: #ff0000;">&quot;${jarsign.signedjar}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">file</span>=<span style="color: #ff0000;">&quot;${dist.jar}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">line</span>=<span style="color: #ff0000;">&quot;${jarsign.alias}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/exec<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;echo<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Signed Jar '${jarsign.signedjar}' created<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/echo<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>And that&#8217;s it. The next time you <strong>build</strong> your project, a signed copy of the .jar file should be created automatically at the path you specified. You should also see a confirmation message in the build output.</p>
<p><strong>Enjoy!</strong></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fezzatron.com%2F2009%2F09%2F29%2Fautomatically-signing-jar-files-in-netbeans%2F';
  addthis_title  = 'Automatically+signing+.jar+files+in+NetBeans';
  addthis_pub    = 'ezzatron';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://ezzatron.com/2009/09/29/automatically-signing-jar-files-in-netbeans/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Patent idea: Method and device for compression of caffeinated beverages</title>
		<link>http://ezzatron.com/2009/08/27/coffee-compression/</link>
		<comments>http://ezzatron.com/2009/08/27/coffee-compression/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 05:22:20 +0000</pubDate>
		<dc:creator>Erin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Patent ideas]]></category>
		<category><![CDATA[beverage]]></category>
		<category><![CDATA[caffeine]]></category>
		<category><![CDATA[coffee]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[idea]]></category>
		<category><![CDATA[patent]]></category>
		<category><![CDATA[patent idea]]></category>

		<guid isPermaLink="false">http://ezzatron.com/?p=123</guid>
		<description><![CDATA[
By Jove, I&#8217;ve done it!
Yes my friends, after much trial and error, I&#8217;ve invented a method of compressing coffee into a smaller size, making it possible to carry around numerous coffees safely and easily.

The process involves compressing the coffee into small metal discs, called &#8220;Coins&#8221;. The coffee in these coins can then be extracted at [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-131" title="coffee_compression" src="http://ezzatron.com/wp-content/uploads/2009/08/coffee_compression.jpg" alt="coffee_compression" width="500" height="323" /></p>
<p>By Jove, I&#8217;ve done it!</p>
<p>Yes my friends, after much trial and error, I&#8217;ve invented a method of <strong>compressing coffee</strong> into a smaller size, making it possible to carry around numerous coffees safely and easily.</p>
<p><span id="more-123"></span></p>
<p>The process involves compressing the coffee into small metal discs, called &#8220;Coins&#8221;. The coffee in these coins can then be extracted at a special coffee extraction point, or &#8220;Café&#8221;.</p>
<p>This is a major step forward over traditional <em>lossy </em>coffee compression systems, such as <strong>instant coffee</strong>. This new compression method is completely <em>lossless</em>, meaning the exact flavour and other important characteristics of the coffee are preserved.</p>
<p>I&#8217;ve filed a patent for the technology, and I&#8217;m currently working on a  prototype implementation in the <a title="Java" href="http://www.java.com/">Java</a> programming language.</p>
<p>Initial testing indicates that coffee quality can vary depending on the extraction point used. Therefore, extraction point operators (or &#8220;Baristas&#8221;) will require special training to ensure that the quality of coffee extracted from the coins remains at a consistent level. Further testing is planned over the coming months.</p>
<p>Stay tuned for further developments.</p>
<p><em>Props to <a title="Horus Kol" href="http://horuskol.net/">Horus Kol</a> for inspiration on this post.</em></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fezzatron.com%2F2009%2F08%2F27%2Fcoffee-compression%2F';
  addthis_title  = 'Patent+idea%3A+Method+and+device+for+compression+of+caffeinated+beverages';
  addthis_pub    = 'ezzatron';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://ezzatron.com/2009/08/27/coffee-compression/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Revisited: foreachif()</title>
		<link>http://ezzatron.com/2009/07/22/foreachif-revisited/</link>
		<comments>http://ezzatron.com/2009/07/22/foreachif-revisited/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 07:39:28 +0000</pubDate>
		<dc:creator>Erin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[wish list]]></category>

		<guid isPermaLink="false">http://ezzatron.com/?p=107</guid>
		<description><![CDATA[A while ago I blogged about my desire for a foreachif() construct in PHP. A recent comment from a reader made me re-think the concept and consider ways in which it could be implemented elegantly, without the need for changes to PHP&#8217;s syntax.

Why implement it in PHP code rather than make a change to the [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I blogged about <a title="PHP wish list - part 1: foreachif()" href="http://ezzatron.com/2008/12/04/php-wishlist-part-1-foreachif/">my desire for a foreachif() construct in PHP</a>. A <a href="http://ezzatron.com/2008/12/04/php-wishlist-part-1-foreachif/comment-page-1/#comment-94">recent comment</a> from a reader made me re-think the concept and consider ways in which it could be implemented elegantly, without the need for changes to <a title="PHP: Hypertext Preprocessor" href="http://php.net/">PHP</a>&#8217;s syntax.</p>
<p><span id="more-107"></span></p>
<p>Why implement it in PHP code rather than make a change to the syntax itself? Well, the reason is fairly simple; having too many syntaxes for the same thing can make code very difficult to read and understand unless the reader is a guru in that particular language. Anyone who has been forced to use <a title="Perl" href="http://www.perl.org/">Perl</a> will know what I mean.</p>
<p>The above comment suggested the use of the <strong>eval()</strong> function. Whilst this would work, I don&#8217;t particularly like the idea for a number of reasons:</p>
<ul>
<li>If there is an error in the eval&#8217;d code, this will show up in a back-trace as occurring in eval&#8217;d code rather than pointing to the actual problem itself &#8211; messy.</li>
<li>If like me, you are used to a nice, cushy IDE, you&#8217;ll know that almost all of your code completion / highlighting immediately goes out the window inside of a string.</li>
<li>I try to avoid <strong>eval()</strong> as a rule of thumb. It just makes me feel <em>dirty</em>.</li>
</ul>
<p>I thought I might try a similar solution however, using PHP 5.3&#8217;s new <a title="PHP: Anonymous functions - Manual" href="http://php.net/closures">closures</a> feature. Closures (A.K.A. <em>anonymous functions</em>) will most likely be familiar to anyone who has used JavaScript in any serious fashion, so I will not go into them here. If you are unfamiliar with the concept, please <a title="PHP: Anonymous functions - Manual" href="http://php.net/closures">RTFM</a>.</p>
<p>In order to make this work there are a few things we need:</p>
<ul>
<li>An array to iterate over</li>
<li>A condition of some sort to evaluate on each loop</li>
<li>A callback to execute if the condition evaluates to true</li>
<li>Some measure of control over variable names passed to the callback would also be nice</li>
</ul>
<p>The bottom line is that it is possible, but it&#8217;s nowhere near as nice, or elegant as I had hoped.</p>
<h2>Method 1: using closures</h2>
<p>Using nothing but the new closures syntax I was able to come up with the following reasonable-looking foreachif() function:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> foreachif<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$array</span><span style="color: #339933;">,</span> <span style="color: #000088;">$condition</span><span style="color: #339933;">,</span> <span style="color: #000088;">$callback</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_callable</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$condition</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'condition must be a valid callback'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_callable</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$callback</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'callback must be a valid callback'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$condition</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
         <span style="color: #000088;">$callback</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This seemed fine until the time came to actually <em>use</em> the thing. Reproducing one of the examples from the aforementioned article resulted in this mess:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$array</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
foreachif <span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span> <span style="color: #339933;">%</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$value</span><span style="color: #339933;">.</span><span style="color: #0000ff;">','</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Not particularly readable huh? Downright horrible is more like it.</p>
<h2>Method 2: mixed closures and eval&#8217;d strings</h2>
<p>The above mess made me think perhaps I could just use eval() for the condition &#8211; perhaps this would help remove some clutter from the statement? Well, yes it does, but it also presents its own problems. Here is the new function:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> foreachif<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$array</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value_name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$condition</span><span style="color: #339933;">,</span> <span style="color: #000088;">$callback</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_callable</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$callback</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'callback must be a valid callback'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$$value_name</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #990000;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\$</span>run = <span style="color: #006699; font-weight: bold;">$condition</span>;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$run</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$callback</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #339933;">,</span> <span style="color: #000088;">$$value_name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In order to retain flexibility in naming the variable used to store the current iteration value, I was forced to pass the variable name as a string. I didn&#8217;t like this at all, and the situation would only get worse if you wanted to be able to choose the name of the array <em>key </em>inside the condition also.</p>
<p>For the sake of completeness, here is an example the utilises the above function:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$array</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
foreachif <span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'this_value'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'$this_value % 2 == 0'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this_value</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this_value</span><span style="color: #339933;">.</span><span style="color: #0000ff;">','</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Then suddenly I realised I was forgetting a very, very important point; <em>variable scope</em>.</p>
<h2>The big problem</h2>
<p>What neither of the above implementations give you is access to any variables defined outside of the closure / eval&#8217;d code itself. Granted this could be worked around by grabbing <em>every</em> defined variable and re-defining them within the scope of the loop content, but this would almost certainly have major performance issues when used in any real-world situation.</p>
<p>At this point I basically abandoned the search for a function-based implementation and started considering PHP syntax alternatives, which turned out to be a much more elegant solution in the end&#8230;</p>
<h2>Method 3: using existing PHP syntax in alternative ways</h2>
<p>Starting with the ultra-obvious solution gives us the following:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$array</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span> <span style="color: #339933;">%</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$value</span><span style="color: #339933;">.</span><span style="color: #0000ff;">','</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>There is also PHP&#8217;s alternate syntax for these structures to consider, and I think the following actually comes out looking quite nice:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span> <span style="color: #339933;">%</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$value</span><span style="color: #339933;">.</span><span style="color: #0000ff;">','</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span></pre></div></div>

<p>The main area in which I intended to use this structure was in native PHP templating. In line with this thinking, here is the above restated as I would present it in a template:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span> <span style="color: #339933;">%</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$value</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>,
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>As you can see, these last three examples are actually quite readable (the last one as much so as native PHP templating can be). The big bonus of course is that they still allow access to all variables in their scope and have no significant performance impact (provided of course that your condition is not intensive on resources).</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fezzatron.com%2F2009%2F07%2F22%2Fforeachif-revisited%2F';
  addthis_title  = 'Revisited%3A+foreachif%28%29';
  addthis_pub    = 'ezzatron';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://ezzatron.com/2009/07/22/foreachif-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Monthly metal clip: Textures&#8217; &#8220;Awake&#8221;</title>
		<link>http://ezzatron.com/2009/03/07/monthly-metal-clip-textures-awake/</link>
		<comments>http://ezzatron.com/2009/03/07/monthly-metal-clip-textures-awake/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 11:38:04 +0000</pubDate>
		<dc:creator>Erin</dc:creator>
				<category><![CDATA[Metal]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Videos]]></category>
		<category><![CDATA[clip]]></category>
		<category><![CDATA[monthly metal clip]]></category>
		<category><![CDATA[silhouettes]]></category>
		<category><![CDATA[textures]]></category>

		<guid isPermaLink="false">http://ezzatron.com/?p=103</guid>
		<description><![CDATA[This month we are treated to a clip from Dutch band Textures. This is the official clip for the song &#8220;Awake&#8221; from their latest offering &#8220;Silhouettes&#8220;. Enjoy!

&#8220;Awake&#8221; from the 2008 album &#8220;Silhouettes&#8221;

  addthis_url    = 'http%3A%2F%2Fezzatron.com%2F2009%2F03%2F07%2Fmonthly-metal-clip-textures-awake%2F';
  addthis_title  = 'Monthly+metal+clip%3A+Textures%26%238217%3B+%26%238220%3BAwake%26%238221%3B';
  addthis_pub    = 'ezzatron';

]]></description>
			<content:encoded><![CDATA[<p>This month we are treated to a clip from Dutch band <a title="Textures" href="http://www.myspace.com/textures">Textures</a>. This is the official clip for the song &#8220;Awake&#8221; from their latest offering &#8220;<a title="Silhouettes" href="http://en.wikipedia.org/wiki/Silhouettes_(album)">Silhouettes</a>&#8220;. Enjoy!</p>
<p><object width="500" height="315" data="http://www.youtube-nocookie.com/v/oSYNhfkNGco&amp;hl=en&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01&amp;border=1" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube-nocookie.com/v/oSYNhfkNGco&amp;hl=en&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01&amp;border=1" /><param name="allowfullscreen" value="true" /></object></p>
<p><em>&#8220;Awake&#8221; from the 2008 album &#8220;Silhouettes&#8221;</em></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fezzatron.com%2F2009%2F03%2F07%2Fmonthly-metal-clip-textures-awake%2F';
  addthis_title  = 'Monthly+metal+clip%3A+Textures%26%238217%3B+%26%238220%3BAwake%26%238221%3B';
  addthis_pub    = 'ezzatron';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://ezzatron.com/2009/03/07/monthly-metal-clip-textures-awake/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Monthly metal clip: The Acacia Strain&#8217;s &#8220;Skynet&#8221;</title>
		<link>http://ezzatron.com/2009/02/02/monthly-metal-clip-the-acacia-strains-skynet/</link>
		<comments>http://ezzatron.com/2009/02/02/monthly-metal-clip-the-acacia-strains-skynet/#comments</comments>
		<pubDate>Sun, 01 Feb 2009 23:51:17 +0000</pubDate>
		<dc:creator>Erin</dc:creator>
				<category><![CDATA[Metal]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Videos]]></category>
		<category><![CDATA[clip]]></category>
		<category><![CDATA[continent]]></category>
		<category><![CDATA[funny]]></category>
		<category><![CDATA[monthly]]></category>
		<category><![CDATA[monthly metal clip]]></category>
		<category><![CDATA[skynet]]></category>
		<category><![CDATA[the acacia strain]]></category>

		<guid isPermaLink="false">http://ezzatron.com/?p=95</guid>
		<description><![CDATA[This month&#8217;s MMC comes from the heavy-as-fuck Massachusetts band The Acacia Strain off their new album &#8220;Continent&#8220;. This track is called &#8220;Skynet&#8221;, and the clip is pretty damn funny, but beware: YouTube has already pulled one version of the video, so get in fast before they do the same with this version!

&#8220;Skynet&#8221; from the 2008 [...]]]></description>
			<content:encoded><![CDATA[<p>This month&#8217;s <acronym title="Monthly Metal Clip">MMC</acronym> comes from the heavy-as-fuck Massachusetts band <a title="The Acacia Strain" href="http://www.myspace.com/theacaciastrain">The Acacia Strain</a> off their new album &#8220;<a title="Continent" href="http://en.wikipedia.org/wiki/Continent_(album)">Continent</a>&#8220;. This track is called &#8220;Skynet&#8221;, and the clip is pretty damn funny, but beware: <a title="YouTube" href="http://youtube.com/">YouTube</a> has already pulled one version of the video, so get in fast before they do the same with this version!</p>
<p><object width="500" height="315" data="http://www.youtube.com/v/e2Xs-pzRyi8&amp;hl=en&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01&amp;border=1" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/e2Xs-pzRyi8&amp;hl=en&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01&amp;border=1" /><param name="allowfullscreen" value="true" /></object></p>
<p><em>&#8220;Skynet&#8221; from the 2008 Album &#8220;Continent&#8221;</em></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fezzatron.com%2F2009%2F02%2F02%2Fmonthly-metal-clip-the-acacia-strains-skynet%2F';
  addthis_title  = 'Monthly+metal+clip%3A+The+Acacia+Strain%26%238217%3Bs+%26%238220%3BSkynet%26%238221%3B';
  addthis_pub    = 'ezzatron';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://ezzatron.com/2009/02/02/monthly-metal-clip-the-acacia-strains-skynet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Monthly metal clip: Gojira&#8217;s &#8220;All the Tears&#8221;</title>
		<link>http://ezzatron.com/2009/01/27/monthly-metal-clip-gojiras-all-the-tears/</link>
		<comments>http://ezzatron.com/2009/01/27/monthly-metal-clip-gojiras-all-the-tears/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 13:02:10 +0000</pubDate>
		<dc:creator>Erin</dc:creator>
				<category><![CDATA[Metal]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Videos]]></category>
		<category><![CDATA[all the tears]]></category>
		<category><![CDATA[clip]]></category>
		<category><![CDATA[first]]></category>
		<category><![CDATA[gojira]]></category>
		<category><![CDATA[monthly]]></category>
		<category><![CDATA[monthly metal clip]]></category>
		<category><![CDATA[the way of all flesh]]></category>

		<guid isPermaLink="false">http://ezzatron.com/?p=88</guid>
		<description><![CDATA[I&#8217;m going to attempt to post a cool metal clip every month, so stay tuned for more of these. I&#8217;ll try to make them recent releases, but that may not always be possible as they don&#8217;t always come along that often.
I&#8217;ll start things off in fairly epic style with French metallers Gojira, and their clip [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m going to attempt to post a cool metal clip every month, so stay tuned for more of these. I&#8217;ll try to make them recent releases, but that may not always be possible as they don&#8217;t always come along that often.</p>
<p>I&#8217;ll start things off in fairly epic style with French metallers <a title="Gojira" href="http://www.myspace.com/gojira">Gojira</a>, and their clip for &#8220;All the Tears&#8221; off their new album &#8220;<a title="The Way of All Flesh" href="http://en.wikipedia.org/wiki/The_Way_of_All_Flesh_(album)">The Way of All Flesh</a>&#8220;. Enjoy!</p>
<p><object width="445" height="364" data="http://www.youtube.com/v/5i7xfk422NA&amp;hl=en&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01&amp;border=1" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/5i7xfk422NA&amp;hl=en&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01&amp;border=1" /><param name="allowfullscreen" value="true" /></object></p>
<p><em>&#8220;All the Tears&#8221; from the 2008 album &#8220;The Way of All Flesh&#8221;</em></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fezzatron.com%2F2009%2F01%2F27%2Fmonthly-metal-clip-gojiras-all-the-tears%2F';
  addthis_title  = 'Monthly+metal+clip%3A+Gojira%26%238217%3Bs+%26%238220%3BAll+the+Tears%26%238221%3B';
  addthis_pub    = 'ezzatron';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://ezzatron.com/2009/01/27/monthly-metal-clip-gojiras-all-the-tears/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Summer gigs update</title>
		<link>http://ezzatron.com/2009/01/27/summer-gigs-update/</link>
		<comments>http://ezzatron.com/2009/01/27/summer-gigs-update/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 12:30:01 +0000</pubDate>
		<dc:creator>Erin</dc:creator>
				<category><![CDATA[Gigs]]></category>
		<category><![CDATA[Metal]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[a day to remember]]></category>
		<category><![CDATA[abrb]]></category>
		<category><![CDATA[adelaide]]></category>
		<category><![CDATA[alaska]]></category>
		<category><![CDATA[as blood runs black]]></category>
		<category><![CDATA[between the buried and me]]></category>
		<category><![CDATA[bleeding through]]></category>
		<category><![CDATA[btbam]]></category>
		<category><![CDATA[cancelled]]></category>
		<category><![CDATA[colors]]></category>
		<category><![CDATA[confession]]></category>
		<category><![CDATA[crater face]]></category>
		<category><![CDATA[declaration]]></category>
		<category><![CDATA[declaration world tour]]></category>
		<category><![CDATA[fowlers]]></category>
		<category><![CDATA[hardcore]]></category>
		<category><![CDATA[hq]]></category>
		<category><![CDATA[in trenches]]></category>
		<category><![CDATA[metalcore]]></category>
		<category><![CDATA[misery signals]]></category>
		<category><![CDATA[parallels]]></category>
		<category><![CDATA[parallels australian tour]]></category>
		<category><![CDATA[parkway drive]]></category>
		<category><![CDATA[photo]]></category>
		<category><![CDATA[plane]]></category>
		<category><![CDATA[prequel to the sequel]]></category>
		<category><![CDATA[soundwave]]></category>
		<category><![CDATA[suicide silence]]></category>
		<category><![CDATA[summer slaughter]]></category>
		<category><![CDATA[sweatfest]]></category>
		<category><![CDATA[the acacia strain]]></category>
		<category><![CDATA[the gov]]></category>
		<category><![CDATA[the governor hindmarsh]]></category>
		<category><![CDATA[the silent circus]]></category>
		<category><![CDATA[unibar]]></category>

		<guid isPermaLink="false">http://ezzatron.com/?p=70</guid>
		<description><![CDATA[Just thought I&#8217;d write a brief update on the gigs I wrote about late last year.
Sweatfest 08 was a bit of a disaster to be honest, as The Acacia Strain, Suicide Silence and A Day To Remember were no-shows due to flight complications. Apparently the story goes that the Virgin Blue flight that all the [...]]]></description>
			<content:encoded><![CDATA[<p>Just thought I&#8217;d write a brief update on the <a title="5 awesome gigs you should attend this summer" href="http://ezzatron.com/2008/12/07/5-awesome-gigs-you-should-attend-this-summer/">gigs</a> I wrote about late last year.</p>
<p><a title="Sweatfest 08" href="http://ezzatron.com/2008/12/07/5-awesome-gigs-you-should-attend-this-summer/#gig_1">Sweatfest 08</a> was a bit of a disaster to be honest, as <a title="The Acacia Strain" href="http://www.myspace.com/theacaciastrain">The Acacia Strain</a>, <a title="Suicide Silence" href="http://www.myspace.com/suicidesilence">Suicide Silence</a> and <a title="A Day to Remember" href="http://www.myspace.com/adaytoremember">A Day To Remember</a> were no-shows due to flight complications. Apparently the story goes that the Virgin Blue flight that all the bands were on was cancelled when the plane touched another in taxi. I couldn&#8217;t find it in any news reports, but I&#8217;ve heard this story from a few different people on the night and since.</p>
<p>Kudos must go out to <a title="Parkway Drive" href="http://www.myspace.com/parkwaydrive">Parkway Drive</a>, who flew all the way from Perth, to Melbourne, and back to Adelaide just to play that night. Their efforts went some way to making up for the disappointment many fans were feeling, although the tiredness <em>was</em> showing, with the band making a few uncharacteristic timing slip ups. Personally, I was so pissed off at missing <strong><acronym title="The Acacia Strain">TAS</acronym></strong> that I don&#8217;t think even their best show ever could have made me forget my sorrows.</p>
<p><span id="more-70"></span>Local act <a title="Crater Face" href="http://www.myspace.com/ilovecraterface">Crater Face</a> were on first, and mostly failed to impress me. They were followed by <a title="Confession" href="http://www.myspace.com/confessionhc">Confession</a>, who put on a pretty tight performance, but whether it was because of my disappointment or otherwise, they just couldn&#8217;t seem to make me <em>care</em>. Then there was what seemed an interminable wait before <strong>Parkway Drive</strong> arrived, weary but undeterred, to play their set. Altogether, not the <em>greatest </em>show I&#8217;ve ever seen.</p>
<p>A couple of nights ago saw the <a title="Declaration World Tour" href="http://ezzatron.com/2008/12/07/5-awesome-gigs-you-should-attend-this-summer/#gig_2">Declaration World Tour</a> wind up right here in our fair city. I have to say how much I enjoy watching shows at the <a title="The Governor Hindmarsh Hotel" href="http://www.thegov.com.au/">Governor Hindmarsh</a>. It&#8217;s a great venue and I&#8217;m always happy when acts choose it over, say, <strong>HQ</strong> or <strong>Fowlers</strong>.</p>
<p>Starting off the night were Melbourne&#8217;s <a title="In Trenches" href="http://www.myspace.com/intrencheshc">In Trenches</a>, who put on a very decent show with an almost <a title="Misery Signals" href="http://www.myspace.com/miserysignals">Misery Signals</a>-y feel to the songs and good stage presence. I may have to check those guys out in more detail at some point. They were followed soon after by <a title="As Blood Runs Black" href="http://www.myspace.com/asbloodrunsblack">As Blood Runs Black</a>, who, whilst certainly being very technically proficient, played a set that quickly bored me, with songs that seemed to deteriorate into a mess of interminable gallop beats and ho-hum breakdowns.</p>
<p>I had a front-row spot to watch the next act, and the reason for me being at the gig, <a title="Between the Buried and Me" href="http://www.myspace.com/betweentheburiedandmeband">Between the Buried and Me</a>,<a title="Between the Buried and Me" href="http://www.myspace.com/betweentheburiedandmeband"> </a>and let me tell you, these guys did <strong>not</strong> disappoint. Their set was absolutely magical from end to end. Astounding musicianship, epic songs, and a fantastic atmosphere left the crowd hungry for more. It seemed to myself and some others that I spoke with that <strong><acronym title="Between the Buried and Me">BTBAM</acronym></strong> drew the biggest crowd of the night, somewhat confirming my thoughts that they should have headlined this gig.</p>
<p>Had they headlined, they most likely would have played all of <a title="Colors" href="http://en.wikipedia.org/wiki/Colors_(Between_the_Buried_and_Me_album)">Colors</a> from start to finish, followed by some older songs, which would have been amazing to see. Time being what it was, the crowd would have to make do with a mix of classic songs from <a title="Alaska" href="http://en.wikipedia.org/wiki/Alaska_(Between_the_Buried_and_Me_album)">Alaska</a> and <a title="Colors" href="http://en.wikipedia.org/wiki/Colors_(Between_the_Buried_and_Me_album)">Colors</a> (and possibly <a title="The Silent Circus" href="http://en.wikipedia.org/wiki/The_Silent_Circus">The Silent Circus</a>? I can&#8217;t remember now). The set ended with massive applause from the audience, and me up on the railings, horns raised, with a massive grin on my face. If you didn&#8217;t go, here&#8217;s a sample of what you missed out on:</p>
<p><object width="500" height="315" data="http://www.youtube.com/v/7lb3rE17Sak&amp;hl=en&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01&amp;border=1" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/7lb3rE17Sak&amp;hl=en&amp;fs=1&amp;color1=0xe1600f&amp;color2=0xfebd01&amp;border=1" /><param name="allowfullscreen" value="true" /></object></p>
<p><em>&#8220;Prequel to the Sequel&#8221; off the 2008 DVD &#8220;<a title="Colors_LIVE" href="http://en.wikipedia.org/wiki/Colors_(DVD)">Colors_LIVE</a>&#8220;</em></p>
<p>Rounding off the gig were California&#8217;s <a title="Bleeding Through" href="http://www.myspace.com/bleedingthrough">Bleeding Through</a>, who put on a solid, intense set, but couldn&#8217;t really live up to the genius and diversity of <strong><acronym title="Between the Buried and Me">BTBAM</acronym></strong>. To my ears, they are still playing exactly the same music as last time I saw them a few years ago at the <a title="Adelaide UniBar" href="http://www.adelaide.edu.au/unibar/">Adelaide UniBar</a>.</p>
<p>I managed to have a chat to some of the guys from <strong><acronym title="Between the Buried and Me">BTBAM</acronym></strong> after the gig and they were all amazingly friendly and genuine for people who just reached the end of a tour and were most likely exhausted. I also got a photo with the bass player, which I&#8217;ll throw up as soon as I grab it from a friend&#8217;s camera.</p>
<p><strong>*UPDATE*</strong> Here&#8217;s that photo:</p>
<p><img class="alignnone size-full wp-image-101" title="Me &amp; Dan Briggs from BTBAM" src="http://ezzatron.com/wp-content/uploads/2009/02/n674699796_1240327_1031.jpg" alt="Me &amp; Dan Briggs from BTBAM" width="435" height="326" /></p>
<p>Still to come this year we have <a title="The Parallels Australian Tour" href="http://ezzatron.com/2008/12/07/5-awesome-gigs-you-should-attend-this-summer/#gig_3">The Parallels Australian Tour</a>, <a title="Soundwave 2009" href="http://ezzatron.com/2008/12/07/5-awesome-gigs-you-should-attend-this-summer/#gig_4">Soundwave 2009</a> and <a title="The Summer Slaughter Tour" href="http://ezzatron.com/2008/12/07/5-awesome-gigs-you-should-attend-this-summer/#gig_5">The Summer Slaughter Tour</a>. Speaking of Soundwave, the <a title="Adelaide Soundwave 09 Timetable" href="http://uploads.kmwproductions.com/timetables/SW09-times-adelaide.pdf">timetable</a> has been released, so check it out if you are going. If you missed out on any of the above, do yourself a favour and get in early this time. You won&#8217;t be dissapointed. Unless another plane gets cancelled of course&#8230;</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fezzatron.com%2F2009%2F01%2F27%2Fsummer-gigs-update%2F';
  addthis_title  = 'Summer+gigs+update';
  addthis_pub    = 'ezzatron';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://ezzatron.com/2009/01/27/summer-gigs-update/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Help stop the Great Firewall of Oz!</title>
		<link>http://ezzatron.com/2008/12/15/help-stop-the-great-firewall-of-oz/</link>
		<comments>http://ezzatron.com/2008/12/15/help-stop-the-great-firewall-of-oz/#comments</comments>
		<pubDate>Sun, 14 Dec 2008 22:16:00 +0000</pubDate>
		<dc:creator>Erin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[censorship]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[internet]]></category>

		<guid isPermaLink="false">http://ezzatron.com/?p=63</guid>
		<description><![CDATA[This is just a quick post to try and rally a few signatures against the ridiculous mandatory internet filter proposed for Australia.
There are so many reasons why this should not go ahead. I won&#8217;t go into detail here, but you should learn more if you don&#8217;t know what I&#8217;m on about. Try Horus Kol&#8217;s article, [...]]]></description>
			<content:encoded><![CDATA[<p>This is just a quick post to try and rally a few signatures against the ridiculous <a title="Internet censorship in Australia - Wikipedia" href="http://en.wikipedia.org/wiki/Internet_censorship_in_Australia">mandatory internet filter proposed for Australia</a>.</p>
<p>There are so many reasons why this should not go ahead. I won&#8217;t go into detail here, but you <strong>should</strong> learn more if you don&#8217;t know what I&#8217;m on about. Try Horus Kol&#8217;s <a title="Great Firewall of Oz - Horus Kol" href="http://www.horuskol.co.uk/great-firewall-of-oz-20081202">article</a>, or <a title="No Clean Feed" href="http://nocleanfeed.com/">No Clean Feed</a> for some good information.</p>
<p>Please use this nifty form to show your support for the fight against mandatory internet censorship:</p>
<div><object width="300" height="250" data="http://www.getup.org.au/flash/widget.swf" type="application/x-shockwave-flash"><param name="quality" value="high" /><param name="src" value="http://www.getup.org.au/flash/widget.swf" /></object></div>
<p>In addition, there is another petition you can sign at <a title="top Australian Internet Censorship - TakingITGlobal" href="http://petitions.takingitglobal.org/oznetcensorship">TakingITGlobal</a>.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fezzatron.com%2F2008%2F12%2F15%2Fhelp-stop-the-great-firewall-of-oz%2F';
  addthis_title  = 'Help+stop+the+Great+Firewall+of+Oz%21';
  addthis_pub    = 'ezzatron';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://ezzatron.com/2008/12/15/help-stop-the-great-firewall-of-oz/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP wish list &#8211; part 2: reverse combined operators</title>
		<link>http://ezzatron.com/2008/12/12/php-wish-list-part-2-reverse-combined-operators/</link>
		<comments>http://ezzatron.com/2008/12/12/php-wish-list-part-2-reverse-combined-operators/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 06:38:39 +0000</pubDate>
		<dc:creator>Erin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[wish list]]></category>

		<guid isPermaLink="false">http://ezzatron.com/?p=40</guid>
		<description><![CDATA[It&#8217;s time for part 2 of my PHP wish list! In this instalment I&#8217;ll detail another feature that I would love to see in PHP: reverse combined operators.
If you missed part 1 (you probably did), you can read it here.
&#8220;What the hell is a reverse combined operator?&#8221; I hear you scream. Well, technically they probably [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s time for part 2 of my <strong>PHP wish list! </strong>In this instalment I&#8217;ll detail another feature that I would love to see in PHP: <strong>reverse combined operators</strong>.</p>
<p>If you missed part 1 (you probably did), you can read it <a title="PHP wish list - part 1: foreachif()" href="http://ezzatron.com/2008/12/04/php-wishlist-part-1-foreachif/">here</a>.</p>
<p><em>&#8220;What the hell is a reverse combined operator?&#8221;</em> I hear you scream. Well, technically they probably don&#8217;t exist yet, so I&#8217;m sure a better name could be found, but bear with me and I&#8217;ll try to explain&#8230;</p>
<p><span id="more-40"></span></p>
<p>If you&#8217;ve ever done any programming, then you&#8217;ve almost certainly used <strong>operators</strong> whether you realise it or not. Basically, they are some of the most basic building blocks of a programming language, things like <strong>+</strong>, <strong>-</strong>, <strong>=</strong> and <strong>==</strong> are all <strong>operators</strong>. For a more detailed description, see the <a title="PHP Manual - Operators" href="http://php.net/operators">PHP manual</a>.</p>
<p>One of the most commonly used operators in any language is the <strong>assignment operator</strong> (=). This operator is used to assign a <strong>value </strong>to a <a href="http://php.net/variables">variable</a>. Here is a simple example:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$variable</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$variable</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// outputs &quot;2&quot;</span></pre></div></div>

<p>In the above example, PHP first uses the <a title="PHP Manual - Arithmetic Operators" href="http://www.php.net/manual/en/language.operators.arithmetic.php">addition operator</a> to get the sum of 1 and 1. It then stores the result in <strong>$variable</strong> using the <strong>assignment operator</strong>.</p>
<p>Now consider the following situation; you have a variable that you want to add a certain amount to. Rather than writing the whole expression out like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$variable</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$variable</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></div></div>

<p>PHP allows you to shorten the above to just:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$variable</span> <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></div></div>

<p>This is called a <strong>combined operator</strong> because it is effectively a combination of the <strong>+</strong> and <strong>=</strong> operators. This combining of operators is only ever done with the assignment operator and one other operator. Here are all the combined operators that I am aware of:</p>
<table style="text-align: left;" border="0" width="477">
<tbody>
<tr>
<th>Operator</th>
<th>Equivalent to</th>
<th>Description</th>
</tr>
<tr>
<td>$a += $b</td>
<td>$a = $a + $b</td>
<td>Addition / array union</td>
</tr>
<tr>
<td>$a -= $b</td>
<td>$a = $a &#8211; $b</td>
<td>Subtraction</td>
</tr>
<tr>
<td>$a *= $b</td>
<td>$a = $a * $b</td>
<td>Multiplication</td>
</tr>
<tr>
<td>$a /= $b</td>
<td>$a = $a / $b</td>
<td>Division</td>
</tr>
<tr>
<td>$a %= $b</td>
<td>$a = $a % $b</td>
<td>Modulus</td>
</tr>
<tr>
<td>$a .= $b</td>
<td>$a = $a . $b</td>
<td>Concatenation</td>
</tr>
<tr>
<td>$a &amp;= $b</td>
<td>$a = $a &amp; $b</td>
<td>Bitwise and</td>
</tr>
<tr>
<td>$a |= $b</td>
<td>$a = $a | $b</td>
<td>Bitwise or</td>
</tr>
<tr>
<td>$a ^= $b</td>
<td>$a = $a ^ $b</td>
<td>Bitwise xor</td>
</tr>
<tr>
<td>$a &lt;&lt;= $b</td>
<td>$a = $a &lt;&lt; $b</td>
<td>Left shift</td>
</tr>
<tr>
<td>$a &gt;&gt;= $b</td>
<td>$a = $a &gt;&gt; $b</td>
<td>Right shift</td>
</tr>
</tbody>
</table>
<p>What I would like to see are <strong>reverse combined operators</strong>. Essentially these would be the same as regular combined operators, except with the order of operands <strong>reversed</strong>. This would produce the following options:</p>
<table style="text-align: left;" border="0" width="477">
<tbody>
<tr>
<th>Operator</th>
<th>Equivalent to</th>
<th>Description</th>
</tr>
<tr>
<td>$a =+ $b</td>
<td>$a = $b + $a</td>
<td>Array union</td>
</tr>
<tr>
<td>$a =- $b</td>
<td>$a = $b &#8211; $a</td>
<td>Subtraction</td>
</tr>
<tr>
<td>$a =/ $b</td>
<td>$a = $b / $a</td>
<td>Division</td>
</tr>
<tr>
<td>$a =% $b</td>
<td>$a = $b % $a</td>
<td>Modulus</td>
</tr>
<tr>
<td>$a =. $b</td>
<td>$a = $b . $a</td>
<td>Concatenation</td>
</tr>
<tr>
<td>$a =&lt;&lt; $b</td>
<td>$a = $b &lt;&lt; $a</td>
<td>Left shift</td>
</tr>
<tr>
<td>$a =&gt;&gt; $b</td>
<td>$a = $b &gt;&gt; $a</td>
<td>Right shift</td>
</tr>
</tbody>
</table>
<p>Note that not every combined operator would imply the need for a reverse version because the order of operands has no effect on the result in some cases.</p>
<p>I&#8217;ll now provide you with a couple of examples where something like this could come in handy.</p>
<p><strong>Inverting a number</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$v</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">100</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$v</span> <span style="color: #339933;">=/</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$v</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// would output &quot;0.01&quot;</span></pre></div></div>

<p><strong>Controlling which array takes precedence</strong> when merging arrays using the <strong>array union operator</strong> (basically just the <strong>+</strong> operator, but when used on arrays you get the union of the two):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$v</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'one'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'two'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'three'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$v</span> <span style="color: #339933;">+=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'apple'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'banana'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'orange'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$v</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">','</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// this would output &quot;one,two,three,orange,&quot;</span>
&nbsp;
<span style="color: #000088;">$v</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'one'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'two'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'three'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$v</span> <span style="color: #339933;">=+</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'apple'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'banana'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'orange'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$v</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">','</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// this would output &quot;one,apple,banana,orange,&quot;</span></pre></div></div>

<p>I&#8217;m sure if you racked your brain you could come up with dozens of other handy little uses for this feature. Let me know if you can think of any others!</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fezzatron.com%2F2008%2F12%2F12%2Fphp-wish-list-part-2-reverse-combined-operators%2F';
  addthis_title  = 'PHP+wish+list+%26%238211%3B+part+2%3A+reverse+combined+operators';
  addthis_pub    = 'ezzatron';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://ezzatron.com/2008/12/12/php-wish-list-part-2-reverse-combined-operators/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
