ILIAS  trunk Revision v11.0_alpha-2645-g16283d3b3f8
ILIAS\Component\Dependencies\Resolver Class Reference
+ Collaboration diagram for ILIAS\Component\Dependencies\Resolver:

Public Member Functions

 resolveDependencies (array $disambiguation, OfComponent ... $components)
 Resolves dependencies of all components. More...
 

Protected Member Functions

 resolvePull (OfComponent $component, In $in, array &$others)
 
 resolveSeek (In $in, array &$others)
 
 resolveUse (OfComponent $component, array &$disambiguation, In $in, array &$others)
 
 disambiguate (OfComponent $component, array &$disambiguation, In $in)
 
 findCycles (OfComponent ... $components)
 
 findCyclesWith (array $visited, OfComponent $component, In $in)
 

Detailed Description

Definition at line 23 of file Resolver.php.

Member Function Documentation

◆ disambiguate()

ILIAS\Component\Dependencies\Resolver::disambiguate ( OfComponent  $component,
array &  $disambiguation,
In  $in 
)
protected

Definition at line 169 of file Resolver.php.

References $c, ILIAS\Component\Dependencies\OfComponent\getComponentName(), ILIAS\Component\Dependencies\In\getName(), and null.

Referenced by ILIAS\Component\Dependencies\Resolver\resolveUse().

169  : ?string
170  {
171  $service_name = (string) $in->getName();
172  foreach ([$component->getComponentName(), "*"] as $c) {
173  if (isset($disambiguation[$c]) && isset($disambiguation[$c][$service_name])) {
174  return $disambiguation[$c][$service_name];
175  }
176  }
177  return null;
178  }
$c
Definition: deliver.php:25
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ findCycles()

ILIAS\Component\Dependencies\Resolver::findCycles ( OfComponent ...  $components)
protected

Definition at line 183 of file Resolver.php.

References ILIAS\Component\Dependencies\Resolver\findCyclesWith().

Referenced by ILIAS\Component\Dependencies\Resolver\resolveDependencies().

183  : \Generator
184  {
185  foreach ($components as $component) {
186  foreach ($component->getInDependencies() as $in) {
187  foreach ($this->findCyclesWith([], $component, $in) as $cycle) {
188  yield $cycle;
189  }
190  }
191  }
192  }
findCyclesWith(array $visited, OfComponent $component, In $in)
Definition: Resolver.php:194
$components
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ findCyclesWith()

ILIAS\Component\Dependencies\Resolver::findCyclesWith ( array  $visited,
OfComponent  $component,
In  $in 
)
protected

Definition at line 194 of file Resolver.php.

References $out, ILIAS\ResourceStorage\Flavour\Machine\DefaultMachines\from(), and ILIAS\Component\Dependencies\In\getResolvedBy().

Referenced by ILIAS\Component\Dependencies\Resolver\findCycles().

194  : \Generator
195  {
196  if (!empty($visited) && $visited[0][0] === $component && $visited[0][1] == $in) {
197  yield $visited;
198  return;
199  }
200 
201  array_push($visited, [$component, $in]);
202  foreach ($in->getResolvedBy() as $out) {
203  $other = $out->getComponent();
204  array_push($visited, [$component, $out]);
205  foreach ($out->getDependencies() as $next) {
206  yield from $this->findCyclesWith($visited, $out->getComponent(), $next);
207  }
208  array_pop($visited);
209  }
210  array_pop($visited);
211  }
findCyclesWith(array $visited, OfComponent $component, In $in)
Definition: Resolver.php:194
$out
Definition: buildRTE.php:24
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ resolveDependencies()

ILIAS\Component\Dependencies\Resolver::resolveDependencies ( array  $disambiguation,
OfComponent ...  $components 
)

Resolves dependencies of all components.

This is unambigous for all types of dependencies but the use/implement-pair. If there would be ambiguities, these can be disambiguated by the first argument.

The structure of the first argument is as such: keys are components that use services ("dependant") that need disambiguation, value for each dependant is an array where the key is the definition ("dependency") and the value is the implementation ("implementation") to be used.

The entry "*" for the dependant will define fallbacks to be used for all components that have no explicit disambiguation.

So, the array might look as such:

[ "*" => [ "ILIAS\Logger\Logger" => ILIAS ], "ILIAS\Database\DB" => [ "ILIAS\Logger\Logger" => ILIAS ] ]

Parameters
array<string,array<string,string>>$disambiguation
OfComponent[]
Returns
OfComponent[]

Definition at line 53 of file Resolver.php.

References $components, Vendor\Package\$d, ILIAS\Component\Dependencies\Resolver\findCycles(), ILIAS\Component\Dependencies\Resolver\resolvePull(), ILIAS\Component\Dependencies\Resolver\resolveSeek(), and ILIAS\Component\Dependencies\Resolver\resolveUse().

53  : array
54  {
55  foreach ($components as $component) {
56  foreach ($component->getInDependencies() as $d) {
57  switch ($d->getType()) {
58  case InType::PULL:
59  $this->resolvePull($component, $d, $components);
60  break;
61  case InType::SEEK:
62  $this->resolveSeek($d, $components);
63  break;
64  case InType::USE:
65  $this->resolveUse($component, $disambiguation, $d, $components);
66  break;
67  }
68  }
69  }
70 
71  $cycles = iterator_to_array($this->findCycles(...$components));
72  if (!empty($cycles)) {
73  throw new \LogicException(
74  "Detected Cycles in Dependency Tree: " .
75  join("\n", array_map(
76  fn($cycle) => join(
77  " <- ",
78  array_map(
79  fn($v) => "{$v[0]->getComponentName()} ({$v[1]})",
80  $cycle
81  )
82  ),
83  $cycles
84  ))
85  );
86  }
87 
88  return $components;
89  }
findCycles(OfComponent ... $components)
Definition: Resolver.php:183
resolveSeek(In $in, array &$others)
Definition: Resolver.php:114
resolveUse(OfComponent $component, array &$disambiguation, In $in, array &$others)
Definition: Resolver.php:126
resolvePull(OfComponent $component, In $in, array &$others)
Definition: Resolver.php:91
$components
+ Here is the call graph for this function:

◆ resolvePull()

ILIAS\Component\Dependencies\Resolver::resolvePull ( OfComponent  $component,
In  $in,
array &  $others 
)
protected

Definition at line 91 of file Resolver.php.

References ILIAS\Component\Dependencies\In\addResolution(), ILIAS\Component\Dependencies\In\getName(), and null.

Referenced by ILIAS\Component\Dependencies\Resolver\resolveDependencies().

91  : void
92  {
93  $candidate = null;
94 
95  foreach ($others as $other) {
96  if ($other->offsetExists("PROVIDE: " . $in->getName())) {
97  if (!is_null($candidate)) {
98  throw new \LogicException(
99  "Dependency {$in->getName()} is provided (at least) twice."
100  );
101  }
102  // For PROVIDEd dependencies, there only ever is one implementation.
103  $candidate = $other["PROVIDE: " . $in->getName()][0];
104  }
105  }
106 
107  if (is_null($candidate)) {
108  throw new \LogicException("Could not resolve dependency for {$component->getComponentName()}: " . (string) $in);
109  }
110 
111  $in->addResolution($candidate);
112  }
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ resolveSeek()

ILIAS\Component\Dependencies\Resolver::resolveSeek ( In  $in,
array &  $others 
)
protected

Definition at line 114 of file Resolver.php.

References ILIAS\Component\Dependencies\In\addResolution(), and ILIAS\Component\Dependencies\In\getName().

Referenced by ILIAS\Component\Dependencies\Resolver\resolveDependencies().

114  : void
115  {
116  foreach ($others as $other) {
117  if ($other->offsetExists("CONTRIBUTE: " . $in->getName())) {
118  // For CONTRIBUTEd, we just use all contributions.
119  foreach ($other["CONTRIBUTE: " . $in->getName()] as $o) {
120  $in->addResolution($o);
121  }
122  }
123  }
124  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ resolveUse()

ILIAS\Component\Dependencies\Resolver::resolveUse ( OfComponent  $component,
array &  $disambiguation,
In  $in,
array &  $others 
)
protected

Definition at line 126 of file Resolver.php.

References ILIAS\Component\Dependencies\In\addResolution(), ILIAS\Component\Dependencies\Resolver\disambiguate(), and ILIAS\Component\Dependencies\In\getName().

Referenced by ILIAS\Component\Dependencies\Resolver\resolveDependencies().

126  : void
127  {
128  $candidates = [];
129 
130  foreach ($others as $other) {
131  if ($other->offsetExists("IMPLEMENT: " . $in->getName())) {
132  // For IMPLEMENTed dependencies, we need to make choice.
133  $candidates[] = $other["IMPLEMENT: " . $in->getName()];
134  }
135  }
136 
137  $candidates = array_merge(...$candidates);
138 
139  if (empty($candidates)) {
140  throw new \LogicException(
141  "Could not resolve dependency for {$component->getComponentName()}: " . (string) $in
142  );
143  }
144 
145  if (count($candidates) === 1) {
146  $in->addResolution($candidates[0]);
147  return;
148  }
149 
150  $preferred_class = $this->disambiguate($component, $disambiguation, $in);
151  if (is_null($preferred_class)) {
152  throw new \LogicException(
153  "Dependency {$in->getName()} is provided (at least) twice, " .
154  "no disambiguation for {$component->getComponentName()}."
155  );
156  }
157  foreach ($candidates as $candidate) {
158  if ($candidate->aux["class"] === $preferred_class) {
159  $in->addResolution($candidate);
160  return;
161  }
162  }
163  throw new \LogicException(
164  "Dependency $preferred_class for service {$in->getName()} " .
165  "for {$component->getComponentName()} could not be located."
166  );
167  }
disambiguate(OfComponent $component, array &$disambiguation, In $in)
Definition: Resolver.php:169
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

The documentation for this class was generated from the following file: