From dbce47d7e33780af56d8d40da46f63b1fc2b45ed Mon Sep 17 00:00:00 2001
From: Alexander Schnitzler <git@alexanderschnitzler.de>
Date: Tue, 28 Nov 2017 19:01:10 +0100
Subject: [PATCH] [TASK] Separately extract @validate annotations

Separately exctracting the @validate annotations
makes resolving these annotations more testable.

Also this allows to deprecate the usage of @validate
in favor of a doctrine annotation.

Releases: master
Resolves: #83143
Change-Id: I4dfd93b58e08cd5c458abebee36e82e9ce03ad47
Reviewed-on: https://review.typo3.org/54838
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
---
 .../Classes/Reflection/ClassSchema.php        | 12 +++++
 .../Tests/Unit/Reflection/ClassSchemaTest.php | 33 ++++++++++++++
 .../DummyClassWithValidateAnnotation.php      | 44 +++++++++++++++++++
 3 files changed, 89 insertions(+)
 create mode 100644 typo3/sysext/extbase/Tests/Unit/Reflection/Fixture/DummyClassWithValidateAnnotation.php

diff --git a/typo3/sysext/extbase/Classes/Reflection/ClassSchema.php b/typo3/sysext/extbase/Classes/Reflection/ClassSchema.php
index 7b86160c8c69..e0683f267a80 100644
--- a/typo3/sysext/extbase/Classes/Reflection/ClassSchema.php
+++ b/typo3/sysext/extbase/Classes/Reflection/ClassSchema.php
@@ -179,6 +179,11 @@ class ClassSchema
             $this->properties[$propertyName]['annotations']['type'] = null;
             $this->properties[$propertyName]['annotations']['cascade'] = null;
             $this->properties[$propertyName]['annotations']['dependency'] = null;
+            $this->properties[$propertyName]['annotations']['validators'] = [];
+
+            if ($docCommentParser->isTaggedWith('validate')) {
+                $this->properties[$propertyName]['annotations']['validators'] = $docCommentParser->getTagValues('validate');
+            }
 
             if ($annotationReader->getPropertyAnnotation($reflectionProperty, Lazy::class) instanceof Lazy) {
                 $this->properties[$propertyName]['annotations']['lazy'] = true;
@@ -301,9 +306,13 @@ class ClassSchema
             $this->methods[$methodName]['abstract']     = $reflectionMethod->isAbstract();
             $this->methods[$methodName]['params']       = [];
             $this->methods[$methodName]['tags']         = [];
+            $this->methods[$methodName]['annotations']  = [];
 
             $docCommentParser = new DocCommentParser(true);
             $docCommentParser->parseDocComment($reflectionMethod->getDocComment());
+
+            $this->methods[$methodName]['annotations']['validators'] = [];
+
             foreach ($docCommentParser->getTagsValues() as $tag => $values) {
                 if ($tag === 'ignorevalidation') {
                     trigger_error(
@@ -311,6 +320,9 @@ class ClassSchema
                         E_USER_DEPRECATED
                     );
                 }
+                if ($tag === 'validate') {
+                    $this->methods[$methodName]['annotations']['validators'] = $values;
+                }
                 $this->methods[$methodName]['tags'][$tag] = array_map(function ($value) {
                     return ltrim($value, '$');
                 }, $values);
diff --git a/typo3/sysext/extbase/Tests/Unit/Reflection/ClassSchemaTest.php b/typo3/sysext/extbase/Tests/Unit/Reflection/ClassSchemaTest.php
index db68e415a17f..7d03fab6774e 100644
--- a/typo3/sysext/extbase/Tests/Unit/Reflection/ClassSchemaTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Reflection/ClassSchemaTest.php
@@ -347,4 +347,37 @@ class ClassSchemaTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         static::assertArrayNotHasKey('author', $tags);
         static::assertArrayNotHasKey('version', $tags);
     }
+
+    /**
+     * @test
+     */
+    public function classSchemaDetectsValidateAnnotation()
+    {
+        $classSchema = new ClassSchema(Fixture\DummyClassWithValidateAnnotation::class);
+
+        static::assertSame(
+            [],
+            $classSchema->getProperty('propertyWithoutValidateAnnotations')['annotations']['validators']
+        );
+        static::assertSame(
+            [
+                'NotEmpty',
+                'Empty (Foo=Bar)'
+            ],
+            $classSchema->getProperty('propertyWithValidateAnnotations')['annotations']['validators']
+        );
+
+        static::assertSame(
+            [],
+            $classSchema->getMethod('methodWithoutValidateAnnotations')['annotations']['validators']
+        );
+
+        static::assertSame(
+            [
+                '$fooParam FooValidator (FooValidatorOptionKey=FooValidatorOptionValue)',
+                '$fooParam BarValidator'
+            ],
+            $classSchema->getMethod('methodWithValidateAnnotations')['annotations']['validators']
+        );
+    }
 }
diff --git a/typo3/sysext/extbase/Tests/Unit/Reflection/Fixture/DummyClassWithValidateAnnotation.php b/typo3/sysext/extbase/Tests/Unit/Reflection/Fixture/DummyClassWithValidateAnnotation.php
new file mode 100644
index 000000000000..51314b192474
--- /dev/null
+++ b/typo3/sysext/extbase/Tests/Unit/Reflection/Fixture/DummyClassWithValidateAnnotation.php
@@ -0,0 +1,44 @@
+<?php
+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\DomainObject\AbstractEntity;
+
+/**
+ * Fixture class with @validate annotations
+ */
+class DummyClassWithValidateAnnotation extends AbstractEntity
+{
+    protected $propertyWithoutValidateAnnotations;
+
+    /**
+     * @validate NotEmpty
+     * @validate Empty (Foo=Bar)
+     */
+    protected $propertyWithValidateAnnotations;
+
+    public function methodWithoutValidateAnnotations()
+    {
+    }
+
+    /**
+     * @param $fooParam
+     * @validate $fooParam FooValidator (FooValidatorOptionKey=FooValidatorOptionValue)
+     * @validate $fooParam BarValidator
+     */
+    public function methodWithValidateAnnotations($fooParam)
+    {
+    }
+}
-- 
GitLab