ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
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 
38 
39 final class DICMemberResolver
40 {
41  public const DIC = 'DIC';
42  public const THIS = 'this';
43  public const GLOBALS = 'GLOBALS';
44  protected TypeProvidingExprFromClassResolver $typeProvidingExprFromClassResolver;
46  protected PropertyToAddCollector $propertyToAddCollector;
47  protected ClassInsertManipulator $classInsertManipulator;
49  protected NodesToAddCollector $nodesToAddCollector;
50  protected \Rector\Core\PhpParser\Node\NodeFactory $nodeFactory;
51  protected ConstructorClassMethodFactory $constructClassMethodFactory;
52  protected \Rector\Core\NodeDecorator\PropertyTypeDecorator $propertyTypeDecorator;
53  protected \Rector\ChangesReporting\Collector\RectorChangeCollector $rectorChangeCollector;
54 
55  public function __construct(
56  TypeProvidingExprFromClassResolver $typeProvidingExprFromClassResolver,
57  DICDependencyManipulator $classDependencyManipulator,
58  PropertyToAddCollector $propertyToAddCollector,
59  ClassInsertManipulator $classInsertManipulator,
60  NodesToAddCollector $nodesToAddCollector,
61  \Rector\Core\PhpParser\Node\NodeFactory $nodeFactory,
62  ConstructorClassMethodFactory $constructClassMethodFactory,
63  \Rector\Core\NodeDecorator\PropertyTypeDecorator $propertyTypeDecorator,
64  \Rector\ChangesReporting\Collector\RectorChangeCollector $rectorChangeCollector
65  ) {
66  $this->typeProvidingExprFromClassResolver = $typeProvidingExprFromClassResolver;
67  $this->dicDependencyManipulator = $classDependencyManipulator;
68  $this->propertyToAddCollector = $propertyToAddCollector;
69  $this->classInsertManipulator = $classInsertManipulator;
70  $this->nodesToAddCollector = $nodesToAddCollector;
71  $this->nodeFactory = $nodeFactory;
72  $this->constructClassMethodFactory = $constructClassMethodFactory;
73  $this->propertyTypeDecorator = $propertyTypeDecorator;
74  $this->rectorChangeCollector = $rectorChangeCollector;
75  $this->DICMemberMap = new DICMemberMap();
76  }
77 
82  private function getStaticDICCall(
83  DICMember $DICMember,
84  Class_ $class,
85  ClassMethod $classMethod
86  ): \PhpParser\Node\Expr\Variable {
87  // $DIC;
88  $dic_variable = $this->dicDependencyManipulator->ensureGlobalDICinMethod($classMethod, $class);
89  // new variable like $main_tpl;
90  $dic_dependenc_variable = new Variable($DICMember->getPropertyName());
91  // MethodCall to get DIC Dependency
92  $property_assign = new Expression(
93  new Assign(
94  $dic_dependenc_variable,
95  $this->appendDICMethods(
96  $DICMember,
97  $dic_variable
98  )
99  )
100  );
101  $this->dicDependencyManipulator->addStmtToMethodIfNotThereAfterGlobalDIC(
102  $classMethod,
103  $class,
104  $property_assign
105  );
106 
107  return $dic_dependenc_variable;
108  }
109 
110  public function ensureDICDependency(
111  string $name,
112  Class_ $class,
113  ClassMethod $classMethod
114  ): Expr {
115  $DICMember = $this->getDICMemberByName($name);
116 
117  // return simple $GLOBALS access in static methods or
118  // return simple $GLOBALS access in static methods if we are in
119  // constructor itself, since currently we have problems to assign the
120  // member then...
121  $classMethodName = $classMethod->name->name ?? null;
122  if ($classMethod->isStatic()
123  || $classMethodName === \Rector\Core\ValueObject\MethodName::CONSTRUCT) {
124  return $this->getStaticDICCall($DICMember, $class, $classMethod);
125  }
126 
127  // Test primary class
128  $primary = $DICMember->getMainClass();
129  $dicPropertyFetch = $this->typeProvidingExprFromClassResolver->resolveTypeProvidingExprFromClass(
130  $class,
131  $classMethod,
132  $this->getObjectType($primary)
133  );
134  if ($dicPropertyFetch instanceof PropertyFetch) {
135  return $dicPropertyFetch;
136  }
137 
138  // try alternatives
139  $alternatives = $DICMember->getAlternativeClasses();
140  foreach ($alternatives as $alternative) {
141  $dicPropertyFetch = $this->typeProvidingExprFromClassResolver->resolveTypeProvidingExprFromClass(
142  $class,
143  $classMethod,
144  $this->getObjectType($alternative)
145  );
146  if ($dicPropertyFetch instanceof PropertyFetch) {
147  return $dicPropertyFetch;
148  }
149  }
150 
151  // Add property
152  $this->propertyToAddCollector->addPropertyWithoutConstructorToClass(
153  $DICMember->getPropertyName(),
154  $this->getObjectType($primary),
155  $class
156  );
157 
158  $dicPropertyFetch = new PropertyFetch(
159  new Variable(self::THIS),
160  $DICMember->getPropertyName()
161  );
162  // Method call to get DIC dependency
163  $methodCall = $this->appendDICMethods(
164  $DICMember,
165  new Variable(self::DIC)
166  );
167  // global $DIC
168  $this->dicDependencyManipulator->ensureGlobalDICinConstructor(
169  $class
170  );
171  // $this->xy = $DIC->xy()
172  $property_assign = new Expression(
173  new Assign(
174  $dicPropertyFetch,
175  $methodCall
176  )
177  );
178  $this->dicDependencyManipulator->addStmtToConstructorIfNotThereAfterGlobalDIC(
179  $class,
180  $property_assign
181  );
182 
183  return $dicPropertyFetch;
184  }
185 
186  private function appendDICMethods(DICMember $m, Expr $methodCall)
187  {
188  foreach ($m->getDicServiceMethod() as $call) {
189  $methodCall = new MethodCall(
190  $methodCall,
191  $call
192  );
193  }
194  return $methodCall;
195  }
196 
197  private function getDICMemberByName(string $name): DICMember
198  {
199  return $this->DICMemberMap->getByName($name);
200  }
201 
202  private function getObjectType(string $name): ObjectType
203  {
204  return new ObjectType($name);
205  }
206 }
ConstructorClassMethodFactory $constructClassMethodFactory
Rector ChangesReporting Collector RectorChangeCollector $rectorChangeCollector
ClassInsertManipulator $classInsertManipulator
TypeProvidingExprFromClassResolver $typeProvidingExprFromClassResolver
Rector Core NodeDecorator PropertyTypeDecorator $propertyTypeDecorator
__construct(TypeProvidingExprFromClassResolver $typeProvidingExprFromClassResolver, DICDependencyManipulator $classDependencyManipulator, PropertyToAddCollector $propertyToAddCollector, ClassInsertManipulator $classInsertManipulator, NodesToAddCollector $nodesToAddCollector, \Rector\Core\PhpParser\Node\NodeFactory $nodeFactory, ConstructorClassMethodFactory $constructClassMethodFactory, \Rector\Core\NodeDecorator\PropertyTypeDecorator $propertyTypeDecorator, \Rector\ChangesReporting\Collector\RectorChangeCollector $rectorChangeCollector)
appendDICMethods(DICMember $m, Expr $methodCall)
Rector Core PhpParser Node NodeFactory $nodeFactory
if($format !==null) $name
Definition: metadata.php:247
PropertyToAddCollector $propertyToAddCollector
ensureDICDependency(string $name, Class_ $class, ClassMethod $classMethod)
getStaticDICCall(DICMember $DICMember, Class_ $class, ClassMethod $classMethod)
DICDependencyManipulator $dicDependencyManipulator