ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
BaseNavigator.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
27
28abstract class BaseNavigator implements BaseNavigatorInterface
29{
31
35 private array $elements;
36
40 private array $previous_steps;
41
45 private array $remaining_steps;
47 private bool $leads_to_one;
48
49 public function __construct(
51 BaseElementInterface $start_element,
53 ) {
54 $this->bridge = $bridge;
55 $this->previous_steps = [];
56 $this->remaining_steps = iterator_to_array($path->steps());
57 $this->leadsToOne($path->leadsToExactlyOneElement());
58 if ($path->isRelative()) {
59 $this->elements = [$start_element];
60 return;
61 }
62 while (!$start_element->isRoot()) {
63 $start_element = $start_element->getSuperElement();
64 if (!isset($start_element)) {
65 throw new \ilMDPathException(
66 'Can not navigate on an invalid metadata set.'
67 );
68 }
69 }
70 $this->elements = [$start_element];
71 }
72
73 protected function leadsToOne(bool $leads_to_one): void
74 {
75 $this->leads_to_one = $leads_to_one;
76 }
77
78 public function currentStep(): ?StepInterface
79 {
81 }
82
83 public function nextStep(): ?BaseNavigatorInterface
84 {
85 if (empty($this->remaining_steps)) {
86 return null;
87 }
88 $clone = clone $this;
89
90 $clone->elements = iterator_to_array($clone->bridge->getNextElementsByStep(
91 $clone->remaining_steps[0],
92 ...$clone->elements
93 ));
94 $clone->previous_steps[] = $clone->current_step;
95 $clone->current_step = $clone->remaining_steps[0];
96 array_shift($clone->remaining_steps);
97 return $clone;
98 }
99
101 {
102 if (empty($this->previous_steps)) {
103 return null;
104 }
105 $clone = clone $this;
106 $clone->elements = iterator_to_array($clone->bridge->getParents(...$clone->elements));
107 $next_step = array_pop($clone->previous_steps);
108 array_unshift($clone->remaining_steps, $clone->current_step);
109 $clone->current_step = $next_step;
110 return $clone;
111 }
112
113 public function hasPreviousStep(): bool
114 {
115 return count($this->previous_steps) > 0;
116 }
117
118 public function hasNextStep(): bool
119 {
120 return count($this->remaining_steps) > 0;
121 }
122
123 public function hasElements(): bool
124 {
125 return count($this->elements) > 0;
126 }
127
132 public function elementsAtFinalStep(): \Generator
133 {
134 $clone = clone $this;
135 while ($next = $clone->nextStep()) {
136 $clone = $next;
137 }
138 yield from $clone->elements();
139 }
140
145 {
146 $return = null;
147 foreach ($this->elementsAtFinalStep() as $element) {
148 $return = $element;
149 }
150 return $return;
151 }
152
157 public function elements(): \Generator
158 {
159 $this->checkLeadsToOne();
160 yield from $this->elements;
161 }
162
167 {
168 $return = null;
169 foreach ($this->elements() as $element) {
170 $return = $element;
171 }
172 return $return;
173 }
174
178 protected function checkLeadsToOne(): void
179 {
180 if (!$this->leads_to_one) {
181 return;
182 }
183 if (count($this->elements) !== 1) {
184 throw new \ilMDPathException(
185 'Path should lead to exactly one element but does not.'
186 );
187 }
188 }
189}
nextStep()
Returns null if there is no next step.
__construct(PathInterface $path, BaseElementInterface $start_element, NavigatorBridge $bridge)
hasElements()
Should return true if the navigator contains at least one element at the current step.
leadsToExactlyOneElement()
Specifies whether the path should point to exactly one element, or whether it can also lead to no or ...
$path
Definition: ltiservices.php:30