mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 02:58:43 +02:00
N°6414 Move existing AbstractSimpleField::Validate impl to custom validators
- LinkedSetField - SelectObjectField - MultipleChoicesField (warning this hierarchy contains non multiple value fields like SelectField !) Also change AbstractValidator::Validate signature : now we are returning an array of error messages, so that we can return multiple ones
This commit is contained in:
@@ -26,12 +26,13 @@ class AbstractSimpleField extends Field
|
||||
|
||||
if (!$bEmpty || $this->GetMandatory()) {
|
||||
foreach ($this->GetValidators() as $oValidator) {
|
||||
[$bIsFieldValid, $sValidationErrorMessage] = $oValidator->Validate($this->GetCurrentValue());
|
||||
$aValidationErrorMessages = $oValidator->Validate($this->GetCurrentValue());
|
||||
|
||||
/** @var bool $bIsFieldValid */
|
||||
if (false === $bIsFieldValid) {
|
||||
if (count($aValidationErrorMessages) > 0) {
|
||||
$this->SetValid(false);
|
||||
$this->AddErrorMessage($sValidationErrorMessage);
|
||||
foreach ($aValidationErrorMessages as $sErrorMessage) {
|
||||
$this->AddErrorMessage($sErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,15 +505,33 @@ abstract class Field
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sValidatorClassName validator class name, should be one of {@see AbstractValidator} children
|
||||
* @return $this
|
||||
* @since 3.1.0 N°6414
|
||||
*/
|
||||
final public function RemoveValidatorsOfClass(string $sValidatorClassName)
|
||||
{
|
||||
foreach ($this->aValidators as $iKey => $oValue) {
|
||||
if ($oValue instanceof $sValidatorClassName) {
|
||||
unset($this->aValidators[$iKey]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be add from outside
|
||||
*
|
||||
* @param string $sErrorMessage
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function AddErrorMessage(string $sErrorMessage)
|
||||
{
|
||||
$this->aErrorMessages[] = $sErrorMessage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
namespace Combodo\iTop\Form\Field;
|
||||
|
||||
use Closure;
|
||||
use Dict;
|
||||
use ormLinkSet;
|
||||
use Combodo\iTop\Form\Validator\LinkedSetValidator;
|
||||
|
||||
/**
|
||||
* Description of LinkedSetField
|
||||
@@ -55,7 +54,7 @@ class LinkedSetField extends AbstractSimpleField
|
||||
protected $aLimitedAccessItemIDs;
|
||||
/** @var array $aAttributesToDisplay */
|
||||
protected $aAttributesToDisplay;
|
||||
/** @var array $aLnkAttributesToDisplay */
|
||||
/** @var array $aLnkAttributesToDisplay attcode as key */
|
||||
protected $aLnkAttributesToDisplay;
|
||||
/** @var string $sSearchEndpoint */
|
||||
protected $sSearchEndpoint;
|
||||
@@ -281,25 +280,25 @@ class LinkedSetField extends AbstractSimpleField
|
||||
public function GetLnkAttributesToDisplay(bool $bAttCodesOnly = false)
|
||||
{
|
||||
return ($bAttCodesOnly) ? array_keys($this->aLnkAttributesToDisplay) : $this->aLnkAttributesToDisplay;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param array $aAttributesToDisplay
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetLnkAttributesToDisplay(array $aAttributesToDisplay)
|
||||
{
|
||||
$this->aLnkAttributesToDisplay = $aAttributesToDisplay;
|
||||
/**
|
||||
* @param array $aAttributesToDisplay
|
||||
* @return $this
|
||||
* @since 3.1.0 N°803
|
||||
*/
|
||||
public function SetLnkAttributesToDisplay(array $aAttributesToDisplay)
|
||||
{
|
||||
$this->aLnkAttributesToDisplay = $aAttributesToDisplay;
|
||||
|
||||
return $this;
|
||||
}
|
||||
$this->RemoveValidatorsOfClass(LinkedSetValidator::class);
|
||||
$this->AddValidator(new LinkedSetValidator($aAttributesToDisplay));
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function GetSearchEndpoint()
|
||||
{
|
||||
@@ -349,39 +348,4 @@ class LinkedSetField extends AbstractSimpleField
|
||||
{
|
||||
return in_array($iItemID, $this->aLimitedAccessItemIDs, false);
|
||||
}
|
||||
|
||||
/** @inheritdoc @since 3.1 */
|
||||
public function Validate()
|
||||
{
|
||||
$bValid = parent::Validate();
|
||||
|
||||
/** @var ormLinkSet $oSet */
|
||||
$oSet = $this->GetCurrentValue();
|
||||
|
||||
// retrieve displayed attributes
|
||||
$aAttributesToDisplayCodes = $this->GetLnkAttributesToDisplay(true);
|
||||
|
||||
// validate each links...
|
||||
/** @var \DBObject $oItem */
|
||||
foreach ($oSet as $oItem) {
|
||||
$aChanges = $oItem->ListChanges();
|
||||
foreach ($aChanges as $sAttCode => $value) {
|
||||
if (!in_array($sAttCode, $aAttributesToDisplayCodes)) {
|
||||
continue;
|
||||
}
|
||||
$res = $oItem->CheckValue($sAttCode);
|
||||
if ($res !== true) {
|
||||
$sAttLabel = $this->GetLabel($sAttCode);
|
||||
$sItem = $oItem->Get('friendlyname') != '' ? $oItem->Get('friendlyname') : Dict::S('UI:Links:NewItem');
|
||||
$sIssue = Dict::Format('Core:CheckValueError', $sAttLabel, $sAttCode, $res);
|
||||
$this->AddErrorMessage('<b>'.$sItem.' : </b>'.$sIssue);
|
||||
$bValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oSet->Rewind();
|
||||
|
||||
return $bValid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
namespace Combodo\iTop\Form\Field;
|
||||
|
||||
use Closure;
|
||||
use ContextTag;
|
||||
use utils;
|
||||
use Combodo\iTop\Form\Validator\MultipleChoicesValidator;
|
||||
|
||||
/**
|
||||
* Description of MultipleChoicesField
|
||||
@@ -51,6 +50,8 @@ abstract class MultipleChoicesField extends AbstractSimpleField
|
||||
$this->bMultipleValuesEnabled = static::DEFAULT_MULTIPLE_VALUES_ENABLED;
|
||||
$this->aChoices = array();
|
||||
$this->currentValue = array();
|
||||
|
||||
$this->InitValidators();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,69 +180,68 @@ abstract class MultipleChoicesField extends AbstractSimpleField
|
||||
public function SetChoices(array $aChoices)
|
||||
{
|
||||
$this->aChoices = $aChoices;
|
||||
|
||||
$this->InitValidators();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sId
|
||||
* @param null $choice
|
||||
* @param null $choice choice value (eg label)
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddChoice(string $sId, $choice = null)
|
||||
{
|
||||
if ($choice === null)
|
||||
{
|
||||
if ($choice === null) {
|
||||
$choice = $sId;
|
||||
}
|
||||
$this->aChoices[$sId] = $choice;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sId
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function RemoveChoice(string $sId)
|
||||
{
|
||||
if (in_array($sId, $this->aChoices))
|
||||
{
|
||||
unset($this->aChoices[$sId]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
$this->InitValidators();
|
||||
|
||||
public function Validate() {
|
||||
$this->SetValid(true);
|
||||
$this->EmptyErrorMessages();
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ((ContextTag::Check(ContextTag::TAG_REST)) && ($this->GetReadOnly() === false)) {
|
||||
// Only doing the check when coming from the REST API, as the user portal might send invalid values (see VerifyCurrentValue() method below)
|
||||
// Also do not check read only fields, are they are send with a null value when submitting request template from the console
|
||||
if (count($this->currentValue) > 0) {
|
||||
foreach ($this->currentValue as $sCode => $value) {
|
||||
if (utils::IsNullOrEmptyString($value)) {
|
||||
continue;
|
||||
}
|
||||
if (false === array_key_exists($value, $this->aChoices)) {
|
||||
$this->SetValid(false);
|
||||
$this->AddErrorMessage("Value ({$value}) is not part of the field possible values list");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param string $sId
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function RemoveChoice(string $sId)
|
||||
{
|
||||
if (in_array($sId, $this->aChoices)) {
|
||||
unset($this->aChoices[$sId]);
|
||||
}
|
||||
|
||||
foreach ($this->GetValidators() as $oValidator) {
|
||||
foreach ($this->currentValue as $value) {
|
||||
if (!preg_match($oValidator->GetRegExp(true), $value)) {
|
||||
$this->SetValid(false);
|
||||
$this->AddErrorMessage($oValidator->GetErrorMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->GetValid();
|
||||
}
|
||||
/**
|
||||
* @param bool $bReadOnly
|
||||
* @return MultipleChoicesField
|
||||
* @since 3.1.0 N°6414
|
||||
*/
|
||||
public function SetReadOnly(bool $bReadOnly)
|
||||
{
|
||||
if ($bReadOnly) {
|
||||
/** @noinspection PhpRedundantOptionalArgumentInspection */
|
||||
$this->SetValidationDisabled(true);
|
||||
} else {
|
||||
$this->SetValidationDisabled(false);
|
||||
}
|
||||
|
||||
return parent::SetReadOnly($bReadOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @since 3.1.0 N°6414
|
||||
*/
|
||||
protected function InitValidators(): void
|
||||
{
|
||||
$this->RemoveValidatorsOfClass(MultipleChoicesValidator::class);
|
||||
$this->AddValidator(new MultipleChoicesValidator($this->aChoices));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,5 +28,4 @@ class MultipleSelectField extends SelectField
|
||||
{
|
||||
/** @inheritDoc */
|
||||
const DEFAULT_MULTIPLE_VALUES_ENABLED = true;
|
||||
|
||||
}
|
||||
|
||||
@@ -20,18 +20,14 @@
|
||||
|
||||
namespace Combodo\iTop\Form\Field;
|
||||
|
||||
use BinaryExpression;
|
||||
use Closure;
|
||||
use Combodo\iTop\Form\Helper\FieldHelper;
|
||||
use Combodo\iTop\Form\Validator\AbstractValidator;
|
||||
use Combodo\iTop\Form\Validator\NotEmptyExtKeyValidator;
|
||||
use ContextTag;
|
||||
use DBObjectSet;
|
||||
use Combodo\iTop\Form\Validator\SelectObjectValidator;
|
||||
use DBSearch;
|
||||
use DeprecatedCallsLog;
|
||||
use FieldExpression;
|
||||
use MetaModel;
|
||||
use ScalarExpression;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Description of SelectObjectField
|
||||
@@ -95,6 +91,9 @@ class SelectObjectField extends AbstractSimpleField
|
||||
{
|
||||
$this->oSearch = $oSearch;
|
||||
|
||||
$this->RemoveValidatorsOfClass(SelectObjectValidator::class);
|
||||
$this->AddValidator(new SelectObjectValidator($oSearch));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -229,27 +228,6 @@ class SelectObjectField extends AbstractSimpleField
|
||||
return $this->sSearchEndpoint;
|
||||
}
|
||||
|
||||
public function Validate() {
|
||||
if ((ContextTag::Check(ContextTag::TAG_REST)) && ($this->GetReadOnly() === false)) {
|
||||
// Only doing the check when coming from the REST API, as the user portal might send invalid values (see VerifyCurrentValue() method below)
|
||||
// Also do not check read only fields, are they are send with a null value when submitting request template from the console
|
||||
$sCurrentValueForExtKey = $this->currentValue;
|
||||
if (utils::IsNotNullOrEmptyString($sCurrentValueForExtKey) && ($sCurrentValueForExtKey !== 0)) {
|
||||
$oSetForExistingCurrentValue = $this->GetObjectsSet();
|
||||
$iObjectsCount = $oSetForExistingCurrentValue->CountWithLimit(1);
|
||||
|
||||
if ($iObjectsCount === 0) {
|
||||
$this->SetValid(false);
|
||||
$this->AddErrorMessage("Value $sCurrentValueForExtKey does not match the corresponding filter set");
|
||||
|
||||
return $this->GetValid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::Validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets current value if not among allowed ones.
|
||||
* By default, reset is done ONLY when the field is not read-only.
|
||||
@@ -283,25 +261,11 @@ class SelectObjectField extends AbstractSimpleField
|
||||
*/
|
||||
public function ResetCurrentValueIfNotAmongAllowedValues(bool $bAlways = false) {
|
||||
if (!$this->GetReadOnly() || $bAlways) {
|
||||
$oValuesSet = $this->GetObjectsSet();
|
||||
$oValuesSet = FieldHelper::GetObjectsSetFromSearchAndCurrentValueId($this->oSearch, $this->currentValue);
|
||||
|
||||
if ($oValuesSet->Count() === 0) {
|
||||
$this->currentValue = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final protected function GetObjectsSet() {
|
||||
$sCurrentValueForExtKey = $this->currentValue;
|
||||
|
||||
$oSearchForExistingCurrentValue = $this->oSearch->DeepClone();
|
||||
$oCheckIdAgainstCurrentValueExpression = new BinaryExpression(
|
||||
new FieldExpression('id', $oSearchForExistingCurrentValue->GetClassAlias()),
|
||||
'=',
|
||||
new ScalarExpression($sCurrentValueForExtKey)
|
||||
);
|
||||
$oSearchForExistingCurrentValue->AddConditionExpression($oCheckIdAgainstCurrentValueExpression);
|
||||
|
||||
return new DBObjectSet($oSearchForExistingCurrentValue);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user