Development

Changeset 10419

You must first sign up to be able to contribute.

Changeset 10419

Show
Ignore:
Timestamp:
07/22/08 07:26:13 (5 years ago)
Author:
Kris.Wallsmith
Message:

sfFormtasticPlugin:

  • moved YAML form generation logic into generator classes
  • changed YAML syntax to remove all option/attribute nested arrays
  • added more convenience methods to sfFormtasticBase
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/sfFormtasticPlugin/trunk/config/config_handlers.yml

    r10217 r10419  
    1 config/form/*.yml: 
     1form/*.yml: 
    22  class: sfFormtasticConfigHandler 
  • plugins/sfFormtasticPlugin/trunk/config/form/example.yml

    r10364 r10419  
    2020    birthday: 
    2121      type:                 date 
    22       options:              { years: [1980, 1981] } 
     22      years:                [1980, 1981] 
    2323      sfValidatorDate: 
    2424        min:                <?php echo strtotime('-18 years')."\n" ?> 
     
    2626    gender: 
    2727      type:                 radio 
    28       options:              { choices: { male: Male, female, Female }
     28      choices:              { male: Male, female, Female
    2929      required: 
    3030        msg:                Please select your gender. 
  • plugins/sfFormtasticPlugin/trunk/lib/config/sfFormtasticConfigHandler.class.php

    r10364 r10419  
    1111class sfFormtasticConfigHandler extends sfYamlConfigHandler 
    1212{ 
    13   static protected 
    14     $typeToWidgetMap = array( 
    15       'date'      => 'sfWidgetFormDate', 
    16       'datetime'  => 'sfWidgetFormDateTime', 
    17       'timestamp' => 'sfWidgetFormDateTime', 
    18       'input'     => 'sfWidgetFormInput', 
    19       'checkbox'  => 'sfWidgetFormInputCheckbox', 
    20       'file'      => 'sfWidgetFormInputFile', 
    21       'upload'    => 'sfWidgetFormInputFile', 
    22       'hidden'    => 'sfWidgetFormInputHidden', 
    23       'password'  => 'sfWidgetFormInputPassword', 
    24       'select'    => 'sfWidgetFormSelect', 
    25       'dropdown'  => 'sfWidgetFormSelect', 
    26       'many'      => 'sfWidgetFormSelectMany', 
    27       'radio'     => 'sfWidgetFormSelectRadio', 
    28       'textarea'  => 'sfWidgetFormTextarea', 
    29       'time'      => 'sfWidgetFormTime', 
    30     ), 
    31     $impliedValidatorMap = array( 
    32       'sfWidgetFormDate'        => 'sfValidatorDate', 
    33       'sfWidgetFormDateTime'    => 'sfValidatorDateTime', 
    34       'sfWidgetFormInputFile'   => 'sfValidatorFile', 
    35       'sfWidgetFormSelect'      => 'sfValidatorChoice', 
    36       'sfWidgetFormSelectMany'  => 'sfValidatorChoiceMany', 
    37       'sfWidgetFormSelectRadio' => 'sfValidatorChoice', 
    38       'sfWidgetFormTime'        => 'sfValidatorTime', 
    39     ); 
    40    
    41   protected 
    42     $data   = array(), 
    43     $class  = null, 
    44     $config = array(); 
    45    
    4613  /** 
    4714   * @see sfConfigHandler 
     
    4916  public function execute($configFiles) 
    5017  { 
    51     $this->data[] = '<?php'; 
    52     $this->data[] = ''; 
    53     $this->data[] = '/*'; 
    54     $this->data[] = ' * auto-generated by sfFormtasticConfigHandler'; 
    55     $this->data[] = ' * date: '.date('Y/m/d H:i:s'); 
    56     $this->data[] = ' */'; 
    57     $this->data[] = ''; 
     18    $config = $this->getConfiguration($configFiles); 
     19    $generator = new sfFormtasticGeneratorManager($config); 
    5820     
    59     // parse the yaml 
    60     foreach ($this->getConfiguration($configFiles) as $class => $config) 
    61     { 
    62       $this->class  = $class; 
    63       $this->config = $config; 
    64        
    65       $extends = 'sfFormtastic'; 
    66       if (isset($this->config['extends'])) 
    67       { 
    68         if (class_exists($this->config['extends'])) 
    69         { 
    70           $rc = new ReflectionClass($this->config['extends']); 
    71           if ($rc->isSubclassOf(new ReflectionClass('sfForm'))) 
    72           { 
    73             $extends = $this->config['extends']; 
    74           } 
    75           else 
    76           { 
    77             throw new InvalidArgumentException(sprintf('The class "%s" is not an extension of sfForm', $this->config['extends'])); 
    78           } 
    79         } 
    80         else 
    81         { 
    82           throw new InvalidArgumentException(sprintf('The class "%s" could not be found', $this->config['extends'])); 
    83         } 
    84       } 
    85        
    86       $this->data[] = '/**'; 
    87       $this->data[] = ' * '.$class.' form.'; 
    88       $this->data[] = ' * '; 
    89       $this->data[] = ' * @package    symfony'; 
    90       $this->data[] = ' * @subpackage form'; 
    91       $this->data[] = ' * @author     Auto-generated from YAML'; 
    92       $this->data[] = ' * @version    SVN: $Id$'; 
    93       $this->data[] = ' */'; 
    94       $this->data[] = 'class '.$class.' extends '.$extends; 
    95       $this->data[] = '{'; 
    96       $this->data[] = '  /**'; 
    97       $this->data[] = '   * @see sfForm'; 
    98       $this->data[] = '   */'; 
    99       $this->data[] = '  public function configure()'; 
    100       $this->data[] = '  {'; 
    101        
    102       if ('sfFormtastic' != $extends) 
    103       { 
    104         $this->data[] = '    parent::configure();'; 
    105         $this->data[] = ''; 
    106       } 
    107        
    108       $this->addWidgets(); 
    109       $this->addValidators(); 
    110       $this->addLabels(); 
    111       $this->addHelps(); 
    112        
    113       if (isset($this->config['name_format'])) 
    114       { 
    115         $this->data[] = sprintf('    $this->widgetSchema->setNameFormat(%s);', $this->varExport($this->config['name_format'])); 
    116       } 
    117        
    118       $this->data[] = '  }'; 
    119       $this->data[] = '}'; 
    120       $this->data[] = ''; 
    121     } 
    122      
    123     return join("\n", $this->data); 
    124   } 
    125    
    126   /** 
    127    * Add widgets. 
    128    */ 
    129   protected function addWidgets() 
    130   { 
    131     $widgets = array(); 
    132     if (isset($this->config['fields'])) 
    133     { 
    134       foreach ($this->config['fields'] as $name => $config) 
    135       { 
    136         $widget     = 'sfWidgetFormInput'; 
    137         $options    = isset($config['options']) ? $config['options'] : array(); 
    138         $attributes = isset($config['attributes']) ? $config['attributes'] : array(); 
    139          
    140         if (isset($config['type'])) 
    141         { 
    142           $widget = $this->convertTypeToWidgetClass($config['type']); 
    143         } 
    144         else 
    145         { 
    146           // smart-configure based on field name 
    147           switch ($name) 
    148           { 
    149             case 'id': 
    150             $widget = 'sfWidgetFormInputHidden'; 
    151             break; 
    152           } 
    153         } 
    154          
    155         $this->configureImpliedValidator($name, $widget, $options); 
    156          
    157         $widgets[$name] = array($widget, $options, $attributes); 
    158       } 
    159     } 
    160      
    161     // build call to ->setWidgets() 
    162     if (count($widgets)) 
    163     { 
    164       $this->data[] = '    $this->setWidgets(array('; 
    165       foreach ($widgets as $name => $params) 
    166       { 
    167         $this->data[] = sprintf('      %s => %s,', $this->varExport($name), $this->buildWidget($params)); 
    168       } 
    169       $this->data[] = '    ));'; 
    170       $this->data[] = ''; 
    171     } 
    172   } 
    173    
    174   /** 
    175    * Convert a user-friendly "type" value to a widget class. 
    176    *  
    177    * @param   string $type 
    178    *  
    179    * @return  string A subclass of sfWidget 
    180    */ 
    181   protected function convertTypeToWidgetClass($type) 
    182   { 
    183     static $map = null; 
    184      
    185     if (is_null($map)) 
    186     { 
    187       $map = array_merge(self::$typeToWidgetMap, sfConfig::get('app_sf_formtastic_plugin_type_to_widget_map', array())); 
    188     }  
    189      
    190     $widgetClass = isset($map[$type]) ? $map[$type] : $type; 
    191     if (class_exists($widgetClass)) 
    192     { 
    193       $rc = new ReflectionClass($widgetClass); 
    194       if (!$rc->isSubclassOf(new ReflectionClass('sfWidget'))) 
    195       { 
    196         throw new InvalidArgumentException(sprintf('The class "%s" is not a subclass of sfWidget', $widgetClass)); 
    197       } 
    198     } 
    199     else 
    200     { 
    201       throw new InvalidArgumentException(sprintf('The class "%s" could not be found', $widgetClass)); 
    202     } 
    203      
    204     return $widgetClass; 
    205   } 
    206    
    207   /** 
    208    * Add an implied validator to the form configuration. 
    209    *  
    210    * @param   string  $name 
    211    * @param   string  $widget 
    212    * @param   array   $widgetOptions 
    213    */ 
    214   protected function configureImpliedValidator($name, $widget, $widgetOptions = array()) 
    215   { 
    216     if (isset(self::$impliedValidatorMap[$widget])) 
    217     { 
    218       $validator = self::$impliedValidatorMap[$widget]; 
    219        
    220       $validatorParams = array(); 
    221       if (false !== strpos($validator, 'Choice')) 
    222       { 
    223         if (isset($widgetOptions['choices'])) 
    224         { 
    225           $validatorParams['choices'] = $widgetOptions['choices']; 
    226         } 
    227       } 
    228        
    229       if (isset($this->config['fields'][$name][$validator])) 
    230       { 
    231         $this->config['fields'][$name][$validator] = array_merge($validatorParams, (array) $this->config['fields'][$name][$validator]); 
    232       } 
    233       else 
    234       { 
    235         $this->config['fields'][$name][$validator] = $validatorParams; 
    236       } 
    237     } 
    238   } 
    239    
    240   /** 
    241    * Build a widget instantiation. 
    242    *  
    243    * @param   array $params 
    244    *  
    245    * @return  string 
    246    */ 
    247   protected function buildWidget($params = array()) 
    248   { 
    249     list($widget, $options, $attributes) = $params; 
    250      
    251     if (count($attributes)) 
    252     { 
    253       return sprintf('new %s(%s, %s)', $widget, $this->varExport($options), $this->varExport($attributes)); 
    254     } 
    255     elseif (count($options)) 
    256     { 
    257       return sprintf('new %s(%s)', $widget, $this->varExport($options)); 
    258     } 
    259     else 
    260     { 
    261       return sprintf('new %s', $widget); 
    262     } 
    263   } 
    264    
    265   /** 
    266    * Add validators. 
    267    */ 
    268   protected function addValidators() 
    269   { 
    270     $formValidators = array(); 
    271     foreach ($this->config['fields'] as $name => $config) 
    272     { 
    273       $validators = array(); 
    274        
    275       $required = isset($config['required']); 
    276       $requiredMessage = isset($config['required']['msg']) ? $config['required']['msg'] : null; 
    277        
    278       // validator configuration 
    279       if (is_array($config)) 
    280       { 
    281         foreach ($config as $validator => $params) 
    282         { 
    283           if (class_exists($validator)) 
    284           { 
    285             $rc = new ReflectionClass($validator); 
    286             if ($rc->isSubclassOf(new ReflectionClass('sfValidatorBase'))) 
    287             { 
    288               $options = array(); 
    289               $messages = array(); 
    290                
    291               if (!$required) 
    292               { 
    293                 $options['required'] = false; 
    294               } 
    295                
    296               if (is_array($params)) 
    297               { 
    298                 foreach ($params as $key => $value) 
    299                 { 
    300                   if (in_array($key, array('invalid', 'error'))) 
    301                   { 
    302                     $messages['invalid'] = $value; 
    303                   } 
    304                   elseif (preg_match('/^(\w+)_error$/', $key, $match)) 
    305                   { 
    306                     $messages[$match[1]] = $value; 
    307                   } 
    308                   else 
    309                   { 
    310                     $options[$key] = $value; 
    311                   } 
    312                 } 
    313               } 
    314                
    315               $validators[$validator] = array($options, $messages); 
    316             } 
    317           } 
    318         } 
    319       } 
    320        
    321       // smart-configure validator based on field name 
    322       if (!count($validators)) 
    323       { 
    324         $options = array(); 
    325         if (!$required) 
    326         { 
    327           $options['required'] = false; 
    328         } 
    329          
    330         if (false !== strpos($name, 'email')) 
    331         { 
    332           $validators['sfValidatorEmail'] = array($options, array()); 
    333         } 
    334         elseif ('id' == $name) 
    335         { 
    336           $validators['sfValidatorInteger'] = array($options, array()); 
    337         } 
    338         else 
    339         { 
    340           if ($required) 
    341           { 
    342             $validators['sfValidatorString'] = array(array(), array()); 
    343           } 
    344           else 
    345           { 
    346             $validators['sfValidatorPass'] = array(array(), array()); 
    347           } 
    348         } 
    349       } 
    350        
    351       $formValidators[$name] = array($validators, $required, $requiredMessage); 
    352     } 
    353      
    354     // build call to ->setValidators() 
    355     if (count($formValidators)) 
    356     { 
    357       $this->data[] = '    $this->setValidators(array('; 
    358       foreach ($formValidators as $name => $formValidator) 
    359       { 
    360         list($validators, $required, $requiredMessage) = $formValidator; 
    361          
    362         if (count($validators) > 1) 
    363         { 
    364           // use sfValidatorAnd 
    365           $this->data[] = sprintf('      %s => new sfValidatorAnd(array(', $this->varExport($name)); 
    366           foreach ($validators as $validator => $params) 
    367           { 
    368             $this->data[] = '        '.$this->buildValidator($validator, $params).','; 
    369           } 
    370            
    371           $options = array(); 
    372           $messages = array(); 
    373            
    374           if (!$required) 
    375           { 
    376             $options['required'] = false; 
    377           } 
    378           elseif ($requiredMessage) 
    379           { 
    380             $messages['required'] = $requiredMessage; 
    381           } 
    382            
    383           $this->data[] = sprintf('      ), %s, %s),', $this->varExport($options), $this->varExport($messages)); 
    384         } 
    385         else 
    386         { 
    387           $validator = key($validators); 
    388            
    389           $this->data[] = sprintf('      %s => %s,', $this->varExport($name), $this->buildValidator($validator, $validators[$validator], $requiredMessage)); 
    390         } 
    391       } 
    392       $this->data[] = '    ));'; 
    393       $this->data[] = ''; 
    394     } 
    395   } 
    396    
    397   /** 
    398    * Build a validator instantiation. 
    399    *  
    400    * @param   string  $validator 
    401    * @param   array   $params 
    402    * @param   string  $requiredMessage 
    403    *  
    404    * @return  string 
    405    */ 
    406   protected function buildValidator($validator, $params, $requiredMessage = null) 
    407   { 
    408     list($options, $messages) = $params; 
    409      
    410     if ($requiredMessage) 
    411     { 
    412       $messages['required'] = $requiredMessage; 
    413     } 
    414      
    415     if (count($messages)) 
    416     { 
    417       return sprintf('new %s(%s, %s)', $validator, $this->varExport($options), $this->varExport($messages)); 
    418     } 
    419     elseif (count($options)) 
    420     { 
    421       return sprintf('new %s(%s)', $validator, $this->varExport($options)); 
    422     } 
    423     else 
    424     { 
    425       return sprintf('new %s', $validator); 
    426     } 
    427   } 
    428    
    429   /** 
    430    * Add labels. 
    431    */ 
    432   protected function addLabels() 
    433   { 
    434     $labels = array(); 
    435     foreach ($this->config['fields'] as $name => $config) 
    436     { 
    437       if (isset($config['label'])) 
    438       { 
    439         $labels[$name] = $config['label']; 
    440       } 
    441     } 
    442      
    443     if (count($labels)) 
    444     { 
    445       $this->data[] = '    $this->widgetSchema->setLabels(array('; 
    446       foreach ($labels as $name => $label) 
    447       { 
    448         $this->data[] = sprintf('      %s => %s,', $this->varExport($name), $this->varExport($label)); 
    449       } 
    450       $this->data[] = '    ));'; 
    451       $this->data[] = ''; 
    452     } 
    453   } 
    454    
    455   /** 
    456    * Add helps. 
    457    */ 
    458   protected function addHelps() 
    459   { 
    460     $helps = array(); 
    461     foreach ($this->config['fields'] as $name => $config) 
    462     { 
    463       if (isset($config['help'])) 
    464       { 
    465         $helps[$name] = $config['help']; 
    466       } 
    467     } 
    468      
    469     if (count($helps)) 
    470     { 
    471       $this->data[] = '    $this->widgetSchema->setHelps(array('; 
    472       foreach ($helps as $name => $help) 
    473       { 
    474         $this->data[] = sprintf('      %s => %s,', $this->varExport($name), $this->varExport($help)); 
    475       } 
    476       $this->data[] = '    ));'; 
    477       $this->data[] = ''; 
    478     } 
    479   } 
    480    
    481   /** 
    482    * Export and clean up. 
    483    *  
    484    * @param   mixed $var 
    485    *  
    486    * @return  string 
    487    */ 
    488   protected function varExport($var) 
    489   { 
    490     $export = var_export($var, true); 
    491      
    492     if (0 === strpos($export, 'array (')) 
    493     { 
    494       $export = preg_replace('/\s+/', ' ', $export); 
    495       $export = str_replace(array(' ( ', ', )'), array('(', ')'), $export); 
    496       if (false === strpos('\' => ', $export)) 
    497       { 
    498         $export = preg_replace('/\d+ => /', '', $export); 
    499       } 
    500     } 
    501      
    502     return $export; 
     21    return $generator->generate(); 
    50322  } 
    50423   
  • plugins/sfFormtasticPlugin/trunk/lib/form/sfFormtasticBase.class.php

    r10281 r10419  
    174174   
    175175  /** 
     176   * @see sfWidgetSchema::setNameFormat() 
     177   */ 
     178  public function setNameFormat($format) 
     179  { 
     180    $this->widgetSchema->setNameFormat($format); 
     181  } 
     182   
     183  /** 
     184   * @see sfWidgetSchema::setLabels() 
     185   */ 
     186  public function setLabels($labels) 
     187  { 
     188    $this->widgetSchema->setLabels($labels); 
     189  } 
     190   
     191  /** 
     192   * @see sfWidgetSchema::setHelps() 
     193   */ 
     194  public function setHelps($helps) 
     195  { 
     196    $this->widgetSchema->setHelps($helps); 
     197  } 
     198   
     199  /** 
     200   * @see sfValidatorSchema::setPreValidator() 
     201   */ 
     202  public function setPreValidator(sfValidatorBase $validator) 
     203  { 
     204    $this->validatorSchema->setPreValidator($validator); 
     205  } 
     206   
     207  /** 
     208   * @see sfValidatorSchema::setPostValidator() 
     209   */ 
     210  public function setPostValidator(sfValidatorBase $validator) 
     211  { 
     212    $this->validatorSchema->setPostValidator($validator); 
     213  } 
     214   
     215  /** 
    176216   * Make sure the CSRF field is there. 
    177217   */