diff --git a/css/form-sdk/form.css b/css/form-sdk/form.css index 0de671705..08151b6e4 100644 --- a/css/form-sdk/form.css +++ b/css/form-sdk/form.css @@ -8,10 +8,10 @@ /* debug purpose */ .form-type-pictograms{ display: inline-block; + float: right; margin-left: 5px; color: grey; cursor: pointer; - background-color: #f8f8f8; padding: 0px 5px; border-radius: 8px; } diff --git a/sources/FormImplementation/Controller/TestController.php b/sources/FormImplementation/Controller/TestController.php index fc5675c27..c7a689056 100644 --- a/sources/FormImplementation/Controller/TestController.php +++ b/sources/FormImplementation/Controller/TestController.php @@ -5,36 +5,25 @@ namespace Combodo\iTop\FormImplementation\Controller; use Combodo\iTop\Controller\AbstractAppController; use Combodo\iTop\FormImplementation\Dto\ObjectSearchDto; use Combodo\iTop\FormImplementation\Helper\FormHelper; -use Combodo\iTop\FormImplementation\Helper\SelectDataProvider; use Combodo\iTop\FormSDK\Service\FormManager; use Combodo\iTop\Service\Base\ObjectRepository; -use DateTime; use Exception; -use JsonPage; -use MetaModel; -use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader; -use Symfony\Component\Form\Extension\Core\Type\DateType; -use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\MapQueryString; -use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\RouterInterface; -use Symfony\Component\Validator\Constraints\Length; -use Symfony\Component\Validator\Constraints\Regex; -use utils; class TestController extends AbstractAppController { - #[Route('/formSDK/test_form', name: 'formSDK_test_form')] - public function form(Request $oRequest, FormManager $oFormManager, RouterInterface $oRouter): Response + #[Route('/formSDK/test_form/{mode}', name: 'formSDK_test_form')] + public function form(Request $oRequest, FormManager $oFormManager, RouterInterface $oRouter, int $mode): Response { // create factory try{ - $oFactory = FormHelper::CreateSampleFormFactory($oFormManager, $oRouter); + $oFactory = FormHelper::CreateSampleFormFactory($oFormManager, $oRouter, $mode); } catch (Exception $e) { throw $this->createNotFoundException('unable to create sample form factory', $e); @@ -52,12 +41,12 @@ class TestController extends AbstractAppController // retrieve form data $data = $oForm->getData(); - // let's adaptaters save theirs data + // let's adapters save theirs data foreach($oFactory->GetAllAdapters() as $oAdapter){ $oAdapter->UpdateFieldsData($data); } - dump($data); +// dump($data); // return $this->redirectToRoute('app_success'); } diff --git a/sources/FormImplementation/Helper/FormHelper.php b/sources/FormImplementation/Helper/FormHelper.php index eed12474f..0c31fc036 100644 --- a/sources/FormImplementation/Helper/FormHelper.php +++ b/sources/FormImplementation/Helper/FormHelper.php @@ -2,12 +2,11 @@ namespace Combodo\iTop\FormImplementation\Helper; -use Combodo\iTop\Controller\AbstractAppController; use Combodo\iTop\FormImplementation\Dto\CountDto; use Combodo\iTop\FormSDK\Field\FormFieldDescription; use Combodo\iTop\FormSDK\Field\FormFieldTypeEnumeration; +use Combodo\iTop\FormSDK\Service\FormFactory; use Combodo\iTop\FormSDK\Service\FormManager; -use DateInterval; use DateTime; use MetaModel; use Symfony\Component\Routing\RouterInterface; @@ -16,19 +15,35 @@ use Symfony\Component\Validator\Constraints\Regex; class FormHelper { - static private int $PERSON_COUNT = 5; + static private int $PERSON_COUNT = 1; + + static private array $MODES_DEFINITIONS = [ + 0 => [ + 'group' => false, + 'layout' => false + ], + 1 => [ + 'group' => true, + 'layout' => false + ], + 2 => [ + 'group' => true, + 'layout' => true + ], + ]; /** * Create a sample form factory for demo purpose. * * @param \Combodo\iTop\FormSDK\Service\FormManager $oFormManager * @param \Symfony\Component\Routing\RouterInterface $oRouter + * @param int $iMode * * @return \Combodo\iTop\FormSDK\Service\FormFactory * @throws \ArchivedObjectException * @throws \CoreException */ - static public function CreateSampleFormFactory(FormManager $oFormManager, RouterInterface $oRouter) + static public function CreateSampleFormFactory(FormManager $oFormManager, RouterInterface $oRouter, int $iMode) : FormFactory { // create a factory $oFormFactory = $oFormManager->CreateFactory(); @@ -42,7 +57,7 @@ class FormHelper 'counts' => ['count1' => 10, 'count2' => 20, 'count3' => 30], 'counts2' => new CountDto(), 'interval' => ['days' => '12', 'hours' => '13', 'years' => '10', 'months' => '6', 'minutes' => '0', 'seconds' => '0', 'weeks' => '3'], - 'blog' => 'Your story', + 'blog' => '

Your story


bla bla bla bla bla bla
bla bla bla bla bla bla
bla bla bla bla bla bla
bla bla bla bla bla bla', 'notify' => true, 'language' => 'FR FR', 'mode' => '1', @@ -57,7 +72,7 @@ class FormHelper $oPerson = MetaModel::GetObject('Person', $i+1); // create object adapter - $oObjectPlugin = $oFormFactory->CreateObjectAdapter($oPerson, false); + $oObjectPlugin = $oFormFactory->CreateObjectAdapter($oPerson, self::$MODES_DEFINITIONS[$iMode]['group']); $oObjectPlugin->AddAttribute('name'); $oObjectPlugin->AddAttribute('mobile_phone'); } @@ -193,26 +208,37 @@ class FormHelper ] ]); - // layout description - $oFormFactory->SetLayoutDescription([ + if(self::$MODES_DEFINITIONS[$iMode]['layout']){ - 'row__1' => [ - 'column__1' => [ - 'css_classes' => 'custom-container container-flower layout-grow', - 'fieldset__1' => [ 'birthday', 'city', 'tel'], - ], - 'column__2' => [ - 'css_classes' => 'custom-container container-color', - 'fieldset__2' => ['mode', 'interval', 'Person_2'], - ], + $aDescription = [ - ], - 'row__2' => [ - 'css_classes' => 'custom-container container-color2', - 'fieldset__1' => [ 'Person_1', 'Person_3'], - 'fieldset__2' => [ 'Person_1_name'], - ] - ]); + 'row__1' => [ + 'column__1' => [ + 'css_classes' => 'custom-container container-flower layout-grow', + 'fieldset__1' => [ 'birthday', 'city', 'tel'], + ], + 'column__2' => [ + 'css_classes' => 'custom-container container-color mb-3', + 'fieldset__2' => ['mode', 'interval'], + ], + + ], + 'row__2' => [ + 'css_classes' => 'custom-container container-color2 mb-3', + ] + ]; + + if(self::$MODES_DEFINITIONS[$iMode]['group']){ + $aDescription['row__1']['column__2']['fieldset__2'][] = 'Person_2'; + $aDescription['row__2']['fieldset__1'] = [ 'Person_1', 'Person_3']; + } + else{ + $aDescription['row__2']['fieldset__1'] = [ 'Person_1_name']; + } + + // layout description + $oFormFactory->SetLayoutDescription($aDescription); + } return $oFormFactory; } diff --git a/sources/FormSDK/Field/FormFieldDescription.php b/sources/FormSDK/Field/FormFieldDescription.php index 575388161..131d53b6f 100644 --- a/sources/FormSDK/Field/FormFieldDescription.php +++ b/sources/FormSDK/Field/FormFieldDescription.php @@ -36,6 +36,8 @@ class FormFieldDescription * @param string $sName * @param FormFieldTypeEnumeration $oType * @param array $aOptions + * + * @throws \Exception */ public function __construct( private readonly string $sName, diff --git a/sources/FormSDK/Field/FormFieldTypeEnumeration.php b/sources/FormSDK/Field/FormFieldTypeEnumeration.php index 8a2818872..2c0a2e3dd 100644 --- a/sources/FormSDK/Field/FormFieldTypeEnumeration.php +++ b/sources/FormSDK/Field/FormFieldTypeEnumeration.php @@ -47,7 +47,7 @@ enum FormFieldTypeEnumeration : string $aOptions = ['required', 'disabled', 'attr', 'label', 'label_attr', 'help', 'inherit_data']; // specific options - $test = match ($this) { + return match ($this) { FormFieldTypeEnumeration::TEXT => array_merge($aOptions, ['constraints'] ), @@ -61,12 +61,10 @@ enum FormFieldTypeEnumeration : string ['input', 'with_minutes', 'with_seconds', 'with_weeks', 'with_days'] ), FormFieldTypeEnumeration::FIELDSET => array_merge($aOptions, - ['fields'] + ['fields', 'layout'] ), default => $aOptions, }; - - return $test; } /** diff --git a/sources/FormSDK/Service/FactoryAdapter/FormFactoryObjectAdapter.php b/sources/FormSDK/Service/FactoryAdapter/FormFactoryObjectAdapter.php index 6cbe7f870..8c1991708 100644 --- a/sources/FormSDK/Service/FactoryAdapter/FormFactoryObjectAdapter.php +++ b/sources/FormSDK/Service/FactoryAdapter/FormFactoryObjectAdapter.php @@ -139,20 +139,6 @@ final class FormFactoryObjectAdapter implements FormFactoryAdapterInterface return $this->bGroup ? $sAttributeCode : $this->GetIdentifier() . '_' . $sAttributeCode; } - public function GetLayoutDescription() - { - return [ - 'row__1' => [ - 'column__1' => [ - 'fieldset__1' => [ 'name'], - ], - 'column__2' => [ - 'fieldset__2' => ['mobile_phone'], - ], - ], - ]; - } - /** @inheritdoc */ public function GetFieldsData() : array { @@ -177,7 +163,9 @@ final class FormFactoryObjectAdapter implements FormFactoryAdapterInterface } } - /** @inheritdoc */ + /** @inheritdoc + * @throws \Exception + */ public function GetFieldsDescriptions() : array { $aFieldsDescriptions = []; @@ -195,6 +183,16 @@ final class FormFactoryObjectAdapter implements FormFactoryAdapterInterface $oGroupDescriptions = new FormFieldDescription($this->GetIdentifier(), FormFieldTypeEnumeration::FIELDSET, [ 'fields' => $aFieldsDescriptions, 'label' => $this->GetLabel(), + 'layout' => [ + 'row__1' => [ + 'column__1' => [ + 'fieldset__1' => [ 'name'], + ], + 'column__2' => [ + 'fieldset__2' => ['mobile_phone'], + ], + ], + ] ]); return [$this->GetIdentifier() => $oGroupDescriptions]; } diff --git a/sources/FormSDK/Service/FormFactory.php b/sources/FormSDK/Service/FormFactory.php index d0440c1cf..9c334554e 100644 --- a/sources/FormSDK/Service/FormFactory.php +++ b/sources/FormSDK/Service/FormFactory.php @@ -19,19 +19,11 @@ namespace Combodo\iTop\FormSDK\Service; -use Combodo\iTop\FormSDK\Service\FormFactoryBuilderTrait; use Combodo\iTop\FormSDK\Service\FactoryAdapter\FormFactoryObjectAdapter; use Combodo\iTop\FormSDK\Service\FactoryAdapter\FormFactoryAdapterInterface; use Combodo\iTop\FormSDK\Symfony\SymfonyBridge; -use Combodo\iTop\FormSDK\Field\FormFieldDescription; -use Combodo\iTop\FormSDK\Field\FormFieldTypeEnumeration; use DBObject; -use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader; -use Symfony\Component\Form\FormInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Symfony\Component\Validator\Constraints\Length; -use Symfony\Component\Validator\Constraints\Regex; -use utils; /** * Form factory. @@ -52,8 +44,8 @@ class FormFactory /** @var mixed $oFieldsData form data */ private mixed $oFieldsData = []; - /** @var array $aLayoutDecription description of the layout */ - private array $aLayoutDecription; + /** @var array $aLayoutDescription description of the layout */ + private array $aLayoutDescription = []; /** builder */ use FormFactoryBuilderTrait; @@ -65,8 +57,8 @@ class FormFactory * @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $oRouter */ public function __construct( - private SymfonyBridge $oSymfonyBridge, - private UrlGeneratorInterface $oRouter + private readonly SymfonyBridge $oSymfonyBridge, + private readonly UrlGeneratorInterface $oRouter ) { @@ -82,10 +74,14 @@ class FormFactory // prepare data $aResult = $this->aFieldsDescriptions; - // merge each adapter data... foreach ($this->GetAllAdapters() as $oAdapter){ - $aResult = array_merge($aResult, $oAdapter->GetFieldsDescriptions()); + try{ + $aResult = array_merge($aResult, $oAdapter->GetFieldsDescriptions()); + } + catch(Exception $e){ + ExceptionLog::LogException($e); + } } return $aResult; @@ -98,7 +94,7 @@ class FormFactory */ public function GetLayoutDescription() : array { - return $this->aLayoutDecription; + return $this->aLayoutDescription; } /** @@ -147,13 +143,15 @@ class FormFactory * * @return $this */ - public function SetLayoutDescription(array $aLayoutDescription) + public function SetLayoutDescription(array $aLayoutDescription) : FormFactory { - $this->aLayoutDecription = $aLayoutDescription; + $this->aLayoutDescription = $aLayoutDescription; return $this; } /** + * Set form data. + * * @param mixed $oData * * @return void @@ -164,6 +162,8 @@ class FormFactory } /*** + * Get form data. + * * @return array */ public function GetData() : mixed diff --git a/sources/FormSDK/Service/FormFactoryBuilderTrait.php b/sources/FormSDK/Service/FormFactoryBuilderTrait.php index e0779fa23..3aad60ef4 100644 --- a/sources/FormSDK/Service/FormFactoryBuilderTrait.php +++ b/sources/FormSDK/Service/FormFactoryBuilderTrait.php @@ -4,8 +4,6 @@ namespace Combodo\iTop\FormSDK\Service; use Combodo\iTop\FormSDK\Field\FormFieldDescription; use Combodo\iTop\FormSDK\Field\FormFieldTypeEnumeration; -use Combodo\iTop\FormSDK\Service\FormFactory; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Validator\Constraints\Regex; trait FormFactoryBuilderTrait @@ -17,7 +15,8 @@ trait FormFactoryBuilderTrait * @param string $sKey * @param array $aOptions * - * @return $this + * @return \Combodo\iTop\FormSDK\Service\FormFactory + * @throws \Exception */ public function AddTextField(string $sKey, array $aOptions) : FormFactory { @@ -49,7 +48,8 @@ trait FormFactoryBuilderTrait * @param string $sKey * @param array $aOptions * - * @return $this + * @return \Combodo\iTop\FormSDK\Service\FormFactory + * @throws \Exception */ public function AddNumberField(string $sKey, array $aOptions) : FormFactory { @@ -64,7 +64,8 @@ trait FormFactoryBuilderTrait * @param string $sKey * @param array $aOptions * - * @return $this + * @return \Combodo\iTop\FormSDK\Service\FormFactory + * @throws \Exception */ public function AddAreaField(string $sKey, array $aOptions) : FormFactory { @@ -86,7 +87,8 @@ trait FormFactoryBuilderTrait * @param string $sKey * @param array $aOptions * - * @return $this + * @return \Combodo\iTop\FormSDK\Service\FormFactory + * @throws \Exception */ public function AddDateField(string $sKey, array $aOptions) : FormFactory { @@ -101,7 +103,8 @@ trait FormFactoryBuilderTrait * @param string $sKey * @param array $aOptions * - * @return $this + * @return \Combodo\iTop\FormSDK\Service\FormFactory + * @throws \Exception */ public function AddDurationField(string $sKey, array $aOptions) : FormFactory { @@ -116,7 +119,8 @@ trait FormFactoryBuilderTrait * @param string $sKey * @param array $aOptions * - * @return $this + * @return \Combodo\iTop\FormSDK\Service\FormFactory + * @throws \Exception */ public function AddSelectField(string $sKey, array $aOptions) : FormFactory { @@ -212,7 +216,8 @@ trait FormFactoryBuilderTrait * @param string $sKey * @param array $aOptions * - * @return $this + * @return \Combodo\iTop\FormSDK\Service\FormFactory + * @throws \Exception */ public function AddSwitchField(string $sKey, array $aOptions) : FormFactory { @@ -232,7 +237,8 @@ trait FormFactoryBuilderTrait * @param string $sKey * @param array $aOptions * - * @return $this + * @return \Combodo\iTop\FormSDK\Service\FormFactory + * @throws \Exception */ public function AddFieldSet(string $sKey, array $aOptions) : FormFactory { diff --git a/sources/FormSDK/Symfony/SymfonyBridge.php b/sources/FormSDK/Symfony/SymfonyBridge.php index aa739cd69..b74269377 100644 --- a/sources/FormSDK/Symfony/SymfonyBridge.php +++ b/sources/FormSDK/Symfony/SymfonyBridge.php @@ -22,7 +22,6 @@ namespace Combodo\iTop\FormSDK\Symfony; use Combodo\iTop\FormSDK\Field\FormFieldDescription; use Combodo\iTop\FormSDK\Field\FormFieldTypeEnumeration; use Combodo\iTop\FormSDK\Symfony\Type\Compound\FieldsetType; -use Combodo\iTop\FormSDK\Symfony\Type\Compound\FormObjectType; use Combodo\iTop\FormSDK\Symfony\Type\Layout\ColumnType; use Combodo\iTop\FormSDK\Symfony\Type\Layout\RowType; use LogAPI; @@ -36,7 +35,6 @@ use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormInterface; -use Symfony\Component\Validator\Constraints\Length; /** * Symfony implementation bridge. @@ -108,7 +106,7 @@ class SymfonyBridge $aFields = []; foreach ($aOptions['fields'] as $oChildFormDescription){ $aSymfony = $this->ToSymfonyFormType($oChildFormDescription); - $aFields[] = $aSymfony; + $aFields[$oChildFormDescription->GetName()] = $aSymfony; } $aOptions['fields'] = $aFields; return [ @@ -162,12 +160,21 @@ class SymfonyBridge $aSymfonyTypesDeclaration[$sKey] = $this->ToSymfonyFormType($oFormDescription); } - // create layout types + // prepare fieldset types layout... + foreach ($aSymfonyTypesDeclaration as &$aSymfonyTypeDeclaration){ + if($aSymfonyTypeDeclaration['type'] === FieldsetType::class && isset($aSymfonyTypeDeclaration['options']['layout'])){ + ['types' => $aItems] = $this->CreateLayoutTypes($aSymfonyTypeDeclaration['options']['layout'], $oFormBuilder, $aSymfonyTypeDeclaration['options']['fields']); + $aSymfonyTypeDeclaration['options']['fields'] = array_merge($aItems, $aSymfonyTypeDeclaration['options']['fields']); + $aTest = 'test'; + } + } + + // prepare general layout types ['types' => $aItems] = $this->CreateLayoutTypes($aLayout, $oFormBuilder, $aSymfonyTypesDeclaration); - $oTest = array_merge($aItems, $aSymfonyTypesDeclaration); + $aSymfonyTypesDeclaration = array_merge($aItems, $aSymfonyTypesDeclaration); // add symfony types to builder... - foreach ($oTest as $oSymfonyTypeDeclaration){ + foreach ($aSymfonyTypesDeclaration as $oSymfonyTypeDeclaration){ // add type to form $oFormBuilder->add( diff --git a/sources/FormSDK/Symfony/Type/Compound/FieldsetType.php b/sources/FormSDK/Symfony/Type/Compound/FieldsetType.php index bfc52c6d6..e53ad6433 100644 --- a/sources/FormSDK/Symfony/Type/Compound/FieldsetType.php +++ b/sources/FormSDK/Symfony/Type/Compound/FieldsetType.php @@ -60,6 +60,7 @@ class FieldsetType extends AbstractType $resolver->setDefaults([ 'fields' => [], 'view' => [], + 'layout' => [] ]); } diff --git a/sources/FormSDK/Symfony/Type/Compound/FormObjectType.php b/sources/FormSDK/Symfony/Type/Compound/FormObjectType.php deleted file mode 100644 index 8da495ed0..000000000 --- a/sources/FormSDK/Symfony/Type/Compound/FormObjectType.php +++ /dev/null @@ -1,75 +0,0 @@ -add($oField['name'], $oField['type'], $oField['options']); - } - } - - private function handleRow(FormBuilderInterface $builder, array $aData){ - - } - - private function handleColumn(FormBuilderInterface $builder, array $aData){ - - } - - /** @inheritdoc */ - public function configureOptions(OptionsResolver $resolver): void - { - $resolver->setDefaults([ - 'fields' => [], - 'view' => [], - 'attr' => [ - 'class' => 'form-object-row' - ] - ]); - } - - /** @inheritdoc */ - public function getParent(): string - { - return FormType::class; - } - -} \ No newline at end of file diff --git a/sources/FormSDK/Symfony/Type/Layout/ColumnType.php b/sources/FormSDK/Symfony/Type/Layout/ColumnType.php index dd44e9408..61e055625 100644 --- a/sources/FormSDK/Symfony/Type/Layout/ColumnType.php +++ b/sources/FormSDK/Symfony/Type/Layout/ColumnType.php @@ -19,11 +19,7 @@ namespace Combodo\iTop\FormSDK\Symfony\Type\Layout; -use Combodo\iTop\FormSDK\Field\FormFieldDescription; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; /** * Type representing a layout column; diff --git a/sources/FormSDK/Symfony/Type/Layout/LayoutType.php b/sources/FormSDK/Symfony/Type/Layout/LayoutType.php index 06d148ff2..8b14f9bc8 100644 --- a/sources/FormSDK/Symfony/Type/Layout/LayoutType.php +++ b/sources/FormSDK/Symfony/Type/Layout/LayoutType.php @@ -48,7 +48,6 @@ class LayoutType extends AbstractType { $resolver->setDefaults([ 'fields' => [], - 'view' => [], 'inherit_data' => true // this type is abstract and used for grouping ]); } diff --git a/sources/FormSDK/Symfony/Type/Layout/RowType.php b/sources/FormSDK/Symfony/Type/Layout/RowType.php index 79c985fd5..219b2582b 100644 --- a/sources/FormSDK/Symfony/Type/Layout/RowType.php +++ b/sources/FormSDK/Symfony/Type/Layout/RowType.php @@ -19,11 +19,7 @@ namespace Combodo\iTop\FormSDK\Symfony\Type\Layout; -use Combodo\iTop\FormSDK\Field\FormFieldDescription; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; /** * Type representing a layout row;