From 08370e2fc7e6c9040a6c1473c38a731bf131aad7 Mon Sep 17 00:00:00 2001 From: Alexander Schnitzler <git@alexanderschnitzler.de> Date: Sat, 25 Nov 2017 16:25:02 +0100 Subject: [PATCH] [FEATURE] Replace @ignorevalidation with @Extbase\IgnoreValidation This patch introduces the "TYPO3\CMS\Extbase\Annotation\IgnoreValidation" annotation that replaces the @ignorevalidation annotation which is deprecated from now on. Releases: master Resolves: #83094 Change-Id: Ic8b05d754a9d5da3097b971780f1c229b06ac1c8 Reviewed-on: https://review.typo3.org/54762 Reviewed-by: Tymoteusz Motylewski <t.motylewski@gmail.com> Tested-by: Tymoteusz Motylewski <t.motylewski@gmail.com> Reviewed-by: Henning Liebe <h.liebe@neusta.de> Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> --- typo3/sysext/core/Classes/Core/Bootstrap.php | 5 +- ...O3CMSExtbaseAnnotationIgnoreValidation.rst | 32 +++++++ ...O3CMSExtbaseAnnotationIgnoreValidation.rst | 69 +++++++++++++++ .../Classes/Annotation/IgnoreValidation.php | 42 +++++++++ .../Mvc/Controller/ActionController.php | 10 +-- .../sysext/extbase/Classes/Mvc/Dispatcher.php | 2 +- .../Classes/Reflection/ClassSchema.php | 19 ++++- .../Tests/Unit/Reflection/ClassSchemaTest.php | 9 ++ ...WithIgnoreValidationDoctrineAnnotation.php | 35 ++++++++ .../Reflection/ClassSchemaTest.php | 6 ++ ...ntrollerWithIgnorevalidationAnnotation.php | 31 +++++++ .../Classes/Controller/UpgradeController.php | 5 ++ .../Php/Matcher/MethodAnnotationMatcher.php | 85 +++++++++++++++++++ .../Php/MethodAnnotationMatcher.php | 9 ++ .../MethodAnnotationMatcherFixture.php | 29 +++++++ .../Matcher/MethodAnnotationMatcherTest.php | 61 +++++++++++++ 16 files changed, 440 insertions(+), 9 deletions(-) create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Deprecation-83094-ReplaceIgnorevalidationWithTYPO3CMSExtbaseAnnotationIgnoreValidation.rst create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Feature-83094-ReplaceIgnorevalidationWithTYPO3CMSExtbaseAnnotationIgnoreValidation.rst create mode 100644 typo3/sysext/extbase/Classes/Annotation/IgnoreValidation.php create mode 100644 typo3/sysext/extbase/Tests/Unit/Reflection/Fixture/DummyControllerWithIgnoreValidationDoctrineAnnotation.php create mode 100644 typo3/sysext/extbase/Tests/UnitDeprecated/Reflection/Fixture/DummyControllerWithIgnorevalidationAnnotation.php create mode 100644 typo3/sysext/install/Classes/ExtensionScanner/Php/Matcher/MethodAnnotationMatcher.php create mode 100644 typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodAnnotationMatcher.php create mode 100644 typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/MethodAnnotationMatcherFixture.php create mode 100644 typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/MethodAnnotationMatcherTest.php diff --git a/typo3/sysext/core/Classes/Core/Bootstrap.php b/typo3/sysext/core/Classes/Core/Bootstrap.php index 25c542dd679b..a6649baddb5c 100644 --- a/typo3/sysext/core/Classes/Core/Bootstrap.php +++ b/typo3/sysext/core/Classes/Core/Bootstrap.php @@ -237,10 +237,13 @@ class Bootstrap AnnotationReader::addGlobalIgnoredName('cascade'); AnnotationReader::addGlobalIgnoredName('ignorevalidation'); AnnotationReader::addGlobalIgnoredName('cli'); - AnnotationReader::addGlobalIgnoredName('flushesCashes'); + AnnotationReader::addGlobalIgnoredName('flushesCaches'); AnnotationReader::addGlobalIgnoredName('uuid'); AnnotationReader::addGlobalIgnoredName('identity'); + // Annotations used in unit tests + AnnotationReader::addGlobalIgnoredName('test'); + // Annotations that control the extension scanner AnnotationReader::addGlobalIgnoredName('extensionScannerIgnoreFile'); AnnotationReader::addGlobalIgnoredName('extensionScannerIgnoreLine'); diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-83094-ReplaceIgnorevalidationWithTYPO3CMSExtbaseAnnotationIgnoreValidation.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-83094-ReplaceIgnorevalidationWithTYPO3CMSExtbaseAnnotationIgnoreValidation.rst new file mode 100644 index 000000000000..0b17b16907bf --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-83094-ReplaceIgnorevalidationWithTYPO3CMSExtbaseAnnotationIgnoreValidation.rst @@ -0,0 +1,32 @@ +.. include:: ../../Includes.txt + +=================================================================================================== +Deprecation: #83094 - Replace @ignorevalidation with @TYPO3\CMS\Extbase\Annotation\IgnoreValidation +=================================================================================================== + +See :issue:`83094` + +Description +=========== + +The `@ignorevalidation` annotation has been deprecated and must be replaced with the doctrine annotation `@TYPO3\CMS\Extbase\Annotation\IgnoreValidation`. + + +Impact +====== + +From version 9.0 on, `@ignorevalidation` is deprecated and will be removed in version 10. + + +Affected Installations +====================== + +All extensions that use `@ignorevalidation` + + +Migration +========= + +Use `@TYPO3\CMS\Extbase\Annotation\IgnoreValidation` instead. + +.. index:: PHP-API, ext:extbase, FullyScanned diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-83094-ReplaceIgnorevalidationWithTYPO3CMSExtbaseAnnotationIgnoreValidation.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-83094-ReplaceIgnorevalidationWithTYPO3CMSExtbaseAnnotationIgnoreValidation.rst new file mode 100644 index 000000000000..c1caf55172e7 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-83094-ReplaceIgnorevalidationWithTYPO3CMSExtbaseAnnotationIgnoreValidation.rst @@ -0,0 +1,69 @@ +.. include:: ../../Includes.txt + +=============================================================================================== +Feature: #83094 - Replace @ignorevalidation with @TYPO3\CMS\Extbase\Annotation\IgnoreValidation +=============================================================================================== + +See :issue:`83094` + +Description +=========== + +As a successor to the `@ignorevalidation` annotation, the doctrine annotation `@TYPO3\CMS\Extbase\Annotation\IgnoreValidation` has been introduced. + +Example: + +.. code-block:: php + + /** + * @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("param") + */ + public function method($param) + { + } + +Doctrine annotations are actual defined classes, therefore you can also use the annotation with a use statement. + +Example: + +.. code-block:: php + + use TYPO3\CMS\Extbase\Annotation\IgnoreValidation; + +.. code-block:: php + + /** + * @IgnoreValidation("param") + */ + public function method($param) + { + } + +Used annotations can also be aliased which the core will most likely be using a lot in the future. + +Example: + +.. code-block:: php + + use TYPO3\CMS\Extbase\Annotation as Extbase; + +.. code-block:: php + + /** + * @Extbase\IgnoreValidation("param") + */ + public function method($param) + { + } + +.. tip:: + + Please mind that `@TYPO3\CMS\Extbase\Annotation\IgnoreValidation` does no longer accept parameter names prepended with dollar signs `$`. + Example: `@ignorevalidation $foo` becomes `@Extbase\IgnoreValidation("foo")` + +Impact +====== + +In 9.x there is no actual impact. Both the simple `@ignorevalidation` and `@TYPO3\CMS\Extbase\Annotation\IgnoreValidation` can be used side by side. However, `@ignorevalidation` is deprecated in 9.x and will be removed in version 10. + +.. index:: PHP-API, ext:extbase, FullyScanned diff --git a/typo3/sysext/extbase/Classes/Annotation/IgnoreValidation.php b/typo3/sysext/extbase/Classes/Annotation/IgnoreValidation.php new file mode 100644 index 000000000000..112edfe7f7ea --- /dev/null +++ b/typo3/sysext/extbase/Classes/Annotation/IgnoreValidation.php @@ -0,0 +1,42 @@ +<?php +declare(strict_types=1); + +namespace TYPO3\CMS\Extbase\Annotation; + +/* + * 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! + */ + +/** + * @Annotation + * @Target({"METHOD"}) + */ +class IgnoreValidation +{ + /** + * @var string + */ + public $argumentName; + + /** + * @param array $values + * @throws \InvalidArgumentException + */ + public function __construct(array $values) + { + if (isset($values['value'])) { + $this->argumentName = $values['value']; + } elseif (isset($values['argumentName'])) { + $this->argumentName = $values['argumentName']; + } + } +} diff --git a/typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php b/typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php index ebc0bba86111..d5af3a1a4d03 100644 --- a/typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php +++ b/typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php @@ -316,18 +316,16 @@ class ActionController extends AbstractController $actionResult = call_user_func_array([$this, $this->actionMethodName], $preparedArguments); } else { $methodTagsValues = $this->reflectionService->getMethodTagsValues(static::class, $this->actionMethodName); - $ignoreValidationAnnotations = []; - if (isset($methodTagsValues['ignorevalidation'])) { - $ignoreValidationAnnotations = $methodTagsValues['ignorevalidation']; - } - // if there exist errors which are not ignored with @ignorevalidation => call error method + $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 (array_search('$' . $argumentName, $ignoreValidationAnnotations) !== false) { + if (in_array($argumentName, $ignoreValidationAnnotations, true)) { continue; } $shouldCallActionMethod = false; diff --git a/typo3/sysext/extbase/Classes/Mvc/Dispatcher.php b/typo3/sysext/extbase/Classes/Mvc/Dispatcher.php index 6d82759185e6..5bd8709e3854 100644 --- a/typo3/sysext/extbase/Classes/Mvc/Dispatcher.php +++ b/typo3/sysext/extbase/Classes/Mvc/Dispatcher.php @@ -65,7 +65,7 @@ class Dispatcher implements \TYPO3\CMS\Core\SingletonInterface $dispatchLoopCount = 0; while (!$request->isDispatched()) { if ($dispatchLoopCount++ > 99) { - throw new \TYPO3\CMS\Extbase\Mvc\Exception\InfiniteLoopException('Could not ultimately dispatch the request after ' . $dispatchLoopCount . ' iterations. Most probably, a @ignorevalidation annotation is missing on re-displaying a form with validation errors.', 1217839467); + throw new \TYPO3\CMS\Extbase\Mvc\Exception\InfiniteLoopException('Could not ultimately dispatch the request after ' . $dispatchLoopCount . ' iterations. Most probably, a @' . \TYPO3\CMS\Extbase\Annotation\IgnoreValidation::class . ' annotation is missing on re-displaying a form with validation errors.', 1217839467); } $controller = $this->resolveController($request); try { diff --git a/typo3/sysext/extbase/Classes/Reflection/ClassSchema.php b/typo3/sysext/extbase/Classes/Reflection/ClassSchema.php index 8082e894b7fc..7b86160c8c69 100644 --- a/typo3/sysext/extbase/Classes/Reflection/ClassSchema.php +++ b/typo3/sysext/extbase/Classes/Reflection/ClassSchema.php @@ -17,6 +17,7 @@ namespace TYPO3\CMS\Extbase\Reflection; use Doctrine\Common\Annotations\AnnotationReader; use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Utility\ClassNamingUtility; +use TYPO3\CMS\Extbase\Annotation\IgnoreValidation; use TYPO3\CMS\Extbase\Annotation\Inject; use TYPO3\CMS\Extbase\Annotation\ORM\Cascade; use TYPO3\CMS\Extbase\Annotation\ORM\Lazy; @@ -287,6 +288,8 @@ class ClassSchema */ protected function reflectMethods(\ReflectionClass $reflectionClass) { + $annotationReader = new AnnotationReader(); + foreach ($reflectionClass->getMethods() as $reflectionMethod) { $methodName = $reflectionMethod->getName(); @@ -302,7 +305,21 @@ class ClassSchema $docCommentParser = new DocCommentParser(true); $docCommentParser->parseDocComment($reflectionMethod->getDocComment()); foreach ($docCommentParser->getTagsValues() as $tag => $values) { - $this->methods[$methodName]['tags'][$tag] = $values; + if ($tag === 'ignorevalidation') { + trigger_error( + 'Tagging methods with @ignorevalidation is deprecated and will be removed in TYPO3 v10.0.', + E_USER_DEPRECATED + ); + } + $this->methods[$methodName]['tags'][$tag] = array_map(function ($value) { + return ltrim($value, '$'); + }, $values); + } + + foreach ($annotationReader->getMethodAnnotations($reflectionMethod) as $annotation) { + if ($annotation instanceof IgnoreValidation) { + $this->methods[$methodName]['tags']['ignorevalidation'][] = $annotation->argumentName; + } } $this->methods[$methodName]['description'] = $docCommentParser->getDescription(); diff --git a/typo3/sysext/extbase/Tests/Unit/Reflection/ClassSchemaTest.php b/typo3/sysext/extbase/Tests/Unit/Reflection/ClassSchemaTest.php index cd266a52e95a..db68e415a17f 100644 --- a/typo3/sysext/extbase/Tests/Unit/Reflection/ClassSchemaTest.php +++ b/typo3/sysext/extbase/Tests/Unit/Reflection/ClassSchemaTest.php @@ -276,6 +276,15 @@ class ClassSchemaTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase static::assertNull($propertyDefinition['annotations']['cascade']); } + public function testClassSchemaDetectsIgnoreValidationAnnotation() + { + $classSchema = new ClassSchema(Fixture\DummyControllerWithIgnoreValidationDoctrineAnnotation::class); + static::assertTrue(isset($classSchema->getMethod('someAction')['tags']['ignorevalidation'])); + static::assertTrue(in_array('foo', $classSchema->getMethod('someAction')['tags']['ignorevalidation'], true)); + static::assertTrue(in_array('bar', $classSchema->getMethod('someAction')['tags']['ignorevalidation'], true)); + static::assertFalse(in_array('baz', $classSchema->getMethod('someAction')['tags']['ignorevalidation'], true)); + } + public function testClassSchemaDetectsTypeAndElementType() { $classSchema = new ClassSchema(Fixture\DummyClassWithAllTypesOfProperties::class); diff --git a/typo3/sysext/extbase/Tests/Unit/Reflection/Fixture/DummyControllerWithIgnoreValidationDoctrineAnnotation.php b/typo3/sysext/extbase/Tests/Unit/Reflection/Fixture/DummyControllerWithIgnoreValidationDoctrineAnnotation.php new file mode 100644 index 000000000000..cff943601aae --- /dev/null +++ b/typo3/sysext/extbase/Tests/Unit/Reflection/Fixture/DummyControllerWithIgnoreValidationDoctrineAnnotation.php @@ -0,0 +1,35 @@ +<?php +declare(strict_types=1); + +namespace TYPO3\CMS\Extbase\Tests\Unit\Reflection\Fixture; + +/* + * 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\Annotation\IgnoreValidation; + +/** + * Dummy controller with @TYPO3\CMS\Extbase\Annotation\IgnoreValidation annotation + */ +class DummyControllerWithIgnoreValidationDoctrineAnnotation +{ + /** + * @param $foo + * @param $bar + * @ignorevalidation("foo") + * @IgnoreValidation("bar") + */ + public function someAction($foo, $bar) + { + } +} diff --git a/typo3/sysext/extbase/Tests/UnitDeprecated/Reflection/ClassSchemaTest.php b/typo3/sysext/extbase/Tests/UnitDeprecated/Reflection/ClassSchemaTest.php index 84fc91e184c8..92be1f1f7e25 100644 --- a/typo3/sysext/extbase/Tests/UnitDeprecated/Reflection/ClassSchemaTest.php +++ b/typo3/sysext/extbase/Tests/UnitDeprecated/Reflection/ClassSchemaTest.php @@ -54,4 +54,10 @@ class ClassSchemaTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase $propertyDefinition = $classSchema->getProperty('propertyWithCascadeAnnotationWithoutVarAnnotation'); static::assertNull($propertyDefinition['annotations']['cascade']); } + + public function testClassSchemaDetectsIgnoreValidationAnnotation() + { + $classSchema = new ClassSchema(Fixture\DummyControllerWithIgnorevalidationAnnotation::class); + static::assertTrue(isset($classSchema->getMethod('someAction')['tags']['ignorevalidation'])); + } } diff --git a/typo3/sysext/extbase/Tests/UnitDeprecated/Reflection/Fixture/DummyControllerWithIgnorevalidationAnnotation.php b/typo3/sysext/extbase/Tests/UnitDeprecated/Reflection/Fixture/DummyControllerWithIgnorevalidationAnnotation.php new file mode 100644 index 000000000000..ec47c39cd63b --- /dev/null +++ b/typo3/sysext/extbase/Tests/UnitDeprecated/Reflection/Fixture/DummyControllerWithIgnorevalidationAnnotation.php @@ -0,0 +1,31 @@ +<?php +namespace TYPO3\CMS\Extbase\Tests\UnitDeprecated\Reflection\Fixture; + +/* + * 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! + */ + +/** + * Fixture class with getters and setters + */ +class DummyControllerWithIgnorevalidationAnnotation +{ + /** + * @param $someArgument + * @ignorevalidation $someArgument + * @ignorevalidation $foo + * @ignorevalidation $foo $bar + */ + public function someAction($someArgument) + { + } +} diff --git a/typo3/sysext/install/Classes/Controller/UpgradeController.php b/typo3/sysext/install/Classes/Controller/UpgradeController.php index 9e84755e5578..fe3dd966bf59 100644 --- a/typo3/sysext/install/Classes/Controller/UpgradeController.php +++ b/typo3/sysext/install/Classes/Controller/UpgradeController.php @@ -42,6 +42,7 @@ use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ClassNameMatcher; use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ConstantMatcher; use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\FunctionCallMatcher; use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\InterfaceMethodChangedMatcher; +use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodAnnotationMatcher; use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodArgumentDroppedMatcher; use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodArgumentDroppedStaticMatcher; use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodArgumentRequiredMatcher; @@ -104,6 +105,10 @@ class UpgradeController extends AbstractController 'class' => PropertyAnnotationMatcher::class, 'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/PropertyAnnotationMatcher.php', ], + [ + 'class' => MethodAnnotationMatcher::class, + 'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/MethodAnnotationMatcher.php', + ], [ 'class' => FunctionCallMatcher::class, 'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/FunctionCallMatcher.php', diff --git a/typo3/sysext/install/Classes/ExtensionScanner/Php/Matcher/MethodAnnotationMatcher.php b/typo3/sysext/install/Classes/ExtensionScanner/Php/Matcher/MethodAnnotationMatcher.php new file mode 100644 index 000000000000..43013e7233b3 --- /dev/null +++ b/typo3/sysext/install/Classes/ExtensionScanner/Php/Matcher/MethodAnnotationMatcher.php @@ -0,0 +1,85 @@ +<?php +declare(strict_types=1); +namespace TYPO3\CMS\Install\ExtensionScanner\Php\Matcher; + +/* + * 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 PhpParser\Comment\Doc; +use PhpParser\Node; +use PhpParser\Node\Stmt\ClassMethod; + +/** + * Find usages of method annotations + */ +class MethodAnnotationMatcher extends AbstractCoreMatcher +{ + /** + * Prepare $this->flatMatcherDefinitions once and validate config + * + * @param array $matcherDefinitions Incoming main configuration + */ + public function __construct(array $matcherDefinitions) + { + $this->matcherDefinitions = $matcherDefinitions; + $this->validateMatcherDefinitions(); + } + + /** + * Called by PhpParser. + * Test for method annotations (strong match) + * + * @param Node $node + */ + public function enterNode(Node $node) + { + if ($node instanceof ClassMethod + && ($docComment = $node->getDocComment()) instanceof Doc + && !$this->isFileIgnored($node) + && !$this->isLineIgnored($node) + ) { + $isPossibleMatch = false; + $match = [ + 'restFiles' => [], + 'line' => $node->getAttribute('startLine'), + 'indicator' => 'strong', + ]; + + $matches = []; + preg_match_all( + '/\s*\s@(?<annotations>[^\s.]*).*\n/', + $docComment->getText(), + $matches + ); + + foreach ($matches['annotations'] as $annotation) { + $annotation = '@' . $annotation; + + if (!isset($this->matcherDefinitions[$annotation])) { + continue; + } + + $isPossibleMatch = true; + $match['message'] = 'Method "' . $node->name . '" uses an ' . $annotation . ' annotation.'; + $match['restFiles'] = array_unique(array_merge( + $match['restFiles'], + $this->matcherDefinitions[$annotation]['restFiles'] + )); + } + + if ($isPossibleMatch) { + $this->matches[] = $match; + } + } + } +} diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodAnnotationMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodAnnotationMatcher.php new file mode 100644 index 000000000000..3aafed70fc04 --- /dev/null +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodAnnotationMatcher.php @@ -0,0 +1,9 @@ +<?php +return [ + '@ignorevalidation' => [ + 'restFiles' => [ + 'Feature-83094-ReplaceIgnorevalidationWithTYPO3CMSExtbaseAnnotationIgnoreValidation.rst', + 'Deprecation-83094-ReplaceIgnorevalidationWithTYPO3CMSExtbaseAnnotationIgnoreValidation.rst', + ], + ], +]; diff --git a/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/MethodAnnotationMatcherFixture.php b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/MethodAnnotationMatcherFixture.php new file mode 100644 index 000000000000..cc6f0450f7a4 --- /dev/null +++ b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/MethodAnnotationMatcherFixture.php @@ -0,0 +1,29 @@ +<?php +declare(strict_types=1); +namespace TYPO3\CMS\Install\Tests\Unit\ExtensionScanner\Php\Matcher\Fixtures; + +/* + * 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! + */ + +/** + * Fixture file + */ +class MethodAnnotationMatcherFixture +{ + /** + * @inject + */ + public function foo() + { + } +} diff --git a/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/MethodAnnotationMatcherTest.php b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/MethodAnnotationMatcherTest.php new file mode 100644 index 000000000000..0aacd651e733 --- /dev/null +++ b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/MethodAnnotationMatcherTest.php @@ -0,0 +1,61 @@ +<?php +declare(strict_types=1); +namespace TYPO3\CMS\Install\Tests\Unit\ExtensionScanner\Php\Matcher; + +/* + * 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 PhpParser\NodeTraverser; +use PhpParser\NodeVisitor\NameResolver; +use PhpParser\ParserFactory; +use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodAnnotationMatcher; +use TYPO3\TestingFramework\Core\Unit\UnitTestCase; + +/** + * Test case + */ +class MethodAnnotationMatcherTest extends UnitTestCase +{ + /** + * @test + */ + public function hitsFromFixtureAreFound() + { + $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); + $fixtureFile = __DIR__ . '/Fixtures/MethodAnnotationMatcherFixture.php'; + $statements = $parser->parse(file_get_contents($fixtureFile)); + + $traverser = new NodeTraverser(); + $traverser->addVisitor(new NameResolver()); + + $configuration = [ + '@inject' => [ + 'restFiles' => [ + 'Feature-82869-ReplaceInjectWithTYPO3CMSExtbaseAnnotationInject.rst', + 'Deprecation-82869-ReplaceInjectWithTYPO3CMSExtbaseAnnotationInject.rst', + ], + ], + ]; + $subject = new MethodAnnotationMatcher($configuration); + $traverser->addVisitor($subject); + $traverser->traverse($statements); + $expectedHitLineNumbers = [ + 26, + ]; + $actualHitLineNumbers = []; + foreach ($subject->getMatches() as $hit) { + $actualHitLineNumbers[] = $hit['line']; + } + $this->assertEquals($expectedHitLineNumbers, $actualHitLineNumbers); + } +} -- GitLab