ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
ObjectiveIterator.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 2019 Richard Klees <richard.klees@concepts-and-training.de> Extended GPL, see docs/LICENSE */
4
5namespace ILIAS\Setup;
6
10
18{
22 protected $environment;
23
27 protected $objective;
28
32 protected $stack;
33
37 protected $current;
38
42 protected $returned;
43
47 protected $failed;
48
53
54
56 {
58 $this->objective = $objective;
59 $this->rewind();
60 }
61
62 public function setEnvironment(Environment $environment) : void
63 {
65 }
66
68 {
69 if (!isset($this->returned[$objective->getHash()])) {
70 throw new \LogicException(
71 "You may only mark objectives as failed that have been returned by this iterator."
72 );
73 }
74
75 $this->failed[$objective->getHash()] = true;
76 }
77
78 public function rewind()
79 {
80 $this->stack = [$this->objective];
81 $this->current = null;
82 $this->returned = [];
83 $this->failed = [];
84 $this->reverse_dependencies = [];
85 $this->next();
86 }
87
88 public function current()
89 {
90 if ($this->current === null) {
91 throw new \LogicException(
92 "Iterator is finished or wasn't initialized correctly internally."
93 );
94 }
95 return $this->current;
96 }
97
98 public function key()
99 {
100 return $this->current()->getHash();
101 }
102
103 public function next()
104 {
105 if (count($this->stack) === 0) {
106 $this->current = null;
107 return;
108 }
109
110 $cur = array_pop($this->stack);
111 $hash = $cur->getHash();
112
113 if (isset($this->returned[$hash]) || isset($this->filed[$hash])) {
114 $this->next();
115 return;
116 }
117
118 $preconditions = array_filter(
119 $cur->getPreconditions($this->environment),
120 function ($p) {
121 $h = $p->getHash();
122 return !isset($this->returned[$h]) || isset($this->failed[$h]);
123 }
124 );
125
126 $failed_preconditions = array_filter(
127 $preconditions,
128 function ($p) {
129 return isset($this->failed[$p->getHash()]);
130 }
131 );
132
133 // We only have preconditions left that we know to have failed.
134 if (count($preconditions) !== 0
135 && count($preconditions) === count($failed_preconditions)) {
136 throw new UnachievableException(
137 "Objective only has failed preconditions."
138 );
139 }
140
141 // No preconditions open, we can proceed with the objective.
142 if (count($preconditions) === 0) {
143 $this->returned[$hash] = true;
144 $this->current = $cur;
145 return;
146 }
147
148 $this->stack[] = $cur;
149 $this->detectDependencyCycles($hash, $hash);
150 foreach (array_reverse($preconditions) as $p) {
151 $this->stack[] = $p;
152 $this->setReverseDependency($p->getHash(), $hash);
153 }
154 $this->next();
155 }
156
157 public function valid()
158 {
159 return $this->current !== null;
160 }
161
162 protected function detectDependencyCycles(string $cur, string $next)
163 {
164 if (!isset($this->reverse_dependencies[$next])) {
165 return;
166 }
167 if (in_array($cur, $this->reverse_dependencies[$next])) {
168 throw new UnachievableException(
169 "The objectives contain a dependency cycle and won't all be achievable."
170 );
171 }
172 foreach ($this->reverse_dependencies[$next] as $d) {
173 $this->detectDependencyCycles($cur, $d);
174 }
175 }
176
177 protected function setReverseDependency(string $other, string $cur)
178 {
179 if (!isset($this->reverse_dependencies[$other])) {
180 $this->reverse_dependencies[$other] = [];
181 }
182 $this->reverse_dependencies[$other][] = $cur;
183 }
184}
An exception for terminatinating execution or to throw for unit testing.
Tries to enumerate all preconditions for the given objective, where the ones that can be achieved (i....
setEnvironment(Environment $environment)
markAsFailed(Objective $objective)
setReverseDependency(string $other, string $cur)
detectDependencyCycles(string $cur, string $next)
__construct(Environment $environment, Objective $objective)
Signals that some goal won't be achievable by actions of the system ever.
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
environment()
Definition: environment.php:3
An environment holds resources to be used in the setup process.
Definition: Environment.php:12
An objective is a desired state of the system that is supposed to be created by the setup.
Definition: Objective.php:15