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

<channel>
	<title>blog.barros.ws &#187; conditional validator</title>
	<atom:link href="http://blog.barros.ws/tag/conditional-validator/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.barros.ws</link>
	<description>web development tips</description>
	<lastBuildDate>Sun, 06 Jun 2010 00:34:52 +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>Conditional validator in Symfony, another approach</title>
		<link>http://blog.barros.ws/2008/11/05/conditional-validator-in-symfony-another-approach/</link>
		<comments>http://blog.barros.ws/2008/11/05/conditional-validator-in-symfony-another-approach/#comments</comments>
		<pubDate>Wed, 05 Nov 2008 12:10:27 +0000</pubDate>
		<dc:creator>Carlos Barros</dc:creator>
				<category><![CDATA[symfony]]></category>
		<category><![CDATA[conditional validator]]></category>
		<category><![CDATA[form]]></category>

		<guid isPermaLink="false">http://blog.barros.ws/?p=53</guid>
		<description><![CDATA[Today morning I was reading the Symfony blog, more specifically A week of symfony #96 and then I came across a tutorial talking about conditional validators.This is very usefull, I find myself using this technique very often, so I decided to write about another techinique I use sometimes to implement a conditional validation, but for [...]]]></description>
			<content:encoded><![CDATA[<p>Today morning I was reading the Symfony blog, more specifically <a title="A week of symfony #96" href="http://www.symfony-project.org/blog/2008/11/02/a-week-of-symfony-96-27-october-2-november-2008" target="_blank">A week of symfony #96</a> and then I came across a <a title="How to implement a conditional validator?" href="http://www.symfony-project.org/cookbook/1_2/en/conditional-validator" target="_blank">tutorial talking about conditional validators</a>.This is very usefull, I find myself using this technique very often, so I decided to write about another techinique I use sometimes to implement a conditional validation, but for a different scenario. Imagine the following: you have a contact form where the users specify how they want to be contacted, email or phone, throught a select box. Then you have two input boxes where the users can enter both email and phone. If the user opts to be contacted via email, email field becomes mandatory and phone number optional, and the opposite happens if the user opts to be contacted via phone. So, how to implement such a form in symfony? </p>
<p><span id="more-53"></span><br />
A normal form would look like this:</p>
<p>lib/form/ContactForm.class.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> ContactForm <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: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setWidgets</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'method'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormSelect<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'choices'</span><span style="color: #339933;">=&gt;</span>array<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'phone'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'Phone'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'email'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'Email'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'email'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormInput<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'phone'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormInput<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'msg'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfWidgetFormTextarea<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setValidators</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'method'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorChoice<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'choices'</span><span style="color: #339933;">=&gt;</span>array<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'phone'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'email'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'email'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorEmail<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'required'</span><span style="color: #339933;">=&gt;</span>true<span style="color: #339933;">,</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;">'required'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'Please enter your email address'</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'invalid'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'Invalid email address'</span>
		<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'phone'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorString<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'required'</span><span style="color: #339933;">=&gt;</span>true<span style="color: #339933;">,</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;">'required'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'Please enter your phone number'</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;">'msg'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorString<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'required'</span><span style="color: #339933;">=&gt;</span>true<span style="color: #339933;">,</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;">'required'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'Please enter your message'</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: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLabels</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'email'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Email:'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'phone'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Phone:'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'method'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Contact type:'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'msg'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Message:'</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setNameFormat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'contact[%s]'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">errorSchema</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> sfValidatorErrorSchema<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>The problem with this form is the fact that both phone and email are ALWAYS mandatory, regardless of the value of method. So, what we need is a way to intercept method&#8217;s value and update validators. So, what we need is intercept the <em><strong>bind</strong></em> method in order to check method&#8217;s value:</p>
<p>lib/form/ContactForm.class.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> 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: #339933;">@</span><span style="color: #000088;">$taintedValues</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;method&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'phone'</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;email&quot;</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: #b1b100;">else</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;phone&quot;</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>
&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></pre></div></div>

<p>As can be seen, we create our own bind method, overriding parent one, and before calling the actual bind method, we inspect the values sent by the user and if <em>method</em> is <em>phone</em>, we remove the required option from <em>email</em> validator, otherwise we remove the required option from <em>phone</em> validator and finally call parent method.</p>
<p>The resulting form <a title="Conditional Validator" href="http://blog.barros.ws/symfony/contact" target="_blank">can be seen here</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.barros.ws/2008/11/05/conditional-validator-in-symfony-another-approach/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>
