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