engine = $engine; $this->article = $article; $this->formelCalc = new Formel($engine, $article); } public function perform($withFormel = true): void { $this->validRec($this->article->getOptions(), $withFormel); } private function validRec(\ArrayIterator $options, $withFormel = true): void { foreach ($options as $option) { if ($option instanceof Row) { foreach ($option->getColumns() as $col) { $this->validRec($col->getOptions(), $withFormel); } } if ($option instanceof Input) { if ($option->getMaxValue() && $option->getRawValue() > $option->getMaxValue()) { $option->addValidationError(new Max(intval($option->getRawValue()), $option->getMaxValue())); } if ($option->getMinValue() && $option->getRawValue() < $option->getMinValue()) { $option->addValidationError(new Min(intval($option->getRawValue()), $option->getMinValue())); } } if (($option instanceof Select || $option instanceof Checkbox) && !($option instanceof ColorDBSelect)) { $valid = false; $nextShouldBeValid = false; $isDefaultValid = true; $option->clearSelected(); /** @var Select\Opt $opt */ foreach ($option->getOptions() as $opt) { if (count($opt->getEdgesCollectionContainer()) > 0) { $opt->setIsValid(false); } $groupsValid = []; /** @var EdgeCollection $collection */ foreach ($opt->getEdgesCollectionContainer() as $collection) { if (!$withFormel && trim($collection->getFormel()) != '') continue; $groupsValid[$collection->getName()] = false; if (trim($collection->getFormel()) != '') { $value = $this->formelCalc->parse($collection->getFormel(), true); eval('$value = ' . $value . ';'); /** @var Edge $edge */ foreach ($collection as $edge) { if ($this->edgeIsValidWithValue($value, $edge)) { //$opt->setIsValid(true); $groupsValid[$collection->getName()] = true; } } } else { /** @var Edge $edge */ foreach ($collection as $edge) { if ($this->edgeIsValid($collection->getName(), $edge)) { //$opt->setIsValid(true); $groupsValid[$collection->getName()] = true; } } } } if (!in_array(false, $groupsValid)) { $opt->setIsValid(true); } if ( !$opt->isValid() && $opt->getId() == $option->getDefault() && $option->getSelectedOptions()->count() == 0 ) { $isDefaultValid = false; } if ($option->getDefault() === null && $opt->isValid()) { $option->setDefault($opt->getId()); if (!$this->engine->hasVariable($option->getId())) { $this->engine->setVariable($option->getId(), $opt->getId()); } } if ($option->getDefault() !== null && $opt->isValid() && !$isDefaultValid) { $option->setDefault($opt->getId()); $this->engine->setVariable($option->getId(), $opt->getId()); if ( isset($this->engine->validVars[$option->getId()]) && $opt->getId() != $this->engine->validVars[$option->getId()] ) { $this->engine->validDirty = true; } $isDefaultValid = true; } if ($option instanceof Checkbox) { if ( isset($this->engine->getVariables()[$option->getId()]) && is_array($this->engine->getVariables()[$option->getId()]) && in_array($opt->getId(), $this->engine->getVariables()[$option->getId()]) ) { $option->addSelectedOption($opt); } } else { if ( isset($this->engine->getVariables()[$option->getId()]) && $this->engine->getVariables()[$option->getId()] == $opt->getId() ) { if (!$opt->isValid()) { $nextShouldBeValid = true; } else { $option->addSelectedOption($opt); } } else { if ($nextShouldBeValid && $opt->isValid()) { $this->engine->getVariables()[$option->getId()] = $opt->getId(); $option->addSelectedOption($opt); $nextShouldBeValid = false; } } } if ($opt->isValid() && !$valid) { $valid = true; } } if ($nextShouldBeValid && $option->getSelectedOptions()->count() === 0) { foreach ($option->getOptions() as $opt) { if ($opt->isValid()) { $option->addSelectedOption($opt); break; } } } $option->processValue(); $option->setIsValid($valid); } if ($option instanceof ColorDBSelect) { if (isset($this->engine->getVariables()[$option->getId()])) { $element = array_find((array) $option->getOptions(), function (ColorOpt $o1) use ($option) { return $o1->getId() === $this->engine->getVariables()[$option->getId()]; }); if ($element) { $option->addSelectedOption($element); } else { $option->addSelectedOption($option->getOptions()[0]); } } elseif ($option->getDefault() != null) { $element = array_find((array) $option->getOptions(), function (ColorOpt $o1) use ($option) { return $o1->getId() === $option->getDefault(); }); $option->addSelectedOption($element); } else { $option->addSelectedOption($option->getOptions()[0]); } } $mainEdges = true; foreach ($option->getEdgesCollectionContainer() as $collection) { /** @var Edge $edge */ $collValid = false; foreach ($collection as $edge) { if (!$collValid && $this->edgeIsValid($collection->getName(), $edge)) { $collValid = true; } } if (!$collValid) { $mainEdges = false; break; } } if (!$mainEdges && $option->isValid()) { $option->setIsValid(false); } $this->engine->setVariables($option->parseAdditionalValues($this->engine->getVariables())); $this->engine->addCalcVariable($option->getId() . '_valid', (int) $option->isValid()); } } private function edgeIsValid(mixed $section, Edge $edge): bool { $valid = false; $skipTests = false; if (!isset($this->engine->getVariables()[$section])) { $skipTests = true; } if ( !$skipTests && !$valid && $edge->isRegion() && $edge->getFrom() <= $this->engine->getVariables()[$section] && $edge->getTo() >= $this->engine->getVariables()[$section] ) { $valid = true; } if ( !$skipTests && !$valid && $edge->isRegion() && $edge->getFrom() <= $this->engine->getVariables()[$section] && $edge->getTo() == 0 ) { $valid = true; } if ( !$skipTests && !$valid && !$edge->isRegion() && in_array($this->engine->getVariables()[$section], $edge->getValues()) ) { $valid = true; } if (!$skipTests && $valid && $edge->getEdgesCollectionContainer()->count()) { $valid = false; /** @var EdgeCollection $collection */ foreach ($edge->getEdgesCollectionContainer() as $collection) { foreach ($collection as $subEdge) { if (!$valid) { $valid = $this->edgeIsValid($collection->getName(), $subEdge); } } } } return $valid; } private function edgeIsValidWithValue(mixed $value, Edge $edge): bool { if ($edge->isRegion() && $edge->getFrom() <= $value && $edge->getTo() >= $value) { return true; } if ($edge->isRegion() && $edge->getFrom() <= $value && $edge->getTo() == 0) { return true; } if (!$edge->isRegion() && in_array($value, $edge->getValues())) { return true; } return false; } }