diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85012-OnlyValidateMethodParamsIfNeeded.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85012-OnlyValidateMethodParamsIfNeeded.rst new file mode 100644 index 0000000000000000000000000000000000000000..6d09a511b3f87471910e57f1854aeb674d3d3149 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85012-OnlyValidateMethodParamsIfNeeded.rst @@ -0,0 +1,38 @@ +.. include:: ../../Includes.txt + +=========================================================== +Deprecation: #85012 - Only validate method params if needed +=========================================================== + +See :issue:`85012` + +Description +=========== + +The following public methods have been marked as deprecated: + +* :php:`TYPO3\CMS\Extbase\Mvc\Controller\Argument::getValidationResults()` +* :php:`TYPO3\CMS\Extbase\Mvc\Controller\Arguments::getValidationResults()` + +Impact +====== + +Calling the method triggers a deprecation log entry. + + +Affected Installations +====================== + +Extensions that call that method. The extension scanner will find usages. + + +Migration +========= + +Use the following methods instead: + +* :php:`TYPO3\CMS\Extbase\Mvc\Controller\Argument::validate()` +* :php:`TYPO3\CMS\Extbase\Mvc\Controller\Arguments::validate()` + + +.. index:: PHP-API, FullyScanned, ext:extbase diff --git a/typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php b/typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php index 4ace0e0199ca09acc1806333e51fafc3bd824223..0b7aa14c323d4460cf23dd27495c44cf50395a2f 100644 --- a/typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php +++ b/typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php @@ -257,8 +257,16 @@ class ActionController extends AbstractController $classSchema = $this->reflectionService->getClassSchema(static::class); + $ignoreValidationAnnotations = array_unique(array_flip( + $classSchema->getMethod($this->actionMethodName)['tags']['ignorevalidation'] ?? [] + )); + /** @var \TYPO3\CMS\Extbase\Mvc\Controller\Argument $argument */ foreach ($this->arguments as $argument) { + if (isset($ignoreValidationAnnotations[$argument->getName()])) { + continue; + } + $validator = $this->objectManager->get(ConjunctionValidator::class); $validatorDefinitions = $classSchema->getMethod($this->actionMethodName)['params'][$argument->getName()]['validators'] ?? []; @@ -313,33 +321,12 @@ class ActionController extends AbstractController foreach ($this->arguments as $argument) { $preparedArguments[] = $argument->getValue(); } - $validationResult = $this->arguments->getValidationResults(); + $validationResult = $this->arguments->validate(); if (!$validationResult->hasErrors()) { $this->emitBeforeCallActionMethodSignal($preparedArguments); - $actionResult = call_user_func_array([$this, $this->actionMethodName], $preparedArguments); + $actionResult = $this->{$this->actionMethodName}(...$preparedArguments); } else { - $methodTagsValues = $this->reflectionService->getMethodTagsValues(static::class, $this->actionMethodName); - $ignoreValidationAnnotations = $methodTagsValues['ignorevalidation'] ?? []; - - // if there exist errors which are not ignored with @TYPO3\CMS\Extbase\Annotation\IgnoreValidation => call error method - // else => call action method - $shouldCallActionMethod = true; - foreach ($validationResult->getSubResults() as $argumentName => $subValidationResult) { - if (!$subValidationResult->hasErrors()) { - continue; - } - if (in_array($argumentName, $ignoreValidationAnnotations, true)) { - continue; - } - $shouldCallActionMethod = false; - break; - } - if ($shouldCallActionMethod) { - $this->emitBeforeCallActionMethodSignal($preparedArguments); - $actionResult = call_user_func_array([$this, $this->actionMethodName], $preparedArguments); - } else { - $actionResult = call_user_func([$this, $this->errorMethodName]); - } + $actionResult = $this->{$this->errorMethodName}(); } if ($actionResult === null && $this->view instanceof ViewInterface) { @@ -610,7 +597,7 @@ class ActionController extends AbstractController if ($referringRequest !== null) { $originalRequest = clone $this->request; $this->request->setOriginalRequest($originalRequest); - $this->request->setOriginalRequestMappingResults($this->arguments->getValidationResults()); + $this->request->setOriginalRequestMappingResults($this->arguments->validate()); $this->forward( $referringRequest->getControllerActionName(), $referringRequest->getControllerName(), diff --git a/typo3/sysext/extbase/Classes/Mvc/Controller/Argument.php b/typo3/sysext/extbase/Classes/Mvc/Controller/Argument.php index e13efb9a3717b954a9d6316b50611f0303ebbe9e..798ae6f529a63bffbd5d89072022589fba92d610 100644 --- a/typo3/sysext/extbase/Classes/Mvc/Controller/Argument.php +++ b/typo3/sysext/extbase/Classes/Mvc/Controller/Argument.php @@ -14,6 +14,7 @@ namespace TYPO3\CMS\Extbase\Mvc\Controller; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Extbase\Error\Result; use TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException; use TYPO3\CMS\Extbase\Utility\TypeHandlingUtility; @@ -88,7 +89,12 @@ class Argument * * @var \TYPO3\CMS\Extbase\Error\Result */ - protected $validationResults = null; + protected $validationResults; + + /** + * @var bool + */ + private $hasBeenValidated = false; /** * @param \TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper @@ -124,6 +130,8 @@ class Argument } $this->name = $name; $this->dataType = TypeHandlingUtility::normalizeType($dataType); + + $this->validationResults = new Result(); } /** @@ -274,12 +282,7 @@ class Argument throw $e; } } - $this->validationResults = $this->propertyMapper->getMessages(); - if ($this->validator !== null) { - // @todo Validation API has also changed!!! - $validationMessages = $this->validator->validate($this->value); - $this->validationResults->merge($validationMessages); - } + $this->validationResults->merge($this->propertyMapper->getMessages()); return $this; } @@ -312,18 +315,23 @@ class Argument * @return bool TRUE if the argument is valid, FALSE otherwise * @api */ - public function isValid() + public function isValid(): bool { - return !$this->validationResults->hasErrors(); + return !$this->validate()->hasErrors(); } /** * @return \TYPO3\CMS\Extbase\Error\Result Validation errors which have occurred. - * @api + * @deprecated */ public function getValidationResults() { - return $this->validationResults; + trigger_error( + 'Method ' . __METHOD__ . ' is deprecated and will be removed in TYPO3 v10.0.', + E_USER_DEPRECATED + ); + + return $this->validate(); } /** @@ -336,4 +344,23 @@ class Argument { return (string)$this->value; } + + /** + * @return \TYPO3\CMS\Extbase\Error\Result + * @api + */ + public function validate(): \TYPO3\CMS\Extbase\Error\Result + { + if ($this->hasBeenValidated) { + return $this->validationResults; + } + + if ($this->validator !== null) { + $validationMessages = $this->validator->validate($this->value); + $this->validationResults->merge($validationMessages); + } + + $this->hasBeenValidated = true; + return $this->validationResults; + } } diff --git a/typo3/sysext/extbase/Classes/Mvc/Controller/Arguments.php b/typo3/sysext/extbase/Classes/Mvc/Controller/Arguments.php index c70dc455ce75d4cf7ad28a7a8c90d16e711e490f..e2936fe32ce17cd24ff65a0bc24153b414b3b783 100644 --- a/typo3/sysext/extbase/Classes/Mvc/Controller/Arguments.php +++ b/typo3/sysext/extbase/Classes/Mvc/Controller/Arguments.php @@ -275,13 +275,27 @@ class Arguments extends \ArrayObject * Get all property mapping / validation errors * * @return \TYPO3\CMS\Extbase\Error\Result + * @deprecated */ public function getValidationResults() + { + trigger_error( + 'Method ' . __METHOD__ . ' is deprecated and will be removed in TYPO3 v10.0.', + E_USER_DEPRECATED + ); + + return $this->validate(); + } + + /** + * @return \TYPO3\CMS\Extbase\Error\Result + */ + public function validate(): \TYPO3\CMS\Extbase\Error\Result { $results = new \TYPO3\CMS\Extbase\Error\Result(); /** @var Argument $argument */ foreach ($this as $argument) { - $argumentValidationResults = $argument->getValidationResults(); + $argumentValidationResults = $argument->validate(); if ($argumentValidationResults === null) { continue; } diff --git a/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/ArgumentTest.php b/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/ArgumentTest.php index 8ce709200328d951a804dfee6cc319f1c4133d0a..165b479a03ad8069480b38187eb78b6bc1f23849 100644 --- a/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/ArgumentTest.php +++ b/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/ArgumentTest.php @@ -231,7 +231,7 @@ class ArgumentTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase $this->simpleValueArgument->setValidator($mockValidator); $this->setupPropertyMapperAndSetValue(); $this->assertFalse($this->simpleValueArgument->isValid()); - $this->assertEquals([$error], $this->simpleValueArgument->getValidationResults()->getErrors()); + $this->assertEquals([$error], $this->simpleValueArgument->validate()->getErrors()); } /** diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php index af8dbf5e417c890ede0ac40cf426cb8cc163c403..1dc067d4eb2ecbb6712f8869c8636e5a397eac61 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php @@ -2249,4 +2249,18 @@ return [ 'Deprecation-85005-DeprecateMethodsAndConstantsInValidatorResolver.rst', ], ], + 'TYPO3\CMS\Extbase\Mvc\Controller\Argument->getValidationResults' => [ + 'numberOfMandatoryArguments' => 0, + 'maximumNumberOfArguments' => 0, + 'restFiles' => [ + 'Deprecation-85012-OnlyValidateMethodParamsIfNeeded.rst', + ], + ], + 'TYPO3\CMS\Extbase\Mvc\Controller\Arguments->getValidationResults' => [ + 'numberOfMandatoryArguments' => 0, + 'maximumNumberOfArguments' => 0, + 'restFiles' => [ + 'Deprecation-85012-OnlyValidateMethodParamsIfNeeded.rst', + ], + ], ];