Changeset 3045

Show
Ignore:
Timestamp:
10/16/08 18:06:59 (3 months ago)
Author:
felix
Message:

Merged revisions 3041-3044 via svnmerge from
http://svn.agavi.org/branches/1.0

........

r3041 | david | 2008-10-16 19:50:17 +0200 (Thu, 16 Oct 2008) | 1 line


Ported AgaviValidatorConfigHandler? to XML config system, refs #519

........

r3042 | david | 2008-10-16 19:57:33 +0200 (Thu, 16 Oct 2008) | 1 line


Changelog update, closes #785

........

r3043 | david | 2008-10-16 19:59:20 +0200 (Thu, 16 Oct 2008) | 1 line


Another changelog entry, closes #786

........

r3044 | david | 2008-10-16 20:02:16 +0200 (Thu, 16 Oct 2008) | 1 line


release notes, refs #785

........

Location:
branches/felix-testing-implementation
Files:
7 modified
3 copied

Legend:

Unmodified
Added
Removed
  • branches/felix-testing-implementation

    • Property svnmerge-integrated changed from /branches/1.0:1-2892,2894-2984,2987-2988,2990-3011,3013-3039 to /branches/1.0:1-2892,2894-2984,2987-2988,2990-3011,3013-3044
  • branches/felix-testing-implementation/CHANGELOG

    r3035 r3045  
    55------------------------------- 
    66 
     7CHG: Change Form Population Filter to use validation system's ability to more accurately handle different sources of input (#786) (David) 
     8CHG: Validation system needs to be able to tell two fields of same names, but from different sources, apart (#785) (Dominik) 
    79CHG: Change singular/plural handling in AgaviXmlConfigDomElement convenience methods (#878) (David) 
    810 
  • branches/felix-testing-implementation/RELEASE_NOTES

    r3035 r3045  
    7171Validation 
    7272---------- 
     73A new API for accessing information about the result of a validation run is available through AgaviValidationManager::getReport(). It is more consistent and capable of the previous APIs which have been deprecated. This change also fixes some problems where the validation system could not reliably tell input from different sources apart. 
     74 
    7375Validators are not handed a "method" parameter anymore with the request method they should run for. This was extremely redundant since the validators weren't even registered if the request method was "wrong". For manual registering, registerReadValidators(), registerWriteValidators() etc are always used in actions anyway, so no problem here, either. As a result, AgaviValidator::validatesInMethod() is gone, too. 
    7476 
  • branches/felix-testing-implementation/src/config/AgaviValidatorConfigHandler.class.php

    r2933 r3045  
    3030 * @version    $Id$ 
    3131 */ 
    32 class AgaviValidatorConfigHandler extends AgaviConfigHandler 
     32class AgaviValidatorConfigHandler extends AgaviXmlConfigHandler 
    3333{ 
     34  const XML_NAMESPACE = 'http://agavi.org/agavi/config/parts/validators/1.0'; 
     35   
    3436  /** 
    3537   * @var        array operator => validator mapping 
     
    5557   * @since      0.11.0 
    5658   */ 
    57   public function execute($config, $context = null) 
     59  public function execute(AgaviXmlConfigDomDocument $document) 
    5860  { 
    59     $this->classMap = array( 
    60       'and' => array('class' => 'AgaviAndoperatorValidator', 'parameters' => array('break' => '1')), 
    61       'datetime' => array('class' => 'AgaviDateTimeValidator', 'parameters' => array('check' => '1')), 
    62       'email' => array('class' => 'AgaviEmailValidator', 'parameters' => array()), 
    63       'equals' => array('class' => 'AgaviEqualsValidator', 'parameters' => array()), 
    64       'file' => array('class' => 'AgaviFileValidator', 'parameters' => array()), 
    65       'imagefile' => array('class' => 'AgaviImageFileValidator', 'parameters' => array()), 
    66       'inarray' => array('class' => 'AgaviInarrayValidator', 'parameters' => array('sep' => ',')), 
    67       'isset' => array('class' => 'AgaviIssetValidator', 'parameters' => array()), 
    68       'isnotempty' => array('class' => 'AgaviIsNotEmptyValidator', 'parameters' => array()), 
    69       'not' => array('class' => 'AgaviNotoperatorValidator', 'parameters' => array()), 
    70       'number' => array('class' => 'AgaviNumberValidator', 'parameters' => array('type' => 'int')), 
    71       'or' => array('class' => 'AgaviOroperatorValidator', 'parameters' => array('break' => '1')), 
    72       'regex' => array('class' => 'AgaviRegexValidator', 'parameters' => array('match' => '1')), 
    73       'set' => array('class' => 'AgaviSetValidator', 'parameters' => array()), 
    74       'string' => array('class' => 'AgaviStringValidator', 'parameters' => array('min' => '1')), 
    75       'xor' => array('class' => 'AgaviXoroperatorValidator', 'parameters' => array()), 
    76     ); 
    77  
    78     // parse the config file 
    79     $configurations = $this->orderConfigurations(AgaviConfigCache::parseConfig($config, true, $this->getValidationFile(), $this->parser)->configurations, AgaviConfig::get('core.environment'), $context); 
    80  
     61    $document->setDefaultNamespace(self::XML_NAMESPACE, 'validators'); 
     62     
     63    $config = $document->documentURI; 
     64     
     65    $classMap = array(); 
    8166    $code = array();//array('lines' => array(), 'order' => array()); 
    82  
    83     foreach($configurations as $cfg) { 
    84       if(isset($cfg->validator_definitions)) { 
    85         foreach($cfg->validator_definitions as $vDev) { 
    86           $name = $vDev->getAttribute('name'); 
     67     
     68    foreach($document->getConfigurationElements() as $cfg) { 
     69      if($cfg->has('validator_definitions')) { 
     70        foreach($cfg->get('validator_definitions') as $def) { 
     71          $name = $def->getAttribute('name'); 
    8772          if(!isset($this->classMap[$name])) { 
    88             $this->classMap[$name] = array('class' => $vDev->getAttribute('class'), 'parameters' => array()); 
     73            $this->classMap[$name] = array('class' => $def->getAttribute('class'), 'parameters' => array()); 
    8974          } 
    90           $this->classMap[$name]['class'] = $vDev->getAttribute('class',$this->classMap[$name]['class']); 
    91           $this->classMap[$name]['parameters'] = $this->getItemParameters($vDev, $this->classMap[$name]['parameters']); 
     75          $this->classMap[$name]['class'] = $def->getAttribute('class',$this->classMap[$name]['class']); 
     76          $this->classMap[$name]['parameters'] = $def->getAgaviParameters($this->classMap[$name]['parameters']); 
    9277        } 
    9378      } 
    94  
    95       if(isset($cfg->validators)) { 
    96         $hasValidators = false; 
    97         foreach($cfg->getChildren() as $validators) { 
    98           if($validators->getName() == 'validators') { 
    99             $hasValidators = true; 
    100             $stdSeverity = $validators->getAttribute('severity', 'error'); 
    101             $stdMethod = $validators->getAttribute('method'); 
    102             foreach($validators as $validator) { 
    103               $code = $this->getValidatorArray($validator, $code, $stdSeverity, 'validationManager', $stdMethod); 
    104             } 
    105           } 
    106         } 
    107         if(!$hasValidators) { 
    108           foreach($cfg->validators as $validator) { 
    109             $code = $this->getValidatorArray($validator, $code, 'error', 'validationManager', null); 
    110           } 
    111         } 
    112       } 
     79       
     80      $code = $this->processValidatorElements($cfg, $code, 'validationManager'); 
    11381    } 
    11482 
     
    133101   * Builds an array of php code strings, each of them creating a validator 
    134102   * 
    135    * @param      AgaviConfigValueHolder The value holder of this validator. 
    136    * @param      array  The code of old validators (we simply overwrite "old"  
    137    *                    validators here). 
    138    * @param      string The severity of the parent container. 
    139    * @param      string The name of the parent container. 
    140    * @param      string The method of the parent container. 
    141    * @param      bool Whether the parent container is required. 
    142    * 
    143    * @return     array php code blocks that register the validators 
     103   * @param      AgaviXmlConfigDomElement The value holder of this validator. 
     104   * @param      array                    The code of old validators (we simply 
     105   *                                      overwrite "old" validators here). 
     106   * @param      string                   The name of the parent container. 
     107   * @param      string                   The severity of the parent container. 
     108   * @param      string                   The method of the parent container. 
     109   * @param      bool                     Whether parent container is required. 
     110   * 
     111   * @return     array PHP code blocks that register the validators 
    144112   * 
    145113   * @author     Uwe Mesecke <uwe@mesecke.net> 
    146114   * @author     Dominik del Bondio <ddb@bitxtender.com> 
     115   * @author     David Zülke <david.zuelke@bitextender.com> 
    147116   * @since      0.11.0 
    148117   */ 
    149   public function getValidatorArray($validator, $code, $stdSeverity, $parent, $stdMethod, $stdRequired = true) 
     118  protected function getValidatorArray($validator, $code, $parent, $stdSeverity, $stdMethod, $stdRequired = true) 
    150119  { 
    151120    if(!isset($this->classMap[$validator->getAttribute('class')])) { 
     
    179148    $parameters = array_merge($this->classMap[$validator->getAttribute('class')]['parameters'], $parameters); 
    180149    $parameters = array_merge($parameters, $validator->getAttributes()); 
    181     $parameters = $this->getItemParameters($validator, $parameters); 
    182     if(isset($validator->arguments)) { 
    183       if($validator->arguments->hasAttribute('base')) { 
    184         $parameters['base'] = $validator->arguments->getAttribute('base'); 
    185       } 
    186       $args = array(); 
    187       foreach($validator->arguments as $argument) { 
    188         if($argument->hasAttribute('name')) { 
    189           $args[$argument->getAttribute('name')] = $argument->getValue(); 
    190         } else { 
    191           $args[] = $argument->getValue(); 
     150    $parameters = $validator->getAgaviParameters($parameters); 
     151     
     152    foreach($validator->get('arguments') as $argument) { 
     153      // let's see if this buddy has a <arguments> parent with valuable information 
     154      if($argument->parentNode->localName == 'arguments') { 
     155        if($argument->parentNode->hasAttribute('base')) { 
     156          $parameters['base'] = $argument->parentNode->getAttribute('base'); 
    192157        } 
    193158      } 
    194       $arguments = $args; 
    195     } 
    196     if(isset($validator->errors)) { 
    197       foreach($validator->errors as $error) { 
    198         if($error->hasAttribute('for')) { 
    199           $errors[$error->getAttribute('for')] = $error->getValue(); 
    200         } else { 
    201           $errors[''] = $error->getValue(); 
    202         } 
    203       } 
    204     } 
     159       
     160      if($argument->hasAttribute('name')) { 
     161        $arguments[$argument->getAttribute('name')] = $argument->getValue(); 
     162      } else { 
     163        $arguments[] = $argument->getValue(); 
     164      } 
     165    } 
     166     
     167    foreach($validator->get('errors') as $error) { 
     168      if($error->hasAttribute('for')) { 
     169        $errors[$error->getAttribute('for')] = $error->getValue(); 
     170      } else { 
     171        $errors[''] = $error->getValue(); 
     172      } 
     173    } 
     174     
    205175    if($validator->hasAttribute('required')) { 
    206176      $stdRequired = $parameters['required'] = AgaviToolkit::literalize($validator->getAttribute('required')); 
     
    233203      )); 
    234204    } 
    235  
    236     if(isset($validator->validators)) { 
    237       $childSeverity = $validator->validators->getAttribute('severity', $stdSeverity); 
    238       $childMethod = $validator->validators->getAttribute('method', $stdMethod); 
    239       $childRequired = $stdRequired; 
    240       if($validator->validators->hasAttribute('required')) { 
    241         $childRequired = AgaviToolkit::literalize($validator->validators->getAttribute('required')); 
    242       } 
    243       foreach($validator->validators as $v) { 
    244         $code = $this->getValidatorArray($v, $code, $childSeverity, $name, $childMethod, $childRequired); 
    245       } 
    246         // create child validators 
    247     } 
    248  
     205     
     206    // more <validator> or <validators> children 
     207    $code = $this->processValidatorElements($validator, $code, $name, $stdSeverity, $stdMethod, $stdRequired); 
     208     
     209    return $code; 
     210  } 
     211   
     212  /** 
     213   * Grabs generated code from the given element. 
     214   * 
     215   * @see        AgaviValidatorConfigHandler::getValidatorArray() 
     216   * 
     217   * @param      AgaviXmlConfigDomElement The value holder of this validator. 
     218   * @param      array                    The code of old validators (we simply 
     219   *                                      overwrite "old" validators here). 
     220   * @param      string                   The severity of the parent container. 
     221   * @param      string                   The name of the parent container. 
     222   * @param      string                   The method of the parent container. 
     223   * @param      bool                     Whether parent container is required. 
     224   * 
     225   * @return     array PHP code blocks that register the validators 
     226   * 
     227   * @author     Uwe Mesecke <uwe@mesecke.net> 
     228   * @author     Dominik del Bondio <ddb@bitxtender.com> 
     229   * @author     David Zülke <david.zuelke@bitextender.com> 
     230   * @since      0.11.0 
     231   */ 
     232  protected function processValidatorElements($node, $code, $name, $defaultSeverity = 'error', $defaultMethod = null, $defaultRequired = true) 
     233  { 
     234    // the problem here is that the <validators> parent is not just optional, but can also occur more than once 
     235    foreach($node->get('validators') as $validator) { 
     236      // let's see if this buddy has a <validators> parent with valuable information 
     237      if($validator->parentNode->localName == 'validators') { 
     238        $severity = $validator->parentNode->getAttribute('severity', $defaultSeverity); 
     239        $method = $validator->parentNode->getAttribute('method', $defaultMethod); 
     240        $required = $defaultRequired; 
     241      } 
     242       
     243      // append the code to generate 
     244      $code = $this->getValidatorArray($validator, $code, $name, $severity, $method, $required); 
     245    } 
     246     
    249247    return $code; 
    250248  } 
  • branches/felix-testing-implementation/src/config/defaults/config_handlers.xml

    r2812 r3045  
    109109 
    110110      <handler pattern="%core.module_dir%/*/validate/*.xml" class="AgaviValidatorConfigHandler"> 
    111         <validation>%core.agavi_dir%/config/xsd/validators.xsd</validation> 
     111        <validation>%core.agavi_dir%/config/rng/validators.rng</validation> 
     112        <transformation>%core.agavi_dir%/config/xsl/validators.xsl</transformation> 
    112113      </handler> 
    113114 
  • branches/felix-testing-implementation/src/config/rng/_common.rng

    r2827 r3045  
    120120  </define> 
    121121   
     122  <define name="data-nestring"> 
     123    <data type="string"> 
     124      <param name="minLength">1</param> 
     125    </data> 
     126  </define> 
     127   
    122128  <define name="data-identifier"> 
    123129    <data type="string"> 
  • branches/felix-testing-implementation/src/config/xsl/_common.xsl

    r2965 r3045  
    33  version="1.0" 
    44  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     5  xmlns:exslt-common="http://exslt.org/common" 
     6  xmlns:saxon="http://icl.com/saxon" 
    57  xmlns:envelope_0_11="http://agavi.org/agavi/1.0/config" 
    68  xmlns:envelope_1_0="http://agavi.org/agavi/config/global/envelope/1.0"> 
     
    1214  <xsl:template name="_common-migrate-envelope-element"> 
    1315    <!-- param for the target namespace; defaults to 1.0 --> 
    14     <xsl:param name="namespace"><xsl:value-of select="$envelope_1_0" /></xsl:param> 
     16    <xsl:param name="namespace" select="$envelope_1_0" /> 
     17    <!-- attributes to insert, defaults to empty node set --> 
     18    <xsl:param name="attributes" select="self::node()[false()]" /> 
    1519     
    1620    <xsl:call-template name="_common-migrate-element"> 
    17       <xsl:with-param name="namespace"><xsl:value-of select="$namespace" /></xsl:with-param> 
     21      <xsl:with-param name="namespace" select="$namespace" /> 
     22      <xsl:with-param name="attributes" select="$attributes" /> 
    1823    </xsl:call-template> 
    1924  </xsl:template> 
     
    2227    <!-- param for the target namespace; no default --> 
    2328    <xsl:param name="namespace" /> 
     29    <!-- attributes to insert, defaults to empty node set --> 
     30    <xsl:param name="attributes" select="self::node()[false()]" /> 
    2431     
    2532    <!-- create an element of the same name --> 
    2633    <xsl:element name="{local-name()}" namespace="{$namespace}"> 
    27       <xsl:copy-of select="@*" /> 
    2834      <!-- also copy all namespace declarations, except the one of the current element (otherwise, we'd overwrite the namespace in the <element> above if it's just xmlns etc) --> 
    2935      <xsl:copy-of select="namespace::*[not(. = namespace-uri(current()))]" /> 
     36      <xsl:copy-of select="@*" /> 
     37      <xsl:copy-of select="exslt-common:node-set($attributes)//@*" /> 
    3038      <xsl:apply-templates /> 
    3139    </xsl:element>