Commit fe68cec4 authored by Ad Schellevis's avatar Ad Schellevis

(model) refactor getConstraintValidators() in BaseField, add...

(model) refactor getConstraintValidators() in BaseField, add getConstraintByName() to retrieve a constraint by name/key and add functionality to explain the model field relations.

Using reference tags in the constraints section its possible to tell the model which fields interact to avoid the need for a full model validation after each change.
For example if fieldA has a constraint which relates to fieldB, the latter can add a reference to trigger validation when only fieldB changes.

<Constraints>
   <check001>
     <reference>fieldB.check000</reference>
   </check001>
</Constraints>
parent b2bd051c
...@@ -362,25 +362,58 @@ abstract class BaseField ...@@ -362,25 +362,58 @@ abstract class BaseField
} }
/** /**
* fetch all additional validators * retrieve constraint objects by defined constraints name (/key)
* @param $name
* @return null|object
*/ */
private function getConstraintValidators() public function getConstraintByName($name)
{ {
$result = array(); if (isset($this->internalConstraints[$name])) {
foreach ($this->internalConstraints as $name => $constraint) { $constraint = $this->internalConstraints[$name];
if (!empty($constraint['type'])) { if (!empty($constraint['type'])) {
try { try {
$constr_class = new \ReflectionClass($constraint['type']); $constr_class = new \ReflectionClass($constraint['type']);
if ($constr_class->getParentClass()->name == 'OPNsense\Base\Constraints\BaseConstraint') { if ($constr_class->getParentClass()->name == 'OPNsense\Base\Constraints\BaseConstraint') {
$constraint['name'] = $name; $constraint['name'] = $name;
$constraint['node'] = $this; $constraint['node'] = $this;
$result[] = $constr_class->newInstance($constraint); return $constr_class->newInstance($constraint);
} }
} catch (\ReflectionException $e) { } catch (\ReflectionException $e) {
null; // ignore configuration errors, if the constraint can't be found, skip. null; // ignore configuration errors, if the constraint can't be found, skip.
} }
} }
} }
return null;
}
/**
* fetch all additional validators
* @return array
*/
private function getConstraintValidators()
{
$result = array();
foreach ($this->internalConstraints as $name => $constraint) {
if (!empty($constraint['reference'])) {
// handle references (should use the same level)
$parts = explode('.', $constraint['reference']);
$parentNode = $this->getParentNode();
if (count($parts) == 2) {
$tagName = $parts[0];
if (isset($parentNode->__items[$tagName])) {
$ref_constraint = $parentNode->$tagName->getConstraintByName($parts[1]);
if ($ref_constraint != null) {
$result[] = $ref_constraint;
}
}
}
} elseif (!empty($constraint['type'])) {
$constraintObj = $this->getConstraintByName($name);
if ($constraintObj != null) {
$result[] = $constraintObj;
}
}
}
return $result; return $result;
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment