calc/src/Calc/Valid.php

237 lines
8.2 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\Input;
use PSC\Library\Calc\Option\Type\Select;
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);
}
/**
* @return void
*/
public function perform($withFormel = true)
{
/** @var Base $option */
foreach($this->article->getOptions() as $option) {
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) {
$valid = false;
$nextShouldBeValid = false;
/** @var Select\Opt $opt */
foreach ($option->getOptions() as $opt) {
$opt->setIsSelected(false);
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());
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($option->getDefault() === null && $opt->isValid()) {
$option->setDefault($opt->getId());
$this->engine->setVariable($option->getId(), $opt->getId());
}
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()])) {
$opt->setIsSelected(true);
} else {
$opt->setIsSelected(false);
}
}else {
if (isset($this->engine->getVariables()[$option->getId()]) && $this->engine->getVariables()[$option->getId()] == $opt->getId()) {
if(!$opt->isValid()) {
$nextShouldBeValid = true;
} else {
$opt->setIsSelected(true);
}
} else {
if($nextShouldBeValid && $opt->isValid()) {
$this->engine->getVariables()[$option->getId()] = $opt->getId();
$opt->setIsSelected(true);
$nextShouldBeValid = false;
} else{
$opt->setIsSelected(false);
}
}
}
if($opt->isValid() && !$valid) {
$valid = true;
}
}
if($nextShouldBeValid) {
foreach($option->getOptions() as $opt) {
if($opt->isValid()) {
$opt->setIsSelected(true);
break;
}
}
}
$option->processValue();
$option->setIsValid($valid);
}
if(count($option->getEdgesCollectionContainer()) > 0) {
$option->setIsValid(false);
}
/** @var EdgeCollection $collection */
foreach($option->getEdgesCollectionContainer() as $collection) {
/** @var Edge $edge */
foreach($collection as $edge) {
if($this->edgeIsValid($collection->getName(), $edge)) {
$option->setIsValid(true);
}
}
}
$this->engine->setVariables($option->parseAdditionalValues($this->engine->getVariables()));
}
}
/**
* @param $section
* @param Edge $edge
* @return bool
*/
private function edgeIsValid($section, $edge)
{
$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;
}
/**
* @param $section
* @param Edge $edge
* @return bool
*/
private function edgeIsValidWithValue($value, $edge)
{
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;
}
}