19 declare(strict_types=1);
76 $elements = $this->navigator_factory->navigator($path, $my_set->getRoot())->elementsAtFinalStep();
77 $target_elements = [];
78 foreach ($elements as $element) {
80 $target_elements[] = $element;
100 $my_set = clone $set;
101 $elements_to_update = $this->getElementsToUpdate($my_set->getRoot(),
$path, ...$values);
102 $remaining_values = array_slice($values, 0, count($values) - count($elements_to_update));
103 $elements_to_create = $this->getElementsToCreate($my_set->getRoot(),
$path, ...$remaining_values);
104 $target_elements = array_merge($elements_to_update, $elements_to_create);
117 $my_set = clone $set;
118 $target_elements = $this->getElementsToCreate($my_set->getRoot(),
$path, ...$values);
123 protected function getElementsToUpdate(
132 $path_conditions = $this->path_utilities_factory->pathConditionsCollection($path);
133 $path_checker = $this->path_utilities_factory->pathConditionChecker($path_conditions);
134 $target_elements = [];
135 $navigators = [$this->navigator_factory->navigator($path_conditions->getPathWithoutConditions(), $set_root)];
137 if (count($values) <= 0) {
142 while (count($navigators) > 0) {
143 $curr_navi = array_shift($navigators)->nextStep();
144 $at_least_one_path_condition_met = $path_checker->atLeastOnePathConditionIsMet(
145 $curr_navi->currentStep(),
146 ...$curr_navi->elements()
150 if ($at_least_one_path_condition_met && $curr_navi->hasElements() && !$curr_navi->hasNextStep()) {
151 $roots = iterator_to_array($path_checker->getRootsThatMeetPathCondition(
152 $curr_navi->currentStep(),
153 ...$curr_navi->elements()
156 $missing_target_count = max(0, count($values) - count($target_elements));
157 $targets = array_slice($roots, 0, $missing_target_count);
158 array_push($target_elements, ...$targets);
163 if ($at_least_one_path_condition_met && $curr_navi->hasElements() && $curr_navi->hasNextStep()) {
164 $roots = iterator_to_array($path_checker->getRootsThatMeetPathCondition(
165 $curr_navi->currentStep(),
166 ...$curr_navi->elements()
168 foreach ($roots as $root) {
169 $navigators[] = $this->navigator_factory->navigator(
178 return $target_elements;
181 protected function getElementsToCreate(
192 $path_conditions = $this->path_utilities_factory->pathConditionsCollection($path);
193 $path_checker = $this->path_utilities_factory->pathConditionChecker($path_conditions);
194 $target_elements = [];
195 $loose_end_roots = [];
196 $loose_end_paths = [];
197 $navigators = [$this->navigator_factory->navigator($path_conditions->getPathWithoutConditions(), $set_root)];
199 if (count($values) <= 0) {
204 while (count($navigators) > 0) {
205 $orig_navi = array_shift($navigators);
206 $curr_navi = $orig_navi->nextStep();
207 $at_least_one_path_condition_met = $path_checker->atLeastOnePathConditionIsMet(
208 $curr_navi->currentStep(),
209 ...$curr_navi->elements()
213 if (!$at_least_one_path_condition_met) {
214 $roots = iterator_to_array($orig_navi->elements());
216 array_push($loose_end_roots, ...$roots);
217 array_push($loose_end_paths, ...$paths);
222 if ($at_least_one_path_condition_met && !$curr_navi->hasElements() && !$curr_navi->hasNextStep()) {
223 $roots = iterator_to_array($orig_navi->elements());
225 array_push($loose_end_roots, ...$roots);
226 array_push($loose_end_paths, ...$paths);
231 if ($at_least_one_path_condition_met && !$curr_navi->hasElements() && $curr_navi->hasNextStep()) {
232 $roots = iterator_to_array($path_checker->getRootsThatMeetPathCondition(
233 $curr_navi->currentStep(),
234 ...$curr_navi->elements()
237 array_push($loose_end_roots, ...$roots);
238 array_push($loose_end_paths, ...$paths);
243 if ($at_least_one_path_condition_met && $curr_navi->hasElements() && $curr_navi->hasNextStep()) {
244 $roots = iterator_to_array($path_checker->getRootsThatMeetPathCondition(
245 $curr_navi->currentStep(),
246 ...$curr_navi->elements()
248 foreach ($roots as $root) {
249 $navigators[] = $this->navigator_factory->navigator(
259 $missing_target_count = max(0, count($values) - count($target_elements));
260 if (count($loose_end_roots) > 0 && $missing_target_count > 0) {
262 array_shift($loose_end_paths),
263 array_shift($loose_end_roots),
270 $path_conditions->getPathWithoutConditions(),
276 if ($navigator->hasPreviousStep()) {
277 $navigator = $navigator->previousStep();
281 $missing_target_count = max(0, count($values) - count($target_elements));
282 $loose_end_paths = array_slice($loose_end_paths, 0, $missing_target_count);
283 $loose_end_roots = array_slice($loose_end_roots, 0, $missing_target_count);
284 array_push($target_elements, ...$this->
createTargetElements($loose_end_roots, $loose_end_paths, $path_conditions));
287 $missing_target_count = max(0, count($values) - count($target_elements));
289 $root = $navigator->lastElement();
290 $target_paths = array_fill(0, $missing_target_count, $remaining_path);
291 $target_roots = array_fill(0, $missing_target_count, $root);
292 array_push($target_elements, ...$this->
createTargetElements($target_roots, $target_paths, $path_conditions));
294 return $target_elements;
310 $builder = $this->path_factory->custom()
312 ->withLeadsToExactlyOneElement(
false);
313 while (!is_null($navigator)) {
315 $navigator = $navigator->
nextStep();
318 $builder = $builder->withNextStepFromStep($navigator->
currentStep(),
false);
319 $navigator = $navigator->
nextStep();
321 return $builder->get();
328 $navigator = $this->navigator_factory->navigator($path, $root);
329 while ($navigator->hasNextStep() && $navigator->nextStep()->hasElements()) {
330 $navigator = $navigator->
nextStep();
343 $navigator = $this->navigator_factory->navigator($path, $root);
344 $navigator = $navigator->nextStep();
346 while (!is_null($navigator)) {
348 if (is_null($scaffold)) {
350 'Cannot create scaffold at step: ' . $navigator->currentStep()->name() .
', invalid path.' 354 if ($condition_path->steps()->valid()) {
357 $navigator = $navigator->nextStep();
373 $target_elements = [];
374 while (0 < count($paths)) {
381 return $target_elements;
391 $navigator = $this->navigator_factory->navigator($condition_path, $root);
392 $navigator = $navigator->nextStep();
394 while (!is_null($navigator)) {
396 if (is_null($scaffold)) {
399 $navigator = $navigator->nextStep();
417 if (!isset($scaffold)) {
421 foreach ($step->
filters() as $filter) {
423 $data = $filter->values()->current();
428 $this->marker_factory,
429 Action::CREATE_OR_UPDATE,
442 $element->
mark($this->marker_factory, Action::CREATE_OR_UPDATE, $value);
443 }, $target_elements, $values);
450 }, $target_elements);