1<?php 2namespace TYPO3\CMS\Extbase\Validation\Validator; 3 4/* 5 * This file is part of the TYPO3 CMS project. 6 * 7 * It is free software; you can redistribute it and/or modify it under 8 * the terms of the GNU General Public License, either version 2 9 * of the License, or any later version. 10 * 11 * For the full copyright and license information, please read the 12 * LICENSE.txt file that was distributed with this source code. 13 * 14 * The TYPO3 project - inspiring people to share! 15 */ 16 17/** 18 * An abstract composite validator consisting of other validators 19 */ 20abstract class AbstractCompositeValidator implements ObjectValidatorInterface, \Countable 21{ 22 /** 23 * This contains the supported options, their default values and descriptions. 24 * 25 * @var array 26 */ 27 protected $supportedOptions = []; 28 29 /** 30 * @var array 31 */ 32 protected $options = []; 33 34 /** 35 * @var \SplObjectStorage 36 */ 37 protected $validators; 38 39 /** 40 * @var \SplObjectStorage 41 */ 42 protected $validatedInstancesContainer; 43 44 /** 45 * Constructs the composite validator and sets validation options 46 * 47 * @param array $options Options for the validator 48 * @throws \TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationOptionsException 49 */ 50 public function __construct(array $options = []) 51 { 52 // check for options given but not supported 53 if (($unsupportedOptions = array_diff_key($options, $this->supportedOptions)) !== []) { 54 throw new \TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationOptionsException('Unsupported validation option(s) found: ' . implode(', ', array_keys($unsupportedOptions)), 1339079804); 55 } 56 57 // check for required options being set 58 array_walk( 59 $this->supportedOptions, 60 function ($supportedOptionData, $supportedOptionName, $options) { 61 if (isset($supportedOptionData[3]) && !array_key_exists($supportedOptionName, $options)) { 62 throw new \TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationOptionsException('Required validation option not set: ' . $supportedOptionName, 1339163922); 63 } 64 }, 65 $options 66 ); 67 68 // merge with default values 69 $this->options = array_merge( 70 array_map( 71 function ($value) { 72 return $value[0]; 73 }, 74 $this->supportedOptions 75 ), 76 $options 77 ); 78 $this->validators = new \SplObjectStorage(); 79 } 80 81 /** 82 * Adds a new validator to the conjunction. 83 * 84 * @param \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator The validator that should be added 85 */ 86 public function addValidator(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator) 87 { 88 if ($validator instanceof ObjectValidatorInterface) { 89 // @todo: provide bugfix as soon as it is fixed in TYPO3.Flow (http://forge.typo3.org/issues/48093) 90 $validator->setValidatedInstancesContainer = $this->validatedInstancesContainer; 91 } 92 $this->validators->attach($validator); 93 } 94 95 /** 96 * Removes the specified validator. 97 * 98 * @param \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator The validator to remove 99 * @throws \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException 100 */ 101 public function removeValidator(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator) 102 { 103 if (!$this->validators->contains($validator)) { 104 throw new \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException('Cannot remove validator because its not in the conjunction.', 1207020177); 105 } 106 $this->validators->detach($validator); 107 } 108 109 /** 110 * Returns the number of validators contained in this conjunction. 111 * 112 * @return int The number of validators 113 */ 114 public function count() 115 { 116 return count($this->validators); 117 } 118 119 /** 120 * Returns the child validators of this Composite Validator 121 * 122 * @return \SplObjectStorage 123 */ 124 public function getValidators() 125 { 126 return $this->validators; 127 } 128 129 /** 130 * Returns the options for this validator 131 * 132 * @return array 133 */ 134 public function getOptions() 135 { 136 return $this->options; 137 } 138 139 /** 140 * Allows to set a container to keep track of validated instances. 141 * 142 * @param \SplObjectStorage $validatedInstancesContainer A container to keep track of validated instances 143 */ 144 public function setValidatedInstancesContainer(\SplObjectStorage $validatedInstancesContainer) 145 { 146 $this->validatedInstancesContainer = $validatedInstancesContainer; 147 } 148} 149