Development

Changeset 6954

You must first sign up to be able to contribute.

Changeset 6954

Show
Ignore:
Timestamp:
01/05/08 22:19:15 (11 months ago)
Author:
fabien
Message:

Allow schema validator to throw named validation errors

  • sfValidatorCompare has a new throw_global_error option (false by default)
  • added some unit tests to sfValidatorSchemaForEach
  • errors from pre and post validators are merged into the current errors
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.1/lib/validator/sfValidatorErrorSchema.class.php

    r6196 r6954  
    4646   * Adds an error. 
    4747   * 
     48   * This method merges sfValidatorErrorSchema errors with the current instance. 
     49   * 
    4850   * @param sfValidatorError A sfValidatorError instance 
    4951   * @param string           The error name 
     
    5153  public function addError(sfValidatorError $error, $name = null) 
    5254  { 
    53     if (is_null($name)
     55    if (is_null($name) || is_integer($name)
    5456    { 
     57      if ($error instanceof sfValidatorErrorSchema) 
     58      { 
     59        throw new LogicException('Unable to merge a sfValidatorErrorSchema to global errors.'); 
     60      } 
     61 
    5562      $this->globalErrors[] = $error; 
    5663      $this->errors[] = $error; 
    5764    } 
    58     else if (is_integer($name)) 
    59     { 
    60       $this->namedErrors[$name] = $error; 
    61       $this->errors[$name] = $error; 
    62     } 
    6365    else 
    6466    { 
    65       $this->namedErrors[$name] = $error; 
    66       $this->errors[$name] = $error; 
     67      if (!isset($this->namedErrors[$name]) && !$error instanceof sfValidatorErrorSchema) 
     68      { 
     69        $this->namedErrors[$name] = $error; 
     70        $this->errors[$name] = $error; 
     71      } 
     72      else 
     73      { 
     74        if (!isset($this->namedErrors[$name])) 
     75        { 
     76          $this->namedErrors[$name] = new sfValidatorErrorSchema($error->getValidator()); 
     77          $this->errors[$name] = new sfValidatorErrorSchema($error->getValidator()); 
     78        } 
     79        else if (!$this->namedErrors[$name] instanceof sfValidatorErrorSchema) 
     80        { 
     81          $current = $this->namedErrors[$name]; 
     82          $this->namedErrors[$name] = new sfValidatorErrorSchema($current->getValidator()); 
     83          $this->errors[$name] = new sfValidatorErrorSchema($current->getValidator()); 
     84 
     85          $method = $current instanceof sfValidatorErrorSchema ? 'addErrors' : 'addError'; 
     86          $this->namedErrors[$name]->$method($current); 
     87          $this->errors[$name]->$method($current); 
     88        } 
     89 
     90        $method = $error instanceof sfValidatorErrorSchema ? 'addErrors' : 'addError'; 
     91        $this->namedErrors[$name]->$method($error); 
     92        $this->errors[$name]->$method($error); 
     93      } 
    6794    } 
    6895 
     
    249276  protected function updateCode() 
    250277  { 
    251     $this->code = implode(" ", array_merge( 
     278    $this->code = implode(' ', array_merge( 
    252279      array_map(create_function('$e', 'return $e->getCode();'), $this->globalErrors), 
    253280      array_map(create_function('$n,$e', 'return $n.\' [\'.$e->getCode().\']\';'), array_keys($this->namedErrors), array_values($this->namedErrors)) 
     
    260287  protected function updateMessage() 
    261288  { 
    262     $this->message = implode(" ", array_merge( 
     289    $this->message = implode(' ', array_merge( 
    263290      array_map(create_function('$e', 'return $e->getMessage();'), $this->globalErrors), 
    264291      array_map(create_function('$n,$e', 'return $n.\' [\'.$e->getMessage().\']\';'), array_keys($this->namedErrors), array_values($this->namedErrors)) 
  • branches/1.1/lib/validator/sfValidatorSchema.class.php

    r6951 r6954  
    107107    $clean  = array(); 
    108108    $unused = array_keys($this->fields); 
    109     $errors = array(); 
     109    $errorSchema = new sfValidatorErrorSchema($this); 
    110110 
    111111    // pre validator 
     
    114114      $this->preClean($values); 
    115115    } 
     116    catch (sfValidatorErrorSchema $e) 
     117    { 
     118      $errorSchema->addErrors($e); 
     119    } 
    116120    catch (sfValidatorError $e) 
    117121    { 
    118       $errors[] = $e
     122      $errorSchema->addError($e)
    119123    } 
    120124 
     
    127131        if (!$this->options['allow_extra_fields']) 
    128132        { 
    129           $errors[] = new sfValidatorError($this, 'extra_fields', array('field' => $name)); 
     133          $errorSchema->addError(new sfValidatorError($this, 'extra_fields', array('field' => $name))); 
    130134        } 
    131135        else if (!$this->options['filter_extra_fields']) 
     
    148152        $clean[$name] = null; 
    149153 
    150         $errors[$name] = $e
     154        $errorSchema->addError($e, (string) $name)
    151155      } 
    152156    } 
     
    162166      catch (sfValidatorError $e) 
    163167      { 
    164         $errors[$name] = $e
     168        $errorSchema->addError($e, (string) $name)
    165169      } 
    166170    } 
     
    171175      $clean = $this->postClean($clean); 
    172176    } 
     177    catch (sfValidatorErrorSchema $e) 
     178    { 
     179      $errorSchema->addErrors($e); 
     180    } 
    173181    catch (sfValidatorError $e) 
    174182    { 
    175       $errors[] = $e
    176     } 
    177  
    178     if (count($errors)) 
    179     { 
    180       throw new sfValidatorErrorSchema($this, $errors)
     183      $errorSchema->addError($e)
     184    } 
     185 
     186    if (count($errorSchema)) 
     187    { 
     188      throw $errorSchema
    181189    } 
    182190 
  • branches/1.1/lib/validator/sfValidatorSchemaCompare.class.php

    r6196 r6954  
    2929   * Constructor. 
    3030   * 
    31    * Available operator
     31   * Available options
    3232   * 
    33    *  * self::EQUAL 
    34    *  * self::NOT_EQUAL 
    35    *  * self::LESS_THAN 
    36    *  * self::LESS_THAN_EQUAL 
    37    *  * self::GREATER_THAN 
    38    *  * self::GREATER_THAN_EQUAL 
     33   *  * left_field:         The left field name 
     34   *  * operator:           The comparison operator 
     35   *                          * self::EQUAL 
     36   *                          * self::NOT_EQUAL 
     37   *                          * self::LESS_THAN 
     38   *                          * self::LESS_THAN_EQUAL 
     39   *                          * self::GREATER_THAN 
     40   *                          * self::GREATER_THAN_EQUAL 
     41   *  * right_field:        The right field name 
     42   *  * throw_global_error: Whether to throw a global error (false by default) or an error tied to the left field 
    3943   * 
    4044   * @param string The left field name 
     
    5155    $this->addOption('operator', $operator); 
    5256    $this->addOption('right_field', $rightField); 
     57 
     58    $this->addOption('throw_global_error', false); 
    5359 
    5460    parent::__construct(null, $options, $messages); 
     
    97103    if (!$valid) 
    98104    { 
    99       throw new sfValidatorError($this, 'invalid', array( 
     105      $error = new sfValidatorError($this, 'invalid', array( 
    100106        'left_field'  => $leftValue, 
    101107        'right_field' => $rightValue, 
    102108        'operator'    => $this->getOption('operator'), 
    103109      )); 
     110      if ($this->getOption('throw_global_error')) 
     111      { 
     112        throw $error; 
     113      } 
     114 
     115      throw new sfValidatorErrorSchema($this, array($this->getOption('left_field') => $error)); 
    104116    } 
    105117 
  • branches/1.1/test/unit/validator/sfValidatorErrorSchemaTest.php

    r6197 r6954  
    1111require_once(dirname(__FILE__).'/../../bootstrap/unit.php'); 
    1212 
    13 $t = new lime_test(19, new lime_output_color()); 
     13$t = new lime_test(24, new lime_output_color()); 
    1414 
    1515$v1 = new sfValidatorString(); 
     
    3232$e->addError($e1); 
    3333$e->addError($e2, 'e2'); 
    34 $e->addError($e1, 2); 
    35 $t->is($e->getErrors(), array($e1, 'e2' => $e2, 2 => $e1), '->addError() adds an error to the error schema'); 
     34$e->addError($e1, '2'); 
     35$t->is($e->getErrors(), array($e1, 'e2' => $e2, '2' => $e1), '->addError() adds an error to the error schema'); 
     36 
     37$t->diag('embedded errors'); 
     38$es1 = new sfValidatorErrorSchema($v1, array($e1, 'e1' => $e1, 'e2' => $e2)); 
     39$es = new sfValidatorErrorSchema($v1, array($e1, 'e1' => $e1, 'e2' => $es1)); 
     40$es->addError($e2, 'e1'); 
     41$t->is($es->getCode(), 'max_length e1 [max_length min_length] e2 [max_length e1 [max_length] e2 [min_length]]', '->addError() adds an error to the error schema'); 
     42$es->addError($e2); 
     43$t->is($es->getCode(), 'max_length min_length e1 [max_length min_length] e2 [max_length e1 [max_length] e2 [min_length]]', '->addError() adds an error to the error schema'); 
     44$es->addError($es1, 'e3'); 
     45$t->is($es->getCode(), 'max_length min_length e1 [max_length min_length] e2 [max_length e1 [max_length] e2 [min_length]] e3 [max_length e1 [max_length] e2 [min_length]]', '->addError() adds an error to the error schema'); 
     46try 
     47
     48  $es->addError($es1); 
     49  $t->fail('->addError() throws a LogicException if you try to add a global sfValidatorErrorSchema'); 
     50
     51catch (LogicException $e) 
     52
     53  $t->pass('->addError() throws a LogicException if you try to add a global sfValidatorErrorSchema'); 
     54
     55 
     56$es = new sfValidatorErrorSchema($v1, array($e1, 'e1' => $e1, 'e2' => $es1)); 
     57$es2 = new sfValidatorErrorSchema($v1, array($e1, 'e1' => $e1, 'e2' => $es1)); 
     58$es->addError($es2, 'e2'); 
     59$t->is($es->getCode(), 'max_length e1 [max_length] e2 [max_length max_length e1 [max_length max_length] e2 [min_length max_length e1 [max_length] e2 [min_length]]]', '->addError() adds an error to the error schema'); 
    3660 
    3761// ->getGlobalErrors() 
    3862$t->diag('->getGlobalErrors()'); 
     63$e = new sfValidatorErrorSchema($v1); 
     64$e->addError($e1); 
     65$e->addError($e2, 'e2'); 
     66$e->addError($e1, '2'); 
    3967$t->is($e->getGlobalErrors(), array($e1), '->getGlobalErrors() returns all globals/non named errors'); 
    4068 
    4169// ->getNamedErrors() 
    4270$t->diag('->getNamedErrors()'); 
    43 $t->is($e->getNamedErrors(), array('e2' => $e2, 2 => $e1), '->getNamedErrors() returns all named errors'); 
     71$t->is($e->getNamedErrors(), array('e2' => $e2, '2' => $e1), '->getNamedErrors() returns all named errors'); 
    4472 
    4573// ->getValue() 
     
    7199// implements Iterator 
    72100$t->diag('implements Iterator'); 
    73 $e = new sfValidatorErrorSchema($v1, array('e1' => $e1, 2 => $e2, $e2)); 
     101$e = new sfValidatorErrorSchema($v1, array('e1' => $e1, $e2)); 
     102$e->addError($e2, '2'); 
    74103$errors = array(); 
    75104foreach ($e as $name => $error) 
     
    77106  $errors[$name] = $error; 
    78107} 
    79 $t->is($errors, array('e1' => $e1, 2 => $e2, $e2), 'sfValidatorErrorSchema implements the Iterator interface'); 
     108$t->is($errors, array('e1' => $e1, 0 => $e2, '2' => $e2), 'sfValidatorErrorSchema implements the Iterator interface'); 
    80109 
    81110// implements ArrayAccess 
    82111$t->diag('implements ArrayAccess'); 
    83 $e = new sfValidatorErrorSchema($v1, array('e1' => $e1, $e2, 2 => $e2)); 
     112$e = new sfValidatorErrorSchema($v1, array('e1' => $e1, $e2)); 
     113$e->addError($e2, '2'); 
    84114$t->is($e['e1'], $e1, 'sfValidatorErrorSchema implements the ArrayAccess interface'); 
    85115$t->is($e[0], $e2, 'sfValidatorErrorSchema implements the ArrayAccess interface'); 
    86 $t->is($e[2], $e2, 'sfValidatorErrorSchema implements the ArrayAccess interface'); 
     116$t->is($e['2'], $e2, 'sfValidatorErrorSchema implements the ArrayAccess interface'); 
    87117$t->is(isset($e['e1']), true, 'sfValidatorErrorSchema implements the ArrayAccess interface'); 
    88118$t->is(isset($e['e2']), false, 'sfValidatorErrorSchema implements the ArrayAccess interface'); 
  • branches/1.1/test/unit/validator/sfValidatorSchemaCompareTest.php

    r6945 r6954  
    1111require_once(dirname(__FILE__).'/../../bootstrap/unit.php'); 
    1212 
    13 $t = new lime_test(27, new lime_output_color()); 
     13$t = new lime_test(43, new lime_output_color()); 
    1414 
    1515$v = new sfValidatorSchemaCompare('left', sfValidatorSchemaCompare::EQUAL, 'right'); 
     
    4545  $v->setOption('operator', $values[1]); 
    4646 
    47   try 
     47  foreach (array(true, false) as $globalError) 
    4848  { 
    49     $v->clean($values[0]); 
    50     $t->fail('->clean() throws an sfValidatorError if the value is the comparison failed'); 
    51     $t->skip('', 1); 
    52   } 
    53   catch (sfValidatorError $e) 
    54   { 
    55     $t->pass('->clean() throws an sfValidatorError if the value is the comparison failed'); 
    56     $t->is($e->getCode(), 'invalid', '->clean() throws a sfValidatorError'); 
     49    $v->setOption('throw_global_error', $globalError); 
     50    try 
     51    { 
     52      $v->clean($values[0]); 
     53      $t->fail('->clean() throws an sfValidatorError if the value is the comparison failed'); 
     54      $t->skip('', 1); 
     55    } 
     56    catch (sfValidatorError $e) 
     57    { 
     58      $t->pass('->clean() throws an sfValidatorError if the value is the comparison failed'); 
     59      $t->is($e->getCode(), $globalError ? 'invalid' : 'left [invalid]', '->clean() throws a sfValidatorError'); 
     60    } 
    5761  } 
    5862} 
  • branches/1.1/test/unit/validator/sfValidatorSchemaForEachTest.php

    r5581 r6954  
    1111require_once(dirname(__FILE__).'/../../bootstrap/unit.php'); 
    1212 
    13 $t = new lime_test(2, new lime_output_color()); 
     13$t = new lime_test(5, new lime_output_color()); 
    1414 
    15 $v1 = new sfValidatorString(array('max_length' => 3)); 
     15$v1 = new sfValidatorString(array('min_length' => 3)); 
    1616 
    1717// __construct() 
     
    2020$t->is($v->getFields(), array($v1, $v1, $v1), '->__construct() takes a sfValidator object as its first argument'); 
    2121 
    22 $v = new sfValidatorSchemaForEach($v1, 5); 
    23 $t->is($v->getFields(), array($v1, $v1, $v1, $v1, $v1), '->__construct() takes a number of times to duplicate the validator'); 
     22$v = new sfValidatorSchemaForEach($v1, 6); 
     23$t->is($v->getFields(), array($v1, $v1, $v1, $v1, $v1, $v1), '->__construct() takes a number of times to duplicate the validator'); 
     24 
     25// ->clean() 
     26$t->diag('->clean()'); 
     27try 
     28
     29  $v->clean(array('f', 'a', 'b', 'i', 'e', 'n')); 
     30  $t->fail('->clean() throws an sfValidatorError'); 
     31  $t->skip('', 2); 
     32
     33catch (sfValidatorError $e) 
     34
     35  $t->pass('->clean() throws an sfValidatorError'); 
     36  $t->is(count($e->getGlobalErrors()), 0, '->clean() does not throw global errors'); 
     37  $t->is(count($e->getNamedErrors()), 6, '->clean() throws named errors'); 
     38
  • branches/1.1/test/unit/validator/sfValidatorSchemaTest.php

    r6942 r6954  
    1111require_once(dirname(__FILE__).'/../../bootstrap/unit.php'); 
    1212 
    13 $t = new lime_test(46, new lime_output_color()); 
     13$t = new lime_test(60, new lime_output_color()); 
    1414 
    1515class PreValidator extends sfValidator 
     
    251251  $t->is($e['s1']->getCode(), 'max_length', '->clean() throws an exception with all error messages'); 
    252252} 
     253 
     254$t->diag('postValidator can throw named errors or global errors'); 
     255$comparator = new sfValidatorSchemaCompare('left', sfValidatorSchemaCompare::EQUAL, 'right'); 
     256$userValidator = new sfValidatorSchema(array( 
     257  'test'  => new sfValidatorString(array('min_length' => 10)), 
     258  'left'  => new sfValidatorString(array('min_length' => 2)), 
     259  'right' => new sfValidatorString(array('min_length' => 2)), 
     260)); 
     261$userValidator->setPostValidator($comparator); 
     262$v = new sfValidatorSchema(array( 
     263  'test'     => new sfValidatorString(array('min_length' => 10)), 
     264  'left'     => new sfValidatorString(array('min_length' => 2)), 
     265  'right'    => new sfValidatorString(array('min_length' => 2)), 
     266  'embedded' => $userValidator, 
     267)); 
     268$v->setPostValidator($comparator); 
     269 
     270$t->diag('postValidator throws global errors'); 
     271$comparator->setOption('throw_global_error', true); 
     272try 
     273{ 
     274  $v->clean(array('test' => 'fabien', 'right' => 'bar', 'embedded' => array('test' => 'fabien', 'left' => 'oof', 'right' => 'rab'))); 
     275  $t->skip('', 7); 
     276} 
     277catch (sfValidatorErrorSchema $e) 
     278{ 
     279  $t->is(count($e->getNamedErrors()), 3, '->clean() throws an exception with all error messages'); 
     280  $t->is(count($e->getGlobalErrors()), 1, '->clean() throws an exception with all error messages'); 
     281  $t->is(count($e['embedded']->getNamedErrors()), 1, '->clean() throws an exception with all error messages'); 
     282  $t->is(count($e['embedded']->getGlobalErrors()), 1, '->clean() throws an exception with all error messages'); 
     283  $t->is(isset($e['left']) ? $e['left']->getCode() : '', 'required', '->clean() throws an exception with all error messages'); 
     284  $t->is(isset($e['embedded']['left']) ? $e['embedded']['left']->getCode() : '', '', '->clean() throws an exception with all error messages'); 
     285  $t->is($e->getCode(), 'invalid test [min_length] embedded [invalid test [min_length]] left [required]', '->clean() throws an exception with all error messages'); 
     286} 
     287 
     288$t->diag('postValidator throws named errors'); 
     289$comparator->setOption('throw_global_error', false); 
     290try 
     291{ 
     292  $v->clean(array('test' => 'fabien', 'right' => 'bar', 'embedded' => array('test' => 'fabien', 'left' => 'oof', 'right' => 'rab'))); 
     293  $t->skip('', 7); 
     294} 
     295catch (sfValidatorErrorSchema $e) 
     296{ 
     297  $t->is(count($e->getNamedErrors()), 3, '->clean() throws an exception with all error messages'); 
     298  $t->is(count($e->getGlobalErrors()), 0, '->clean() throws an exception with all error messages'); 
     299  $t->is(count($e['embedded']->getNamedErrors()), 2, '->clean() throws an exception with all error messages'); 
     300  $t->is(count($e['embedded']->getGlobalErrors()), 0, '->clean() throws an exception with all error messages'); 
     301  $t->is(isset($e['left']) ? $e['left']->getCode() : '', 'required invalid', '->clean() throws an exception with all error messages'); 
     302  $t->is(isset($e['embedded']['left']) ? $e['embedded']['left']->getCode() : '', 'invalid', '->clean() throws an exception with all error messages'); 
     303  $t->is($e->getCode(), 'test [min_length] embedded [test [min_length] left [invalid]] left [required invalid]', '->clean() throws an exception with all error messages'); 
     304}