Completed
Push — master ( 82c1c1...2b79fa )
by Tim
02:12
created

ReflectionUtility::getReflectionService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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 (strpos($rc->getDocComment(), '@' . $tag) === false) {
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
        $tags = $reflectionService->getClassSchema($className)->getProperty($property)['tags'];
183
184
        $configuration = [];
185
        foreach ($tagNames as $tagName) {
186
            if (!\is_array($tags[$tagName])) {
187
                continue;
188
            }
189
            $configuration[$tagName] = '';
190
            foreach ($tags[$tagName] as $c) {
191
                $configuration[$tagName] = trim($configuration[$tagName] . ' ' . $c);
192
            }
193
        }
194
195
        return $configuration;
196
    }
197
198
    /**
199
     * Get public method names.
200
     *
201
     * @param string $className
202
     *
203
     * @return array
204
     */
205
    public static function getPropertyNames(string $className): array
206
    {
207
        $reflectionService = self::getReflectionService();
208
209
        return \array_keys($reflectionService->getClassSchema($className)->getProperties());
210
    }
211
212
    /**
213
     * @param string $className
214
     * @param string $tag
215
     *
216
     * @throws \ReflectionException
217
     * @return array
218
     */
219
    public static function getPropertiesTaggedWith(string $className, string $tag): array
220
    {
221
        $classReflection = new \ReflectionClass($className);
222
        $props = $classReflection->getProperties();
223
        $result = [];
224
        foreach ($props as $prop) {
225
            /** @var $prop \ReflectionProperty */
226
            if (strpos($prop->getDocComment(), '@' . $tag) !== false) {
227
                $result[] = $prop->getName();
228
            }
229
        }
230
        return $result;
231
    }
232
233
    /**
234
     * Get public method names.
235
     *
236
     * @param string $className
237
     *
238
     * @return array
239
     */
240
    public static function getPublicMethodNames(string $className): array
241
    {
242
        $methodNames = [];
243
244
        if (self::is9orHigher()) {
245
            $reflectionService = self::getReflectionService();
246
            $schema = $reflectionService->getClassSchema($className);
247
            $methods = $schema->getMethods();
248
            foreach ($methods as $key => $method) {
249
                if ($method['public']) {
250
                    $methodNames[] = $key;
251
                }
252
            }
253
254
            return $methodNames;
255
        }
256
257
        $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...
258
            ->getMethods(\ReflectionMethod::IS_PUBLIC);
259
        foreach ($methods as $method) {
260
            $methodNames[] = $method->getName();
261
        }
262
263
        return $methodNames;
264
    }
265
266
    /**
267
     * Get properties of the given class, that are als declared in the given class.
268
     *
269
     * @param string $className
270
     *
271
     * @return array
272
     */
273
    public static function getDeclaringProperties(string $className)
274
    {
275
        $classReflection = new \ReflectionClass($className);
276
        $own = \array_filter($classReflection->getProperties(), function ($property) use ($className) {
277
            return trim((string)$property->class, '\\') === trim($className, '\\');
278
        });
279
280
        return \array_map(function ($item) {
281
            return (string)$item->name;
282
        }, $own);
283
    }
284
285
    /**
286
     * Is 9 or higher.
287
     *
288
     * @return bool
289
     */
290
    public static function is9orHigher(): bool
291
    {
292
        return VersionNumberUtility::convertVersionNumberToInteger(TYPO3_branch) >= VersionNumberUtility::convertVersionNumberToInteger('9.0');
293
    }
294
295
    /**
296
     * Create reflection service
297
     *
298
     * @return ReflectionService
299
     */
300
    protected static function getReflectionService()
301
    {
302
        $objectManager = new ObjectManager();
303
        return $objectManager->get(ReflectionService::class);
304
    }
305
}
306