[FEATURE] Add symfony dependency injection for core and extbase
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / DependencyInjection / AutowireInjectMethodsPass.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Core\DependencyInjection;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass;
19 use Symfony\Component\DependencyInjection\Definition;
20
21 /**
22 * Looks for definitions with autowiring enabled and registers their corresponding "inject*" methods as setters.
23 */
24 class AutowireInjectMethodsPass extends AbstractRecursivePass
25 {
26 /**
27 * @param mixed $value
28 * @param bool $isRoot
29 * @return mixed
30 */
31 protected function processValue($value, $isRoot = false)
32 {
33 $value = parent::processValue($value, $isRoot);
34
35 if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) {
36 return $value;
37 }
38 if (!$reflectionClass = $this->container->getReflectionClass($value->getClass(), false)) {
39 return $value;
40 }
41
42 $alreadyCalledMethods = [];
43
44 foreach ($value->getMethodCalls() as list($method)) {
45 $alreadyCalledMethods[strtolower($method)] = true;
46 }
47
48 $addInitCall = false;
49
50 foreach ($reflectionClass->getMethods() as $reflectionMethod) {
51 $r = $reflectionMethod;
52
53 if ($r->isConstructor() || isset($alreadyCalledMethods[strtolower($r->name)])) {
54 continue;
55 }
56
57 if ($reflectionMethod->isPublic() && strpos($reflectionMethod->name, 'inject') === 0) {
58 if ($reflectionMethod->name === 'injectSettings') {
59 continue;
60 }
61
62 $value->addMethodCall($reflectionMethod->name);
63 }
64
65 if ($reflectionMethod->name === 'initializeObject' && $reflectionMethod->isPublic()) {
66 $addInitCall = true;
67 }
68 }
69
70 if ($addInitCall) {
71 // Add call to initializeObject() which is required by classes that need to perform
72 // constructions tasks after the inject* method based injection of dependencies.
73 $value->addMethodCall('initializeObject');
74 }
75
76 return $value;
77 }
78 }