Changeset 3045
- Timestamp:
- 10/16/08 18:06:59 (3 months ago)
- Location:
- branches/felix-testing-implementation
- Files:
-
- 7 modified
- 3 copied
-
. (modified) (1 prop)
-
CHANGELOG (modified) (1 diff)
-
RELEASE_NOTES (modified) (1 diff)
-
src/config/AgaviValidatorConfigHandler.class.php (modified) (5 diffs)
-
src/config/defaults/config_handlers.xml (modified) (1 diff)
-
src/config/defaults/validators.xml (copied) (copied from branches/1.0/src/config/defaults/validators.xml)
-
src/config/rng/_common.rng (modified) (1 diff)
-
src/config/rng/validators.rng (copied) (copied from branches/1.0/src/config/rng/validators.rng)
-
src/config/xsl/_common.xsl (modified) (3 diffs)
-
src/config/xsl/validators.xsl (copied) (copied from branches/1.0/src/config/xsl/validators.xsl)
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 5 5 ------------------------------- 6 6 7 CHG: Change Form Population Filter to use validation system's ability to more accurately handle different sources of input (#786) (David) 8 CHG: Validation system needs to be able to tell two fields of same names, but from different sources, apart (#785) (Dominik) 7 9 CHG: Change singular/plural handling in AgaviXmlConfigDomElement convenience methods (#878) (David) 8 10 -
branches/felix-testing-implementation/RELEASE_NOTES
r3035 r3045 71 71 Validation 72 72 ---------- 73 A 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 73 75 Validators 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. 74 76 -
branches/felix-testing-implementation/src/config/AgaviValidatorConfigHandler.class.php
r2933 r3045 30 30 * @version $Id$ 31 31 */ 32 class AgaviValidatorConfigHandler extends Agavi ConfigHandler32 class AgaviValidatorConfigHandler extends AgaviXmlConfigHandler 33 33 { 34 const XML_NAMESPACE = 'http://agavi.org/agavi/config/parts/validators/1.0'; 35 34 36 /** 35 37 * @var array operator => validator mapping … … 55 57 * @since 0.11.0 56 58 */ 57 public function execute( $config, $context = null)59 public function execute(AgaviXmlConfigDomDocument $document) 58 60 { 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(); 81 66 $code = array();//array('lines' => array(), 'order' => array()); 82 83 foreach($ configurationsas $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'); 87 72 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()); 89 74 } 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']); 92 77 } 93 78 } 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'); 113 81 } 114 82 … … 133 101 * Builds an array of php code strings, each of them creating a validator 134 102 * 135 * @param Agavi ConfigValueHolderThe value holder of this validator.136 * @param array The code of old validators (we simply overwrite "old"137 * validators here).138 * @param string The severityof the parent container.139 * @param string The nameof the parent container.140 * @param string The method of the parent container.141 * @param bool Whether theparent container is required.142 * 143 * @return array phpcode blocks that register the validators103 * @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 144 112 * 145 113 * @author Uwe Mesecke <uwe@mesecke.net> 146 114 * @author Dominik del Bondio <ddb@bitxtender.com> 115 * @author David Zülke <david.zuelke@bitextender.com> 147 116 * @since 0.11.0 148 117 */ 149 p ublic function getValidatorArray($validator, $code, $stdSeverity, $parent, $stdMethod, $stdRequired = true)118 protected function getValidatorArray($validator, $code, $parent, $stdSeverity, $stdMethod, $stdRequired = true) 150 119 { 151 120 if(!isset($this->classMap[$validator->getAttribute('class')])) { … … 179 148 $parameters = array_merge($this->classMap[$validator->getAttribute('class')]['parameters'], $parameters); 180 149 $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'); 192 157 } 193 158 } 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 205 175 if($validator->hasAttribute('required')) { 206 176 $stdRequired = $parameters['required'] = AgaviToolkit::literalize($validator->getAttribute('required')); … … 233 203 )); 234 204 } 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 249 247 return $code; 250 248 } -
branches/felix-testing-implementation/src/config/defaults/config_handlers.xml
r2812 r3045 109 109 110 110 <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> 112 113 </handler> 113 114 -
branches/felix-testing-implementation/src/config/rng/_common.rng
r2827 r3045 120 120 </define> 121 121 122 <define name="data-nestring"> 123 <data type="string"> 124 <param name="minLength">1</param> 125 </data> 126 </define> 127 122 128 <define name="data-identifier"> 123 129 <data type="string"> -
branches/felix-testing-implementation/src/config/xsl/_common.xsl
r2965 r3045 3 3 version="1.0" 4 4 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 5 xmlns:exslt-common="http://exslt.org/common" 6 xmlns:saxon="http://icl.com/saxon" 5 7 xmlns:envelope_0_11="http://agavi.org/agavi/1.0/config" 6 8 xmlns:envelope_1_0="http://agavi.org/agavi/config/global/envelope/1.0"> … … 12 14 <xsl:template name="_common-migrate-envelope-element"> 13 15 <!-- 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()]" /> 15 19 16 20 <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" /> 18 23 </xsl:call-template> 19 24 </xsl:template> … … 22 27 <!-- param for the target namespace; no default --> 23 28 <xsl:param name="namespace" /> 29 <!-- attributes to insert, defaults to empty node set --> 30 <xsl:param name="attributes" select="self::node()[false()]" /> 24 31 25 32 <!-- create an element of the same name --> 26 33 <xsl:element name="{local-name()}" namespace="{$namespace}"> 27 <xsl:copy-of select="@*" />28 34 <!-- 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) --> 29 35 <xsl:copy-of select="namespace::*[not(. = namespace-uri(current()))]" /> 36 <xsl:copy-of select="@*" /> 37 <xsl:copy-of select="exslt-common:node-set($attributes)//@*" /> 30 38 <xsl:apply-templates /> 31 39 </xsl:element>

