diff --git a/sources/autoload.php b/sources/autoload.php index 7fda62487..9ed0bd849 100644 --- a/sources/autoload.php +++ b/sources/autoload.php @@ -30,6 +30,7 @@ require_once APPROOT . 'sources/form/field/stringfield.class.inc.php'; require_once APPROOT . 'sources/form/field/textareafield.class.inc.php'; require_once APPROOT . 'sources/form/field/multiplechoicesfield.class.inc.php'; require_once APPROOT . 'sources/form/field/selectfield.class.inc.php'; +require_once APPROOT . 'sources/form/field/selectobjectfield.class.inc.php'; require_once APPROOT . 'sources/form/field/checkboxfield.class.inc.php'; require_once APPROOT . 'sources/form/field/radiofield.class.inc.php'; require_once APPROOT . 'sources/form/validator/validator.class.inc.php'; diff --git a/sources/form/field/field.class.inc.php b/sources/form/field/field.class.inc.php index 4851cbe04..ba2bb6b94 100644 --- a/sources/form/field/field.class.inc.php +++ b/sources/form/field/field.class.inc.php @@ -378,5 +378,19 @@ abstract class Field * * @return boolean */ - abstract public function Validate(); + public function Validate() + { + $this->SetValid(true); + $this->EmptyErrorMessages(); + foreach ($this->GetValidators() as $oValidator) + { + if (!preg_match($oValidator->GetRegExp(true), $this->GetCurrentValue())) + { + $this->SetValid(false); + $this->AddErrorMessage($oValidator->GetErrorMessage()); + } + } + + return $this->GetValid(); + } } diff --git a/sources/form/field/selectobjectfield.class.inc.php b/sources/form/field/selectobjectfield.class.inc.php new file mode 100644 index 000000000..e07594a70 --- /dev/null +++ b/sources/form/field/selectobjectfield.class.inc.php @@ -0,0 +1,102 @@ + + +namespace Combodo\iTop\Form\Field; + +use \Closure; +use Combodo\iTop\Form\Validator\NotEmptyExtKeyValidator; + +/** + * Description of SelectObjectField + * + */ +class SelectObjectField extends Field +{ + protected $sOqlQuery; + protected $iMaximumComboLength; + protected $iMinAutoCompleteChars; + + public function __construct($sId, Closure $onFinalizeCallback = null) + { + parent::__construct($sId, $onFinalizeCallback); + $this->sOqlQuery = null; + $this->iMaximumComboLength = null; + $this->iMinAutoCompleteChars = 3; + } + + public function SetOqlQuery($sOqlQuery) + { + $this->sOqlQuery = $sOqlQuery; + } + + public function SetMaximumComboLength($iMaximumComboLength) + { + $this->iMaximumComboLength = $iMaximumComboLength; + } + + public function SetMinAutoCompleteChars($iMinAutoCompleteChars) + { + $this->iMinAutoCompleteChars = $iMinAutoCompleteChars; + } + + /** + * Sets if the field is mandatory or not. + * Setting the value will automatically add/remove a MandatoryValidator to the Field + * + * @param boolean $bMandatory + * @return \Combodo\iTop\Form\Field\Field + */ + public function SetMandatory($bMandatory) + { + // Before changing the property, we check if it was already mandatory. If not, we had the mandatory validator + if ($bMandatory && !$this->bMandatory) + { + $this->AddValidator(new NotEmptyExtKeyValidator()); + } + + if (!$bMandatory) + { + foreach ($this->aValidators as $iKey => $oValue) + { + if ($oValue::Getname() === NotEmptyExtKeyValidator::GetName()) + { + unset($this->aValidators[$iKey]); + } + } + } + + $this->bMandatory = $bMandatory; + return $this; + } + + public function GetOqlQuery() + { + return $this->sOqlQuery; + } + + public function GetMaximumComboLength() + { + return $this->iMaximumComboLength; + } + + public function GetMinAutoCompleteChars() + { + return $this->iMinAutoCompleteChars; + } +} diff --git a/sources/form/field/textfield.class.inc.php b/sources/form/field/textfield.class.inc.php index bd9b36b1b..c7dbb6744 100644 --- a/sources/form/field/textfield.class.inc.php +++ b/sources/form/field/textfield.class.inc.php @@ -29,26 +29,4 @@ use \Combodo\iTop\Form\Field\Field; abstract class TextField extends Field { - /** - * Checks the validators to see if the field's current value is valid. - * Then sets $bValid and $aErrorMessages. - * - * @return boolean - */ - public function Validate() - { - $this->SetValid(true); - $this->EmptyErrorMessages(); - foreach ($this->GetValidators() as $oValidator) - { - if (!preg_match($oValidator->GetRegExp(true), $this->GetCurrentValue())) - { - $this->SetValid(false); - $this->AddErrorMessage($oValidator->GetErrorMessage()); - } - } - - return $this->GetValid(); - } - } diff --git a/sources/form/form.class.inc.php b/sources/form/form.class.inc.php index 47e56f477..cb9b07886 100644 --- a/sources/form/form.class.inc.php +++ b/sources/form/form.class.inc.php @@ -397,16 +397,47 @@ class Form } /** - * + * Finalizes each field, following the dependencies so that a field can compute its value or other properties, + * depending on other fields */ public function Finalize() { - //TODO : Call GetOrderedFields - // Must call OnFinalize on each fields, regarding the dependencies order - // On a SubFormField, will call its own Finalize - foreach ($this->aFields as $sId => $oField) - { - $oField->OnFinalize(); + $aFieldList = array(); // Fields ordered by dependence + // Clone the dependency data : $aDependencies will be truncated as the fields are added to the list + $aDependencies = $this->aDependencies; + $bMadeProgress = true; // Safety net in case of circular references + while ($bMadeProgress && count($aFieldList) < count($this->aFields)) + { + $bMadeProgress = false; + foreach ($this->aFields as $sId => $oField) + { + if (array_key_exists($sId, $aFieldList)) continue; + if (isset($aDependencies[$sId]) && count($aDependencies[$sId]) > 0) continue; + + // Add the field at the end of the list + $aFieldList[$sId] = $oField; + $bMadeProgress = true; + + // Track that this dependency has been solved + foreach ($aDependencies as $sImpactedBy => $aSomeFields) + { + foreach ($aSomeFields as $i => $sSomeId) + { + if ($sSomeId == $sId) + { + unset($aDependencies[$sImpactedBy][$i]); + } + } + } + } + } + if (!$bMadeProgress) + { + throw new Exception('Unmet dependencies: '.implode(', ', array_keys($aDependencies))); + } + foreach ($aFieldList as $sId => $oField) + { + $oField->OnFinalize(); } } diff --git a/sources/renderer/console/consoleformrenderer.class.inc.php b/sources/renderer/console/consoleformrenderer.class.inc.php index 66d228a0e..95c6be45d 100644 --- a/sources/renderer/console/consoleformrenderer.class.inc.php +++ b/sources/renderer/console/consoleformrenderer.class.inc.php @@ -20,7 +20,6 @@ namespace Combodo\iTop\Renderer\Console; use Combodo\iTop\Form\Form; use Combodo\iTop\Renderer\FormRenderer; -use Combodo\iTop\Renderer\RenderingOutput; use \Dict; require_once('fieldrenderer/consolesimplefieldrenderer.class.inc.php'); @@ -36,6 +35,7 @@ class ConsoleFormRenderer extends FormRenderer $this->AddSupportedField('HiddenField', 'ConsoleSimpleFieldRenderer'); $this->AddSupportedField('StringField', 'ConsoleSimpleFieldRenderer'); $this->AddSupportedField('SelectField', 'ConsoleSimpleFieldRenderer'); + $this->AddSupportedField('SelectObjectField', 'ConsoleSimpleFieldRenderer'); $this->AddSupportedField('SubFormField', 'ConsoleSubFormFieldRenderer'); } } \ No newline at end of file diff --git a/sources/renderer/console/fieldrenderer/consolesimplefieldrenderer.class.inc.php b/sources/renderer/console/fieldrenderer/consolesimplefieldrenderer.class.inc.php index f1c4ff300..30f3eee37 100644 --- a/sources/renderer/console/fieldrenderer/consolesimplefieldrenderer.class.inc.php +++ b/sources/renderer/console/fieldrenderer/consolesimplefieldrenderer.class.inc.php @@ -82,6 +82,46 @@ class ConsoleSimpleFieldRenderer extends FieldRenderer $oOutput->AddHtml(''); $oOutput->AddHtml(''); break; + + case 'Combodo\\iTop\\Form\\Field\\SelectObjectField': + $oOutput->AddHtml('