SDK Form demonstrator refactor AbstractType for dynamic behaviour

This commit is contained in:
Eric Espie
2025-04-16 17:04:52 +02:00
parent 5466b506ee
commit 782cff655b
6 changed files with 84 additions and 95 deletions

View File

@@ -430,6 +430,7 @@ return array(
'Combodo\\iTop\\Dependencies\\NPM\\iTopNPM' => $baseDir . '/sources/Dependencies/NPM/iTopNPM.php', 'Combodo\\iTop\\Dependencies\\NPM\\iTopNPM' => $baseDir . '/sources/Dependencies/NPM/iTopNPM.php',
'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php', 'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php',
'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php', 'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php',
'Combodo\\iTop\\FormType\\Base\\AbstractType' => $baseDir . '/sources/FormType/Base/AbstractType.php',
'Combodo\\iTop\\FormType\\Base\\HiddenType' => $baseDir . '/sources/FormType/Base/HiddenType.php', 'Combodo\\iTop\\FormType\\Base\\HiddenType' => $baseDir . '/sources/FormType/Base/HiddenType.php',
'Combodo\\iTop\\FormType\\Base\\TextType' => $baseDir . '/sources/FormType/Base/TextType.php', 'Combodo\\iTop\\FormType\\Base\\TextType' => $baseDir . '/sources/FormType/Base/TextType.php',
'Combodo\\iTop\\FormType\\Base\\TextareaType' => $baseDir . '/sources/FormType/Base/TextareaType.php', 'Combodo\\iTop\\FormType\\Base\\TextareaType' => $baseDir . '/sources/FormType/Base/TextareaType.php',

View File

@@ -785,6 +785,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Dependencies\\NPM\\iTopNPM' => __DIR__ . '/../..' . '/sources/Dependencies/NPM/iTopNPM.php', 'Combodo\\iTop\\Dependencies\\NPM\\iTopNPM' => __DIR__ . '/../..' . '/sources/Dependencies/NPM/iTopNPM.php',
'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php', 'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php', 'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
'Combodo\\iTop\\FormType\\Base\\AbstractType' => __DIR__ . '/../..' . '/sources/FormType/Base/AbstractType.php',
'Combodo\\iTop\\FormType\\Base\\HiddenType' => __DIR__ . '/../..' . '/sources/FormType/Base/HiddenType.php', 'Combodo\\iTop\\FormType\\Base\\HiddenType' => __DIR__ . '/../..' . '/sources/FormType/Base/HiddenType.php',
'Combodo\\iTop\\FormType\\Base\\TextType' => __DIR__ . '/../..' . '/sources/FormType/Base/TextType.php', 'Combodo\\iTop\\FormType\\Base\\TextType' => __DIR__ . '/../..' . '/sources/FormType/Base/TextType.php',
'Combodo\\iTop\\FormType\\Base\\TextareaType' => __DIR__ . '/../..' . '/sources/FormType/Base/TextareaType.php', 'Combodo\\iTop\\FormType\\Base\\TextareaType' => __DIR__ . '/../..' . '/sources/FormType/Base/TextareaType.php',

View File

@@ -0,0 +1,57 @@
<?php
/*
* @copyright Copyright (C) 2010-2025 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\FormType\Base;
use Symfony\Component\Form\AbstractType as SymfonyAbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\OptionsResolver\OptionsResolver;
abstract class AbstractType extends SymfonyAbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
if (isset($options['callback']) && isset($options['hook_type'])) {
$builder->addEventListener($options['hook_type'], function (FormEvent $event) use ($options): void {
\IssueLog::Info($event->getForm()->getName().' '.$options['hook_type']);
call_user_func($options['callback'], $event);
});
}
}
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefined('callback')
->setAllowedTypes('callback', 'callable');
$resolver->setDefined('hook_type')
->setAllowedTypes('hook_type', 'string');
}
/**
* Called only when GetPrerequisites() is not null
* @param array $aUserOptions
* @param array $aModelData
*
* @return array|null null if field is not present
*/
public function BuildOptions(array $aUserOptions, array $aModelData): ?array
{
return null;
}
/**
* @param array $aUserOptions
*
* @return array|null null if not dynamic
*/
public function GetPrerequisites(array $aUserOptions): ?array
{
return null;
}
}

View File

@@ -6,36 +6,41 @@
namespace Combodo\iTop\FormType\Orm; namespace Combodo\iTop\FormType\Orm;
use Combodo\iTop\FormType\Base\AbstractType;
use Dict; use Dict;
use Exception; use Exception;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType as SymfonyChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType as SymfonyChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AttCodeGroupByType extends AbstractType class AttCodeGroupByType extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener($options['hook_type'], function (FormEvent $event) use ($options): void {
\IssueLog::Info($event->getForm()->getName().' '.$options['hook_type']);
call_user_func($options['callback'], $event);
});
}
public function getParent() public function getParent()
{ {
return SymfonyChoiceType::class; return SymfonyChoiceType::class;
} }
public function configureOptions(OptionsResolver $resolver) public function BuildOptions(array $aUserOptions, array $aModelData): ?array
{ {
parent::configureOptions($resolver); $oModelReflection = new \ModelReflectionRuntime();
$resolver->setDefined('callback') $sClassOrOql = $aModelData[$aUserOptions['source_class']];
->setAllowedTypes('callback', 'callable'); if ($oModelReflection->IsValidClass($sClassOrOql)) {
$resolver->setDefined('hook_type') $sClass = $sClassOrOql;
->setAllowedTypes('hook_type', 'string'); } else {
try {
$oQuery = $oModelReflection->GetQuery($sClassOrOql);
} catch (Exception $e) {
return null;
}
$sClass = $oQuery->GetClass();
}
$aFormOptions['choices'] = $this->GetGroupByOptions($sClass);
$aFormOptions['multiple'] = false;
return $aFormOptions;
}
public function GetPrerequisites(array $aUserOptions): ?array
{
return [$aUserOptions['source_class']];
} }
protected function GetGroupByOptions($sClassOrOql) protected function GetGroupByOptions($sClassOrOql)
@@ -104,29 +109,4 @@ class AttCodeGroupByType extends AbstractType
} }
return array_flip($aGroupBy); return array_flip($aGroupBy);
} }
public function BuildOptions(array $aUserOptions, array $aModelData): ?array
{
$oModelReflection = new \ModelReflectionRuntime();
$sClassOrOql = $aModelData[$aUserOptions['source_class']];
if ($oModelReflection->IsValidClass($sClassOrOql)) {
$sClass = $sClassOrOql;
} else {
try {
$oQuery = $oModelReflection->GetQuery($sClassOrOql);
} catch (Exception $e) {
return null;
}
$sClass = $oQuery->GetClass();
}
$aFormOptions['choices'] = $this->GetGroupByOptions($sClass);
$aFormOptions['multiple'] = false;
return $aFormOptions;
}
public function GetPrerequisites(array $aUserOptions): ?array
{
return [$aUserOptions['source_class']];
}
} }

View File

@@ -6,34 +6,12 @@
namespace Combodo\iTop\FormType\Orm; namespace Combodo\iTop\FormType\Orm;
use Symfony\Component\Form\AbstractType; use Combodo\iTop\FormType\Base\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType as SymfonyTextareaType; use Symfony\Component\Form\Extension\Core\Type\TextareaType as SymfonyTextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
class QueryType extends AbstractType class QueryType extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
\IssueLog::Info($event->getForm()->getName().' PRE_SET_DATA');
});
$builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use ($options): void {
\IssueLog::Info($event->getForm()->getName().' POST_SET_DATA');
});
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
\IssueLog::Info($event->getForm()->getName().' PRE_SUBMIT');
});
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($options): void {
\IssueLog::Info($event->getForm()->getName().' POST_SUBMIT');
});
}
public function getParent(): ?string public function getParent(): ?string
{ {
return SymfonyTextareaType::class; return SymfonyTextareaType::class;

View File

@@ -6,45 +6,17 @@
namespace Combodo\iTop\FormType\Orm; namespace Combodo\iTop\FormType\Orm;
use Symfony\Component\Form\AbstractType; use Combodo\iTop\FormType\Base\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType as SymfonyChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType as SymfonyChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use utils; use utils;
class ValuesFromAttcodeType extends AbstractType class ValuesFromAttcodeType extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
\IssueLog::Info($event->getForm()->getName().' PRE_SET_DATA');
});
$builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) {
\IssueLog::Info($event->getForm()->getName().' POST_SET_DATA');
});
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
\IssueLog::Info($event->getForm()->getName().' PRE_SUBMIT');
});
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
\IssueLog::Info($event->getForm()->getName().' POST_SUBMIT');
});
}
public function getParent() public function getParent()
{ {
return SymfonyChoiceType::class; return SymfonyChoiceType::class;
} }
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefault('attr', ['class' => 'ibo-input ibo-input-select']);
}
public function BuildOptions(array $aUserOptions, array $aModelData): ?array public function BuildOptions(array $aUserOptions, array $aModelData): ?array
{ {
$sAttCode = $aModelData[$aUserOptions['source_attcode']] ?? null; $sAttCode = $aModelData[$aUserOptions['source_attcode']] ?? null;