mirror of
https://github.com/Combodo/iTop.git
synced 2026-03-02 15:44:11 +01:00
N°8772 - dynamic form
This commit is contained in:
@@ -491,9 +491,12 @@ return array(
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextFormBlock.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\\IDataModelBlock' => $baseDir . '/sources/Forms/Block/DataModel/IDataModelBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/OqlFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Expression\\ExpressionFormBlock' => $baseDir . '/sources/Forms/Block/Expression/ExpressionFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockDescription' => $baseDir . '/sources/Forms/Block/FormBlockDescription.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockException' => $baseDir . '/sources/Forms/Block/FormBlockException.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockFactory' => $baseDir . '/sources/Forms/Block/FormBlockFactory.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => $baseDir . '/sources/Forms/FormBuilder/DependencyHandler.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyMap' => $baseDir . '/sources/Forms/FormBuilder/DependencyMap.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilder' => $baseDir . '/sources/Forms/FormBuilder/FormBuilder.php',
|
||||
@@ -528,6 +531,7 @@ return array(
|
||||
'Combodo\\iTop\\Forms\\Register\\IORegister' => $baseDir . '/sources/Forms/Register/IORegister.php',
|
||||
'Combodo\\iTop\\Forms\\Register\\Option' => $baseDir . '/sources/Forms/Register/Option.php',
|
||||
'Combodo\\iTop\\Forms\\Register\\OptionsRegister' => $baseDir . '/sources/Forms/Register/OptionsRegister.php',
|
||||
'Combodo\\iTop\\Forms\\Register\\RegisterException' => $baseDir . '/sources/Forms/Register/RegisterException.php',
|
||||
'Combodo\\iTop\\Forms\\Twig\\Extension\\FormCompatibilityExtension' => $baseDir . '/sources/Forms/Twig/Extension/FormCompatibilityExtension.php',
|
||||
'Combodo\\iTop\\PhpParser\\Evaluation\\PhpExpressionEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/PhpExpressionEvaluator.php',
|
||||
'Combodo\\iTop\\Renderer\\BlockRenderer' => $baseDir . '/sources/Renderer/BlockRenderer.php',
|
||||
|
||||
@@ -872,9 +872,12 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextFormBlock.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\\IDataModelBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/IDataModelBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/OqlFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Expression\\ExpressionFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Expression/ExpressionFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockDescription' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockDescription.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockException' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockException.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockFactory' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockFactory.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/DependencyHandler.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyMap' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/DependencyMap.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilder' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/FormBuilder.php',
|
||||
@@ -909,6 +912,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Forms\\Register\\IORegister' => __DIR__ . '/../..' . '/sources/Forms/Register/IORegister.php',
|
||||
'Combodo\\iTop\\Forms\\Register\\Option' => __DIR__ . '/../..' . '/sources/Forms/Register/Option.php',
|
||||
'Combodo\\iTop\\Forms\\Register\\OptionsRegister' => __DIR__ . '/../..' . '/sources/Forms/Register/OptionsRegister.php',
|
||||
'Combodo\\iTop\\Forms\\Register\\RegisterException' => __DIR__ . '/../..' . '/sources/Forms/Register/RegisterException.php',
|
||||
'Combodo\\iTop\\Forms\\Twig\\Extension\\FormCompatibilityExtension' => __DIR__ . '/../..' . '/sources/Forms/Twig/Extension/FormCompatibilityExtension.php',
|
||||
'Combodo\\iTop\\PhpParser\\Evaluation\\PhpExpressionEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/PhpExpressionEvaluator.php',
|
||||
'Combodo\\iTop\\Renderer\\BlockRenderer' => __DIR__ . '/../..' . '/sources/Renderer/BlockRenderer.php',
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Combodo\iTop\Forms\Block;
|
||||
|
||||
use Combodo\iTop\Forms\IO\Format\BooleanIOFormat;
|
||||
use Combodo\iTop\Forms\Register\IORegister;
|
||||
use Combodo\iTop\Forms\Register\OptionsRegister;
|
||||
|
||||
abstract class AbstractTypeFormBlock extends AbstractFormBlock
|
||||
{
|
||||
@@ -80,4 +81,14 @@ abstract class AbstractTypeFormBlock extends AbstractFormBlock
|
||||
{
|
||||
$this->bIsAddedToForm = $bIsAdded;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function UpdateOptions(OptionsRegister $oOptionsRegister): void
|
||||
{
|
||||
parent::UpdateOptions($oOptionsRegister);
|
||||
|
||||
if($this->GetInput(self::INPUT_ENABLE)->IsBound()){
|
||||
$oOptionsRegister->SetOption('disabled', !$this->GetInputValue(self::INPUT_ENABLE));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,29 +66,54 @@ class FormBlock extends AbstractTypeFormBlock
|
||||
* Add a child form.
|
||||
*
|
||||
* @param string $sName block name
|
||||
* @param string $sType block class name
|
||||
* @param array $aSymfonyOptions options
|
||||
* @param string $sBlockClass block class name
|
||||
* @param array $aOptions options
|
||||
*
|
||||
* @return $this
|
||||
* @throws ReflectionException
|
||||
* @throws \Combodo\iTop\Forms\Block\FormBlockException
|
||||
* @throws FormBlockException
|
||||
*/
|
||||
public function Add(string $sName, string $sType, array $aSymfonyOptions, array $aOptions = []): AbstractFormBlock
|
||||
public function Add(string $sName, string $sBlockClass,array $aOptions = []): AbstractFormBlock
|
||||
{
|
||||
$oRef = new ReflectionClass($sType);
|
||||
if($oRef->isSubclassOf(AbstractFormBlock::class) === false){
|
||||
throw new FormBlockException("The block type '$sType' is not a subclass of AbstractFormBlock.");
|
||||
}
|
||||
$this->VerifyBlockName($sName);
|
||||
$this->VerifyBlockClassName($sBlockClass);
|
||||
|
||||
$aOptions['priority'] = -count($this->aChildrenBlocks);
|
||||
$oSubFormBlock = new ($sType)($sName, $aSymfonyOptions, $aOptions);
|
||||
$oSubFormBlock = new ($sBlockClass)($sName, $aOptions);
|
||||
$this->aChildrenBlocks[$sName] = $oSubFormBlock;
|
||||
$oSubFormBlock->SetParent($this);
|
||||
|
||||
return $oSubFormBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sBlockName
|
||||
*
|
||||
* @return void
|
||||
* @throws FormBlockException
|
||||
*/
|
||||
private function VerifyBlockName(string $sBlockName): void
|
||||
{
|
||||
if(!ctype_alnum(str_replace(array('-', '_'), '', $sBlockName))) {
|
||||
throw new FormBlockException("Block name '$sBlockName' is not valid. Only alphanumeric characters, hyphens and underscores are allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sBlockClass
|
||||
*
|
||||
* @return void
|
||||
* @throws FormBlockException
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private function VerifyBlockClassName(string $sBlockClass): void
|
||||
{
|
||||
$oRef = new ReflectionClass($sBlockClass);
|
||||
if($oRef->isSubclassOf(AbstractFormBlock::class) === false){
|
||||
throw new FormBlockException("The block type '$sBlockClass' is not a subclass of AbstractFormBlock.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the children forms.
|
||||
*
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Combodo\iTop\Forms\FormBuilder;
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Combodo\iTop\Forms\Block\AbstractTypeFormBlock;
|
||||
use Combodo\iTop\Forms\Block\Base\FormBlock;
|
||||
use Combodo\iTop\Forms\Block\FormBlockException;
|
||||
use Exception;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormError;
|
||||
@@ -156,7 +157,7 @@ class DependencyHandler
|
||||
* @param string|null $sEventType
|
||||
*
|
||||
* @return void
|
||||
* @throws \Combodo\iTop\Forms\Block\FormBlockException
|
||||
* @throws FormBlockException
|
||||
*/
|
||||
private function CheckDependencies(FormInterface|FormBuilderInterface $oForm, string $sOutputBlock = null, string $sEventType = null): void
|
||||
{
|
||||
|
||||
@@ -22,9 +22,12 @@ class OptionsRegister
|
||||
* @param bool $bTypeOption
|
||||
*
|
||||
* @return void
|
||||
* @throws RegisterException
|
||||
*/
|
||||
public function SetOption(string $sOptionName, mixed $mDefaultValue = null, bool $bTypeOption = true): void
|
||||
{
|
||||
$this->VerifyOptionName($sOptionName);
|
||||
|
||||
if(isset($this->aOptions[$sOptionName])){
|
||||
$this->aOptions[$sOptionName]->oValue = $mDefaultValue;
|
||||
}
|
||||
@@ -33,6 +36,19 @@ class OptionsRegister
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sOptionName
|
||||
*
|
||||
* @return void
|
||||
* @throws RegisterException
|
||||
*/
|
||||
private function VerifyOptionName(string $sOptionName): void
|
||||
{
|
||||
if(!ctype_alnum(str_replace(array('-', '_'), '', $sOptionName))) {
|
||||
throw new RegisterException("Option name '$sOptionName' is not valid. Only alphanumeric characters, hyphens and underscores are allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an option array value.
|
||||
*
|
||||
|
||||
18
sources/Forms/Register/RegisterException.php
Normal file
18
sources/Forms/Register/RegisterException.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Forms\Register;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class RegisterException extends Exception
|
||||
{
|
||||
public function __construct(string $message = '', int $code = 0, ?Throwable $previous = null, array $aContext = [])
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,10 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Forms;
|
||||
namespace Forms\Block;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Combodo\iTop\Forms\Block\AbstractTypeFormBlock;
|
||||
use Combodo\iTop\Forms\Block\Base\CheckboxFormBlock;
|
||||
use Combodo\iTop\Forms\Block\Base\ChoiceFormBlock;
|
||||
use Combodo\iTop\Forms\Block\Base\FormBlock;
|
||||
use Combodo\iTop\Forms\Block\Base\TextFormBlock;
|
||||
use Combodo\iTop\Forms\Block\FormBlockException;
|
||||
@@ -26,7 +24,7 @@ use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
* Test forms block.
|
||||
*
|
||||
*/
|
||||
class Block extends ItopDataTestCase
|
||||
class BlockTest extends ItopDataTestCase
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -34,7 +32,7 @@ class Block extends ItopDataTestCase
|
||||
*
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function testFormBlockProvideSymfonyFormType(): void
|
||||
public function testGetFormTypeReturnSymfonyType(): void
|
||||
{
|
||||
$aFormBlocks = InterfaceDiscovery::GetInstance()->FindItopClasses(iFormBlock::class);
|
||||
foreach ($aFormBlocks as $sFormBlock) {
|
||||
@@ -51,7 +49,7 @@ class Block extends ItopDataTestCase
|
||||
*
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function testAddBlockFromSymfonyType(): void
|
||||
public function testAddChildBlockClass(): void
|
||||
{
|
||||
$oFormBlock = new FormBlock('formBlock');
|
||||
$this->expectException(FormBlockException::class);
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Forms\Register;
|
||||
|
||||
use Combodo\iTop\Forms\Register\OptionsRegister;
|
||||
use Combodo\iTop\Forms\Register\RegisterException;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
|
||||
class OptionsRegisterTest extends ItopDataTestCase
|
||||
{
|
||||
private OptionsRegister $oOptionsRegister;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->oOptionsRegister = new OptionsRegister();
|
||||
}
|
||||
|
||||
public function testSetOptionWithInvalidName(): void
|
||||
{
|
||||
$this->oOptionsRegister->SetOption('valid_option_name', 'value');
|
||||
|
||||
$this->expectException(RegisterException::class);
|
||||
$this->oOptionsRegister->SetOption('not valid option name', 'value');
|
||||
}
|
||||
|
||||
public function testSetNonTypeOption(): void
|
||||
{
|
||||
$this->oOptionsRegister->SetOption('not_a_type_option', 'value', false);
|
||||
|
||||
$this->assertArrayNotHasKey('not_a_type_option', $this->oOptionsRegister->GetOptions());
|
||||
}
|
||||
|
||||
public function testSetOptionArrayValue(): void
|
||||
{
|
||||
$this->oOptionsRegister->SetOptionArrayValue('att', 'class', 'ibo-class');
|
||||
|
||||
$this->assertEquals('ibo-class', $this->oOptionsRegister->GetOption('att')['class']);
|
||||
}
|
||||
|
||||
public function testHasOption(): void
|
||||
{
|
||||
$this->oOptionsRegister->SetOption('option', true);
|
||||
|
||||
$this->assertTrue($this->oOptionsRegister->HasOption('option'));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user