Completed
Push — master ( 2e24e7...974c75 )
by Tim
12:10
created

ReflectionUtility::getTagConfiguration()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 0
cts 0
cp 0
rs 9.6333
c 0
b 0
f 0
cc 4
nc 3
nop 2
crap 20
1
<?php
2
3
/**
4
 * Reflection helper.
5
 */
6
declare(strict_types=1);
7
8
namespace HDNET\Autoloader\Utility;
9
10
use TYPO3\CMS\Core\Utility\GeneralUtility;
11
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
12
use TYPO3\CMS\Extbase\Reflection\ClassReflection;
13
use TYPO3\CMS\Extbase\Reflection\ReflectionService;
14
15
/**
16
 * Reflection helper.
17
 */
18
class ReflectionUtility
19
{
20
    /**
21
     * Create a new class reflection. Do not use the makeInstance or objectManager
22
     * because the reflection API is also used in front of the caching framework.
23
     *
24
     * @param string $className
25
     *
26
     * @return ClassReflection
27
     *
28
     * @deprecated
29
     */
30
    public static function createReflectionClass($className)
31
    {
32
        return new ClassReflection($className);
33
    }
34
35
    /**
36
     * Check if the given class is instantiable.
37
     *
38
     * @param string $className
39
     *
40
     * @return bool
41
     */
42
    public static function isInstantiable($className): bool
43
    {
44
        if (self::is9orHigher()) {
45
            $reflectionClass = new \ReflectionClass($className);
46
47
            return (bool) $reflectionClass->isInstantiable();
48
        }
49
50
        return (bool) self::createReflectionClass($className)
0 ignored issues
show
Deprecated Code introduced by
The method HDNET\Autoloader\Utility...createReflectionClass() has been deprecated.

This method has been deprecated.

Loading history...
51
            ->isInstantiable();
52
    }
53
54
    /**
55
     * Get the name of the parent class.
56
     *
57
     * @param string $className
58
     *
59
     * @return string
60
     */
61
    public static function getParentClassName($className)
62
    {
63
        if (self::is9orHigher()) {
64
            $reflectionClass = new \ReflectionClass($className);
65
66
            return $reflectionClass->getParentClass()->getName();
67
        }
68
69
        return self::createReflectionClass($className)
0 ignored issues
show
Deprecated Code introduced by
The method HDNET\Autoloader\Utility...createReflectionClass() has been deprecated.

This method has been deprecated.

Loading history...
70
            ->getParentClass()
71
            ->getName();
72
    }
73
74
    /**
75
     * Get all properties that are tagged with the given tag.
76
     *
77
     * @param string $className
78
     * @param string $tag
79
     *
80
     * @return array
81
     */
82
    public static function getPropertyNamesTaggedWith($className, $tag): array
83
    {
84
        $properties = self::getPropertyNames($className);
85
        $return = [];
86
        foreach ($properties as $property) {
87
            $config = self::getTagConfigurationForProperty($className, $property, [$tag]);
88
            if (!empty($config[$tag])) {
89
                $return[] = $property;
90
            }
91
        }
92
93
        return $return;
94
    }
95
96
    /**
97
     * Get first class tag information.
98
     * The trimmed value if the tag exists and FALSE if the tag do not exists.
99
     *
100
     * @param string $className
101
     * @param string $tag
102
     *
103
     * @return string|bool
104
     */
105
    public static function getFirstTagValue(string $className, string $tag)
106
    {
107
        if (self::is9orHigher()) {
108
            $reflectionService = GeneralUtility::makeInstance(ReflectionService::class);
109
            $values = $reflectionService->getClassTagValues($className, $tag);
110
        } else {
111
            $classReflection = self::createReflectionClass($className);
0 ignored issues
show
Deprecated Code introduced by
The method HDNET\Autoloader\Utility...createReflectionClass() has been deprecated.

This method has been deprecated.

Loading history...
112
            if (!$classReflection->isTaggedWith($tag)) {
113
                return false;
114
            }
115
            $values = $classReflection->getTagValues($tag);
116
        }
117
118
        if (\is_array($values)) {
119
            return \trim((string) $values[0]);
120
        }
121
122
        return false;
123
    }
124
125
    /**
126
     * Get the tag configuration from this method and respect multiple line and space configuration.
127
     *
128
     * @param string $className
129
     * @param        $methodName
130
     * @param array  $tagNames
131
     *
132
     * @return array
133
     */
134
    public static function getTagConfigurationForMethod($className, $methodName, array $tagNames): array
135
    {
136
        $reflectionService = GeneralUtility::makeInstance(ReflectionService::class);
137
        $tags = $reflectionService->getMethodTagsValues($className, $methodName);
138
139
        $configuration = [];
140
        foreach ($tagNames as $tagName) {
141
            $configuration[$tagName] = [];
142
            if (!\is_array($tags[$tagName])) {
143
                continue;
144
            }
145
            foreach ($tags[$tagName] as $c) {
146
                $configuration[$tagName] = \array_merge(
147
                    $configuration[$tagName],
148
                    GeneralUtility::trimExplode(' ', $c, true)
149
                );
150
            }
151
        }
152
153
        return $configuration;
154
    }
155
156
    /**
157
     * Get the tag configuration from this method and respect multiple line and space configuration.
158
     *
159
     * @param string $className
160
     * @param array  $tagNames
161
     *
162
     * @return array
163
     */
164
    public static function getTagConfigurationForClass(string $className, array $tagNames): array
165
    {
166
        $reflectionService = GeneralUtility::makeInstance(ReflectionService::class);
167
        $tags = $reflectionService->getClassTagsValues($className);
168
169
        $configuration = [];
170
        foreach ($tagNames as $tagName) {
171
            $configuration[$tagName] = [];
172
            if (!\is_array($tags[$tagName])) {
173
                continue;
174
            }
175
            foreach ($tags[$tagName] as $c) {
176
                $configuration[$tagName] = \array_merge(
177
                    $configuration[$tagName],
178
                    GeneralUtility::trimExplode(' ', $c, true)
179
                );
180
            }
181
        }
182
183
        return $configuration;
184
    }
185
186
    /**
187
     * Get the tag configuration from this method and respect multiple line and space configuration.
188
     *
189
     * @param string $className
190
     * @param string $property
191
     * @param array  $tagNames
192
     *
193
     * @return array
194
     */
195
    public static function getTagConfigurationForProperty(string $className, string $property, array $tagNames): array
196
    {
197
        $reflectionService = GeneralUtility::makeInstance(ReflectionService::class);
198
        $tags = $reflectionService->getClassSchema($className)->getProperty($property)['tags'];
199
200
        $configuration = [];
201
        foreach ($tagNames as $tagName) {
202
            $configuration[$tagName] = [];
203
            if (!\is_array($tags[$tagName])) {
204
                continue;
205
            }
206
            foreach ($tags[$tagName] as $c) {
207
                $configuration[$tagName] = \array_merge(
208
                    $configuration[$tagName],
209
                    GeneralUtility::trimExplode(' ', $c, true)
210
                );
211
            }
212
        }
213
214
        return $configuration;
215
    }
216
217
    /**
218
     * Get public method names.
219
     *
220
     * @param string $className
221
     *
222
     * @return array
223
     */
224
    public static function getPropertyNames(string $className): array
225
    {
226
        $reflectionService = GeneralUtility::makeInstance(ReflectionService::class);
227
228
        return \array_keys($reflectionService->getClassSchema($className)->getProperties());
229
    }
230
231
    /**
232
     * Get public method names.
233
     *
234
     * @param string $className
235
     *
236
     * @return array
237
     */
238
    public static function getPublicMethodNames(string $className): array
239
    {
240
        $methodNames = [];
241
242
        if (self::is9orHigher()) {
243
            $reflectionService = GeneralUtility::makeInstance(ReflectionService::class);
244
            $schema = $reflectionService->getClassSchema($className);
245
            $methods = $schema->getMethods();
246
            foreach ($methods as $key => $method) {
247
                if ($method['public']) {
248
                    $methodNames[] = $key;
249
                }
250
            }
251
252
            return $methodNames;
253
        }
254
255
        $methods = self::createReflectionClass($className)
0 ignored issues
show
Deprecated Code introduced by
The method HDNET\Autoloader\Utility...createReflectionClass() has been deprecated.

This method has been deprecated.

Loading history...
256
            ->getMethods(\ReflectionMethod::IS_PUBLIC);
257
        foreach ($methods as $method) {
258
            $methodNames[] = $method->getName();
259
        }
260
261
        return $methodNames;
262
    }
263
264
    /**
265
     * Get properties of the given class, that are als declared in the given class.
266
     *
267
     * @param string $className
268
     *
269
     * @return array
270
     */
271
    public static function getDeclaringProperties($className)
272
    {
273
        $classReflection = new \ReflectionClass($className);
274
        $own = \array_filter($classReflection->getProperties(), function ($property) use ($className) {
275
            return $property->class === $className;
276
        });
277
278
        return \array_map(function ($item) {
279
            return $item->name;
280
        }, $own);
281
    }
282
283
    /**
284
     * Is 9 or higher.
285
     *
286
     * @return bool
287
     */
288
    public static function is9orHigher(): bool
289
    {
290
        return VersionNumberUtility::convertVersionNumberToInteger(TYPO3_branch) >= VersionNumberUtility::convertVersionNumberToInteger('9.0');
291
    }
292
}
293