first commit
This commit is contained in:
commit
1218dd1517
12716 files changed
+989233
No files matched your search
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* This object holds a validation error.
|
||||
*/
|
||||
class Error extends \TYPO3\CMS\Extbase\Error\Error
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $message = 'Unknown validation error';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $code = 1201447005;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A generic validation exception
|
||||
*/
|
||||
class Exception extends \TYPO3\CMS\Extbase\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Exception;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An "Invalid TypeHint" Exception
|
||||
*/
|
||||
class InvalidTypeHintException extends \TYPO3\CMS\Extbase\Validation\Exception
|
||||
{
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Exception;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A "InvalidValidationConfiguration" Exception
|
||||
*/
|
||||
class InvalidValidationConfigurationException extends \TYPO3\CMS\Extbase\Validation\Exception
|
||||
{
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Exception;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A "InvalidValidationOptions" Exception
|
||||
*/
|
||||
class InvalidValidationOptionsException extends \TYPO3\CMS\Extbase\Validation\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Exception;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A "NoSuchValidator" Exception
|
||||
*/
|
||||
class NoSuchValidatorException extends \TYPO3\CMS\Extbase\Validation\Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* An abstract composite validator consisting of other validators
|
||||
*/
|
||||
abstract class AbstractCompositeValidator implements ObjectValidatorInterface, \Countable
|
||||
{
|
||||
/**
|
||||
* This contains the supported options, their default values and descriptions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedOptions = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* @var \SplObjectStorage
|
||||
*/
|
||||
protected $validators;
|
||||
|
||||
/**
|
||||
* @var \SplObjectStorage
|
||||
*/
|
||||
protected $validatedInstancesContainer;
|
||||
|
||||
/**
|
||||
* Constructs the composite validator and sets validation options
|
||||
*
|
||||
* @param array $options Options for the validator
|
||||
* @throws \TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationOptionsException
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
// check for options given but not supported
|
||||
if (($unsupportedOptions = array_diff_key($options, $this->supportedOptions)) !== []) {
|
||||
throw new \TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationOptionsException('Unsupported validation option(s) found: ' . implode(', ', array_keys($unsupportedOptions)), 1339079804);
|
||||
}
|
||||
|
||||
// check for required options being set
|
||||
array_walk(
|
||||
$this->supportedOptions,
|
||||
function ($supportedOptionData, $supportedOptionName, $options) {
|
||||
if (isset($supportedOptionData[3]) && !array_key_exists($supportedOptionName, $options)) {
|
||||
throw new \TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationOptionsException('Required validation option not set: ' . $supportedOptionName, 1339163922);
|
||||
}
|
||||
},
|
||||
$options
|
||||
);
|
||||
|
||||
// merge with default values
|
||||
$this->options = array_merge(
|
||||
array_map(
|
||||
function ($value) {
|
||||
return $value[0];
|
||||
},
|
||||
$this->supportedOptions
|
||||
),
|
||||
$options
|
||||
);
|
||||
$this->validators = new \SplObjectStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new validator to the conjunction.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator The validator that should be added
|
||||
*/
|
||||
public function addValidator(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator)
|
||||
{
|
||||
if ($validator instanceof ObjectValidatorInterface) {
|
||||
// @todo: provide bugfix as soon as it is fixed in TYPO3.Flow (http://forge.typo3.org/issues/48093)
|
||||
$validator->setValidatedInstancesContainer = $this->validatedInstancesContainer;
|
||||
}
|
||||
$this->validators->attach($validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified validator.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator The validator to remove
|
||||
* @throws \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException
|
||||
*/
|
||||
public function removeValidator(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator)
|
||||
{
|
||||
if (!$this->validators->contains($validator)) {
|
||||
throw new \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException('Cannot remove validator because its not in the conjunction.', 1207020177);
|
||||
}
|
||||
$this->validators->detach($validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of validators contained in this conjunction.
|
||||
*
|
||||
* @return int The number of validators
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->validators);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the child validators of this Composite Validator
|
||||
*
|
||||
* @return \SplObjectStorage
|
||||
*/
|
||||
public function getValidators()
|
||||
{
|
||||
return $this->validators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the options for this validator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to set a container to keep track of validated instances.
|
||||
*
|
||||
* @param \SplObjectStorage $validatedInstancesContainer A container to keep track of validated instances
|
||||
*/
|
||||
public function setValidatedInstancesContainer(\SplObjectStorage $validatedInstancesContainer)
|
||||
{
|
||||
$this->validatedInstancesContainer = $validatedInstancesContainer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationOptionsException;
|
||||
|
||||
/**
|
||||
* Abstract validator
|
||||
*/
|
||||
abstract class AbstractValidator implements ValidatorInterface
|
||||
{
|
||||
/**
|
||||
* Specifies whether this validator accepts empty values.
|
||||
*
|
||||
* If this is TRUE, the validators isValid() method is not called in case of an empty value
|
||||
* Note: A value is considered empty if it is NULL or an empty string!
|
||||
* By default all validators except for NotEmpty and the Composite Validators accept empty values
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $acceptsEmptyValues = true;
|
||||
|
||||
/**
|
||||
* This contains the supported options, their default values, types and descriptions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedOptions = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Error\Result
|
||||
*/
|
||||
protected $result;
|
||||
|
||||
/**
|
||||
* Constructs the validator and sets validation options
|
||||
*
|
||||
* @param array $options Options for the validator
|
||||
* @throws InvalidValidationOptionsException
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
// check for options given but not supported
|
||||
if (($unsupportedOptions = array_diff_key($options, $this->supportedOptions)) !== []) {
|
||||
throw new InvalidValidationOptionsException('Unsupported validation option(s) found: ' . implode(', ', array_keys($unsupportedOptions)), 1379981890);
|
||||
}
|
||||
|
||||
// check for required options being set
|
||||
array_walk(
|
||||
$this->supportedOptions,
|
||||
function ($supportedOptionData, $supportedOptionName, $options) {
|
||||
if (isset($supportedOptionData[3]) && $supportedOptionData[3] === true && !array_key_exists($supportedOptionName, $options)) {
|
||||
throw new InvalidValidationOptionsException('Required validation option not set: ' . $supportedOptionName, 1379981891);
|
||||
}
|
||||
},
|
||||
$options
|
||||
);
|
||||
|
||||
// merge with default values
|
||||
$this->options = array_merge(
|
||||
array_map(
|
||||
function ($value) {
|
||||
return $value[0];
|
||||
},
|
||||
$this->supportedOptions
|
||||
),
|
||||
$options
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given value is valid according to the validator, and returns
|
||||
* the error messages object which occurred.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
* @return \TYPO3\CMS\Extbase\Error\Result
|
||||
*/
|
||||
public function validate($value)
|
||||
{
|
||||
$this->result = new \TYPO3\CMS\Extbase\Error\Result();
|
||||
if ($this->acceptsEmptyValues === false || $this->isEmpty($value) === false) {
|
||||
$this->isValid($value);
|
||||
}
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if $value is valid. If it is not valid, needs to add an error
|
||||
* to result.
|
||||
*
|
||||
* @param mixed $value
|
||||
*/
|
||||
abstract protected function isValid($value);
|
||||
|
||||
/**
|
||||
* Creates a new validation error object and adds it to $this->results
|
||||
*
|
||||
* @param string $message The error message
|
||||
* @param int $code The error code (a unix timestamp)
|
||||
* @param array $arguments Arguments to be replaced in message
|
||||
* @param string $title title of the error
|
||||
*/
|
||||
protected function addError($message, $code, array $arguments = [], $title = '')
|
||||
{
|
||||
$this->result->addError(new \TYPO3\CMS\Extbase\Validation\Error($message, $code, $arguments, $title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the options of this validator
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return bool TRUE if the given $value is NULL or an empty string ('')
|
||||
*/
|
||||
final protected function isEmpty($value)
|
||||
{
|
||||
return $value === null || $value === '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap static call to LocalizationUtility to simplify unit testing
|
||||
*
|
||||
* @param string $translateKey
|
||||
* @param string $extensionName
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function translateErrorMessage($translateKey, $extensionName, $arguments = [])
|
||||
{
|
||||
return \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate(
|
||||
$translateKey,
|
||||
$extensionName,
|
||||
$arguments
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for alphanumeric strings
|
||||
*/
|
||||
class AlphanumericValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* The given $value is valid if it is an alphanumeric string, which is defined as [\pL\d]*.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value) || preg_match('/^[\pL\d]*$/u', $value) !== 1) {
|
||||
$this->addError($this->translateErrorMessage('validator.alphanumeric.notvalid', 'extbase'), 1221551320);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for boolean values
|
||||
*/
|
||||
class BooleanValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedOptions = [
|
||||
// The default is set to NULL here, because we need to be backward compatible here, because this
|
||||
// BooleanValidator is called automatically on boolean action arguments. If we would set it to TRUE,
|
||||
// every FALSE value for an action argument would break.
|
||||
// @todo with next patches: deprecate this BooleanValidator and introduce a BooleanValueValidator, like
|
||||
// in Flow, which won't be called on boolean action arguments.
|
||||
'is' => [null, 'Boolean value', 'boolean|string|integer']
|
||||
];
|
||||
|
||||
/**
|
||||
* Check if $value matches the expectation given to the validator.
|
||||
* If it does not match, the function adds an error to the result.
|
||||
*
|
||||
* Also testing for '1' (true), '0' and '' (false) because casting varies between
|
||||
* tests and actual usage. This makes the validator loose but still keeping functionality.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
// see comment above, check if expectation is NULL, then nothing to do!
|
||||
if ($this->options['is'] === null) {
|
||||
return;
|
||||
}
|
||||
switch (strtolower((string)$this->options['is'])) {
|
||||
case 'true':
|
||||
case '1':
|
||||
$expectation = true;
|
||||
break;
|
||||
case 'false':
|
||||
case '':
|
||||
case '0':
|
||||
$expectation = false;
|
||||
break;
|
||||
default:
|
||||
$this->addError('The given expectation is not valid.', 1361959227);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($value !== $expectation) {
|
||||
if (!is_bool($value)) {
|
||||
$this->addError($this->translateErrorMessage(
|
||||
'validator.boolean.nottrue',
|
||||
'extbase'
|
||||
), 1361959230);
|
||||
} else {
|
||||
if ($expectation) {
|
||||
$this->addError($this->translateErrorMessage(
|
||||
'validator.boolean.nottrue',
|
||||
'extbase'
|
||||
), 1361959228);
|
||||
} else {
|
||||
$this->addError($this->translateErrorMessage(
|
||||
'validator.boolean.notfalse',
|
||||
'extbase'
|
||||
), 1361959229);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A generic collection validator.
|
||||
*/
|
||||
class CollectionValidator extends GenericObjectValidator
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedOptions = [
|
||||
'elementValidator' => [null, 'The validator type to use for the collection elements', 'string'],
|
||||
'elementType' => [null, 'The type of the elements in the collection', 'string'],
|
||||
'validationGroups' => [null, 'The validation groups to link to', 'string'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Validation\ValidatorResolver
|
||||
*/
|
||||
protected $validatorResolver;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Validation\ValidatorResolver $validatorResolver
|
||||
*/
|
||||
public function injectValidatorResolver(\TYPO3\CMS\Extbase\Validation\ValidatorResolver $validatorResolver)
|
||||
{
|
||||
$this->validatorResolver = $validatorResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given value is valid according to the validator, and returns
|
||||
* the Error Messages object which occurred.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
* @return \TYPO3\CMS\Extbase\Error\Result
|
||||
*/
|
||||
public function validate($value)
|
||||
{
|
||||
$this->result = new \TYPO3\CMS\Extbase\Error\Result();
|
||||
|
||||
if ($this->acceptsEmptyValues === false || $this->isEmpty($value) === false) {
|
||||
if ((is_object($value) && !\TYPO3\CMS\Extbase\Utility\TypeHandlingUtility::isCollectionType(get_class($value))) && !is_array($value)) {
|
||||
$this->addError('The given subject was not a collection.', 1317204797);
|
||||
return $this->result;
|
||||
}
|
||||
if ($value instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyObjectStorage && !$value->isInitialized()) {
|
||||
return $this->result;
|
||||
}
|
||||
if (is_object($value)) {
|
||||
if ($this->isValidatedAlready($value)) {
|
||||
return $this->result;
|
||||
}
|
||||
$this->markInstanceAsValidated($value);
|
||||
}
|
||||
$this->isValid($value);
|
||||
}
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for a collection and if needed validates the items in the collection.
|
||||
* This is done with the specified element validator or a validator based on
|
||||
* the given element type and validation group.
|
||||
*
|
||||
* Either elementValidator or elementType must be given, otherwise validation
|
||||
* will be skipped.
|
||||
*
|
||||
* @param mixed $value A collection to be validated
|
||||
*/
|
||||
protected function isValid($value)
|
||||
{
|
||||
foreach ($value as $index => $collectionElement) {
|
||||
if (isset($this->options['elementValidator'])) {
|
||||
$collectionElementValidator = $this->validatorResolver->createValidator($this->options['elementValidator']);
|
||||
} elseif (isset($this->options['elementType'])) {
|
||||
$collectionElementValidator = $this->validatorResolver->getBaseValidatorConjunction($this->options['elementType']);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if ($collectionElementValidator instanceof ObjectValidatorInterface) {
|
||||
$collectionElementValidator->setValidatedInstancesContainer($this->validatedInstancesContainer);
|
||||
}
|
||||
$this->result->forProperty($index)->merge($collectionElementValidator->validate($collectionElement));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\Error\Result;
|
||||
|
||||
/**
|
||||
* Validator to chain many validators in a conjunction (logical and).
|
||||
*/
|
||||
class ConjunctionValidator extends AbstractCompositeValidator
|
||||
{
|
||||
/**
|
||||
* Checks if the given value is valid according to the validators of the conjunction.
|
||||
* Every validator has to be valid, to make the whole conjunction valid.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
* @return Result
|
||||
*/
|
||||
public function validate($value)
|
||||
{
|
||||
$validators = $this->getValidators();
|
||||
if ($validators->count() > 0) {
|
||||
/** @var Result $result */
|
||||
$result = null;
|
||||
/** @var AbstractValidator $validator */
|
||||
foreach ($validators as $validator) {
|
||||
if ($result === null) {
|
||||
$result = $validator->validate($value);
|
||||
} else {
|
||||
$result->merge($validator->validate($value));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$result = new Result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for DateTime/DateTimeImmutable objects.
|
||||
*/
|
||||
class DateTimeValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* Checks if the given value is a valid DateTime object. If this is not
|
||||
* the case, the function adds an error.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$this->result->clear();
|
||||
if ($value instanceof \DateTimeInterface) {
|
||||
return;
|
||||
}
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.datetime.notvalid',
|
||||
'extbase',
|
||||
[
|
||||
gettype($value)
|
||||
]
|
||||
),
|
||||
1238087674,
|
||||
[gettype($value)]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator to chain many validators in a disjunction (logical or).
|
||||
*/
|
||||
class DisjunctionValidator extends AbstractCompositeValidator
|
||||
{
|
||||
/**
|
||||
* Checks if the given value is valid according to the validators of the
|
||||
* disjunction.
|
||||
*
|
||||
* So only one validator has to be valid, to make the whole disjunction valid.
|
||||
* Errors are only returned if all validators failed.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
* @return \TYPO3\CMS\Extbase\Error\Result
|
||||
*/
|
||||
public function validate($value)
|
||||
{
|
||||
$validators = $this->getValidators();
|
||||
if ($validators->count() > 0) {
|
||||
$result = null;
|
||||
foreach ($validators as $validator) {
|
||||
$validatorResult = $validator->validate($value);
|
||||
if ($validatorResult->hasErrors()) {
|
||||
if ($result === null) {
|
||||
$result = $validatorResult;
|
||||
} else {
|
||||
$result->merge($validatorResult);
|
||||
}
|
||||
} else {
|
||||
if ($result === null) {
|
||||
$result = $validatorResult;
|
||||
} else {
|
||||
$result->clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$result = new \TYPO3\CMS\Extbase\Error\Result();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for email addresses
|
||||
*/
|
||||
class EmailAddressValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* Checks if the given value is a valid email address.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value) || !$this->validEmail($value)) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.emailaddress.notvalid',
|
||||
'extbase'
|
||||
),
|
||||
1221559976
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking syntax of input email address
|
||||
*
|
||||
* @param string $emailAddress Input string to evaluate
|
||||
* @return bool Returns TRUE if the $email address (input string) is valid
|
||||
*/
|
||||
protected function validEmail($emailAddress)
|
||||
{
|
||||
return \TYPO3\CMS\Core\Utility\GeneralUtility::validEmail($emailAddress);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for floats.
|
||||
*/
|
||||
class FloatValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* The given value is valid if it is of type float or a string matching the regular expression [0-9.e+-]
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (is_float($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_string($value) || strpos($value, '.') === false || preg_match('/^[0-9.e+-]+$/', $value) !== 1) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.float.notvalid',
|
||||
'extbase'
|
||||
),
|
||||
1221560288
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
|
||||
/**
|
||||
* A generic object validator which allows for specifying property validators
|
||||
*/
|
||||
class GenericObjectValidator extends AbstractValidator implements ObjectValidatorInterface
|
||||
{
|
||||
/**
|
||||
* @var \SplObjectStorage[]
|
||||
*/
|
||||
protected $propertyValidators = [];
|
||||
|
||||
/**
|
||||
* Checks if the given value is valid according to the validator, and returns
|
||||
* the Error Messages object which occurred.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
* @return \TYPO3\CMS\Extbase\Error\Result
|
||||
*/
|
||||
public function validate($value)
|
||||
{
|
||||
if (is_object($value) && $this->isValidatedAlready($value)) {
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
$this->result = new \TYPO3\CMS\Extbase\Error\Result();
|
||||
if ($this->acceptsEmptyValues === false || $this->isEmpty($value) === false) {
|
||||
if (!is_object($value)) {
|
||||
$this->addError('Object expected, %1$s given.', 1241099149, [gettype($value)]);
|
||||
} elseif ($this->isValidatedAlready($value) === false) {
|
||||
$this->markInstanceAsValidated($value);
|
||||
$this->isValid($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the property value to be used for validation.
|
||||
*
|
||||
* In case the object is a doctrine proxy, we need to load the real instance first.
|
||||
*
|
||||
* @param object $object
|
||||
* @param string $propertyName
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getPropertyValue($object, $propertyName)
|
||||
{
|
||||
// @todo add support for lazy loading proxies, if needed
|
||||
if (ObjectAccess::isPropertyGettable($object, $propertyName)) {
|
||||
return ObjectAccess::getProperty($object, $propertyName);
|
||||
}
|
||||
return ObjectAccess::getProperty($object, $propertyName, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified property of the given object is valid, and adds
|
||||
* found errors to the $messages object.
|
||||
*
|
||||
* @param mixed $value The value to be validated
|
||||
* @param \Traversable $validators The validators to be called on the value
|
||||
* @param string $propertyName Name of ther property to check
|
||||
*/
|
||||
protected function checkProperty($value, $validators, $propertyName)
|
||||
{
|
||||
/** @var \TYPO3\CMS\Extbase\Error\Result $result */
|
||||
$result = null;
|
||||
foreach ($validators as $validator) {
|
||||
if ($validator instanceof ObjectValidatorInterface) {
|
||||
$validator->setValidatedInstancesContainer($this->validatedInstancesContainer);
|
||||
}
|
||||
$currentResult = $validator->validate($value);
|
||||
if ($currentResult->hasMessages()) {
|
||||
if ($result == null) {
|
||||
$result = $currentResult;
|
||||
} else {
|
||||
$result->merge($currentResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($result != null) {
|
||||
$this->result->forProperty($propertyName)->merge($result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given value is valid according to the property validators.
|
||||
*
|
||||
* @param mixed $object The value that should be validated
|
||||
*/
|
||||
protected function isValid($object)
|
||||
{
|
||||
foreach ($this->propertyValidators as $propertyName => $validators) {
|
||||
$propertyValue = $this->getPropertyValue($object, $propertyName);
|
||||
$this->checkProperty($propertyValue, $validators, $propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given object can be validated by the validator implementation
|
||||
*
|
||||
* @param mixed $object The object to be checked
|
||||
* @return bool TRUE if the given value is an object
|
||||
*/
|
||||
public function canValidate($object)
|
||||
{
|
||||
return is_object($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given validator for validation of the specified property.
|
||||
*
|
||||
* @param string $propertyName Name of the property to validate
|
||||
* @param ValidatorInterface $validator The property validator
|
||||
*/
|
||||
public function addPropertyValidator($propertyName, ValidatorInterface $validator)
|
||||
{
|
||||
if (!isset($this->propertyValidators[$propertyName])) {
|
||||
$this->propertyValidators[$propertyName] = new \SplObjectStorage();
|
||||
}
|
||||
$this->propertyValidators[$propertyName]->attach($validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $object
|
||||
* @return bool
|
||||
*/
|
||||
protected function isValidatedAlready($object)
|
||||
{
|
||||
if ($this->validatedInstancesContainer === null) {
|
||||
$this->validatedInstancesContainer = new \SplObjectStorage();
|
||||
}
|
||||
if ($this->validatedInstancesContainer->contains($object)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
*/
|
||||
protected function markInstanceAsValidated($object): void
|
||||
{
|
||||
$this->validatedInstancesContainer->attach($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all property validators - or only validators of the specified property
|
||||
*
|
||||
* @param string $propertyName Name of the property to return validators for
|
||||
* @return array An array of validators
|
||||
*/
|
||||
public function getPropertyValidators($propertyName = null)
|
||||
{
|
||||
if ($propertyName !== null) {
|
||||
return $this->propertyValidators[$propertyName] ?? [];
|
||||
}
|
||||
return $this->propertyValidators;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var \SplObjectStorage
|
||||
*/
|
||||
protected $validatedInstancesContainer;
|
||||
|
||||
/**
|
||||
* Allows to set a container to keep track of validated instances.
|
||||
*
|
||||
* @param \SplObjectStorage $validatedInstancesContainer A container to keep track of validated instances
|
||||
*/
|
||||
public function setValidatedInstancesContainer(\SplObjectStorage $validatedInstancesContainer)
|
||||
{
|
||||
$this->validatedInstancesContainer = $validatedInstancesContainer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for integers.
|
||||
*/
|
||||
class IntegerValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* Checks if the given value is a valid integer.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (filter_var($value, FILTER_VALIDATE_INT) === false) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.integer.notvalid',
|
||||
'extbase'
|
||||
),
|
||||
1221560494
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for not empty values.
|
||||
*/
|
||||
class NotEmptyValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* This validator always needs to be executed even if the given value is empty.
|
||||
* See AbstractValidator::validate()
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $acceptsEmptyValues = false;
|
||||
|
||||
/**
|
||||
* Checks if the given property ($propertyValue) is not empty (NULL, empty string, empty array or empty object).
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if ($value === null) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.notempty.null',
|
||||
'extbase'
|
||||
),
|
||||
1221560910
|
||||
);
|
||||
}
|
||||
if ($value === '') {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.notempty.empty',
|
||||
'extbase'
|
||||
),
|
||||
1221560718
|
||||
);
|
||||
}
|
||||
if (is_array($value) && empty($value)) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.notempty.empty',
|
||||
'extbase'
|
||||
),
|
||||
1347992400
|
||||
);
|
||||
}
|
||||
if (is_object($value) && $value instanceof \Countable && $value->count() === 0) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.notempty.empty',
|
||||
'extbase'
|
||||
),
|
||||
1347992453
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for general numbers
|
||||
*/
|
||||
class NumberRangeValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedOptions = [
|
||||
'minimum' => [0, 'The minimum value to accept', 'integer'],
|
||||
'maximum' => [PHP_INT_MAX, 'The maximum value to accept', 'integer']
|
||||
];
|
||||
|
||||
/**
|
||||
* The given value is valid if it is a number in the specified range.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_numeric($value)) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.numberrange.notvalid',
|
||||
'extbase'
|
||||
),
|
||||
1221563685
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$minimum = $this->options['minimum'];
|
||||
$maximum = $this->options['maximum'];
|
||||
|
||||
if ($minimum > $maximum) {
|
||||
$x = $minimum;
|
||||
$minimum = $maximum;
|
||||
$maximum = $x;
|
||||
}
|
||||
if ($value < $minimum || $value > $maximum) {
|
||||
$this->addError($this->translateErrorMessage(
|
||||
'validator.numberrange.range',
|
||||
'extbase',
|
||||
[
|
||||
$minimum,
|
||||
$maximum
|
||||
]
|
||||
), 1221561046, [$minimum, $maximum]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for general numbers.
|
||||
*/
|
||||
class NumberValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* Checks if the given value is a valid number.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_numeric($value)) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.number.notvalid',
|
||||
'extbase'
|
||||
),
|
||||
1221563685
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contract for a validator
|
||||
*/
|
||||
interface ObjectValidatorInterface extends ValidatorInterface
|
||||
{
|
||||
/**
|
||||
* Allows to set a container to keep track of validated instances.
|
||||
*
|
||||
* @param \SplObjectStorage $validatedInstancesContainer A container to keep track of validated instances
|
||||
*/
|
||||
public function setValidatedInstancesContainer(\SplObjectStorage $validatedInstancesContainer);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* A validator which accepts any input.
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
|
||||
*/
|
||||
class RawValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
trigger_error(
|
||||
__CLASS__ . ' is deprecated and will be removed in TYPO3 v10.0.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* This validator is always valid.
|
||||
*
|
||||
* @param mixed $value The value that should be validated (not used here)
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator based on regular expressions.
|
||||
*/
|
||||
class RegularExpressionValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedOptions = [
|
||||
'regularExpression' => ['', 'The regular expression to use for validation, used as given', 'string', true]
|
||||
];
|
||||
|
||||
/**
|
||||
* Checks if the given value matches the specified regular expression.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
* @throws \TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationOptionsException
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
$result = preg_match($this->options['regularExpression'], $value);
|
||||
if ($result === 0) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.regularexpression.nomatch',
|
||||
'extbase'
|
||||
),
|
||||
1221565130
|
||||
);
|
||||
}
|
||||
if ($result === false) {
|
||||
throw new \TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationOptionsException('regularExpression "' . $this->options['regularExpression'] . '" in RegularExpressionValidator contained an error.', 1298273089);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for string length.
|
||||
*/
|
||||
class StringLengthValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedOptions = [
|
||||
'minimum' => [0, 'Minimum length for a valid string', 'integer'],
|
||||
'maximum' => [PHP_INT_MAX, 'Maximum length for a valid string', 'integer']
|
||||
];
|
||||
|
||||
/**
|
||||
* Checks if the given value is a valid string (or can be cast to a string
|
||||
* if an object is given) and its length is between minimum and maximum
|
||||
* specified in the validation options.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
* @throws \TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationOptionsException
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if ($this->options['maximum'] < $this->options['minimum']) {
|
||||
throw new \TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationOptionsException('The \'maximum\' is shorter than the \'minimum\' in the StringLengthValidator.', 1238107096);
|
||||
}
|
||||
|
||||
if (is_object($value)) {
|
||||
if (!method_exists($value, '__toString')) {
|
||||
$this->addError('The given object could not be converted to a string.', 1238110957);
|
||||
return;
|
||||
}
|
||||
} elseif (!is_string($value)) {
|
||||
$this->addError('The given value was not a valid string.', 1269883975);
|
||||
return;
|
||||
}
|
||||
|
||||
$stringLength = mb_strlen($value, 'utf-8');
|
||||
$isValid = true;
|
||||
if ($stringLength < $this->options['minimum']) {
|
||||
$isValid = false;
|
||||
}
|
||||
if ($stringLength > $this->options['maximum']) {
|
||||
$isValid = false;
|
||||
}
|
||||
|
||||
if ($isValid === false) {
|
||||
if ($this->options['minimum'] > 0 && $this->options['maximum'] < PHP_INT_MAX) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.stringlength.between',
|
||||
'extbase',
|
||||
[
|
||||
$this->options['minimum'],
|
||||
$this->options['maximum']
|
||||
]
|
||||
),
|
||||
1428504122,
|
||||
[$this->options['minimum'], $this->options['maximum']]
|
||||
);
|
||||
} elseif ($this->options['minimum'] > 0) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.stringlength.less',
|
||||
'extbase',
|
||||
[
|
||||
$this->options['minimum']
|
||||
]
|
||||
),
|
||||
1238108068,
|
||||
[$this->options['minimum']]
|
||||
);
|
||||
} else {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.stringlength.exceed',
|
||||
'extbase',
|
||||
[
|
||||
$this->options['maximum']
|
||||
]
|
||||
),
|
||||
1238108069,
|
||||
[$this->options['maximum']]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for strings.
|
||||
*/
|
||||
class StringValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* Checks if the given value is a string.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value)) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.string.notvalid',
|
||||
'extbase'
|
||||
),
|
||||
1238108067
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validator for "plain" text.
|
||||
*/
|
||||
class TextValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* Checks if the given value is a valid text (contains no XML tags).
|
||||
*
|
||||
* Be aware that the value of this check entirely depends on the output context.
|
||||
* The validated text is not expected to be secure in every circumstance, if you
|
||||
* want to be sure of that, use a customized regular expression or filter on output.
|
||||
*
|
||||
* See http://php.net/filter_var for details.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if ($value !== filter_var($value, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES)) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.text.notvalid',
|
||||
'extbase'
|
||||
),
|
||||
1221565786
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Validator for url.
|
||||
*/
|
||||
class UrlValidator extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* Checks if the given value is a string.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
*/
|
||||
public function isValid($value)
|
||||
{
|
||||
if (!is_string($value) || !GeneralUtility::isValidUrl($value)) {
|
||||
$this->addError(
|
||||
$this->translateErrorMessage(
|
||||
'validator.url.notvalid',
|
||||
'extbase'
|
||||
),
|
||||
1238108078
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation\Validator;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contract for a validator
|
||||
*/
|
||||
interface ValidatorInterface
|
||||
{
|
||||
/**
|
||||
* Checks if the given value is valid according to the validator, and returns
|
||||
* the Error Messages object which occurred.
|
||||
*
|
||||
* @param mixed $value The value that should be validated
|
||||
* @return \TYPO3\CMS\Extbase\Error\Result
|
||||
*/
|
||||
public function validate($value);
|
||||
|
||||
/**
|
||||
* Returns the options of this validator which can be specified in the constructor
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions();
|
||||
}
|
||||
@@ -0,0 +1,576 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Extbase\Validation;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Log\LogManager;
|
||||
use TYPO3\CMS\Core\Utility\ClassNamingUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Utility\TypeHandlingUtility;
|
||||
use TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException;
|
||||
use TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator;
|
||||
|
||||
/**
|
||||
* Validator resolver to automatically find an appropriate validator for a given subject
|
||||
* @internal only to be used within Extbase, not part of TYPO3 Core API.
|
||||
*/
|
||||
class ValidatorResolver implements \TYPO3\CMS\Core\SingletonInterface
|
||||
{
|
||||
/**
|
||||
* Match validator names and options
|
||||
* @deprecated and will be removed in TYPO3 v10.0.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const PATTERN_MATCH_VALIDATORS = '/
|
||||
(?:^|,\s*)
|
||||
(?P<validatorName>[a-z0-9:.\\\\]+)
|
||||
\s*
|
||||
(?:\(
|
||||
(?P<validatorOptions>(?:\s*[a-z0-9]+\s*=\s*(?:
|
||||
"(?:\\\\"|[^"])*"
|
||||
|\'(?:\\\\\'|[^\'])*\'
|
||||
|(?:\s|[^,"\']*)
|
||||
)(?:\s|,)*)*)
|
||||
\))?
|
||||
/ixS';
|
||||
|
||||
/**
|
||||
* Match validator options (to parse actual options)
|
||||
* @var string
|
||||
* @deprecated and will be removed in TYPO3 v10.0.
|
||||
*/
|
||||
const PATTERN_MATCH_VALIDATOROPTIONS = '/
|
||||
\s*
|
||||
(?P<optionName>[a-z0-9]+)
|
||||
\s*=\s*
|
||||
(?P<optionValue>
|
||||
"(?:\\\\"|[^"])*"
|
||||
|\'(?:\\\\\'|[^\'])*\'
|
||||
|(?:\s|[^,"\']*)
|
||||
)
|
||||
/ixS';
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Reflection\ReflectionService
|
||||
*/
|
||||
protected $reflectionService;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $baseValidatorConjunctions = [];
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService
|
||||
*/
|
||||
public function injectReflectionService(\TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService)
|
||||
{
|
||||
$this->reflectionService = $reflectionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for a given data type. Returns a validator implementing
|
||||
* the \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface or NULL if no validator
|
||||
* could be resolved.
|
||||
*
|
||||
* @param string $validatorType Either one of the built-in data types or fully qualified validator class name
|
||||
* @param array $validatorOptions Options to be passed to the validator
|
||||
* @return \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface Validator or NULL if none found.
|
||||
*/
|
||||
public function createValidator($validatorType, array $validatorOptions = [])
|
||||
{
|
||||
try {
|
||||
/**
|
||||
* @todo remove throwing Exceptions in resolveValidatorObjectName
|
||||
*/
|
||||
$validatorObjectName = $this->resolveValidatorObjectName($validatorType);
|
||||
|
||||
$validator = $this->objectManager->get($validatorObjectName, $validatorOptions);
|
||||
|
||||
// Move this check into ClassSchema
|
||||
if (!($validator instanceof \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface)) {
|
||||
throw new Exception\NoSuchValidatorException('The validator "' . $validatorObjectName . '" does not implement TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface!', 1300694875);
|
||||
}
|
||||
|
||||
return $validator;
|
||||
} catch (NoSuchValidatorException $e) {
|
||||
GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__)->debug($e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves and returns the base validator conjunction for the given data type.
|
||||
*
|
||||
* If no validator could be resolved (which usually means that no validation is necessary),
|
||||
* NULL is returned.
|
||||
*
|
||||
* @param string $targetClassName The data type to search a validator for. Usually the fully qualified object name
|
||||
* @return ConjunctionValidator The validator conjunction or NULL
|
||||
*/
|
||||
public function getBaseValidatorConjunction($targetClassName)
|
||||
{
|
||||
if (!array_key_exists($targetClassName, $this->baseValidatorConjunctions)) {
|
||||
$this->buildBaseValidatorConjunction($targetClassName, $targetClassName);
|
||||
}
|
||||
|
||||
return $this->baseValidatorConjunctions[$targetClassName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects and registers any validators for arguments:
|
||||
* - by the data type specified in the param annotations
|
||||
* - additional validators specified in the validate annotations of a method
|
||||
*
|
||||
* @param string $className
|
||||
* @param string $methodName
|
||||
* @param array $methodParameters Optional pre-compiled array of method parameters
|
||||
* @param array $methodValidateAnnotations Optional pre-compiled array of validate annotations (as array)
|
||||
* @return ConjunctionValidator[] An Array of ValidatorConjunctions for each method parameters.
|
||||
* @throws \TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationConfigurationException
|
||||
* @throws \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException
|
||||
* @throws \TYPO3\CMS\Extbase\Validation\Exception\InvalidTypeHintException
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
|
||||
*/
|
||||
public function buildMethodArgumentsValidatorConjunctions($className, $methodName, array $methodParameters = null, array $methodValidateAnnotations = null)
|
||||
{
|
||||
trigger_error(
|
||||
'Method ' . __METHOD__ . ' is deprecated and will be removed in TYPO3 v10.0.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
/** @var ConjunctionValidator[] $validatorConjunctions */
|
||||
$validatorConjunctions = [];
|
||||
|
||||
if ($methodParameters === null) {
|
||||
$methodParameters = $this->reflectionService
|
||||
->getClassSchema($className)
|
||||
->getMethod($methodName)['params'] ?? [];
|
||||
}
|
||||
if (empty($methodParameters)) {
|
||||
return $validatorConjunctions;
|
||||
}
|
||||
|
||||
foreach ($methodParameters as $parameterName => $methodParameter) {
|
||||
/** @var ConjunctionValidator $validatorConjunction */
|
||||
$validatorConjunction = $this->createValidator(ConjunctionValidator::class);
|
||||
|
||||
if (!array_key_exists('type', $methodParameter)) {
|
||||
throw new Exception\InvalidTypeHintException('Missing type information, probably no @param annotation for parameter "$' . $parameterName . '" in ' . $className . '->' . $methodName . '()', 1281962564);
|
||||
}
|
||||
|
||||
if (strpbrk($methodParameter['type'], '\\') === false) {
|
||||
$typeValidator = $this->createValidator($methodParameter['type']);
|
||||
} else {
|
||||
$typeValidator = null;
|
||||
}
|
||||
|
||||
if ($typeValidator !== null) {
|
||||
$validatorConjunction->addValidator($typeValidator);
|
||||
}
|
||||
$validatorConjunctions[$parameterName] = $validatorConjunction;
|
||||
}
|
||||
|
||||
if ($methodValidateAnnotations === null) {
|
||||
$validateAnnotations = $this->getMethodValidateAnnotations($className, $methodName);
|
||||
$methodValidateAnnotations = array_map(function ($validateAnnotation) {
|
||||
return [
|
||||
'type' => $validateAnnotation['validatorName'],
|
||||
'options' => $validateAnnotation['validatorOptions'],
|
||||
'argumentName' => $validateAnnotation['argumentName'],
|
||||
];
|
||||
}, $validateAnnotations);
|
||||
}
|
||||
|
||||
foreach ($methodValidateAnnotations as $annotationParameters) {
|
||||
$newValidator = $this->createValidator($annotationParameters['type'], $annotationParameters['options']);
|
||||
if ($newValidator === null) {
|
||||
throw new Exception\NoSuchValidatorException('Invalid validate annotation in ' . $className . '->' . $methodName . '(): Could not resolve class name for validator "' . $annotationParameters['type'] . '".', 1239853109);
|
||||
}
|
||||
if (isset($validatorConjunctions[$annotationParameters['argumentName']])) {
|
||||
$validatorConjunctions[$annotationParameters['argumentName']]->addValidator($newValidator);
|
||||
} elseif (strpos($annotationParameters['argumentName'], '.') !== false) {
|
||||
$objectPath = explode('.', $annotationParameters['argumentName']);
|
||||
$argumentName = array_shift($objectPath);
|
||||
$validatorConjunctions[$argumentName]->addValidator($this->buildSubObjectValidator($objectPath, $newValidator));
|
||||
} else {
|
||||
throw new Exception\InvalidValidationConfigurationException('Invalid validate annotation in ' . $className . '->' . $methodName . '(): Validator specified for argument name "' . $annotationParameters['argumentName'] . '", but this argument does not exist.', 1253172726);
|
||||
}
|
||||
}
|
||||
|
||||
return $validatorConjunctions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a chain of nested object validators by specification of the given
|
||||
* object path.
|
||||
*
|
||||
* @param array $objectPath The object path
|
||||
* @param \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $propertyValidator The validator which should be added to the property specified by objectPath
|
||||
* @return \TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
|
||||
*/
|
||||
protected function buildSubObjectValidator(array $objectPath, \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $propertyValidator)
|
||||
{
|
||||
trigger_error(
|
||||
'Method ' . __METHOD__ . ' is deprecated and will be removed in TYPO3 v10.0.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
$rootObjectValidator = $this->objectManager->get(\TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator::class, []);
|
||||
$parentObjectValidator = $rootObjectValidator;
|
||||
|
||||
while (count($objectPath) > 1) {
|
||||
$subObjectValidator = $this->objectManager->get(\TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator::class, []);
|
||||
$subPropertyName = array_shift($objectPath);
|
||||
$parentObjectValidator->addPropertyValidator($subPropertyName, $subObjectValidator);
|
||||
$parentObjectValidator = $subObjectValidator;
|
||||
}
|
||||
|
||||
$parentObjectValidator->addPropertyValidator(array_shift($objectPath), $propertyValidator);
|
||||
|
||||
return $rootObjectValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a base validator conjunction for the given data type.
|
||||
*
|
||||
* The base validation rules are those which were declared directly in a class (typically
|
||||
* a model) through some validate annotations on properties.
|
||||
*
|
||||
* If a property holds a class for which a base validator exists, that property will be
|
||||
* checked as well, regardless of a validate annotation
|
||||
*
|
||||
* Additionally, if a custom validator was defined for the class in question, it will be added
|
||||
* to the end of the conjunction. A custom validator is found if it follows the naming convention
|
||||
* "Replace '\Model\' by '\Validator\' and append 'Validator'".
|
||||
*
|
||||
* Example: $targetClassName is TYPO3\Foo\Domain\Model\Quux, then the validator will be found if it has the
|
||||
* name TYPO3\Foo\Domain\Validator\QuuxValidator
|
||||
*
|
||||
* @param string $indexKey The key to use as index in $this->baseValidatorConjunctions; calculated from target class name and validation groups
|
||||
* @param string $targetClassName The data type to build the validation conjunction for. Needs to be the fully qualified class name.
|
||||
* @param array $validationGroups The validation groups to build the validator for
|
||||
* @throws \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function buildBaseValidatorConjunction($indexKey, $targetClassName, array $validationGroups = [])
|
||||
{
|
||||
$conjunctionValidator = new ConjunctionValidator();
|
||||
$this->baseValidatorConjunctions[$indexKey] = $conjunctionValidator;
|
||||
|
||||
// note: the simpleType check reduces lookups to the class loader
|
||||
if (!TypeHandlingUtility::isSimpleType($targetClassName) && class_exists($targetClassName)) {
|
||||
$classSchema = $this->reflectionService->getClassSchema($targetClassName);
|
||||
|
||||
// Model based validator
|
||||
/** @var \TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator $objectValidator */
|
||||
$objectValidator = $this->objectManager->get(\TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator::class, []);
|
||||
foreach ($classSchema->getProperties() as $classPropertyName => $classPropertyDefinition) {
|
||||
/** @var array|array[] $classPropertyDefinition */
|
||||
$classPropertyTagsValues = $classPropertyDefinition['tags'];
|
||||
|
||||
if (!isset($classPropertyTagsValues['var'])) {
|
||||
throw new \InvalidArgumentException(sprintf('There is no @var annotation for property "%s" in class "%s".', $classPropertyName, $targetClassName), 1363778104);
|
||||
}
|
||||
|
||||
$propertyTargetClassName = $classPropertyDefinition['type'];
|
||||
// note: the outer simpleType check reduces lookups to the class loader
|
||||
if (!TypeHandlingUtility::isSimpleType($propertyTargetClassName)) {
|
||||
if (TypeHandlingUtility::isCollectionType($propertyTargetClassName)) {
|
||||
$collectionValidator = $this->createValidator(
|
||||
\TYPO3\CMS\Extbase\Validation\Validator\CollectionValidator::class,
|
||||
[
|
||||
'elementType' => $classPropertyDefinition['elementType'],
|
||||
'validationGroups' => $validationGroups
|
||||
]
|
||||
);
|
||||
$objectValidator->addPropertyValidator($classPropertyName, $collectionValidator);
|
||||
} elseif (class_exists($propertyTargetClassName) && !TypeHandlingUtility::isCoreType($propertyTargetClassName) && $this->objectManager->isRegistered($propertyTargetClassName) && $this->objectManager->getScope($propertyTargetClassName) === \TYPO3\CMS\Extbase\Object\Container\Container::SCOPE_PROTOTYPE) {
|
||||
$validatorForProperty = $this->getBaseValidatorConjunction($propertyTargetClassName);
|
||||
if ($validatorForProperty !== null && $validatorForProperty->count() > 0) {
|
||||
$objectValidator->addPropertyValidator($classPropertyName, $validatorForProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($classPropertyDefinition['validators'] as $validatorDefinition) {
|
||||
// @todo: Respect validationGroups
|
||||
|
||||
// @todo: At this point we already have the class name of the validator, thus there is not need
|
||||
// @todo: calling \TYPO3\CMS\Extbase\Validation\ValidatorResolver::resolveValidatorObjectName inside
|
||||
// @todo: \TYPO3\CMS\Extbase\Validation\ValidatorResolver::createValidator once again. However, to
|
||||
// @todo: keep things simple for now, we still use the method createValidator here. In the future,
|
||||
// @todo: createValidator must only accept FQCN's.
|
||||
$newValidator = $this->createValidator($validatorDefinition['className'], $validatorDefinition['options']);
|
||||
if ($newValidator === null) {
|
||||
throw new Exception\NoSuchValidatorException('Invalid validate annotation in ' . $targetClassName . '::' . $classPropertyName . ': Could not resolve class name for validator "' . $validatorDefinition['className'] . '".', 1241098027);
|
||||
}
|
||||
$objectValidator->addPropertyValidator($classPropertyName, $newValidator);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($objectValidator->getPropertyValidators())) {
|
||||
$conjunctionValidator->addValidator($objectValidator);
|
||||
}
|
||||
}
|
||||
|
||||
$this->addCustomValidators($targetClassName, $conjunctionValidator);
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds custom validators to the passed $conjunctionValidator.
|
||||
*
|
||||
* A custom validator is found if it follows the naming convention "Replace '\Model\' by '\Validator\' and
|
||||
* append 'Validator'". If found, it will be added to the $conjunctionValidator.
|
||||
*
|
||||
* In addition canValidate() will be called on all implementations of the ObjectValidatorInterface to find
|
||||
* all validators that could validate the target. The one with the highest priority will be added as well.
|
||||
* If multiple validators have the same priority, which one will be added is not deterministic.
|
||||
*
|
||||
* @param string $targetClassName
|
||||
* @param ConjunctionValidator $conjunctionValidator
|
||||
*/
|
||||
protected function addCustomValidators($targetClassName, ConjunctionValidator &$conjunctionValidator)
|
||||
{
|
||||
// @todo: get rid of ClassNamingUtility usage once we dropped underscored class name support
|
||||
$possibleValidatorClassName = ClassNamingUtility::translateModelNameToValidatorName($targetClassName);
|
||||
|
||||
$customValidator = $this->createValidator($possibleValidatorClassName);
|
||||
if ($customValidator !== null) {
|
||||
$conjunctionValidator->addValidator($customValidator);
|
||||
}
|
||||
|
||||
// @todo: find polytype validator for class
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the validator options given in @validate annotations.
|
||||
*
|
||||
* @param string $validateValue
|
||||
* @return array
|
||||
* @internal
|
||||
* @deprecated Helper, remove in TYPO3 v10.0 together with the deprecated consumer methods
|
||||
*/
|
||||
public function parseValidatorAnnotation($validateValue)
|
||||
{
|
||||
trigger_error(
|
||||
'Method ' . __METHOD__ . ' is deprecated and will be removed in TYPO3 v10.0.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
$matches = [];
|
||||
if ($validateValue[0] === '$') {
|
||||
$parts = explode(' ', $validateValue, 2);
|
||||
$validatorConfiguration = ['argumentName' => ltrim($parts[0], '$'), 'validators' => []];
|
||||
preg_match_all(self::PATTERN_MATCH_VALIDATORS, $parts[1], $matches, PREG_SET_ORDER);
|
||||
} else {
|
||||
$validatorConfiguration = ['validators' => []];
|
||||
preg_match_all(self::PATTERN_MATCH_VALIDATORS, $validateValue, $matches, PREG_SET_ORDER);
|
||||
}
|
||||
foreach ($matches as $match) {
|
||||
$validatorOptions = [];
|
||||
if (isset($match['validatorOptions'])) {
|
||||
$validatorOptions = $this->parseValidatorOptions($match['validatorOptions']);
|
||||
}
|
||||
$validatorConfiguration['validators'][] = ['validatorName' => $match['validatorName'], 'validatorOptions' => $validatorOptions];
|
||||
}
|
||||
return $validatorConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses $rawValidatorOptions not containing quoted option values.
|
||||
* $rawValidatorOptions will be an empty string afterwards (pass by ref!).
|
||||
*
|
||||
* @param string $rawValidatorOptions
|
||||
* @return array An array of optionName/optionValue pairs
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
|
||||
*/
|
||||
protected function parseValidatorOptions($rawValidatorOptions)
|
||||
{
|
||||
trigger_error(
|
||||
'Method ' . __METHOD__ . ' is deprecated and will be removed in TYPO3 v10.0.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
$validatorOptions = [];
|
||||
$parsedValidatorOptions = [];
|
||||
preg_match_all(self::PATTERN_MATCH_VALIDATOROPTIONS, $rawValidatorOptions, $validatorOptions, PREG_SET_ORDER);
|
||||
foreach ($validatorOptions as $validatorOption) {
|
||||
$parsedValidatorOptions[trim($validatorOption['optionName'])] = trim($validatorOption['optionValue']);
|
||||
}
|
||||
array_walk($parsedValidatorOptions, [$this, 'unquoteString']);
|
||||
return $parsedValidatorOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes escapings from a given argument string and trims the outermost
|
||||
* quotes.
|
||||
*
|
||||
* This method is meant as a helper for regular expression results.
|
||||
*
|
||||
* @param string &$quotedValue Value to unquote
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
|
||||
*/
|
||||
protected function unquoteString(&$quotedValue)
|
||||
{
|
||||
trigger_error(
|
||||
'Method ' . __METHOD__ . ' is deprecated and will be removed in TYPO3 v10.0.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
switch ($quotedValue[0]) {
|
||||
case '"':
|
||||
$quotedValue = str_replace('\\"', '"', trim($quotedValue, '"'));
|
||||
break;
|
||||
case '\'':
|
||||
$quotedValue = str_replace('\\\'', '\'', trim($quotedValue, '\''));
|
||||
break;
|
||||
}
|
||||
$quotedValue = str_replace('\\\\', '\\', $quotedValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object of an appropriate validator for the given class. If no validator is available
|
||||
* FALSE is returned
|
||||
*
|
||||
* @param string $validatorName Either the fully qualified class name of the validator or the short name of a built-in validator
|
||||
*
|
||||
* @throws Exception\NoSuchValidatorException
|
||||
* @return string Name of the validator object
|
||||
* @internal
|
||||
*/
|
||||
public function resolveValidatorObjectName($validatorName)
|
||||
{
|
||||
if (strpos($validatorName, ':') !== false) {
|
||||
// Found shorthand validator, either extbase or foreign extension
|
||||
// NotEmpty or Acme.MyPck.Ext:MyValidator
|
||||
list($extensionName, $extensionValidatorName) = explode(':', $validatorName);
|
||||
|
||||
if ($validatorName !== $extensionName && $extensionValidatorName !== '') {
|
||||
// Shorthand custom
|
||||
if (strpos($extensionName, '.') !== false) {
|
||||
$extensionNameParts = explode('.', $extensionName);
|
||||
$extensionName = array_pop($extensionNameParts);
|
||||
$vendorName = implode('\\', $extensionNameParts);
|
||||
$possibleClassName = $vendorName . '\\' . $extensionName . '\\Validation\\Validator\\' . $extensionValidatorName;
|
||||
}
|
||||
} else {
|
||||
// Shorthand built in
|
||||
$possibleClassName = 'TYPO3\\CMS\\Extbase\\Validation\\Validator\\' . $this->getValidatorType($validatorName);
|
||||
}
|
||||
} elseif (strpbrk($validatorName, '\\') === false) {
|
||||
// Shorthand built in
|
||||
$possibleClassName = 'TYPO3\\CMS\\Extbase\\Validation\\Validator\\' . $this->getValidatorType($validatorName);
|
||||
} else {
|
||||
// Full qualified
|
||||
// Example: \Acme\Ext\Validation\Validator\FooValidator
|
||||
$possibleClassName = $validatorName;
|
||||
if (!empty($possibleClassName) && $possibleClassName[0] === '\\') {
|
||||
$possibleClassName = substr($possibleClassName, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (substr($possibleClassName, - strlen('Validator')) !== 'Validator') {
|
||||
$possibleClassName .= 'Validator';
|
||||
}
|
||||
|
||||
if (class_exists($possibleClassName)) {
|
||||
$possibleClassNameInterfaces = class_implements($possibleClassName);
|
||||
if (!in_array(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface::class, $possibleClassNameInterfaces)) {
|
||||
// The guessed validatorname is a valid class name, but does not implement the ValidatorInterface
|
||||
throw new NoSuchValidatorException('Validator class ' . $validatorName . ' must implement \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface', 1365776838);
|
||||
}
|
||||
$resolvedValidatorName = $possibleClassName;
|
||||
} else {
|
||||
throw new NoSuchValidatorException('Validator class ' . $validatorName . ' does not exist', 1365799920);
|
||||
}
|
||||
|
||||
return $resolvedValidatorName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to map PHP types to validator types.
|
||||
*
|
||||
* @param string $type Data type to unify
|
||||
* @return string unified data type
|
||||
*/
|
||||
protected function getValidatorType($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'int':
|
||||
$type = 'Integer';
|
||||
break;
|
||||
case 'bool':
|
||||
$type = 'Boolean';
|
||||
break;
|
||||
case 'double':
|
||||
$type = 'Float';
|
||||
break;
|
||||
case 'numeric':
|
||||
$type = 'Number';
|
||||
break;
|
||||
case 'mixed':
|
||||
$type = 'Raw';
|
||||
break;
|
||||
default:
|
||||
$type = ucfirst($type);
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary replacement for $this->reflectionService->getMethodAnnotations()
|
||||
*
|
||||
* @param string $className
|
||||
* @param string $methodName
|
||||
*
|
||||
* @return array
|
||||
* @deprecated Helper, remove in TYPO3 v10.0 together with buildMethodArgumentsValidatorConjunctions()
|
||||
*/
|
||||
public function getMethodValidateAnnotations($className, $methodName)
|
||||
{
|
||||
$validateAnnotations = [];
|
||||
$methodTagsValues = $this->reflectionService->getClassSchema($className)->getMethod($methodName)['tags'] ?? [];
|
||||
if (isset($methodTagsValues['validate']) && is_array($methodTagsValues['validate'])) {
|
||||
foreach ($methodTagsValues['validate'] as $validateValue) {
|
||||
$parsedAnnotations = $this->parseValidatorAnnotation($validateValue);
|
||||
|
||||
foreach ($parsedAnnotations['validators'] as $validator) {
|
||||
$validateAnnotations[] = [
|
||||
'argumentName' => $parsedAnnotations['argumentName'],
|
||||
'validatorName' => $validator['validatorName'],
|
||||
'validatorOptions' => $validator['validatorOptions']
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $validateAnnotations;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user