290 lines
11 KiB
PHP
290 lines
11 KiB
PHP
<?php
|
|
|
|
namespace PSC\Library\Calc\Calc;
|
|
|
|
use PSC\Library\Calc\Article;
|
|
use PSC\Library\Calc\Engine;
|
|
use PSC\Library\Calc\Error\Validation\Input\Max;
|
|
use PSC\Library\Calc\Error\Validation\Input\Min;
|
|
use PSC\Library\Calc\General\Type\Edge;
|
|
use PSC\Library\Calc\General\Type\EdgeCollection;
|
|
use PSC\Library\Calc\General\Type\EdgeCollectionContainer;
|
|
use PSC\Library\Calc\Option\Type\Base;
|
|
use PSC\Library\Calc\Option\Type\Checkbox;
|
|
use PSC\Library\Calc\Option\Type\ColorDBSelect;
|
|
use PSC\Library\Calc\Option\Type\Input;
|
|
use PSC\Library\Calc\Option\Type\Row;
|
|
use PSC\Library\Calc\Option\Type\Select;
|
|
use PSC\Library\Calc\Option\Type\Select\ColorOpt;
|
|
|
|
class Valid
|
|
{
|
|
/** @var Engine */
|
|
protected $engine = null;
|
|
|
|
/** @var Article */
|
|
protected $article = null;
|
|
|
|
/** @var Formel */
|
|
protected $formelCalc;
|
|
|
|
public function __construct($engine, $article)
|
|
{
|
|
$this->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;
|
|
}
|
|
}
|