ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
DICMemberResolver.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 namespace ILIAS\CI\Rector\DIC;
22 
37 
38 final class DICMemberResolver
39 {
40  public const DIC = 'DIC';
41  public const THIS = 'this';
42  public const GLOBALS = 'GLOBALS';
44 
45  public function __construct(
46  protected TypeProvidingExprFromClassResolver $typeProvidingExprFromClassResolver,
47  protected DICDependencyManipulator $dicDependencyManipulator,
48  protected PropertyToAddCollector $propertyToAddCollector,
49  protected ClassInsertManipulator $classInsertManipulator,
50  protected NodesToAddCollector $nodesToAddCollector,
51  protected \Rector\Core\PhpParser\Node\NodeFactory $nodeFactory,
52  protected ConstructorClassMethodFactory $constructorClassMethodFactory,
53  protected \Rector\Core\NodeDecorator\PropertyTypeDecorator $propertyTypeDecorator,
54  protected \Rector\ChangesReporting\Collector\RectorChangeCollector $rectorChangeCollector
55  ) {
56  $this->DICMemberMap = new DICMemberMap();
57  }
58 
62  private function getStaticDICCall(
63  DICMember $DICMember,
64  Class_ $class,
65  ClassMethod $classMethod
66  ): \PhpParser\Node\Expr\Variable {
67  // $DIC;
68  $dic_variable = $this->dicDependencyManipulator->ensureGlobalDICinMethod($classMethod, $class);
69  // new variable like $main_tpl;
70  $variable = new Variable($DICMember->getPropertyName());
71  // MethodCall to get DIC Dependency
72  $expression = new Expression(
73  new Assign(
74  $variable,
75  $this->appendDICMethods(
76  $DICMember,
77  $dic_variable
78  )
79  )
80  );
81  $this->dicDependencyManipulator->addStmtToMethodIfNotThereAfterGlobalDIC(
82  $classMethod,
83  $class,
84  $expression
85  );
86 
87  return $variable;
88  }
89 
90  public function ensureDICDependency(
91  string $name,
92  Class_ $class,
93  ClassMethod $classMethod
94  ): Expr {
95  $DICMember = $this->getDICMemberByName($name);
96 
97  // return simple $GLOBALS access in static methods or
98  // return simple $GLOBALS access in static methods if we are in
99  // constructor itself, since currently we have problems to assign the
100  // member then...
101  $classMethodName = $classMethod->name->name ?? null;
102  if ($classMethod->isStatic()) {
103  return $this->getStaticDICCall($DICMember, $class, $classMethod);
104  }
105  if ($classMethodName === \Rector\Core\ValueObject\MethodName::CONSTRUCT) {
106  return $this->getStaticDICCall($DICMember, $class, $classMethod);
107  }
108 
109  // Test primary class
110  $mainClass = $DICMember->getMainClass();
111  $dicPropertyFetch = $this->typeProvidingExprFromClassResolver->resolveTypeProvidingExprFromClass(
112  $class,
113  $classMethod,
114  $this->getObjectType($mainClass)
115  );
116  if ($dicPropertyFetch instanceof PropertyFetch) {
117  return $dicPropertyFetch;
118  }
119 
120  // try alternatives
121  $alternatives = $DICMember->getAlternativeClasses();
122  foreach ($alternatives as $alternative) {
123  $dicPropertyFetch = $this->typeProvidingExprFromClassResolver->resolveTypeProvidingExprFromClass(
124  $class,
125  $classMethod,
126  $this->getObjectType($alternative)
127  );
128  if ($dicPropertyFetch instanceof PropertyFetch) {
129  return $dicPropertyFetch;
130  }
131  }
132 
133  // Add property
134  $this->propertyToAddCollector->addPropertyWithoutConstructorToClass(
135  $DICMember->getPropertyName(),
136  $this->getObjectType($mainClass),
137  $class
138  );
139 
140  $dicPropertyFetch = new PropertyFetch(
141  new Variable(self::THIS),
142  $DICMember->getPropertyName()
143  );
144  // Method call to get DIC dependency
145  $methodCall = $this->appendDICMethods(
146  $DICMember,
147  new Variable(self::DIC)
148  );
149  // global $DIC
150  $this->dicDependencyManipulator->ensureGlobalDICinConstructor(
151  $class
152  );
153  // $this->xy = $DIC->xy()
154  $expression = new Expression(
155  new Assign(
156  $dicPropertyFetch,
157  $methodCall
158  )
159  );
160  $this->dicDependencyManipulator->addStmtToConstructorIfNotThereAfterGlobalDIC(
161  $class,
162  $expression
163  );
164 
165  return $dicPropertyFetch;
166  }
167 
168  private function appendDICMethods(DICMember $dicMember, Expr $expr): \PhpParser\Node\Expr
169  {
170  foreach ($dicMember->getDicServiceMethod() as $call) {
171  $expr = new MethodCall(
172  $expr,
173  $call
174  );
175  }
176  return $expr;
177  }
178 
179  private function getDICMemberByName(string $name): DICMember
180  {
181  return $this->DICMemberMap->getByName($name);
182  }
183 
184  private function getObjectType(string $name): ObjectType
185  {
186  return new ObjectType($name);
187  }
188 }
__construct(protected TypeProvidingExprFromClassResolver $typeProvidingExprFromClassResolver, protected DICDependencyManipulator $dicDependencyManipulator, protected PropertyToAddCollector $propertyToAddCollector, protected ClassInsertManipulator $classInsertManipulator, protected NodesToAddCollector $nodesToAddCollector, protected \Rector\Core\PhpParser\Node\NodeFactory $nodeFactory, protected ConstructorClassMethodFactory $constructorClassMethodFactory, protected \Rector\Core\NodeDecorator\PropertyTypeDecorator $propertyTypeDecorator, protected \Rector\ChangesReporting\Collector\RectorChangeCollector $rectorChangeCollector)
ensureDICDependency(string $name, Class_ $class, ClassMethod $classMethod)
getStaticDICCall(DICMember $DICMember, Class_ $class, ClassMethod $classMethod)
appendDICMethods(DICMember $dicMember, Expr $expr)