1<?php 2/** 3 * Zend Framework (http://framework.zend.com/) 4 * 5 * @link http://github.com/zendframework/zf2 for the canonical source repository 6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 7 * @license http://framework.zend.com/license/new-bsd New BSD License 8 */ 9 10namespace Zend\InputFilter; 11 12use Zend\Filter\FilterChain; 13use Zend\Validator\NotEmpty; 14use Zend\Validator\ValidatorChain; 15 16class Input implements 17 InputInterface, 18 EmptyContextInterface 19{ 20 /** 21 * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain. 22 * 23 * @var bool 24 */ 25 protected $allowEmpty = false; 26 27 /** 28 * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain. 29 * 30 * @var bool 31 */ 32 protected $continueIfEmpty = false; 33 34 /** 35 * @var bool 36 */ 37 protected $breakOnFailure = false; 38 39 /** 40 * @var string|null 41 */ 42 protected $errorMessage; 43 44 /** 45 * @var FilterChain 46 */ 47 protected $filterChain; 48 49 /** 50 * @var string 51 */ 52 protected $name; 53 54 /** 55 * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain. 56 * 57 * @var bool 58 */ 59 protected $notEmptyValidator = false; 60 61 /** 62 * @var bool 63 */ 64 protected $required = true; 65 66 /** 67 * @var ValidatorChain 68 */ 69 protected $validatorChain; 70 71 /** 72 * @var mixed 73 */ 74 protected $value; 75 76 /** 77 * Flag for distinguish when $value contains the value previously set or the default one. 78 * 79 * @var bool 80 */ 81 protected $hasValue = false; 82 83 /** 84 * @var mixed 85 */ 86 protected $fallbackValue; 87 88 /** 89 * @var bool 90 */ 91 protected $hasFallback = false; 92 93 public function __construct($name = null) 94 { 95 $this->name = $name; 96 } 97 98 /** 99 * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain and set this to `true`. 100 * 101 * @param bool $allowEmpty 102 * @return Input 103 */ 104 public function setAllowEmpty($allowEmpty) 105 { 106 $this->allowEmpty = (bool) $allowEmpty; 107 return $this; 108 } 109 110 /** 111 * @param bool $breakOnFailure 112 * @return Input 113 */ 114 public function setBreakOnFailure($breakOnFailure) 115 { 116 $this->breakOnFailure = (bool) $breakOnFailure; 117 return $this; 118 } 119 120 /** 121 * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain and set this to `true`. 122 * 123 * @param bool $continueIfEmpty 124 * @return Input 125 */ 126 public function setContinueIfEmpty($continueIfEmpty) 127 { 128 $this->continueIfEmpty = (bool) $continueIfEmpty; 129 return $this; 130 } 131 132 /** 133 * @param string|null $errorMessage 134 * @return Input 135 */ 136 public function setErrorMessage($errorMessage) 137 { 138 $this->errorMessage = (null === $errorMessage) ? null : (string) $errorMessage; 139 return $this; 140 } 141 142 /** 143 * @param FilterChain $filterChain 144 * @return Input 145 */ 146 public function setFilterChain(FilterChain $filterChain) 147 { 148 $this->filterChain = $filterChain; 149 return $this; 150 } 151 152 /** 153 * @param string $name 154 * @return Input 155 */ 156 public function setName($name) 157 { 158 $this->name = (string) $name; 159 return $this; 160 } 161 162 /** 163 * @param bool $required 164 * @return Input 165 */ 166 public function setRequired($required) 167 { 168 $this->required = (bool) $required; 169 return $this; 170 } 171 172 /** 173 * @param ValidatorChain $validatorChain 174 * @return Input 175 */ 176 public function setValidatorChain(ValidatorChain $validatorChain) 177 { 178 $this->validatorChain = $validatorChain; 179 return $this; 180 } 181 182 /** 183 * Set the input value. 184 * 185 * If you want to remove/unset the current value use {@link Input::resetValue()}. 186 * 187 * @see Input::getValue() For retrieve the input value. 188 * @see Input::hasValue() For to know if input value was set. 189 * @see Input::resetValue() For reset the input value to the default state. 190 * 191 * @param mixed $value 192 * @return Input 193 */ 194 public function setValue($value) 195 { 196 $this->value = $value; 197 $this->hasValue = true; 198 return $this; 199 } 200 201 /** 202 * Reset input value to the default state. 203 * 204 * @see Input::hasValue() For to know if input value was set. 205 * @see Input::setValue() For set a new value. 206 * 207 * @return Input 208 */ 209 public function resetValue() 210 { 211 $this->value = null; 212 $this->hasValue = false; 213 return $this; 214 } 215 216 /** 217 * @param mixed $value 218 * @return Input 219 */ 220 public function setFallbackValue($value) 221 { 222 $this->fallbackValue = $value; 223 $this->hasFallback = true; 224 return $this; 225 } 226 227 /** 228 * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain. 229 * 230 * @return bool 231 */ 232 public function allowEmpty() 233 { 234 return $this->allowEmpty; 235 } 236 237 /** 238 * @return bool 239 */ 240 public function breakOnFailure() 241 { 242 return $this->breakOnFailure; 243 } 244 245 /** 246 * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain. Should always return `true`. 247 * 248 * @return bool 249 */ 250 public function continueIfEmpty() 251 { 252 return $this->continueIfEmpty; 253 } 254 255 /** 256 * @return string|null 257 */ 258 public function getErrorMessage() 259 { 260 return $this->errorMessage; 261 } 262 263 /** 264 * @return FilterChain 265 */ 266 public function getFilterChain() 267 { 268 if (!$this->filterChain) { 269 $this->setFilterChain(new FilterChain()); 270 } 271 return $this->filterChain; 272 } 273 274 /** 275 * @return string 276 */ 277 public function getName() 278 { 279 return $this->name; 280 } 281 282 /** 283 * @return mixed 284 */ 285 public function getRawValue() 286 { 287 return $this->value; 288 } 289 290 /** 291 * @return bool 292 */ 293 public function isRequired() 294 { 295 return $this->required; 296 } 297 298 /** 299 * @return ValidatorChain 300 */ 301 public function getValidatorChain() 302 { 303 if (!$this->validatorChain) { 304 $this->setValidatorChain(new ValidatorChain()); 305 } 306 return $this->validatorChain; 307 } 308 309 /** 310 * @return mixed 311 */ 312 public function getValue() 313 { 314 $filter = $this->getFilterChain(); 315 return $filter->filter($this->value); 316 } 317 318 /** 319 * Flag for inform if input value was set. 320 * 321 * This flag used for distinguish when {@link Input::getValue()} will return the value previously set or the default. 322 * 323 * @see Input::getValue() For retrieve the input value. 324 * @see Input::setValue() For set a new value. 325 * @see Input::resetValue() For reset the input value to the default state. 326 * 327 * @return bool 328 */ 329 public function hasValue() 330 { 331 return $this->hasValue; 332 } 333 334 /** 335 * @return mixed 336 */ 337 public function getFallbackValue() 338 { 339 return $this->fallbackValue; 340 } 341 342 /** 343 * @return bool 344 */ 345 public function hasFallback() 346 { 347 return $this->hasFallback; 348 } 349 350 public function clearFallbackValue() 351 { 352 $this->hasFallback = false; 353 $this->fallbackValue = null; 354 } 355 356 /** 357 * @param InputInterface $input 358 * @return Input 359 */ 360 public function merge(InputInterface $input) 361 { 362 $this->setBreakOnFailure($input->breakOnFailure()); 363 if ($input instanceof Input) { 364 $this->setContinueIfEmpty($input->continueIfEmpty()); 365 } 366 $this->setErrorMessage($input->getErrorMessage()); 367 $this->setName($input->getName()); 368 $this->setRequired($input->isRequired()); 369 $this->setAllowEmpty($input->allowEmpty()); 370 if (!($input instanceof Input) || $input->hasValue()) { 371 $this->setValue($input->getRawValue()); 372 } 373 374 $filterChain = $input->getFilterChain(); 375 $this->getFilterChain()->merge($filterChain); 376 377 $validatorChain = $input->getValidatorChain(); 378 $this->getValidatorChain()->merge($validatorChain); 379 return $this; 380 } 381 382 /** 383 * @param mixed $context Extra "context" to provide the validator 384 * @return bool 385 */ 386 public function isValid($context = null) 387 { 388 $value = $this->getValue(); 389 $hasValue = $this->hasValue(); 390 $empty = ($value === null || $value === '' || $value === array()); 391 $required = $this->isRequired(); 392 $allowEmpty = $this->allowEmpty(); 393 $continueIfEmpty = $this->continueIfEmpty(); 394 395 if (! $hasValue && $this->hasFallback()) { 396 $this->setValue($this->getFallbackValue()); 397 return true; 398 } 399 400 if (! $hasValue && ! $required) { 401 return true; 402 } 403 404 if (! $hasValue && $required) { 405 if ($this->errorMessage === null) { 406 $this->errorMessage = $this->prepareRequiredValidationFailureMessage(); 407 } 408 return false; 409 } 410 411 if ($empty && ! $required && ! $continueIfEmpty) { 412 return true; 413 } 414 415 if ($empty && $allowEmpty && ! $continueIfEmpty) { 416 return true; 417 } 418 419 // At this point, we need to run validators. 420 // If we do not allow empty and the "continue if empty" flag are 421 // BOTH false, we inject the "not empty" validator into the chain, 422 // which adds that logic into the validation routine. 423 if (! $allowEmpty && ! $continueIfEmpty) { 424 $this->injectNotEmptyValidator(); 425 } 426 427 $validator = $this->getValidatorChain(); 428 $result = $validator->isValid($value, $context); 429 if (! $result && $this->hasFallback()) { 430 $this->setValue($this->getFallbackValue()); 431 $result = true; 432 } 433 434 return $result; 435 } 436 437 /** 438 * @return string[] 439 */ 440 public function getMessages() 441 { 442 if (null !== $this->errorMessage) { 443 return (array) $this->errorMessage; 444 } 445 446 if ($this->hasFallback()) { 447 return array(); 448 } 449 450 $validator = $this->getValidatorChain(); 451 return $validator->getMessages(); 452 } 453 454 /** 455 * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain. 456 * 457 * @return void 458 */ 459 protected function injectNotEmptyValidator() 460 { 461 if ((!$this->isRequired() && $this->allowEmpty()) || $this->notEmptyValidator) { 462 return; 463 } 464 $chain = $this->getValidatorChain(); 465 466 // Check if NotEmpty validator is already in chain 467 $validators = $chain->getValidators(); 468 foreach ($validators as $validator) { 469 if ($validator['instance'] instanceof NotEmpty) { 470 $this->notEmptyValidator = true; 471 return; 472 } 473 } 474 475 $this->notEmptyValidator = true; 476 477 if (class_exists('Zend\ServiceManager\AbstractPluginManager')) { 478 $chain->prependByName('NotEmpty', array(), true); 479 480 return; 481 } 482 483 $chain->prependValidator(new NotEmpty(), true); 484 } 485 486 /** 487 * Create and return the validation failure message for required input. 488 * 489 * @return string[] 490 */ 491 protected function prepareRequiredValidationFailureMessage() 492 { 493 $notEmpty = new NotEmpty(); 494 $templates = $notEmpty->getOption('messageTemplates'); 495 return array( 496 NotEmpty::IS_EMPTY => $templates[NotEmpty::IS_EMPTY], 497 ); 498 } 499} 500