Completed
Push — master ( dfd5cb...5cac00 )
by Tim
09:24
created

ReflectionUtility::isPropertyTaggedWith()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 2
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\Object\ObjectManager;
13
use TYPO3\CMS\Extbase\Reflection\ClassReflection;
14
use TYPO3\CMS\Extbase\Reflection\ReflectionService;
15
16
/**
17
 * Reflection helper.
18
 */
19
class ReflectionUtility
20
{
21
    /**
22
     * Create a new class reflection. Do not use the makeInstance or objectManager
23
     * because the reflection API is also used in front of the caching framework.
24
     *
25
     * @param string $className
26
     *
27
     * @return ClassReflection
28
     *
29
     * @deprecated
30
     */
31
    public static function createReflectionClass($className)
32
    {
33
        return new ClassReflection($className);
34
    }
35
36
    /**
37
     * Check if the given class is instantiable.
38
     *
39
     * @param string $className
40
     *
41
     * @return bool
42
     */
43
    public static function isInstantiable($className): bool
44
    {
45
        if (self::is9orHigher()) {
46
            $reflectionClass = new \ReflectionClass($className);
47
48
            return (bool) $reflectionClass->isInstantiable();
49
        }
50
51
        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...
52
            ->isInstantiable();
53
    }
54
55
    /**
56
     * Get the name of the parent class.
57
     *
58
     * @param string $className
59
     *
60
     * @return string
61
     */
62
    public static function getParentClassName($className)
63
    {
64
        if (self::is9orHigher()) {
65
            $reflectionClass = new \ReflectionClass($className);
66
67
            return $reflectionClass->getParentClass()->getName();
68
        }
69
70
        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...
71
            ->getParentClass()
72
            ->getName();
73
    }
74
75
    /**
76
     * Get first class tag information.
77
     * The trimmed value if the tag exists and FALSE if the tag do not exists.
78
     *
79
     * @param string $className
80
     * @param string $tag
81
     *
82
     * @return string|bool
83
     */
84
    public static function getFirstTagValue(string $className, string $tag)
85
    {
86
        if (self::is9orHigher()) {
87
            $rc = new \ReflectionClass($className);
88
            if (false === \mb_strpos($rc->getDocComment(), '@' . $tag)) {
89
                return false;
90
            }
91
92
            $reflectionService = self::getReflectionService();
93
            $values = $reflectionService->getClassTagValues($className, $tag);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Reflec...ce::getClassTagValues() has been deprecated with message: since TYPO3 v9, will be removed in TYPO3 v10.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
94
        } else {
95
            $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...
96
            if (!$classReflection->isTaggedWith($tag)) {
97
                return false;
98
            }
99
            $values = $classReflection->getTagValues($tag);
100
        }
101
102
        if (\is_array($values)) {
103
            return \trim((string) $values[0]);
104
        }
105
106
        return false;
107
    }
108
109
    /**
110
     * Get the tag configuration from this method and respect multiple line and space configuration.
111
     *
112
     * @param string $className
113
     * @param        $methodName
114
     * @param array  $tagNames
115
     *
116
     * @return array
117
     */
118
    public static function getTagConfigurationForMethod($className, $methodName, array $tagNames): array
119
    {
120
        $reflectionService = self::getReflectionService();
121
        $tags = $reflectionService->getMethodTagsValues($className, $methodName);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Reflec...::getMethodTagsValues() has been deprecated with message: since TYPO3 v9, will be removed in TYPO3 v10.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
122
123
        $configuration = [];
124
        foreach ($tagNames as $tagName) {
125
            $configuration[$tagName] = [];
126
            if (!\is_array($tags[$tagName])) {
127
                continue;
128
            }
129
            foreach ($tags[$tagName] as $c) {
130
                $configuration[$tagName] = \array_merge(
131
                    $configuration[$tagName],
132
                    GeneralUtility::trimExplode(' ', $c, true)
133
                );
134
            }
135
        }
136
137
        return $configuration;
138
    }
139
140
    /**
141
     * Get the tag configuration from this method and respect multiple line and space configuration.
142
     *
143
     * @param string $className
144
     * @param array  $tagNames
145
     *
146
     * @return array
147
     */
148
    public static function getTagConfigurationForClass(string $className, array $tagNames): array
149
    {
150
        $reflectionService = self::getReflectionService();
151
        $tags = $reflectionService->getClassTagsValues($className);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Reflec...e::getClassTagsValues() has been deprecated with message: since TYPO3 v9, will be removed in TYPO3 v10.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
152
153
        $configuration = [];
154
        foreach ($tagNames as $tagName) {
155
            $configuration[$tagName] = [];
156
            if (!\is_array($tags[$tagName])) {
157
                continue;
158
            }
159
            foreach ($tags[$tagName] as $c) {
160
                $configuration[$tagName] = \array_merge(
161
                    $configuration[$tagName],
162
                    GeneralUtility::trimExplode(' ', $c, true)
163
                );
164
            }
165
        }
166
167
        return $configuration;
168
    }
169
170
    /**
171
     * Get the tag configuration from this method and respect multiple line and space configuration.
172
     *
173
     * @param string $className
174
     * @param string $property
175
     * @param array  $tagNames
176
     *
177
     * @return array
178
     */
179
    public static function getTagConfigurationForProperty(string $className, string $property, array $tagNames): array
180
    {
181
        $reflectionService = self::getReflectionService();
182
        if (self::is9orHigher()) {
183
            $tags = $reflectionService->getClassSchema($className)->getProperty($property)['tags'];
184
        } else {
185
            $tags = $reflectionService->getPropertyTagsValues($className, $property);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Reflec...getPropertyTagsValues() has been deprecated with message: since TYPO3 v9, will be removed in TYPO3 v10.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
186
        }
187
188
        $configuration = [];
189
        foreach ($tagNames as $tagName) {
190
            if (!\is_array($tags[$tagName])) {
191
                continue;
192
            }
193
            $configuration[$tagName] = '';
194
            foreach ($tags[$tagName] as $c) {
195
                $configuration[$tagName] = \trim($configuration[$tagName] . ' ' . $c);
196
            }
197
        }
198
199
        return $configuration;
200
    }
201
202
    /**
203
     * Get public method names.
204
     *
205
     * @param string $className
206
     *
207
     * @return array
208
     */
209
    public static function getPropertyNames(string $className): array
210
    {
211
        $reflectionService = self::getReflectionService();
212
213
        return \array_keys($reflectionService->getClassSchema($className)->getProperties());
214
    }
215
216
    /**
217
     * @param string $className
218
     * @param string $tag
219
     *
220
     * @throws \ReflectionException
221
     *
222
     * @return array
223
     */
224
    public static function getPropertiesTaggedWith(string $className, string $tag): array
225
    {
226
        $classReflection = new \ReflectionClass($className);
227
        $props = $classReflection->getProperties();
228
        $result = [];
229
        foreach ($props as $prop) {
230
            /** @var $prop \ReflectionProperty */
231
            if (false !== \mb_strpos($prop->getDocComment(), '@' . $tag)) {
232
                $result[] = $prop->getName();
233
            }
234
        }
235
236
        return $result;
237
    }
238
239
    /**
240
     * Get public method names.
241
     *
242
     * @param string $className
243
     *
244
     * @return array
245
     */
246
    public static function getPublicMethodNames(string $className): array
247
    {
248
        $methodNames = [];
249
250
        if (self::is9orHigher()) {
251
            $reflectionService = self::getReflectionService();
252
            $schema = $reflectionService->getClassSchema($className);
253
            $methods = $schema->getMethods();
254
            foreach ($methods as $key => $method) {
255
                if ($method['public']) {
256
                    $methodNames[] = $key;
257
                }
258
            }
259
260
            return $methodNames;
261
        }
262
263
        $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...
264
            ->getMethods(\ReflectionMethod::IS_PUBLIC);
265
        foreach ($methods as $method) {
266
            $methodNames[] = $method->getName();
267
        }
268
269
        return $methodNames;
270
    }
271
272
    /**
273
     * Get properties of the given class, that are als declared in the given class.
274
     *
275
     * @param string $className
276
     *
277
     * @return array
278
     */
279
    public static function getDeclaringProperties(string $className)
280
    {
281
        $classReflection = new \ReflectionClass($className);
282
        $own = \array_filter($classReflection->getProperties(), function ($property) use ($className) {
283
            return \trim((string) $property->class, '\\') === \trim($className, '\\');
284
        });
285
286
        return \array_map(function ($item) {
287
            return (string) $item->name;
288
        }, $own);
289
    }
290
291
    /**
292
     * Is 9 or higher.
293
     *
294
     * @return bool
295
     */
296
    public static function is9orHigher(): bool
297
    {
298
        return VersionNumberUtility::convertVersionNumberToInteger(TYPO3_branch) >= VersionNumberUtility::convertVersionNumberToInteger('9.0');
299
    }
300
301
    /**
302
     * Check if the method is tagged with the given tag (no value checked).
303
     *
304
     * @param string $className
305
     * @param string $methodName
306
     * @param string $tagName
307
     *
308
     * @return bool
309
     */
310
    public static function isMethodTaggedWith($className, $methodName, $tagName): bool
311
    {
312
        $reflectionService = self::getReflectionService();
313
        $tags = $reflectionService->getMethodTagsValues($className, $methodName);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Reflec...::getMethodTagsValues() has been deprecated with message: since TYPO3 v9, will be removed in TYPO3 v10.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
314
315
        return \array_key_exists($tagName, $tags);
316
    }
317
318
    /**
319
     * Check if the property is tagged with the given tag (no value checked).
320
     *
321
     * @param string $className
322
     * @param string $propertyName
323
     * @param string $tagName
324
     *
325
     * @return bool
326
     */
327
    public static function isPropertyTaggedWith($className, $propertyName, $tagName): bool
328
    {
329
        $properties = self::getPropertiesTaggedWith($className, $tagName);
330
331
        return \in_array($propertyName, $properties, true);
332
    }
333
334
    /**
335
     * Create reflection service.
336
     *
337
     * @return ReflectionService
338
     */
339
    protected static function getReflectionService()
340
    {
341
        $objectManager = new ObjectManager();
342
343
        return $objectManager->get(ReflectionService::class);
344
    }
345
}
346