19 declare(strict_types=1);
74 $elements = $this->navigator_factory->navigator($path, $my_set->getRoot())->elementsAtFinalStep();
75 $target_elements = [];
76 foreach ($elements as $element) {
78 $target_elements[] = $element;
94 $elements_to_update = $this->getElementsToUpdate($my_set->getRoot(),
$path, ...$values);
95 $remaining_values = array_slice($values, 0, count($values) - count($elements_to_update));
96 $elements_to_create = $this->getElementsToCreate($my_set->getRoot(),
$path, ...$remaining_values);
97 $target_elements = array_merge($elements_to_update, $elements_to_create);
110 $my_set = clone $set;
111 $target_elements = $this->getElementsToCreate($my_set->getRoot(),
$path, ...$values);
116 protected function getElementsToUpdate(
125 $path_conditions = $this->path_utilities_factory->pathConditionsCollection($path);
126 $path_checker = $this->path_utilities_factory->pathConditionChecker($path_conditions);
127 $target_elements = [];
128 $navigators = [$this->navigator_factory->navigator($path_conditions->getPathWithoutConditions(), $set_root)];
130 if (count($values) <= 0) {
135 while (count($navigators) > 0) {
136 $curr_navi = array_shift($navigators)->nextStep();
137 $at_least_one_path_condition_met = $path_checker->atLeastOnePathConditionIsMet(
138 $curr_navi->currentStep(),
139 ...$curr_navi->elements()
143 if ($at_least_one_path_condition_met && $curr_navi->hasElements() && !$curr_navi->hasNextStep()) {
144 $roots = iterator_to_array($path_checker->getRootsThatMeetPathCondition(
145 $curr_navi->currentStep(),
146 ...$curr_navi->elements()
149 $missing_target_count = max(0, count($values) - count($target_elements));
150 $targets = array_slice($roots, 0, $missing_target_count);
151 array_push($target_elements, ...$targets);
156 if ($at_least_one_path_condition_met && $curr_navi->hasElements() && $curr_navi->hasNextStep()) {
157 $roots = iterator_to_array($path_checker->getRootsThatMeetPathCondition(
158 $curr_navi->currentStep(),
159 ...$curr_navi->elements()
161 foreach ($roots as $root) {
162 $navigators[] = $this->navigator_factory->navigator(
171 return $target_elements;
174 protected function getElementsToCreate(
185 $path_conditions = $this->path_utilities_factory->pathConditionsCollection($path);
186 $path_checker = $this->path_utilities_factory->pathConditionChecker($path_conditions);
187 $target_elements = [];
188 $loose_end_roots = [];
189 $loose_end_paths = [];
190 $navigators = [$this->navigator_factory->navigator($path_conditions->getPathWithoutConditions(), $set_root)];
192 if (count($values) <= 0) {
197 while (count($navigators) > 0) {
198 $orig_navi = array_shift($navigators);
199 $curr_navi = $orig_navi->nextStep();
200 $at_least_one_path_condition_met = $path_checker->atLeastOnePathConditionIsMet(
201 $curr_navi->currentStep(),
202 ...$curr_navi->elements()
206 if (!$at_least_one_path_condition_met) {
207 $roots = iterator_to_array($orig_navi->elements());
209 array_push($loose_end_roots, ...$roots);
210 array_push($loose_end_paths, ...$paths);
215 if ($at_least_one_path_condition_met && !$curr_navi->hasElements() && !$curr_navi->hasNextStep()) {
216 $roots = iterator_to_array($orig_navi->elements());
218 array_push($loose_end_roots, ...$roots);
219 array_push($loose_end_paths, ...$paths);
224 if ($at_least_one_path_condition_met && !$curr_navi->hasElements() && $curr_navi->hasNextStep()) {
225 $roots = iterator_to_array($path_checker->getRootsThatMeetPathCondition(
226 $curr_navi->currentStep(),
227 ...$curr_navi->elements()
230 array_push($loose_end_roots, ...$roots);
231 array_push($loose_end_paths, ...$paths);
236 if ($at_least_one_path_condition_met && $curr_navi->hasElements() && $curr_navi->hasNextStep()) {
237 $roots = iterator_to_array($path_checker->getRootsThatMeetPathCondition(
238 $curr_navi->currentStep(),
239 ...$curr_navi->elements()
241 foreach ($roots as $root) {
242 $navigators[] = $this->navigator_factory->navigator(
252 $missing_target_count = max(0, count($values) - count($target_elements));
253 if (count($loose_end_roots) > 0 && $missing_target_count > 0) {
255 array_shift($loose_end_paths),
256 array_shift($loose_end_roots),
263 $path_conditions->getPathWithoutConditions(),
269 if ($navigator->hasPreviousStep()) {
270 $navigator = $navigator->previousStep();
274 $missing_target_count = max(0, count($values) - count($target_elements));
275 $loose_end_paths = array_slice($loose_end_paths, 0, $missing_target_count);
276 $loose_end_roots = array_slice($loose_end_roots, 0, $missing_target_count);
277 array_push($target_elements, ...$this->
createTargetElements($loose_end_roots, $loose_end_paths, $path_conditions));
280 $missing_target_count = max(0, count($values) - count($target_elements));
282 $root = $navigator->lastElement();
283 $target_paths = array_fill(0, $missing_target_count, $remaining_path);
284 $target_roots = array_fill(0, $missing_target_count, $root);
285 array_push($target_elements, ...$this->
createTargetElements($target_roots, $target_paths, $path_conditions));
287 return $target_elements;
303 $builder = $this->path_factory->custom()
305 ->withLeadsToExactlyOneElement(
false);
306 while (!is_null($navigator)) {
308 $navigator = $navigator->
nextStep();
311 $builder = $builder->withNextStepFromStep($navigator->
currentStep(),
false);
312 $navigator = $navigator->
nextStep();
314 return $builder->get();
321 $navigator = $this->navigator_factory->navigator($path, $root);
322 while ($navigator->hasNextStep() && $navigator->nextStep()->hasElements()) {
323 $navigator = $navigator->
nextStep();
336 $navigator = $this->navigator_factory->navigator($path, $root);
337 $navigator = $navigator->nextStep();
339 while (!is_null($navigator)) {
341 if (is_null($scaffold)) {
343 'Cannot create scaffold at step: ' . $navigator->currentStep()->name() .
', invalid path.' 347 if ($condition_path->steps()->valid()) {
350 $navigator = $navigator->nextStep();
366 $target_elements = [];
367 while (0 < count($paths)) {
374 return $target_elements;
384 $navigator = $this->navigator_factory->navigator($condition_path, $root);
385 $navigator = $navigator->nextStep();
387 while (!is_null($navigator)) {
389 if (is_null($scaffold)) {
392 $navigator = $navigator->nextStep();
407 $this->scaffold_provider,
410 if (!isset($scaffold)) {
414 foreach ($step->
filters() as $filter) {
416 $data = $filter->values()->current();
421 $this->marker_factory,
422 Action::CREATE_OR_UPDATE,
435 $element->
mark($this->marker_factory, Action::CREATE_OR_UPDATE, $value);
436 }, $target_elements, $values);
443 }, $target_elements);