diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index 8f0a15ef9..963b54e03 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -477,6 +477,7 @@ return array( 'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFormBlock' => $baseDir . '/sources/Forms/Block/Base/ChoiceFormBlock.php', 'Combodo\\iTop\\Forms\\Block\\Base\\StringFormBlock' => $baseDir . '/sources/Forms/Block/Base/StringFormBlock.php', 'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeValueChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php', 'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/OqlFormBlock.php', 'Combodo\\iTop\\Forms\\Block\\FormBlock' => $baseDir . '/sources/Forms/Block/FormBlock.php', 'Combodo\\iTop\\Forms\\Block\\FormInput' => $baseDir . '/sources/Forms/Block/FormInput.php', diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index fe00f4274..027a59725 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -858,6 +858,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/ChoiceFormBlock.php', 'Combodo\\iTop\\Forms\\Block\\Base\\StringFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/StringFormBlock.php', 'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeValueChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php', 'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/OqlFormBlock.php', 'Combodo\\iTop\\Forms\\Block\\FormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlock.php', 'Combodo\\iTop\\Forms\\Block\\FormInput' => __DIR__ . '/../..' . '/sources/Forms/Block/FormInput.php', diff --git a/sources/Forms/Block/AbstractFormBlock.php b/sources/Forms/Block/AbstractFormBlock.php index 674aa684a..87dd97e74 100644 --- a/sources/Forms/Block/AbstractFormBlock.php +++ b/sources/Forms/Block/AbstractFormBlock.php @@ -32,9 +32,10 @@ abstract class AbstractFormBlock return $this->aOptions; } - public function AddSubFormBlock(AbstractFormBlock $oSubFormBlock): void + public function AddSubFormBlock(AbstractFormBlock $oSubFormBlock): AbstractFormBlock { $this->aSubFormBlocks[] = $oSubFormBlock; + return $this; } public function GetSubFormBlocks(): array @@ -57,11 +58,40 @@ abstract class AbstractFormBlock $this->aFormOutputs[$oFormOutput->GetName()] = $oFormOutput; } - public function GetOutput(string $sName): FormOutput + public function GetOutput(string $sName): ?FormOutput { return $this->aFormOutputs[$sName]; } + /** + * @param string $sInputName + * @param string $sOutputBlockName + * @param string $sOutputName + * + * @return $this + * @throws \Combodo\iTop\Forms\Block\FormsBlockException + */ + public function DependsOn(string $sInputName, string $sOutputBlockName, string $sOutputName): AbstractFormBlock + { + $oFormInput = $this->GetInput($sInputName); + if (is_null($oFormInput)) { + throw new FormsBlockException('Missing input ' . $sInputName . ' for ' . $this->sName); + } + $oFormInput->Connect($sOutputBlockName, $sOutputName); + + return $this; + } + + public function HasConnections(): bool + { + foreach ($this->aFormInputs as $oFormInput) { + if ($oFormInput->HasConnections()) { + return true; + } + } + return false; + } + abstract public function GetFormType(): string; abstract public function InitInputs(): void; diff --git a/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php b/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php index ce93dcac1..6e60d6037 100644 --- a/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php +++ b/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php @@ -7,11 +7,11 @@ use Combodo\iTop\Forms\Block\FormInput; class AttributeChoiceFormBlock extends ChoiceFormBlock { - + public const INPUT_CLASS_NAME = 'class_name'; public function InitInputs(): void { - $this->AddInput(new FormInput('class_name', 'string')); + $this->AddInput(new FormInput(self::INPUT_CLASS_NAME, 'string')); } diff --git a/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php b/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php new file mode 100644 index 000000000..a97dfd590 --- /dev/null +++ b/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php @@ -0,0 +1,27 @@ +AddInput(new FormInput(self::INPUT_CLASS_NAME, 'string')); + $this->AddInput(new FormInput(self::INPUT_ATTRIBUTE, 'string')); + } + + +} \ No newline at end of file diff --git a/sources/Forms/Block/DataModel/OqlFormBlock.php b/sources/Forms/Block/DataModel/OqlFormBlock.php index 405c52901..0a5ba104d 100644 --- a/sources/Forms/Block/DataModel/OqlFormBlock.php +++ b/sources/Forms/Block/DataModel/OqlFormBlock.php @@ -8,9 +8,12 @@ use Combodo\iTop\Forms\Block\FormOutput; class OqlFormBlock extends StringFormBlock { + public const OUTPUT_SELECTED_CLASS = 'selected_class'; + public function InitOutputs(): void { - $this->AddOutput(new FormOutput('selected_class', 'string')); + parent::InitOutputs(); + $this->AddOutput(new FormOutput(self::OUTPUT_SELECTED_CLASS, 'string')); } } \ No newline at end of file diff --git a/sources/Forms/Block/FormBlock.php b/sources/Forms/Block/FormBlock.php index 10579eae2..2eb96b302 100644 --- a/sources/Forms/Block/FormBlock.php +++ b/sources/Forms/Block/FormBlock.php @@ -3,17 +3,17 @@ namespace Combodo\iTop\Forms\Block; use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; class FormBlock extends AbstractFormBlock { + public const OUTPUT_VALUE = 'value'; + public function __construct(string $sName, array $aOptions = []) { + $aOptions['form_block'] = $this; parent::__construct($sName, $aOptions); } - public function GetFormType(): string { return FormType::class; @@ -25,14 +25,6 @@ class FormBlock extends AbstractFormBlock public function InitOutputs(): void { - } - - public function Build(FormBuilderInterface $oBuilder): FormInterface - { - foreach ($this->GetSubFormBlocks() as $oSubForm) { - $oBuilder->add($oSubForm->GetName(), $oSubForm->GetFormType(), $oSubForm->GetOptions()); - } - - return $oBuilder->getForm(); + $this->AddOutput(new FormOutput(self::OUTPUT_VALUE, 'string')); } } \ No newline at end of file diff --git a/sources/Forms/Block/FormInput.php b/sources/Forms/Block/FormInput.php index 6eeeaf535..7cb124790 100644 --- a/sources/Forms/Block/FormInput.php +++ b/sources/Forms/Block/FormInput.php @@ -8,6 +8,8 @@ class FormInput private string $sType; + private array $aConnections = []; + public function __construct(string $sName, string $sType) { $this->sName = $sName; @@ -33,4 +35,19 @@ class FormInput { $this->sType = $sType; } + + public function Connect(string $sOutputBlockName, string $sOutputName) + { + $this->aConnections[] = ['block' => $sOutputBlockName, 'output' => $sOutputName]; + } + + public function GetConnections(): array + { + return $this->aConnections; + } + + public function HasConnections(): bool + { + return count($this->aConnections) > 0; + } } \ No newline at end of file diff --git a/sources/Forms/Block/FormOutput.php b/sources/Forms/Block/FormOutput.php index cb75ec696..280759b8f 100644 --- a/sources/Forms/Block/FormOutput.php +++ b/sources/Forms/Block/FormOutput.php @@ -10,7 +10,7 @@ class FormOutput private string $sType; - private AbstractConverter $oConverter; + private null|AbstractConverter $oConverter; public function __construct(string $sName, string $sType, AbstractConverter $oConverter = null) { @@ -41,7 +41,7 @@ class FormOutput public function GetOutputValue(mixed $oData): mixed { - $this->oConverter->Convert($oData); + return $this->oConverter->Convert($oData); } diff --git a/sources/Forms/Block/FormsBlockException.php b/sources/Forms/Block/FormsBlockException.php new file mode 100644 index 000000000..d19e99a45 --- /dev/null +++ b/sources/Forms/Block/FormsBlockException.php @@ -0,0 +1,14 @@ +dependencyHandler === null){ - \IssueLog::Error('create dependency handler ' . $this->builder->getName()); - $this->dependencyHandler = new DependencyHandler($this->builder); - } - - $this->dependencyHandler->AddDependencyDescription($oDependencyDescription); + $this->InitFormBlocks(); } public function add(string|FormBuilderInterface $child, ?string $type = null, array $options = []): static { - if(!empty($options['bindings'])) { - $this->builder->add($child, HiddenType::class); - $this->AddDependency(new DependencyDescription($options['bindings'], $child, $type, $options)); - } - else{ - $this->builder->add($child, $type, $options); - } - + $this->builder->add($child, $type, $options); return $this; } - public function addExpression(string $name, string $expression): static + private function InitFormBlocks() { - $options['bindings'] = [$expression]; - return $this->add($name, null, $options); + $oFormBlock = $this->builder->getOption('form_block'); + if (is_null($oFormBlock)) { + return; + } + + /** @var \Combodo\iTop\Forms\Block\FormBlock $oSubFormBlock */ + foreach ($oFormBlock->GetSubFormBlocks() as $oSubFormBlock) { + if ($oSubFormBlock->HasConnections()) { + $this->builder->add($oSubFormBlock->GetName(), HiddenType::class); + } else { + $this->add($oSubFormBlock->GetName(), $oSubFormBlock->GetFormType(), $oSubFormBlock->getOptions()); + } + } } // pure decoration of FormBuilderInterface diff --git a/sources/Forms/FormBuilder/FormTypeExtension.php b/sources/Forms/FormBuilder/FormTypeExtension.php index 1e6916375..f3f93d2f4 100644 --- a/sources/Forms/FormBuilder/FormTypeExtension.php +++ b/sources/Forms/FormBuilder/FormTypeExtension.php @@ -6,8 +6,6 @@ use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\OptionsResolver; class FormTypeExtension extends AbstractTypeExtension @@ -23,9 +21,7 @@ class FormTypeExtension extends AbstractTypeExtension public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefined([ - 'inputs', - 'outputs', - 'bindings', + 'form_block', 'listener_callback', ]); } diff --git a/sources/Forms/FormsException.php b/sources/Forms/FormsException.php new file mode 100644 index 000000000..73b6c4c43 --- /dev/null +++ b/sources/Forms/FormsException.php @@ -0,0 +1,12 @@ +