<?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>Connecting the dots... &#187; cc expiry</title>
	<atom:link href="http://blog.rajatpandit.com/tag/cc-expiry/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.rajatpandit.com</link>
	<description>Thoughts on Web Development, Infrastructure and Application Scalability</description>
	<lastBuildDate>Thu, 29 Dec 2011 13:21:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Conditional Validator in Symfony</title>
		<link>http://blog.rajatpandit.com/2009/02/22/conditional-validator-in-symfony/</link>
		<comments>http://blog.rajatpandit.com/2009/02/22/conditional-validator-in-symfony/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 22:18:25 +0000</pubDate>
		<dc:creator>rp</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[cc expiry]]></category>
		<category><![CDATA[conditional validator]]></category>
		<category><![CDATA[confirmation]]></category>
		<category><![CDATA[credit card info]]></category>
		<category><![CDATA[credit card validator]]></category>
		<category><![CDATA[password validation]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[widgets]]></category>

		<guid isPermaLink="false">http://blog.rajatpandit.com/?p=216</guid>
		<description><![CDATA[I recently had to work on a signup form where the user was present different set of fields based on where the user came from. Lets take a sample scenario,...]]></description>
			<content:encoded><![CDATA[<p>I recently had to work on a signup form where the  user was present different set of fields based on where the user came from. Lets take a sample scenario, I have a signup form where users get to from the &#8220;Plans&#8221; page.<br />
If the user chooses to go with the Free Plan, he gets to a page which asks for his username and password only where as if the user chooses the &#8220;Paid&#8221; plan, he is presented with the full form including his username, password, credit card info and expiry date.</p>
<p>I shall cover writing the Credit Card Validator for Symony in one of the next few posts potentially for now, just documenting what I did for implementing the conditional validator.</p>
<p>So the standard RegisterForm.class logged like this:</p>
<pre class="brush: php; title: ; notranslate">
  public function configure() {
      // Remove all widgets we don't want to show
      unset(
        $this['is_active'],
        $this['is_super_admin'],
        $this['updated_at'],
        $this['groups_list'],
        $this['permissions_list'],
        $this['last_login'],
        $this['created_at'],
        $this['salt'],
        $this['algorithm']
      );

    // Setup proper password validation with confirmation
    $this-&gt;widgetSchema['password']                          = new sfWidgetFormInputPassword();
    $this-&gt;widgetSchema['password_confirmation']    = new sfWidgetFormInputPassword();

    $this-&gt;widgetSchema['cc']                = new sfWidgetFormInput();
    $this-&gt;widgetSchema['toc']               = new sfWidgetFormInputCheckbox();

    // assuming someone would have a card which
    // expires as far as 10years from today
    $years = range(date('Y'), date('Y') + 10);

    $this-&gt;widgetSchema['cc_expiry_date']    = new sfWidgetFormI18nDate(
                                                    array(
                                                      'can_be_empty' =&gt; 'false',
                                                      'years'=&gt; array_combine($years, $years),
                                                      'culture'=&gt;'en',
                                                      'month_format'=&gt;'name',
                                                      'format'=&gt; '%month% %year%')
                                                    );

    $this-&gt;widgetSchema-&gt;setLabel('username', 'Email');
    $this-&gt;widgetSchema-&gt;setLabel('password_confirmation', 'Confirm Password');
    $this-&gt;widgetSchema-&gt;setLabel('cc', 'Credit Card Number');
    $this-&gt;widgetSchema-&gt;setLabel('cc_expiry_date', 'Credit Card Expiry Date');
    $this-&gt;widgetSchema-&gt;setLabel('toc', 'I agree to the Terms of Service, Privacy, &amp; Refund policies');

    $this-&gt;validatorSchema['username'] 	= new sfValidatorEmail();
    $this-&gt;validatorSchema['cc'] 		    = new sfValidatorCreditCard();
    $this-&gt;validatorSchema['toc']       = new sfValidatorBoolean(
                                            array('required' =&gt; true),
                                            array('required'=&gt; 'You need to accept the terms and conditions to proceed')
                                          );

    $this-&gt;validatorSchema['password_confirmation'] = clone $this-&gt;validatorSchema['password'];
    $this-&gt;validatorSchema['password']-&gt;setOption('required', true);
    $this-&gt;validatorSchema['cc_expiry_date'] = new sfValidateCCExpiryDate(array('min' =&gt; time()),
                                                              array('invalid' =&gt; 'Please enter a valid expiry date'));

    $this-&gt;widgetSchema-&gt;moveField('password_confirmation', 'after', 'password');
    $this-&gt;mergePostValidator(new sfValidatorSchemaCompare('password',
                                    sfValidatorSchemaCompare::EQUAL, 'password_confirmation',
                                    array(),
                                    array('invalid' =&gt; 'The two passwords must be the same.')));
</pre>
<p>as you can see credit card and expiry date are a required field, however i don&#8217;t want to use that validation when it comes to doing a signup for a basic plan which will not have credit card and expiry date fields. So, this is implemented by overriding the <code>bind</code> method to change the validation rules based on the input provided. In the code snippet below the field validations change based on the hidden value <code>price_id</code> passed. </p>
<pre class="brush: bash; title: ; notranslate">
  public function bind(array $taintedValues = null, array $taintedFiles = null)
  {
    $price = PricePeer::retrieveByPK(@$taintedValues['price_id']);
    if (!$price) {
      return false;
    }
    if(0 == $price-&gt;getPrice()) {
      // turn off all the other validations
      $this-&gt;validatorSchema['cc_expiry_date']-&gt;setOption('required',false);
      $this-&gt;validatorSchema['cc']-&gt;setOption('required',false);
   }
    return parent::bind($taintedValues,$taintedFiles);
  }
</pre>
<p>I would be interested in knowing how you worked around this problem. Do leave a comment below.</p>
<div id="in_post_ad_bottom_1" style="clear:both;margin:0;padding:0;"><div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-bp */
google_ad_slot = "7787511801";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-BP-1 */
google_ad_slot = "9111022353";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.rajatpandit.com/2009/02/22/conditional-validator-in-symfony/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

