Author: Krapulator
Date: 2010-02-14 10:06:15 +0100 (Sun, 14 Feb 2010)
New Revision: 28020

Added:
   
plugins/sfJqueryFormValidationPlugin/lib/sfJqueryFormValidationRules.class.php
Modified:
   
plugins/sfJqueryFormValidationPlugin/lib/filter/sfJqueryFormValidationFilter.class.php
   
plugins/sfJqueryFormValidationPlugin/modules/sfJqueryFormVal/actions/actions.class.php
   
plugins/sfJqueryFormValidationPlugin/modules/sfJqueryFormVal/templates/indexSuccess.php
Log:
Started re-engineering plugin to add support for embedded forms and to clean up 
the code

Modified: 
plugins/sfJqueryFormValidationPlugin/lib/filter/sfJqueryFormValidationFilter.class.php
===================================================================
--- 
plugins/sfJqueryFormValidationPlugin/lib/filter/sfJqueryFormValidationFilter.class.php
      2010-02-14 08:00:06 UTC (rev 28019)
+++ 
plugins/sfJqueryFormValidationPlugin/lib/filter/sfJqueryFormValidationFilter.class.php
      2010-02-14 09:06:15 UTC (rev 28020)
@@ -2,7 +2,7 @@
 
 class sfJqueryFormValidationFilter extends sfFilter
 {
-       public function execute($filterChain) 
+  public function execute($filterChain) 
   {
     $filterChain->execute();
     $action = 
$this->getContext()->getActionStack()->getLastEntry()->getActionInstance();
@@ -10,8 +10,24 @@
     {
       if ($value instanceof sfForm && 
(sfConfig::get('app_sf_jquery_form_validation_default') !== 'disabled' || 
in_array(get_class($value), 
sfConfig::get('app_sf_jquery_form_validation_forms'))))
       {
+       $url_params = array(
+          'module' => 'sfJqueryFormVal',
+          'action' => 'index',
+          'form' => get_class($value),
+        );
+        
+        $embedded_forms = array();
+        foreach($value->getEmbeddedForms() as $name => $embedded_form)
+        {
+          $url_params['embedded_form'][$name] = get_class($embedded_form);
+        }
+        if(sizeof($embedded_forms) > 0)
+        {
+               $url_params['embedded_form'] = $embedded_forms;
+        }
+        
         $response = $this->getContext()->getResponse();
-        $response->setContent(str_ireplace('</head>', '<script 
type="text/javascript" src="' . url_for('sfJqueryFormVal/index?form=' . 
get_class($value)) . '"></script></head>',$response->getContent()));
+        $response->setContent(str_ireplace('</head>', '<script 
type="text/javascript" src="' . url_for($url_params) . 
'"></script></head>',$response->getContent()));
       }
     }
   }

Added: 
plugins/sfJqueryFormValidationPlugin/lib/sfJqueryFormValidationRules.class.php
===================================================================
--- 
plugins/sfJqueryFormValidationPlugin/lib/sfJqueryFormValidationRules.class.php  
                            (rev 0)
+++ 
plugins/sfJqueryFormValidationPlugin/lib/sfJqueryFormValidationRules.class.php  
    2010-02-14 09:06:15 UTC (rev 28020)
@@ -0,0 +1,249 @@
+<?php
+  
+  class sfJqueryFormValidationRules
+  {
+    
+       private $rules = array();
+       private $messages = array();
+       private $first_field_id = null;
+       private $form_name = null;
+       private static $widgets = array(
+       
+        'sfValidatorEmail' => array(
+          'rules' => array('email' => true),
+     ),
+     
+     'sfValidatorFile' => array(
+      'rules' => array('accept' => true),
+      'keymap' => array('mime_types' => 'accept'),
+     ),
+     
+     'sfValidatorRegex' => array(
+      'rules' => array('regex' => '%pattern%'),
+      'keymap' =>  array('pattern' => 'invalid'),
+      'msgmap' =>  array('pattern' => 'regex'),
+     ),
+     
+     'sfValidatorUrl' => array(
+      'rules' => array('url' => true),
+      'keymap' =>  array('pattern' => 'invalid'),
+      'msgmap' =>  array('pattern' => 'url'),
+     ),  
+
+     'sfValidatorInteger' => array(
+      'rules' => array('digits' => true),
+      'keymap' =>  array('pattern' => 'invalid'),
+      'msgmap' =>  array('pattern' => 'digits'),
+     ),  
+
+     'sfValidatorDate' => array(
+       'rules' => array('date' => true),
+       'keymap' =>  array('date_format' => 'bad_format'),
+       'msgmap' =>  array('date_format' => 'date'),
+     ),
+     
+       );
+       private static $keymap = array(
+        'min_length' => 'minlength',
+        'max_length' => 'maxlength',
+       );
+       
+       public function __construct(sfForm $form)
+       {
+               $this->processValidationRules($form->getName(), $form);
+               $this->form_name = $form->getName();
+               
+               // if an alternative date method has been specified, update the 
static widget array
+         if(strlen(sfConfig::get('app_sf_jquery_form_validation_date_method')) 
> 0)
+           {
+               self::$widgets['sfValidatorDate']['rules'] = 
array(sfConfig::get('app_sf_jquery_form_validation_date_method') => true);
+               self::$widgets['sfValidatorDate']['keymap'] = 
array('date_format' => 'bad_format');
+        self::$widgets['sfValidatorDate']['msgmap'] = array('date_format' => 
sfConfig::get('app_sf_jquery_form_validation_date_method'));
+           }
+          
+       }
+       
+       public function addEmbeddedForm($name, sfForm $form)
+       {
+               $this->processValidationRules($name, $form, true);
+       }
+       
+       public function generateRules()
+       {
+               return sizeof($this->rules) > 0 ? 
stripslashes(json_encode($this->rules)) : '{}';
+       }
+       
+    public function generateMessages()
+    {
+      $message = sizeof($this->messages) > 0 ? 
stripslashes(json_encode($this->messages)) : '{}';
+      // this is a nasty hack to return a function as a value
+      // see line 185 for the matching hackery
+      $message = str_replace('"[[', 'function(a, elem)', $message);
+      $message = str_replace(']]"', '', $message);
+      $message = str_replace('\" +', '" +', $message);
+      $message = str_replace(' + \"', ' + "', $message);
+      return $message;
+    }          
+    
+    public function getFirstFieldHtmlId()
+    {
+       return $this->first_field_id;
+    }
+    
+    public function processValidationRules($name, sfForm $form, $is_embedded = 
false)
+    {
+       foreach($form->getValidatorSchema()->getFields() as $fieldname => 
$objField)
+       {
+               
+               // ignore the csrf field
+               if($name == '_csrf_token') continue;
+               
+               // get the correct html "name" for this field
+               $validation_name = $this->createValidationName($name, 
$fieldname, $is_embedded);
+               
+               $this->processRules($validation_name, $objField);
+               $this->processMessages($validation_name, $objField);
+      }
+
+    }
+    
+    private function processRules($validation_name, sfWidget $objField)
+    {
+       
+      $field_options = $objField->getOptions();
+       
+      // process the common rules for all widets
+      if($field_options['required'])
+      {
+       $this->addRule($validation_name, 'required', true);
+      }
+      if(isset($field_options['max_length']))
+      {
+        $this->addRule($validation_name, 'maxlength', 
$field_options['max_length']);
+      }
+      if(isset($field_options['min_length']))
+      {
+       $this->addRule($validation_name, 'minlength', 
$field_options['min_length']);
+      }
+        
+      // now add widget specific rules
+      foreach(self::$widgets as $widget_name => $properties)
+      {
+              if($widget_name == get_class($objField))
+              {
+                foreach($properties['rules'] as $key => $val)
+                {
+                       
+                       // if there's a dynamic placehold in the value, do a 
replace for the real value
+                        if(preg_match('/%(.*)%/', $val, $matches) > 0)
+                        {
+                               // remove the slash because it breaks the 
javascript regex syntax
+                               // (hopefully removing the slash doesn't break 
anything else in the future)
+                               $val = str_replace('/', '', 
$field_options[$matches[1]]);
+                        }
+                        
+                        // add the validation rule
+                        $this->addRule($validation_name, $key, $val);
+                        
+                }
+              }
+      }
+    }
+    
+    private function processMessages($validation_name, sfWidget $objField)
+    {
+       $field_options = $objField->getOptions();
+       $messages = $objField->getMessages();
+       $class = get_class($objField);
+       foreach($field_options as $key => $val)
+       {
+               $msg_key = $this->parseMessageKey($key, $objField);
+               if($messages[$msg_key])
+                 $this->addMessage($validation_name, 
isset(self::$widgets[$class]['msgmap'][$key]) ? 
self::$widgets[$class]['msgmap'][$key] : $key, 
$this->parseMessageVal($messages[$msg_key], $objField));
+       }
+    }
+    
+    private function parseMessageKey($key, sfWidget $objField)
+    {
+       $class = get_class($objField);
+       if(isset(self::$widgets[$class]['keymap'][$key]))
+       {
+               $key = self::$widgets[$class]['keymap'][$key];
+       }
+       elseif(isset(self::$keymap[$key]))
+       {
+               $key = self::$keymap[$key];
+       }
+       return $key;
+    }
+    
+    private function parseMessageVal($val, sfWidget $objField)
+    {
+       
+       $field_options = $objField->getOptions();
+       
+       // Make the required message a bit more friendly
+       if($val == 'Required.')
+       {
+               $val = 'Please enter a value for this field.';
+       }
+       
+       // add slashes
+       $val = addslashes($val);
+       
+       // replace any placeholder values
+       // this is a nasty hack (see line 74 for the matching hackery)
+      if(strpos($val, '%value%') !== false)
+      {
+        $val = '[[{ return \'' . str_replace('%value%', "' + $(elem).val() + 
'", $val) . '\';}]]';
+      }
+      
+      if(strpos($val, '%min_length%') !== false)
+      {
+        $val = str_replace('%min_length%', $field_options['min_length'], $val);
+      }     
+
+      if(strpos($val, '%max_length%') !== false)
+      {
+        $val = str_replace('%max_length%', $field_options['max_length'], $val);
+      }       
+       
+       return $val;
+       
+    }
+    
+    private function addRule($validation_name, $rule, $value)
+    {
+      $this->rules[$validation_name][$rule] = $value;
+    }
+    
+    private function addMessage($validation_name, $rule, $value)
+    {
+      $this->messages[$validation_name][$rule] = $value;
+    }
+    
+    private function createValidationName($form_name, $fieldname, $is_embedded)
+    {
+
+       $field_html_name_prefix = $is_embedded ? $this->form_name . 
"[$form_name]" : $form_name;
+       $field_html_id_prefix = $is_embedded ? $this->form_name . "_$form_name" 
: $form_name;
+
+        if(strlen($form_name) > 0)
+        {
+          $validation_name = $field_html_name_prefix . "[$fieldname]";
+          $field_html_id = $field_html_id_prefix . '_' . $fieldname;
+        }
+        else 
+        {
+          $validation_name = ($is_embedded ? "_$this->form_name" : '') . 
$fieldname;
+          $field_html_id = ($is_embedded ? "$this->form_name_" : '') . 
$fieldname;
+        }
+        
+        if($this->first_field_id == null)
+        {
+          $this->first_field_id = $field_html_id;
+        }  
+        return $validation_name;
+    }
+       
+  }
\ No newline at end of file

Modified: 
plugins/sfJqueryFormValidationPlugin/modules/sfJqueryFormVal/actions/actions.class.php
===================================================================
--- 
plugins/sfJqueryFormValidationPlugin/modules/sfJqueryFormVal/actions/actions.class.php
      2010-02-14 08:00:06 UTC (rev 28019)
+++ 
plugins/sfJqueryFormValidationPlugin/modules/sfJqueryFormVal/actions/actions.class.php
      2010-02-14 09:06:15 UTC (rev 28020)
@@ -9,21 +9,27 @@
     $form = $request->getParameter('form');
     
     // make sure that the form class specified actually exists
-    $this->forward404Unless(class_exists($form));
+    // and it is really a symfony form
+    $this->forward404Unless($this->isValidSfFormName($form));
     
-    // make sure the class name provided is actually a symfony form
-    $this->forward404Unless(is_subclass_of($form, 'sfForm'));
+    // create an instance of the sfJqueryFormValidationRules object
+    $this->sf_jq_rules = new sfJqueryFormValidationRules(new $form);
     
-    // instantiate an instance of the form
-    $this->form = new $form;
+    // add embedded forms
+    foreach($request->getParameter('embedded_form') as $name => $form)
+    {
+       if($this->isValidSfFormName($form))
+       {
+               $this->sf_jq_rules->addEmbeddedForm($name, new $form);
+       }
+    }
     
-    // put the form name into a variable for easier reading of code in view
-    $this->name = $this->form->getName();
-    
-    // put the field objects into a variable
-    $this->fields = $this->form->getValidatorSchema()->getFields();
-    
-    // remove the csrf token from the field list if it exists
-    unset($this->fields['_csrf_token']);
   }
+  
+  
+  private function isValidSfFormName($form_class_name)
+  {
+       return class_exists($form_class_name) && 
is_subclass_of($form_class_name, 'sfForm');
+  }
+  
 }

Modified: 
plugins/sfJqueryFormValidationPlugin/modules/sfJqueryFormVal/templates/indexSuccess.php
===================================================================
--- 
plugins/sfJqueryFormValidationPlugin/modules/sfJqueryFormVal/templates/indexSuccess.php
     2010-02-14 08:00:06 UTC (rev 28019)
+++ 
plugins/sfJqueryFormValidationPlugin/modules/sfJqueryFormVal/templates/indexSuccess.php
     2010-02-14 09:06:15 UTC (rev 28020)
@@ -1,34 +1,8 @@
-<?php 
-  use_helper('JqueryFormVal');
-  $fields = $sf_data->getRaw('fields');
-  $field_total = sizeof($fields);
-  $counter = 1;
-?>
-
 jQuery(function($){
   
-  $('#<?php echo strlen($name) > 0 ? $name . '_' . key($fields) : key($fields) 
?>').parents('form').validate({
-    rules: {
-      <?php foreach($fields as $fieldname => $field): ?>
-  
-        '<?php echo (strlen($name) > 0 ? $name . '['  . $fieldname . ']' : 
$fieldname ) . '\': {
-          ' ?>
-            <?php echo function_exists(get_class($field) . '_rules') ? 
call_user_func(get_class($field) . '_rules', $field) : '' ?>
-        
-        }<?php echo $counter < $field_total ? ',' : '' ?>
-<?php $counter++ ?><?php endforeach ?>
-    },<?php $counter = 1 ?>
-    
-    messages: {
-      <?php foreach($fields as $fieldname => $field): ?>
-        '<?php echo (strlen($name) > 0 ? $name . '['  . $fieldname . ']' : 
$fieldname ) . '\': {
-          ' ?>
-            <?php echo sf_form_messages($field, $name . '[' . $fieldname . 
']') ?>
-        
-        }<?php echo $counter < $field_total ? ',' : '' ?>
-        
-<?php $counter++ ?><?php endforeach; ?>
-    },
+  $('#<?php echo $sf_jq_rules->getFirstFieldHtmlId() 
?>').parents('form').validate({
+    rules: <?php echo $sf_jq_rules->generateRules() ?>,
+    messages: <?php echo $sf_jq_rules->generateMessages() ?>,
     wrapper: 'ul class=error_list',
     errorElement: 'li',
     errorPlacement: function(error, element) 
@@ -45,9 +19,9 @@
   
   });
   
-  <?php if($post_validator = $form->getValidatorSchema()->getPostValidator()): 
?>
-      <?php echo function_exists(get_class($post_validator) . '_process') ? 
call_user_func(get_class($post_validator) . '_process', $post_validator, $name) 
: '' ?>
-  <?php endif ?>
+  <?php //if($post_validator = 
$form->getValidatorSchema()->getPostValidator()): ?>
+      <?php //echo function_exists(get_class($post_validator) . '_process') ? 
call_user_func(get_class($post_validator) . '_process', $post_validator, $name) 
: '' ?>
+  <?php //endif ?>
 
 });
 

-- 
You received this message because you are subscribed to the Google Groups 
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/symfony-svn?hl=en.

Reply via email to