mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-18 23:08:46 +02:00
N°8772 - dynamic form
This commit is contained in:
@@ -36,18 +36,18 @@
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
#form select{
|
||||
.form select{
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#form select option{
|
||||
.form select option{
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
form[aria-busy="true"] {
|
||||
.form[aria-busy="true"] {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
|
||||
@@ -474,8 +474,11 @@ return array(
|
||||
'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => $baseDir . '/sources/Form/Validator/NotEmptyExtKeyValidator.php',
|
||||
'Combodo\\iTop\\Form\\Validator\\SelectObjectValidator' => $baseDir . '/sources/Form/Validator/SelectObjectValidator.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\AbstractFormBlock' => $baseDir . '/sources/Forms/Block/AbstractFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\CheckboxFormBlock' => $baseDir . '/sources/Forms/Block/Base/CheckboxFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFormBlock' => $baseDir . '/sources/Forms/Block/Base/ChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\CollectionBlock' => $baseDir . '/sources/Forms/Block/Base/CollectionBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\DateFormBlock' => $baseDir . '/sources/Forms/Block/Base/DateFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\DateTimeFormBlock' => $baseDir . '/sources/Forms/Block/Base/DateTimeFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\FormBlock' => $baseDir . '/sources/Forms/Block/Base/FormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextAreaFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextAreaFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextFormBlock.php',
|
||||
@@ -484,19 +487,20 @@ return array(
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/OqlFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockException' => $baseDir . '/sources/Forms/Block/FormBlockException.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockIOException' => $baseDir . '/sources/Forms/Block/IO/FormBlockIOException.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\AttributeFormType' => $baseDir . '/sources/Forms/Block/FormType/AttributeFormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\AttributeValueFormType' => $baseDir . '/sources/Forms/Block/FormType/AttributeValueFormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\ChoiceFormType' => $baseDir . '/sources/Forms/Block/FormType/ChoiceFormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\CollectionFormType' => $baseDir . '/sources/Forms/Block/FormType/CollectionFormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\FormType' => $baseDir . '/sources/Forms/Block/FormType/FormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\OqlFormType' => $baseDir . '/sources/Forms/Block/FormType/OqlFormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\AbstractFormIO' => $baseDir . '/sources/Forms/Block/IO/AbstractFormIO.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Converter\\AbstractConverter' => $baseDir . '/sources/Forms/Block/IO/Converter/AbstractConverter.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Converter\\OqlToClassConverter' => $baseDir . '/sources/Forms/Block/IO/Converter/OqlToClassConverter.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Converter\\StringToAttributeConverter' => $baseDir . '/sources/Forms/Block/IO/Converter/StringToAttributeConverter.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Converter\\StringToBooleanConverter' => $baseDir . '/sources/Forms/Block/IO/Converter/StringToBooleanConverter.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\FormBinding' => $baseDir . '/sources/Forms/Block/IO/FormBinding.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\FormInput' => $baseDir . '/sources/Forms/Block/IO/FormInput.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\FormOutput' => $baseDir . '/sources/Forms/Block/IO/FormOutput.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Format\\AttributeIOFormat' => $baseDir . '/sources/Forms/Block/IO/Format/AttributeIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Format\\BooleanIOFormat' => $baseDir . '/sources/Forms/Block/IO/Format/BooleanIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Format\\ClassIOFormat' => $baseDir . '/sources/Forms/Block/IO/Format/ClassIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Format\\RawFormat' => $baseDir . '/sources/Forms/Block/IO/Format/RawFormat.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => $baseDir . '/sources/Forms/FormBuilder/DependencyHandler.php',
|
||||
@@ -509,6 +513,7 @@ return array(
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\ResolvedFormTypeFactory' => $baseDir . '/sources/Forms/FormBuilder/ResolvedFormTypeFactory.php',
|
||||
'Combodo\\iTop\\Forms\\Forms' => $baseDir . '/sources/Forms/Forms.php',
|
||||
'Combodo\\iTop\\Forms\\FormsException' => $baseDir . '/sources/Forms/FormsException.php',
|
||||
'Combodo\\iTop\\Forms\\IFormBlock' => $baseDir . '/sources/Forms/IFormBlock.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',
|
||||
@@ -1517,6 +1522,8 @@ return array(
|
||||
'Symfony\\Bridge\\Twig\\Node\\StopwatchNode' => $vendorDir . '/symfony/twig-bridge/Node/StopwatchNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Node\\TransDefaultDomainNode' => $vendorDir . '/symfony/twig-bridge/Node/TransDefaultDomainNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Node\\TransNode' => $vendorDir . '/symfony/twig-bridge/Node/TransNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Test\\FormLayoutTestCase' => $vendorDir . '/symfony/twig-bridge/Test/FormLayoutTestCase.php',
|
||||
'Symfony\\Bridge\\Twig\\Test\\Traits\\RuntimeLoaderProvider' => $vendorDir . '/symfony/twig-bridge/Test/Traits/RuntimeLoaderProvider.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\DumpTokenParser' => $vendorDir . '/symfony/twig-bridge/TokenParser/DumpTokenParser.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\FormThemeTokenParser' => $vendorDir . '/symfony/twig-bridge/TokenParser/FormThemeTokenParser.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\StopwatchTokenParser' => $vendorDir . '/symfony/twig-bridge/TokenParser/StopwatchTokenParser.php',
|
||||
@@ -2450,6 +2457,13 @@ return array(
|
||||
'Symfony\\Component\\Form\\SubmitButton' => $vendorDir . '/symfony/form/SubmitButton.php',
|
||||
'Symfony\\Component\\Form\\SubmitButtonBuilder' => $vendorDir . '/symfony/form/SubmitButtonBuilder.php',
|
||||
'Symfony\\Component\\Form\\SubmitButtonTypeInterface' => $vendorDir . '/symfony/form/SubmitButtonTypeInterface.php',
|
||||
'Symfony\\Component\\Form\\Test\\FormBuilderInterface' => $vendorDir . '/symfony/form/Test/FormBuilderInterface.php',
|
||||
'Symfony\\Component\\Form\\Test\\FormIntegrationTestCase' => $vendorDir . '/symfony/form/Test/FormIntegrationTestCase.php',
|
||||
'Symfony\\Component\\Form\\Test\\FormInterface' => $vendorDir . '/symfony/form/Test/FormInterface.php',
|
||||
'Symfony\\Component\\Form\\Test\\FormPerformanceTestCase' => $vendorDir . '/symfony/form/Test/FormPerformanceTestCase.php',
|
||||
'Symfony\\Component\\Form\\Test\\Traits\\RunTestTrait' => $vendorDir . '/symfony/form/Test/Traits/RunTestTrait.php',
|
||||
'Symfony\\Component\\Form\\Test\\Traits\\ValidatorExtensionTrait' => $vendorDir . '/symfony/form/Test/Traits/ValidatorExtensionTrait.php',
|
||||
'Symfony\\Component\\Form\\Test\\TypeTestCase' => $vendorDir . '/symfony/form/Test/TypeTestCase.php',
|
||||
'Symfony\\Component\\Form\\Util\\FormUtil' => $vendorDir . '/symfony/form/Util/FormUtil.php',
|
||||
'Symfony\\Component\\Form\\Util\\InheritDataAwareIterator' => $vendorDir . '/symfony/form/Util/InheritDataAwareIterator.php',
|
||||
'Symfony\\Component\\Form\\Util\\OptionsResolverWrapper' => $vendorDir . '/symfony/form/Util/OptionsResolverWrapper.php',
|
||||
@@ -2551,6 +2565,17 @@ return array(
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface' => $vendorDir . '/symfony/http-foundation/Session/Storage/SessionStorageInterface.php',
|
||||
'Symfony\\Component\\HttpFoundation\\StreamedJsonResponse' => $vendorDir . '/symfony/http-foundation/StreamedJsonResponse.php',
|
||||
'Symfony\\Component\\HttpFoundation\\StreamedResponse' => $vendorDir . '/symfony/http-foundation/StreamedResponse.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\RequestAttributeValueSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseCookieValueSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseFormatSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseFormatSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasCookie' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasHeader' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderLocationSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHeaderLocationSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsRedirected' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsRedirected.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsSuccessful' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsSuccessful.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsUnprocessable' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsUnprocessable.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseStatusCodeSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\UriSigner' => $vendorDir . '/symfony/http-foundation/UriSigner.php',
|
||||
'Symfony\\Component\\HttpFoundation\\UrlHelper' => $vendorDir . '/symfony/http-foundation/UrlHelper.php',
|
||||
'Symfony\\Component\\HttpKernel\\Attribute\\AsController' => $vendorDir . '/symfony/http-kernel/Attribute/AsController.php',
|
||||
@@ -2747,6 +2772,9 @@ return array(
|
||||
'Symfony\\Component\\Mailer\\Messenger\\MessageHandler' => $vendorDir . '/symfony/mailer/Messenger/MessageHandler.php',
|
||||
'Symfony\\Component\\Mailer\\Messenger\\SendEmailMessage' => $vendorDir . '/symfony/mailer/Messenger/SendEmailMessage.php',
|
||||
'Symfony\\Component\\Mailer\\SentMessage' => $vendorDir . '/symfony/mailer/SentMessage.php',
|
||||
'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailCount' => $vendorDir . '/symfony/mailer/Test/Constraint/EmailCount.php',
|
||||
'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailIsQueued' => $vendorDir . '/symfony/mailer/Test/Constraint/EmailIsQueued.php',
|
||||
'Symfony\\Component\\Mailer\\Test\\TransportFactoryTestCase' => $vendorDir . '/symfony/mailer/Test/TransportFactoryTestCase.php',
|
||||
'Symfony\\Component\\Mailer\\Transport' => $vendorDir . '/symfony/mailer/Transport.php',
|
||||
'Symfony\\Component\\Mailer\\Transport\\AbstractApiTransport' => $vendorDir . '/symfony/mailer/Transport/AbstractApiTransport.php',
|
||||
'Symfony\\Component\\Mailer\\Transport\\AbstractHttpTransport' => $vendorDir . '/symfony/mailer/Transport/AbstractHttpTransport.php',
|
||||
@@ -2837,6 +2865,13 @@ return array(
|
||||
'Symfony\\Component\\Mime\\Part\\SMimePart' => $vendorDir . '/symfony/mime/Part/SMimePart.php',
|
||||
'Symfony\\Component\\Mime\\Part\\TextPart' => $vendorDir . '/symfony/mime/Part/TextPart.php',
|
||||
'Symfony\\Component\\Mime\\RawMessage' => $vendorDir . '/symfony/mime/RawMessage.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailAddressContains' => $vendorDir . '/symfony/mime/Test/Constraint/EmailAddressContains.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailAttachmentCount' => $vendorDir . '/symfony/mime/Test/Constraint/EmailAttachmentCount.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHasHeader' => $vendorDir . '/symfony/mime/Test/Constraint/EmailHasHeader.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHeaderSame' => $vendorDir . '/symfony/mime/Test/Constraint/EmailHeaderSame.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHtmlBodyContains' => $vendorDir . '/symfony/mime/Test/Constraint/EmailHtmlBodyContains.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailSubjectContains' => $vendorDir . '/symfony/mime/Test/Constraint/EmailSubjectContains.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailTextBodyContains' => $vendorDir . '/symfony/mime/Test/Constraint/EmailTextBodyContains.php',
|
||||
'Symfony\\Component\\OptionsResolver\\Debug\\OptionsResolverIntrospector' => $vendorDir . '/symfony/options-resolver/Debug/OptionsResolverIntrospector.php',
|
||||
'Symfony\\Component\\OptionsResolver\\Exception\\AccessException' => $vendorDir . '/symfony/options-resolver/Exception/AccessException.php',
|
||||
'Symfony\\Component\\OptionsResolver\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/options-resolver/Exception/ExceptionInterface.php',
|
||||
@@ -3062,6 +3097,7 @@ return array(
|
||||
'Symfony\\Component\\Security\\Core\\Signature\\Exception\\InvalidSignatureException' => $vendorDir . '/symfony/security-core/Signature/Exception/InvalidSignatureException.php',
|
||||
'Symfony\\Component\\Security\\Core\\Signature\\ExpiredSignatureStorage' => $vendorDir . '/symfony/security-core/Signature/ExpiredSignatureStorage.php',
|
||||
'Symfony\\Component\\Security\\Core\\Signature\\SignatureHasher' => $vendorDir . '/symfony/security-core/Signature/SignatureHasher.php',
|
||||
'Symfony\\Component\\Security\\Core\\Test\\AccessDecisionStrategyTestCase' => $vendorDir . '/symfony/security-core/Test/AccessDecisionStrategyTestCase.php',
|
||||
'Symfony\\Component\\Security\\Core\\User\\AttributesBasedUserProviderInterface' => $vendorDir . '/symfony/security-core/User/AttributesBasedUserProviderInterface.php',
|
||||
'Symfony\\Component\\Security\\Core\\User\\ChainUserChecker' => $vendorDir . '/symfony/security-core/User/ChainUserChecker.php',
|
||||
'Symfony\\Component\\Security\\Core\\User\\ChainUserProvider' => $vendorDir . '/symfony/security-core/User/ChainUserProvider.php',
|
||||
@@ -3171,6 +3207,7 @@ return array(
|
||||
'Symfony\\Component\\VarDumper\\Exception\\ThrowingCasterException' => $vendorDir . '/symfony/var-dumper/Exception/ThrowingCasterException.php',
|
||||
'Symfony\\Component\\VarDumper\\Server\\Connection' => $vendorDir . '/symfony/var-dumper/Server/Connection.php',
|
||||
'Symfony\\Component\\VarDumper\\Server\\DumpServer' => $vendorDir . '/symfony/var-dumper/Server/DumpServer.php',
|
||||
'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => $vendorDir . '/symfony/var-dumper/Test/VarDumperTestTrait.php',
|
||||
'Symfony\\Component\\VarDumper\\VarDumper' => $vendorDir . '/symfony/var-dumper/VarDumper.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ClassNotFoundException' => $vendorDir . '/symfony/var-exporter/Exception/ClassNotFoundException.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/var-exporter/Exception/ExceptionInterface.php',
|
||||
@@ -3518,6 +3555,8 @@ return array(
|
||||
'Twig\\Source' => $vendorDir . '/twig/twig/src/Source.php',
|
||||
'Twig\\Template' => $vendorDir . '/twig/twig/src/Template.php',
|
||||
'Twig\\TemplateWrapper' => $vendorDir . '/twig/twig/src/TemplateWrapper.php',
|
||||
'Twig\\Test\\IntegrationTestCase' => $vendorDir . '/twig/twig/src/Test/IntegrationTestCase.php',
|
||||
'Twig\\Test\\NodeTestCase' => $vendorDir . '/twig/twig/src/Test/NodeTestCase.php',
|
||||
'Twig\\Token' => $vendorDir . '/twig/twig/src/Token.php',
|
||||
'Twig\\TokenParser\\AbstractTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/AbstractTokenParser.php',
|
||||
'Twig\\TokenParser\\ApplyTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ApplyTokenParser.php',
|
||||
|
||||
@@ -855,8 +855,11 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/NotEmptyExtKeyValidator.php',
|
||||
'Combodo\\iTop\\Form\\Validator\\SelectObjectValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/SelectObjectValidator.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\AbstractFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/AbstractFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\CheckboxFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/CheckboxFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/ChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\CollectionBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/CollectionBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\DateFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/DateFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\DateTimeFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/DateTimeFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\FormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/FormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextAreaFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextAreaFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextFormBlock.php',
|
||||
@@ -865,19 +868,20 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/OqlFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockException' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockException.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockIOException' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/FormBlockIOException.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\AttributeFormType' => __DIR__ . '/../..' . '/sources/Forms/Block/FormType/AttributeFormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\AttributeValueFormType' => __DIR__ . '/../..' . '/sources/Forms/Block/FormType/AttributeValueFormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\ChoiceFormType' => __DIR__ . '/../..' . '/sources/Forms/Block/FormType/ChoiceFormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\CollectionFormType' => __DIR__ . '/../..' . '/sources/Forms/Block/FormType/CollectionFormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\FormType' => __DIR__ . '/../..' . '/sources/Forms/Block/FormType/FormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormType\\OqlFormType' => __DIR__ . '/../..' . '/sources/Forms/Block/FormType/OqlFormType.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\AbstractFormIO' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/AbstractFormIO.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Converter\\AbstractConverter' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/Converter/AbstractConverter.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Converter\\OqlToClassConverter' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/Converter/OqlToClassConverter.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Converter\\StringToAttributeConverter' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/Converter/StringToAttributeConverter.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Converter\\StringToBooleanConverter' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/Converter/StringToBooleanConverter.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\FormBinding' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/FormBinding.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\FormInput' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/FormInput.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\FormOutput' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/FormOutput.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Format\\AttributeIOFormat' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/Format/AttributeIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Format\\BooleanIOFormat' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/Format/BooleanIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Format\\ClassIOFormat' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/Format/ClassIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\IO\\Format\\RawFormat' => __DIR__ . '/../..' . '/sources/Forms/Block/IO/Format/RawFormat.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/DependencyHandler.php',
|
||||
@@ -890,6 +894,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\ResolvedFormTypeFactory' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/ResolvedFormTypeFactory.php',
|
||||
'Combodo\\iTop\\Forms\\Forms' => __DIR__ . '/../..' . '/sources/Forms/Forms.php',
|
||||
'Combodo\\iTop\\Forms\\FormsException' => __DIR__ . '/../..' . '/sources/Forms/FormsException.php',
|
||||
'Combodo\\iTop\\Forms\\IFormBlock' => __DIR__ . '/../..' . '/sources/Forms/IFormBlock.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',
|
||||
@@ -1898,6 +1903,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Symfony\\Bridge\\Twig\\Node\\StopwatchNode' => __DIR__ . '/..' . '/symfony/twig-bridge/Node/StopwatchNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Node\\TransDefaultDomainNode' => __DIR__ . '/..' . '/symfony/twig-bridge/Node/TransDefaultDomainNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Node\\TransNode' => __DIR__ . '/..' . '/symfony/twig-bridge/Node/TransNode.php',
|
||||
'Symfony\\Bridge\\Twig\\Test\\FormLayoutTestCase' => __DIR__ . '/..' . '/symfony/twig-bridge/Test/FormLayoutTestCase.php',
|
||||
'Symfony\\Bridge\\Twig\\Test\\Traits\\RuntimeLoaderProvider' => __DIR__ . '/..' . '/symfony/twig-bridge/Test/Traits/RuntimeLoaderProvider.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\DumpTokenParser' => __DIR__ . '/..' . '/symfony/twig-bridge/TokenParser/DumpTokenParser.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\FormThemeTokenParser' => __DIR__ . '/..' . '/symfony/twig-bridge/TokenParser/FormThemeTokenParser.php',
|
||||
'Symfony\\Bridge\\Twig\\TokenParser\\StopwatchTokenParser' => __DIR__ . '/..' . '/symfony/twig-bridge/TokenParser/StopwatchTokenParser.php',
|
||||
@@ -2831,6 +2838,13 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Symfony\\Component\\Form\\SubmitButton' => __DIR__ . '/..' . '/symfony/form/SubmitButton.php',
|
||||
'Symfony\\Component\\Form\\SubmitButtonBuilder' => __DIR__ . '/..' . '/symfony/form/SubmitButtonBuilder.php',
|
||||
'Symfony\\Component\\Form\\SubmitButtonTypeInterface' => __DIR__ . '/..' . '/symfony/form/SubmitButtonTypeInterface.php',
|
||||
'Symfony\\Component\\Form\\Test\\FormBuilderInterface' => __DIR__ . '/..' . '/symfony/form/Test/FormBuilderInterface.php',
|
||||
'Symfony\\Component\\Form\\Test\\FormIntegrationTestCase' => __DIR__ . '/..' . '/symfony/form/Test/FormIntegrationTestCase.php',
|
||||
'Symfony\\Component\\Form\\Test\\FormInterface' => __DIR__ . '/..' . '/symfony/form/Test/FormInterface.php',
|
||||
'Symfony\\Component\\Form\\Test\\FormPerformanceTestCase' => __DIR__ . '/..' . '/symfony/form/Test/FormPerformanceTestCase.php',
|
||||
'Symfony\\Component\\Form\\Test\\Traits\\RunTestTrait' => __DIR__ . '/..' . '/symfony/form/Test/Traits/RunTestTrait.php',
|
||||
'Symfony\\Component\\Form\\Test\\Traits\\ValidatorExtensionTrait' => __DIR__ . '/..' . '/symfony/form/Test/Traits/ValidatorExtensionTrait.php',
|
||||
'Symfony\\Component\\Form\\Test\\TypeTestCase' => __DIR__ . '/..' . '/symfony/form/Test/TypeTestCase.php',
|
||||
'Symfony\\Component\\Form\\Util\\FormUtil' => __DIR__ . '/..' . '/symfony/form/Util/FormUtil.php',
|
||||
'Symfony\\Component\\Form\\Util\\InheritDataAwareIterator' => __DIR__ . '/..' . '/symfony/form/Util/InheritDataAwareIterator.php',
|
||||
'Symfony\\Component\\Form\\Util\\OptionsResolverWrapper' => __DIR__ . '/..' . '/symfony/form/Util/OptionsResolverWrapper.php',
|
||||
@@ -2932,6 +2946,17 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface' => __DIR__ . '/..' . '/symfony/http-foundation/Session/Storage/SessionStorageInterface.php',
|
||||
'Symfony\\Component\\HttpFoundation\\StreamedJsonResponse' => __DIR__ . '/..' . '/symfony/http-foundation/StreamedJsonResponse.php',
|
||||
'Symfony\\Component\\HttpFoundation\\StreamedResponse' => __DIR__ . '/..' . '/symfony/http-foundation/StreamedResponse.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\RequestAttributeValueSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseCookieValueSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseFormatSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseFormatSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasCookie' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasHeader' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderLocationSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHeaderLocationSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsRedirected' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsRedirected.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsSuccessful' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsSuccessful.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsUnprocessable' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsUnprocessable.php',
|
||||
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseStatusCodeSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php',
|
||||
'Symfony\\Component\\HttpFoundation\\UriSigner' => __DIR__ . '/..' . '/symfony/http-foundation/UriSigner.php',
|
||||
'Symfony\\Component\\HttpFoundation\\UrlHelper' => __DIR__ . '/..' . '/symfony/http-foundation/UrlHelper.php',
|
||||
'Symfony\\Component\\HttpKernel\\Attribute\\AsController' => __DIR__ . '/..' . '/symfony/http-kernel/Attribute/AsController.php',
|
||||
@@ -3128,6 +3153,9 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Symfony\\Component\\Mailer\\Messenger\\MessageHandler' => __DIR__ . '/..' . '/symfony/mailer/Messenger/MessageHandler.php',
|
||||
'Symfony\\Component\\Mailer\\Messenger\\SendEmailMessage' => __DIR__ . '/..' . '/symfony/mailer/Messenger/SendEmailMessage.php',
|
||||
'Symfony\\Component\\Mailer\\SentMessage' => __DIR__ . '/..' . '/symfony/mailer/SentMessage.php',
|
||||
'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailCount' => __DIR__ . '/..' . '/symfony/mailer/Test/Constraint/EmailCount.php',
|
||||
'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailIsQueued' => __DIR__ . '/..' . '/symfony/mailer/Test/Constraint/EmailIsQueued.php',
|
||||
'Symfony\\Component\\Mailer\\Test\\TransportFactoryTestCase' => __DIR__ . '/..' . '/symfony/mailer/Test/TransportFactoryTestCase.php',
|
||||
'Symfony\\Component\\Mailer\\Transport' => __DIR__ . '/..' . '/symfony/mailer/Transport.php',
|
||||
'Symfony\\Component\\Mailer\\Transport\\AbstractApiTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/AbstractApiTransport.php',
|
||||
'Symfony\\Component\\Mailer\\Transport\\AbstractHttpTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/AbstractHttpTransport.php',
|
||||
@@ -3218,6 +3246,13 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Symfony\\Component\\Mime\\Part\\SMimePart' => __DIR__ . '/..' . '/symfony/mime/Part/SMimePart.php',
|
||||
'Symfony\\Component\\Mime\\Part\\TextPart' => __DIR__ . '/..' . '/symfony/mime/Part/TextPart.php',
|
||||
'Symfony\\Component\\Mime\\RawMessage' => __DIR__ . '/..' . '/symfony/mime/RawMessage.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailAddressContains' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailAddressContains.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailAttachmentCount' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailAttachmentCount.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHasHeader' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailHasHeader.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHeaderSame' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailHeaderSame.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHtmlBodyContains' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailHtmlBodyContains.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailSubjectContains' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailSubjectContains.php',
|
||||
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailTextBodyContains' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailTextBodyContains.php',
|
||||
'Symfony\\Component\\OptionsResolver\\Debug\\OptionsResolverIntrospector' => __DIR__ . '/..' . '/symfony/options-resolver/Debug/OptionsResolverIntrospector.php',
|
||||
'Symfony\\Component\\OptionsResolver\\Exception\\AccessException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/AccessException.php',
|
||||
'Symfony\\Component\\OptionsResolver\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/ExceptionInterface.php',
|
||||
@@ -3443,6 +3478,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Symfony\\Component\\Security\\Core\\Signature\\Exception\\InvalidSignatureException' => __DIR__ . '/..' . '/symfony/security-core/Signature/Exception/InvalidSignatureException.php',
|
||||
'Symfony\\Component\\Security\\Core\\Signature\\ExpiredSignatureStorage' => __DIR__ . '/..' . '/symfony/security-core/Signature/ExpiredSignatureStorage.php',
|
||||
'Symfony\\Component\\Security\\Core\\Signature\\SignatureHasher' => __DIR__ . '/..' . '/symfony/security-core/Signature/SignatureHasher.php',
|
||||
'Symfony\\Component\\Security\\Core\\Test\\AccessDecisionStrategyTestCase' => __DIR__ . '/..' . '/symfony/security-core/Test/AccessDecisionStrategyTestCase.php',
|
||||
'Symfony\\Component\\Security\\Core\\User\\AttributesBasedUserProviderInterface' => __DIR__ . '/..' . '/symfony/security-core/User/AttributesBasedUserProviderInterface.php',
|
||||
'Symfony\\Component\\Security\\Core\\User\\ChainUserChecker' => __DIR__ . '/..' . '/symfony/security-core/User/ChainUserChecker.php',
|
||||
'Symfony\\Component\\Security\\Core\\User\\ChainUserProvider' => __DIR__ . '/..' . '/symfony/security-core/User/ChainUserProvider.php',
|
||||
@@ -3552,6 +3588,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Symfony\\Component\\VarDumper\\Exception\\ThrowingCasterException' => __DIR__ . '/..' . '/symfony/var-dumper/Exception/ThrowingCasterException.php',
|
||||
'Symfony\\Component\\VarDumper\\Server\\Connection' => __DIR__ . '/..' . '/symfony/var-dumper/Server/Connection.php',
|
||||
'Symfony\\Component\\VarDumper\\Server\\DumpServer' => __DIR__ . '/..' . '/symfony/var-dumper/Server/DumpServer.php',
|
||||
'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => __DIR__ . '/..' . '/symfony/var-dumper/Test/VarDumperTestTrait.php',
|
||||
'Symfony\\Component\\VarDumper\\VarDumper' => __DIR__ . '/..' . '/symfony/var-dumper/VarDumper.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ClassNotFoundException' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/ClassNotFoundException.php',
|
||||
'Symfony\\Component\\VarExporter\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/ExceptionInterface.php',
|
||||
@@ -3899,6 +3936,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Twig\\Source' => __DIR__ . '/..' . '/twig/twig/src/Source.php',
|
||||
'Twig\\Template' => __DIR__ . '/..' . '/twig/twig/src/Template.php',
|
||||
'Twig\\TemplateWrapper' => __DIR__ . '/..' . '/twig/twig/src/TemplateWrapper.php',
|
||||
'Twig\\Test\\IntegrationTestCase' => __DIR__ . '/..' . '/twig/twig/src/Test/IntegrationTestCase.php',
|
||||
'Twig\\Test\\NodeTestCase' => __DIR__ . '/..' . '/twig/twig/src/Test/NodeTestCase.php',
|
||||
'Twig\\Token' => __DIR__ . '/..' . '/twig/twig/src/Token.php',
|
||||
'Twig\\TokenParser\\AbstractTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/AbstractTokenParser.php',
|
||||
'Twig\\TokenParser\\ApplyTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ApplyTokenParser.php',
|
||||
|
||||
@@ -6,8 +6,8 @@ $vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
$vendorDir . '/pear/archive_tar',
|
||||
$vendorDir . '/pear/pear_exception',
|
||||
$vendorDir . '/pear/console_getopt',
|
||||
$vendorDir . '/pear/pear-core-minimal/src',
|
||||
$vendorDir . '/pear/pear_exception',
|
||||
$vendorDir . '/pear/archive_tar',
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
'name' => 'combodo/itop',
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '600a6185a35e5e92bddd4e05894ae39f83a442d6',
|
||||
'reference' => '2c6c084a0f4dc7b999db805c75aa3314fa297d33',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -22,7 +22,7 @@
|
||||
'combodo/itop' => array(
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '600a6185a35e5e92bddd4e05894ae39f83a442d6',
|
||||
'reference' => '2c6c084a0f4dc7b999db805c75aa3314fa297d33',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
||||
7
lib/soundasleep/html2text/phpstan.neon.dist
Normal file
7
lib/soundasleep/html2text/phpstan.neon.dist
Normal file
@@ -0,0 +1,7 @@
|
||||
parameters:
|
||||
level: 6
|
||||
errorFormat: raw
|
||||
editorUrl: '%%file%% %%line%% %%column%%: %%error%%'
|
||||
paths:
|
||||
- src
|
||||
- tests
|
||||
19
lib/symfony/mime/LICENSE
Normal file
19
lib/symfony/mime/LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2010-present Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -8,8 +8,11 @@ namespace Combodo\iTop\Forms\Block;
|
||||
|
||||
use Combodo\iTop\Forms\Block\Base\FormBlock;
|
||||
use Combodo\iTop\Forms\Block\IO\Converter\AbstractConverter;
|
||||
use Combodo\iTop\Forms\Block\IO\Format\BooleanIOFormat;
|
||||
use Combodo\iTop\Forms\Block\IO\Format\RawFormat;
|
||||
use Combodo\iTop\Forms\Block\IO\FormInput;
|
||||
use Combodo\iTop\Forms\Block\IO\FormOutput;
|
||||
use Combodo\iTop\Forms\IFormBlock;
|
||||
use IssueLog;
|
||||
use Symfony\Component\Filesystem\Exception\IOException;
|
||||
|
||||
@@ -21,11 +24,23 @@ use Symfony\Component\Filesystem\Exception\IOException;
|
||||
* It defines its inputs and outputs.
|
||||
*
|
||||
*/
|
||||
abstract class AbstractFormBlock
|
||||
abstract class AbstractFormBlock implements IFormBlock
|
||||
{
|
||||
// Inputs
|
||||
public const INPUT_VISIBLE = 'visible';
|
||||
|
||||
// Outputs
|
||||
public const OUTPUT_VALUE = 'value';
|
||||
|
||||
/** @var null|FormBlock */
|
||||
private ?FormBlock $oParent = null;
|
||||
|
||||
/** @var array form options */
|
||||
private array $aOptions = [];
|
||||
|
||||
/** @var array form dynamic options */
|
||||
protected array $aDynamicOptions = [];
|
||||
|
||||
/** @var array form block inputs */
|
||||
private array $aFormInputs = [];
|
||||
|
||||
@@ -35,6 +50,7 @@ abstract class AbstractFormBlock
|
||||
/** @var bool flag indicating the form insertion */
|
||||
private bool $bIsAddedToForm = false;
|
||||
|
||||
|
||||
/**
|
||||
* Return the form type.
|
||||
*
|
||||
@@ -42,26 +58,18 @@ abstract class AbstractFormBlock
|
||||
*/
|
||||
abstract public function GetFormType(): string;
|
||||
|
||||
/**
|
||||
* Initialize options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function InitOptions(): array;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $sName
|
||||
* @param array $aOptions
|
||||
* @param array $aUserOptions
|
||||
*/
|
||||
public function __construct(private readonly string $sName, protected array $aOptions = [])
|
||||
public function __construct(private readonly string $sName, protected array $aUserOptions = [])
|
||||
{
|
||||
// Attach the form block
|
||||
$this->aOptions['form_block'] = $this;
|
||||
|
||||
// Compute options
|
||||
$this->aOptions = array_merge($this->aOptions, $this->InitOptions());
|
||||
$this->aOptions = $aUserOptions;
|
||||
$this->InitBlockOptions($this->aOptions);
|
||||
|
||||
// Initialize block inputs
|
||||
$this->InitInputs();
|
||||
@@ -70,6 +78,17 @@ abstract class AbstractFormBlock
|
||||
$this->InitOutputs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize options.
|
||||
*
|
||||
* @param array $aUserOptions
|
||||
*
|
||||
*/
|
||||
public function InitBlockOptions(array &$aUserOptions): void
|
||||
{
|
||||
$aUserOptions['form_block'] = $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parent block.
|
||||
*
|
||||
@@ -113,15 +132,24 @@ abstract class AbstractFormBlock
|
||||
return $this->aOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the form block options.
|
||||
* Options will be passed to FormType for building.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function UpdateOptions(): array
|
||||
public function GetOptionsMergedWithDynamic(string $sEventType = null): array
|
||||
{
|
||||
return $this->aOptions;
|
||||
return array_merge($this->aDynamicOptions, $this->aOptions);
|
||||
}
|
||||
|
||||
public function GetDynamicOptions(string $sEventType = null): array
|
||||
{
|
||||
return $this->aDynamicOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $sEventType
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function UpdateDynamicOptions(string $sEventType = null): void
|
||||
{
|
||||
$this->aDynamicOptions = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,7 +264,6 @@ abstract class AbstractFormBlock
|
||||
*
|
||||
* @return $this
|
||||
* @throws FormBlockException
|
||||
* @throws FormBlockIOException
|
||||
*/
|
||||
public function DependsOnParent(string $sInputName, string $sParentInputName): AbstractFormBlock
|
||||
{
|
||||
@@ -339,13 +366,15 @@ abstract class AbstractFormBlock
|
||||
/**
|
||||
* Inputs data ready.
|
||||
*
|
||||
* @param string|null $sType
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IsInputsDataReady(): bool
|
||||
public function IsInputsDataReady(string $sType = null): bool
|
||||
{
|
||||
foreach ($this->aFormInputs as $oFormInput) {
|
||||
if ($oFormInput->IsBound()) {
|
||||
if (!$oFormInput->IsDataReady()) {
|
||||
if (!$oFormInput->IsEventDataReady($sType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -419,7 +448,20 @@ abstract class AbstractFormBlock
|
||||
*/
|
||||
public function InitInputs(): void
|
||||
{
|
||||
$this->AddInput(self::INPUT_VISIBLE, BooleanIOFormat::class);
|
||||
}
|
||||
|
||||
public function IsVisible(string $sEventType = null): bool
|
||||
{
|
||||
$oInput = $this->GetInput(self::INPUT_VISIBLE);
|
||||
|
||||
if(!$oInput->IsBound()){
|
||||
return true;
|
||||
}
|
||||
|
||||
$bVisible = $oInput->GetValue($sEventType);
|
||||
|
||||
return $bVisible !== null && $bVisible->IsTrue();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -427,16 +469,16 @@ abstract class AbstractFormBlock
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function InitOutputs()
|
||||
public function InitOutputs(): void
|
||||
{
|
||||
|
||||
$this->AddOutput(self::OUTPUT_VALUE, RawFormat::class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true
|
||||
*/
|
||||
public function AllowAdd(): bool
|
||||
public function AllowAdd(string $sEventType = null): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
41
sources/Forms/Block/Base/CheckboxFormBlock.php
Normal file
41
sources/Forms/Block/Base/CheckboxFormBlock.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\Base;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Combodo\iTop\Forms\Block\IO\Converter\StringToBooleanConverter;
|
||||
use Combodo\iTop\Forms\Block\IO\Format\BooleanIOFormat;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
|
||||
/**
|
||||
* Form block for checkbox.
|
||||
*
|
||||
*/
|
||||
class CheckboxFormBlock extends AbstractFormBlock
|
||||
{
|
||||
// outputs
|
||||
public const OUTPUT_CHECKED = 'checked';
|
||||
|
||||
/** @inheritdoc */
|
||||
public function GetFormType(): string
|
||||
{
|
||||
return CheckboxType::class;
|
||||
}
|
||||
|
||||
function InitBlockOptions(array &$aUserOptions): void
|
||||
{
|
||||
parent::InitBlockOptions($aUserOptions);
|
||||
$aUserOptions['required'] = false;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
function InitOutputs(): void
|
||||
{
|
||||
parent::InitOutputs();
|
||||
$this->AddOutput(self::OUTPUT_CHECKED, BooleanIOFormat::class, new StringToBooleanConverter());
|
||||
}
|
||||
}
|
||||
@@ -21,10 +21,4 @@ class ChoiceFormBlock extends AbstractFormBlock
|
||||
return ChoiceFormType::class;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function InitOptions(): array
|
||||
{
|
||||
return [
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
namespace Combodo\iTop\Forms\Block\Base;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Combodo\iTop\Forms\Block\FormType\CollectionFormType;
|
||||
use Combodo\iTop\Forms\Block\IO\Format\ClassIOFormat;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||
|
||||
/**
|
||||
@@ -15,33 +17,54 @@ use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||
*/
|
||||
class CollectionBlock extends AbstractFormBlock
|
||||
{
|
||||
// Inputs
|
||||
public const INPUT_CLASS_NAME = 'class_name';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $sName
|
||||
* @param array $aOptions
|
||||
*/
|
||||
public function __construct(string $sName, array $aOptions = [])
|
||||
{
|
||||
parent::__construct($sName, $aOptions);
|
||||
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function GetFormType(): string
|
||||
{
|
||||
return CollectionType::class;
|
||||
return CollectionFormType::class;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function InitOptions(): array
|
||||
public function InitInputs(): void
|
||||
{
|
||||
$sBlockEntryType = $this->GetOptions()['block_entry_type'];
|
||||
$sBlockEntryOptions = $this->GetOptions()['block_entry_options'];
|
||||
parent::InitInputs();
|
||||
$this->AddInput(self::INPUT_CLASS_NAME, ClassIOFormat::class);
|
||||
}
|
||||
|
||||
$this->aOptions = [];
|
||||
/** @inheritdoc */
|
||||
public function InitBlockOptions(array &$aUserOptions): void
|
||||
{
|
||||
parent::InitBlockOptions($aUserOptions);
|
||||
|
||||
$oBlock = new ($sBlockEntryType)('prototype', $sBlockEntryOptions);
|
||||
|
||||
return [
|
||||
'entry_type' => $oBlock->GetFormType(),
|
||||
];
|
||||
// Convert block information in type information
|
||||
if(isset($aUserOptions['block_entry_type'])) {
|
||||
$sBlockEntryType = $aUserOptions['block_entry_type'];
|
||||
$sBlockEntryOptions = $this->aUserOptions['block_entry_options'];
|
||||
$oBlock = new ($sBlockEntryType)('prototype', $sBlockEntryOptions);
|
||||
unset($aUserOptions['block_entry_type']);
|
||||
unset($aUserOptions['block_entry_options']);
|
||||
$aUserOptions['entry_type'] = $oBlock->GetFormType();
|
||||
$aUserOptions['entry_options'] = $oBlock->GetOptions();
|
||||
|
||||
$aUserOptions['prototype'] = true;
|
||||
$aUserOptions['allow_add'] = true;
|
||||
$aUserOptions['prototype_options'] = [
|
||||
'label' => false
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
32
sources/Forms/Block/Base/DateFormBlock.php
Normal file
32
sources/Forms/Block/Base/DateFormBlock.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\Base;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
|
||||
/**
|
||||
* Form block for date.
|
||||
*
|
||||
*/
|
||||
class DateFormBlock extends AbstractFormBlock
|
||||
{
|
||||
/** @inheritdoc */
|
||||
public function GetFormType(): string
|
||||
{
|
||||
return DateType::class;
|
||||
}
|
||||
|
||||
public function InitBlockOptions(array &$aUserOptions): void
|
||||
{
|
||||
parent::InitBlockOptions($aUserOptions);
|
||||
$aUserOptions['widget'] = 'single_text';
|
||||
}
|
||||
}
|
||||
31
sources/Forms/Block/Base/DateTimeFormBlock.php
Normal file
31
sources/Forms/Block/Base/DateTimeFormBlock.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\Base;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
|
||||
/**
|
||||
* Form block for date time.
|
||||
*
|
||||
*/
|
||||
class DateTimeFormBlock extends AbstractFormBlock
|
||||
{
|
||||
/** @inheritdoc */
|
||||
public function GetFormType(): string
|
||||
{
|
||||
return DateTimeType::class;
|
||||
}
|
||||
|
||||
public function InitBlockOptions(array &$aUserOptions): void
|
||||
{
|
||||
parent::InitBlockOptions($aUserOptions);
|
||||
$aUserOptions['widget'] = 'single_text';
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,11 @@
|
||||
namespace Combodo\iTop\Forms\Block\Base;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Combodo\iTop\Forms\Block\FormBlockException;
|
||||
use Combodo\iTop\Forms\Block\FormType\FormType;
|
||||
use Combodo\iTop\Forms\FormsException;
|
||||
use Exception;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Complex form type.
|
||||
@@ -48,24 +50,35 @@ class FormBlock extends AbstractFormBlock
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function InitOptions(): array
|
||||
public function InitBlockOptions(array &$aUserOptions): void
|
||||
{
|
||||
return [
|
||||
'compound' => true,
|
||||
parent::InitBlockOptions($aUserOptions);
|
||||
|
||||
$aUserOptions['compound'] = true;
|
||||
$aUserOptions['attr'] = [
|
||||
'class' => 'form'
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a child form.
|
||||
*
|
||||
* @param string $sType block class name
|
||||
* @param string $sName block name
|
||||
* @param string $sType block class name
|
||||
* @param array $aOptions options
|
||||
*
|
||||
* @return $this
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function Add(string $sType, string $sName, array $aOptions): AbstractFormBlock
|
||||
public function Add(string $sName, string $sType, 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.");
|
||||
}
|
||||
|
||||
$aOptions['priority'] = -count($this->aChildrenBlocks);
|
||||
$oSubFormBlock = new ($sType)($sName, $aOptions);
|
||||
$this->aChildrenBlocks[$sName] = $oSubFormBlock;
|
||||
$oSubFormBlock->SetParent($this);
|
||||
|
||||
@@ -21,9 +21,4 @@ class TextAreaFormBlock extends AbstractFormBlock
|
||||
return TextareaType::class;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function InitOptions(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,5 @@ class TextFormBlock extends AbstractFormBlock
|
||||
return TextType::class;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function InitOptions(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,12 +28,11 @@ class AttributeChoiceFormBlock extends ChoiceFormBlock
|
||||
public const OUTPUT_ATTRIBUTE = 'attribute';
|
||||
|
||||
/** @inheritdoc */
|
||||
public function InitOptions(): array
|
||||
public function InitBlockOptions(array &$aUserOptions): void
|
||||
{
|
||||
$aOptions = parent::InitOptions();
|
||||
parent::InitBlockOptions($aUserOptions);
|
||||
|
||||
// $aOptions['placeholder'] = 'Select an attribute...';
|
||||
return $aOptions;
|
||||
$aUserOptions['placeholder'] = 'Select an attribute...';
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
@@ -50,32 +49,13 @@ class AttributeChoiceFormBlock extends ChoiceFormBlock
|
||||
$this->AddOutput(self::OUTPUT_ATTRIBUTE, AttributeIOFormat::class, new StringToAttributeConverter());
|
||||
}
|
||||
|
||||
/** @inheritdoc
|
||||
* @throws FormBlockException
|
||||
*/
|
||||
public function AllowAdd(): bool
|
||||
/** @inheritdoc */
|
||||
public function UpdateDynamicOptions(string $sEventType = null): void
|
||||
{
|
||||
return $this->GetInput(self::INPUT_CLASS_NAME)->Value() != '';
|
||||
}
|
||||
|
||||
/** @inheritdoc
|
||||
* @throws FormBlockException
|
||||
* @throws CoreException
|
||||
*/
|
||||
public function UpdateOptions(): array
|
||||
{
|
||||
$aOptions = parent::GetOptions();
|
||||
|
||||
$oValue = $this->GetInput(self::INPUT_CLASS_NAME)->Value();
|
||||
if ($oValue == '') {
|
||||
return $aOptions;
|
||||
}
|
||||
$oValue = $this->GetInput(self::INPUT_CLASS_NAME)->GetValue($sEventType);
|
||||
|
||||
$aAttributeCodes = MetaModel::GetAttributesList($oValue);
|
||||
$aAttributeCodes = array_combine($aAttributeCodes, $aAttributeCodes);
|
||||
$aOptions['choices'] = $aAttributeCodes;
|
||||
|
||||
return $aOptions;
|
||||
$this->aDynamicOptions['choices'] = array_combine($aAttributeCodes, $aAttributeCodes);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,15 +29,14 @@ class AttributeValueChoiceFormBlock extends ChoiceFormBlock
|
||||
public const OUTPUT_VALUE = 'value';
|
||||
|
||||
/** @inheritdoc */
|
||||
public function InitOptions(array &$aOptions = []): array
|
||||
public function InitBlockOptions(array &$aUserOptions): void
|
||||
{
|
||||
$aOptions['multiple'] = true;
|
||||
$aOptions['attr'] = [
|
||||
parent::InitBlockOptions($aUserOptions);
|
||||
$aUserOptions['multiple'] = true;
|
||||
$aUserOptions['attr'] = [
|
||||
'size' => 5,
|
||||
'style' => 'height: auto;',
|
||||
];
|
||||
|
||||
return $aOptions;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
@@ -55,51 +54,18 @@ class AttributeValueChoiceFormBlock extends ChoiceFormBlock
|
||||
$this->AddOutput(self::OUTPUT_VALUE, RawFormat::class);
|
||||
}
|
||||
|
||||
/** @inheritdoc
|
||||
* @throws FormBlockException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function AllowAdd(): bool
|
||||
/** @inheritdoc */
|
||||
public function UpdateDynamicOptions(string $sEventType = null): void
|
||||
{
|
||||
$bDependentOk = $this->GetInput(self::INPUT_CLASS_NAME)->Value() != '' && $this->GetInput(self::INPUT_ATTRIBUTE)->Value() != '';
|
||||
$oClassName = $this->GetInput(self::INPUT_CLASS_NAME)->GetValue($sEventType);
|
||||
$oAttribute = $this->GetInput(self::INPUT_ATTRIBUTE)->GetValue($sEventType);
|
||||
|
||||
if ($bDependentOk) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->GetInput(self::INPUT_CLASS_NAME)->Value()->__toString(), $this->GetInput(self::INPUT_ATTRIBUTE)->Value()->__toString());
|
||||
try{
|
||||
$oAttDef = MetaModel::GetAttributeDef(strval($oClassName), strval($oAttribute));
|
||||
$aValues = $oAttDef->GetAllowedValues();
|
||||
|
||||
return $aValues != null;
|
||||
} else {
|
||||
return false;
|
||||
$this->aDynamicOptions['choices'] = array_flip($aValues ?? []);
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritdoc
|
||||
* @throws Exception
|
||||
*/
|
||||
public function UpdateOptions(): array
|
||||
{
|
||||
$aOptions = parent::GetOptions();
|
||||
|
||||
$oClassName = $this->GetInput(self::INPUT_CLASS_NAME)->Value();
|
||||
if ($oClassName == '') {
|
||||
return $aOptions;
|
||||
}
|
||||
|
||||
$oAttribute = $this->GetInput(self::INPUT_ATTRIBUTE)->Value();
|
||||
if ($oAttribute == '') {
|
||||
return $aOptions;
|
||||
}
|
||||
|
||||
$oAttDef = MetaModel::GetAttributeDef(strval($oClassName), strval($oAttribute));
|
||||
$aValues = $oAttDef->GetAllowedValues();
|
||||
|
||||
if ($aValues === null) {
|
||||
return $aOptions;
|
||||
}
|
||||
|
||||
$aOptions['choices'] = array_flip($aValues ?? []);
|
||||
|
||||
return $aOptions;
|
||||
catch(Exception){}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,13 +35,9 @@ class OqlFormBlock extends TextAreaFormBlock
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function InitOptions(): array
|
||||
public function InitBlockOptions(array &$aUserOptions): void
|
||||
{
|
||||
$aOptions = parent::InitOptions();
|
||||
$aOptions['with_ai_button'] = true;
|
||||
|
||||
return $aOptions;
|
||||
parent::InitBlockOptions($aUserOptions);
|
||||
$aUserOptions['with_ai_button'] = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\FormType;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
|
||||
class AttributeFormType extends AbstractType
|
||||
{
|
||||
public function getParent(): string
|
||||
{
|
||||
return ChoiceFormType::class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\FormType;
|
||||
|
||||
use MetaModel;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
|
||||
class AttributeValueFormType extends AbstractType
|
||||
{
|
||||
public function getParent(): string
|
||||
{
|
||||
return ChoiceFormType::class;
|
||||
}
|
||||
|
||||
public static function GetOptionsFromInputs(array $inputs): array
|
||||
{
|
||||
$aValues = [];
|
||||
|
||||
if (!empty($inputs['attribute'])) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($inputs['object_class'], $inputs['attribute']);
|
||||
$aValues = $oAttDef->GetAllowedValues();
|
||||
$aValues = $aValues !== null ? array_combine($aValues, $aValues) : [];
|
||||
}
|
||||
|
||||
return [
|
||||
'choices' => $aValues,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,20 @@ class ChoiceFormType extends AbstractType
|
||||
// on pre submit
|
||||
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (PreSubmitEvent $event) use ($options) {
|
||||
|
||||
if($options['multiple'] === false && $options['required'] === true) {
|
||||
if ($event->getData() === null) {
|
||||
$FirstElement = array_shift($options['choices']);
|
||||
if($FirstElement !== null){
|
||||
$event->setData($FirstElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// on pre submit
|
||||
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (PreSubmitEvent $event) use ($options){
|
||||
|
||||
// reset value if not in available choices
|
||||
if (!empty($event->getData()) && !$this->CheckValue($event->getData(), $options)) {
|
||||
$event->getForm()->addError(new FormError("The value has been reset because it is not part of the available choices anymore."));
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace Combodo\iTop\Forms\Block\FormType;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
@@ -21,16 +23,22 @@ class CollectionFormType extends AbstractType
|
||||
return CollectionType::class;
|
||||
}
|
||||
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
/** @inheritdoc */
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
parent::configureOptions($resolver);
|
||||
|
||||
$resolver->setDefined([
|
||||
'block_entry_type',
|
||||
'block_entry_options',
|
||||
$resolver->setDefaults([
|
||||
'button_label' => 'Add an item',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function buildView(FormView $view, FormInterface $form, array $options): void
|
||||
{
|
||||
parent::buildView($view, $form, $options);
|
||||
|
||||
$view->vars['button_label'] = $options['button_label'];
|
||||
}
|
||||
|
||||
}
|
||||
47
sources/Forms/Block/FormType/FormType.php
Normal file
47
sources/Forms/Block/FormType/FormType.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\FormType;
|
||||
|
||||
use Combodo\iTop\Forms\Block\Base\FormBlock;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
|
||||
class FormType extends AbstractType
|
||||
{
|
||||
public function getParent(): string
|
||||
{
|
||||
return \Symfony\Component\Form\Extension\Core\Type\FormType::class;
|
||||
}
|
||||
|
||||
|
||||
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||
{
|
||||
parent::buildView($view, $form, $options);
|
||||
|
||||
/** @var FormBlock $oBlock */
|
||||
$oBlock = $options['form_block'];
|
||||
|
||||
$aData = [];
|
||||
foreach($oBlock->GetChildren() as $oChild) {
|
||||
|
||||
if($oChild->IsAdded()){
|
||||
$oFormChild = $form->get($oChild->GetName());
|
||||
$aData[] = [
|
||||
'name' => $oChild->GetName(),
|
||||
'added' => $oChild->IsAdded(),
|
||||
'path' => $oFormChild->getPropertyPath(),
|
||||
];
|
||||
}
|
||||
else{
|
||||
$aData[] = [
|
||||
'name' => $oChild->GetName(),
|
||||
'added' => $oChild->IsAdded(),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
$view->vars['blocks'] = $aData;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,25 +6,21 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\FormType;
|
||||
|
||||
use Combodo\iTop\Forms\Block\IO\Converter\OqlToClassConverter;
|
||||
use Exception;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Event\PostSubmitEvent;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class OqlFormType extends AbstractType
|
||||
{
|
||||
/** @inheritdoc */
|
||||
public function getParent(): string
|
||||
{
|
||||
return TextareaType::class;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefault('help', 'An OQL query expression');
|
||||
@@ -48,26 +44,7 @@ class OqlFormType extends AbstractType
|
||||
$resolver->setDefined('with_ai_button');
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
parent::buildForm($builder, $options);
|
||||
|
||||
// on pre submit
|
||||
$builder->addEventListener(FormEvents::POST_SUBMIT, function (PostSubmitEvent $event) use ($options) {
|
||||
|
||||
try {
|
||||
$oClassConverter = new OqlToClassConverter();
|
||||
$oClassConverter->Convert($event->getData());
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$event->getForm()->addError(new FormError($e->getMessage()));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
/** @inheritdoc */
|
||||
public function buildView(FormView $view, FormInterface $form, array $options): void
|
||||
{
|
||||
parent::buildView($view, $form, $options);
|
||||
|
||||
@@ -107,12 +107,15 @@ class AbstractFormIO
|
||||
/**
|
||||
* Get the IO value.
|
||||
*
|
||||
* @param string $sEventType
|
||||
* @param string|null $sEventType
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetValue(string $sEventType): mixed
|
||||
public function GetValue(string $sEventType = null): mixed
|
||||
{
|
||||
if($sEventType === null) {
|
||||
return $this->Value();
|
||||
}
|
||||
return $this->aValues[$sEventType] ?? null;
|
||||
}
|
||||
|
||||
@@ -123,10 +126,22 @@ class AbstractFormIO
|
||||
*/
|
||||
public function HasValue(): bool
|
||||
{
|
||||
$PostSetDataExist = array_key_exists(FormEvents::POST_SET_DATA, $this->aValues) && $this->aValues[FormEvents::POST_SET_DATA] !== null;
|
||||
$PostSubmitExist = array_key_exists(FormEvents::POST_SUBMIT, $this->aValues) && $this->aValues[FormEvents::POST_SUBMIT] !== null;
|
||||
return $this->HasEventValue(FormEvents::POST_SET_DATA) || $this->HasEventValue(FormEvents::POST_SUBMIT);
|
||||
}
|
||||
|
||||
return $PostSetDataExist || $PostSubmitExist;
|
||||
/**
|
||||
* Return true if value exist.
|
||||
*
|
||||
* @param string|null $sEventType
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasEventValue(string $sEventType = null): bool
|
||||
{
|
||||
if($sEventType === null){
|
||||
return $this->HasValue();
|
||||
}
|
||||
return array_key_exists($sEventType, $this->aValues) && $this->aValues[$sEventType] !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,7 +173,7 @@ class AbstractFormIO
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function Value(): mixed
|
||||
private function Value(): mixed
|
||||
{
|
||||
if (array_key_exists(FormEvents::POST_SUBMIT, $this->aValues)) {
|
||||
return $this->aValues[FormEvents::POST_SUBMIT];
|
||||
|
||||
@@ -29,7 +29,7 @@ class OqlToClassConverter extends AbstractConverter
|
||||
if (isset($aMatches[1])) {
|
||||
$sSelectedClass = $aMatches[1];
|
||||
if (!MetaModel::IsValidClass($sSelectedClass)) {
|
||||
throw new IOException('Incorrect OQL select class name '.$sSelectedClass);
|
||||
throw new IOException("Class `$sSelectedClass` not found");
|
||||
}
|
||||
|
||||
return new ClassIOFormat($aMatches[1]);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\IO\Converter;
|
||||
|
||||
use Combodo\iTop\Forms\Block\IO\Format\BooleanIOFormat;
|
||||
|
||||
/**
|
||||
* OQL expression to class converter.
|
||||
*/
|
||||
class StringToBooleanConverter extends AbstractConverter
|
||||
{
|
||||
/** @inheritdoc */
|
||||
public function Convert(mixed $oData): ?BooleanIOFormat
|
||||
{
|
||||
return new BooleanIOFormat($oData );
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,15 @@ class FormInput extends AbstractFormIO
|
||||
return $this->HasValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $sEventType
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IsEventDataReady(string $sEventType = null): bool
|
||||
{
|
||||
return $this->HasEventValue($sEventType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the values of the input.
|
||||
|
||||
@@ -17,7 +17,6 @@ class FormOutput extends AbstractFormIO
|
||||
/** @var AbstractConverter|null */
|
||||
private null|AbstractConverter $oConverter;
|
||||
|
||||
|
||||
/** @var array */
|
||||
private array $aBindingsToOutputs = [];
|
||||
|
||||
@@ -113,4 +112,9 @@ class FormOutput extends AbstractFormIO
|
||||
{
|
||||
return $this->aBindingsToInputs;
|
||||
}
|
||||
|
||||
public function HasBindings(): bool
|
||||
{
|
||||
return count($this->aBindingsToInputs) > 0;
|
||||
}
|
||||
}
|
||||
28
sources/Forms/Block/IO/Format/BooleanIOFormat.php
Normal file
28
sources/Forms/Block/IO/Format/BooleanIOFormat.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\IO\Format;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
class BooleanIOFormat implements JsonSerializable
|
||||
{
|
||||
public function __construct(public bool $bValue)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function IsTrue(): bool
|
||||
{
|
||||
return $this->bValue;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->bValue ? 'true' : 'false';
|
||||
}
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return $this->bValue;
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,6 @@
|
||||
namespace Combodo\iTop\Forms\FormBuilder;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Combodo\iTop\Forms\Block\Base\FormBlock;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
@@ -55,10 +53,10 @@ class DependencyHandler
|
||||
// Add form ready listener
|
||||
$this->AddFormReadyListener();
|
||||
|
||||
// Check the dependencies
|
||||
// Check the dependencies (handle internal binding)
|
||||
$this->CheckDependencies($this->oFormBuilder);
|
||||
|
||||
// Store the dependency handler
|
||||
// Store the dependency handler (debug purpose)
|
||||
self::$aDependencyHandlers[] = $this;
|
||||
}
|
||||
|
||||
@@ -86,7 +84,7 @@ class DependencyHandler
|
||||
$this->oFormBuilder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
|
||||
|
||||
/** Iterate throw listened blocks */
|
||||
foreach ($this->oDependenciesMap->GetListenedOutputBlockNames() as $sOutputBlockName) {
|
||||
foreach ($this->oDependenciesMap->GetInitialBoundOutputBlockNames() as $sOutputBlockName) {
|
||||
|
||||
// inner binding
|
||||
if ($sOutputBlockName === $this->oFormBlock->getName()) {
|
||||
@@ -133,12 +131,10 @@ class DependencyHandler
|
||||
$oFormBlock = $this->aSubBlocks[$oForm->getName()];
|
||||
|
||||
// Compute the block outputs with the data
|
||||
if (!$oFormBlock instanceof FormBlock) {
|
||||
$oFormBlock->ComputeOutputs($sEventType, $oEvent->getData());
|
||||
}
|
||||
$oFormBlock->ComputeOutputs($sEventType, $oForm->getData());
|
||||
|
||||
// Check dependencies
|
||||
$this->CheckDependencies($oForm->getParent());
|
||||
$this->CheckDependencies($oForm->getParent(), $oForm->getName(), $sEventType);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -146,18 +142,32 @@ class DependencyHandler
|
||||
|
||||
/**
|
||||
* @param FormInterface|FormBuilderInterface $oForm
|
||||
* @param string|null $sOutputBlock
|
||||
* @param string|null $sEventType
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function CheckDependencies(FormInterface|FormBuilderInterface $oForm): void
|
||||
private function CheckDependencies(FormInterface|FormBuilderInterface $oForm, string $sOutputBlock = null, string $sEventType = null): void
|
||||
{
|
||||
$aImpactedBlocks = $this->aDependentBlocks;
|
||||
if($sOutputBlock !== null){
|
||||
$aImpactedBlocks = $this->oDependenciesMap->GetBlocksDependingOn($sOutputBlock);
|
||||
}
|
||||
|
||||
if($aImpactedBlocks === null){
|
||||
return;
|
||||
}
|
||||
|
||||
/** Iterate throw dependencies... @var AbstractFormBlock $oDependentBlock */
|
||||
foreach ($this->aDependentBlocks as $qBlockName => $oDependentBlock) {
|
||||
// When dependencies met, add the dependent field if not already done
|
||||
if (!$oDependentBlock->IsAdded() && $oDependentBlock->IsInputsDataReady()) {
|
||||
foreach ($aImpactedBlocks as $qBlockName => $oDependentBlock) {
|
||||
|
||||
|
||||
// When dependencies met, add the dependent field if not already done or options changed
|
||||
if ($oDependentBlock->IsVisible($sEventType) && $oDependentBlock->IsInputsDataReady($sEventType)) {
|
||||
|
||||
// Get the dependent field options
|
||||
$aOptions = $oDependentBlock->UpdateOptions();
|
||||
$oDependentBlock->UpdateDynamicOptions($sEventType);
|
||||
$aOptions = $oDependentBlock->GetOptionsMergedWithDynamic($sEventType);
|
||||
|
||||
// Add the listener callback to the dependent field if it is also a dependency for another field
|
||||
if ($this->oDependenciesMap->IsTheBlockInDependencies($oDependentBlock->getName())) {
|
||||
@@ -168,7 +178,7 @@ class DependencyHandler
|
||||
]);
|
||||
}
|
||||
|
||||
if ($oDependentBlock->AllowAdd()) {
|
||||
if ($oDependentBlock->AllowAdd($sEventType)) {
|
||||
|
||||
$this->aDebugData[] = [
|
||||
'builder' => $this->oFormBuilder->getName(),
|
||||
@@ -180,7 +190,7 @@ class DependencyHandler
|
||||
if (array_key_exists('builder_listener', $aOptions)) {
|
||||
$this->aDebugData[] = [
|
||||
'builder' => $this->oFormBuilder->getName(),
|
||||
'event' => 'form.listen',
|
||||
'event' => 'form.listen.after',
|
||||
'form' => $oDependentBlock->getName(),
|
||||
'value' => 'NA',
|
||||
];
|
||||
@@ -196,11 +206,16 @@ class DependencyHandler
|
||||
|
||||
}
|
||||
|
||||
if ($oDependentBlock->IsAdded() && !$oDependentBlock->IsInputsDataReady()) {
|
||||
$oForm->add($oDependentBlock->GetName(), HiddenType::class, [
|
||||
'form_block' => $oDependentBlock,
|
||||
'prevent_form_build' => true,
|
||||
]);
|
||||
if ($oDependentBlock->IsAdded() && (!$oDependentBlock->IsVisible($sEventType) || !$oDependentBlock->IsInputsDataReady($sEventType))) {
|
||||
$oForm->remove($oDependentBlock->GetName());
|
||||
$oDependentBlock->SetAdded(false);
|
||||
|
||||
$this->aDebugData[] = [
|
||||
'builder' => $this->oFormBuilder->getName(),
|
||||
'event' => 'form.remove',
|
||||
'form' => $oDependentBlock->getName(),
|
||||
'value' => 'NA'
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\FormBuilder;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Combodo\iTop\Forms\Block\FormBlock;
|
||||
use Combodo\iTop\Forms\Block\IO\FormBinding;
|
||||
use Combodo\iTop\Forms\Block\IO\FormInput;
|
||||
use Combodo\iTop\Forms\Block\IO\FormOutput;
|
||||
@@ -16,22 +18,25 @@ use Combodo\iTop\Forms\Block\IO\FormOutput;
|
||||
*/
|
||||
class DependencyMap
|
||||
{
|
||||
/** @var array output to outputs map map */
|
||||
private array $aOutputToInputsMap = [];
|
||||
/** @var array array of blocks with dependencies group by dependence */
|
||||
private array $aBlocksWithDependenciesGroupByDependence = [];
|
||||
|
||||
/** @var array input to inputs map map */
|
||||
private array $aInputToInputsMap = [];
|
||||
/** @var array array of binding (OUT > OUT) grouped by block and output name */
|
||||
private array $aBindingsOutputToInput = [];
|
||||
|
||||
/** @var array output to outputs */
|
||||
private array $aOutputToOutputsMap = [];
|
||||
/** @var array array of binding (IN > IN) grouped by block and output name */
|
||||
private array $aBindingsInputToInput = [];
|
||||
|
||||
/** @var array array of binding (OUT > OUT) grouped by block and output name */
|
||||
private array $aBindingsOutputToOutputs = [];
|
||||
private readonly array $aDependentBlocks;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $aDependentBlocks
|
||||
* @param array $aBlocksWithDependencies
|
||||
*/
|
||||
public function __construct(array $aDependentBlocks)
|
||||
public function __construct(array $aBlocksWithDependencies)
|
||||
{
|
||||
$this->aDependentBlocks = $aDependentBlocks;
|
||||
// Initialization
|
||||
@@ -45,21 +50,23 @@ class DependencyMap
|
||||
*/
|
||||
private function Init(): void
|
||||
{
|
||||
/** Iterate throw blocks with dependencies... @var \Combodo\iTop\Forms\Block\Base\FormBlock $oDependentBlock */
|
||||
foreach ($this->aDependentBlocks as $sBlockName => $oDependentBlock) {
|
||||
/** Iterate throw blocks with dependencies... @var AbstractFormBlock $oDependentBlock */
|
||||
foreach ($this->aBlocksWithDependencies as $oDependentBlock) {
|
||||
|
||||
/** Iterate throw the block inputs bindings... @var FormBinding $oBinding * */
|
||||
foreach ($oDependentBlock->GetInputsBindings() as $oBinding) {
|
||||
|
||||
// Output to inputs map
|
||||
// OUT > IN
|
||||
if ($oBinding->oSourceIO instanceof FormOutput
|
||||
&& $oBinding->oDestinationIO instanceof FormInput) {
|
||||
$this->AddBindingToMap($this->aOutputToInputsMap, $oBinding);
|
||||
$this->AddBindingToMap($this->aBindingsOutputToInput, $oBinding);
|
||||
$this->AddToBlockWithDependenciesMap($oBinding->oSourceIO->GetOwnerBlock()->GetName(), $oDependentBlock);
|
||||
}
|
||||
// Input to inputs map
|
||||
|
||||
// IN > IN
|
||||
if ($oBinding->oSourceIO instanceof FormInput
|
||||
&& $oBinding->oDestinationIO instanceof FormInput) {
|
||||
$this->AddBindingToMap($this->aInputToInputsMap, $oBinding);
|
||||
$this->AddBindingToMap($this->aBindingsInputToInput, $oBinding);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -67,16 +74,45 @@ class DependencyMap
|
||||
/** Iterate throw the block inputs connections... @var FormBinding $oBinding * */
|
||||
foreach ($oDependentBlock->GetOutputBindings() as $oBinding) {
|
||||
|
||||
// Output to outputs map
|
||||
// OUT > OUT
|
||||
if ($oBinding->oSourceIO instanceof FormOutput
|
||||
&& $oBinding->oDestinationIO instanceof FormOutput) {
|
||||
$this->AddBindingToMap($this->aOutputToOutputsMap, $oBinding);
|
||||
$this->AddBindingToMap($this->aBindingsOutputToOutputs, $oBinding);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDependenceBlockName
|
||||
* @param AbstractFormBlock $oBlockWithDependencies
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function AddToBlockWithDependenciesMap(string $sDependenceBlockName, AbstractFormBlock $oBlockWithDependencies): void
|
||||
{
|
||||
// Initialize array for this dependence
|
||||
if(!array_key_exists($sDependenceBlockName, $this->aBlocksWithDependenciesGroupByDependence)){
|
||||
$this->aBlocksWithDependenciesGroupByDependence[$sDependenceBlockName] = [];
|
||||
}
|
||||
|
||||
// Add the block
|
||||
$this->aBlocksWithDependenciesGroupByDependence[$sDependenceBlockName][$oBlockWithDependencies->GetName()] = $oBlockWithDependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sBlockName
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function GetBlocksDependingOn(string $sBlockName): ?array
|
||||
{
|
||||
if(!array_key_exists($sBlockName,$this->aBlocksWithDependenciesGroupByDependence)){
|
||||
return null;
|
||||
}
|
||||
return $this->aBlocksWithDependenciesGroupByDependence[$sBlockName] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,12 +144,15 @@ class DependencyMap
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function GetListenedOutputBlockNames(): array
|
||||
public function GetInitialBoundOutputBlockNames(): array
|
||||
{
|
||||
$aResult = [];
|
||||
|
||||
foreach (array_keys($this->aOutputToInputsMap) as $sOutputBlockName) {
|
||||
if (!array_key_exists($sOutputBlockName, $this->aDependentBlocks)) {
|
||||
// Iterate throw binding OUT > IN
|
||||
foreach (array_keys($this->aBindingsOutputToInput) as $sOutputBlockName) {
|
||||
|
||||
// Exclude block containing dependencies
|
||||
if (!array_key_exists($sOutputBlockName, $this->aBlocksWithDependencies)) {
|
||||
$aResult[] = $sOutputBlockName;
|
||||
}
|
||||
}
|
||||
@@ -143,7 +182,7 @@ class DependencyMap
|
||||
*/
|
||||
public function IsBlockHasOutputs(string $sBlockName): bool
|
||||
{
|
||||
return array_key_exists($sBlockName, $this->aOutputToInputsMap);
|
||||
return array_key_exists($sBlockName, $this->aBindingsOutputToInput);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,37 +192,39 @@ class DependencyMap
|
||||
*/
|
||||
public function GetOutputsForBlock(string $sBlockName): array
|
||||
{
|
||||
return array_keys($this->aOutputToInputsMap[$sBlockName]);
|
||||
return array_keys($this->aBindingsOutputToInput[$sBlockName]);
|
||||
}
|
||||
|
||||
public function GetOutputsDependenciesForBlock(string $sOutputBlockName): array
|
||||
{
|
||||
return $this->aOutputToInputsMap[$sOutputBlockName];
|
||||
return $this->aBindingsOutputToInput[$sOutputBlockName];
|
||||
}
|
||||
|
||||
public function IsTheBlockInDependencies(string $sBlockName): bool
|
||||
{
|
||||
foreach ($this->aDependentBlocks as $oDependentBlock) {
|
||||
if ($oDependentBlock->getName() === $sBlockName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
// foreach ($this->aDependentBlocks as $oDependentBlock)
|
||||
// {
|
||||
// if($oDependentBlock->getName() === $sBlockName) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
return $this->GetBlocksDependingOn($sBlockName) !== null;
|
||||
}
|
||||
|
||||
public function GetOutputToInputs(): array
|
||||
{
|
||||
return $this->aOutputToInputsMap;
|
||||
return $this->aBindingsOutputToInput;
|
||||
}
|
||||
|
||||
public function GetInputToInputs(): array
|
||||
{
|
||||
return $this->aInputToInputsMap;
|
||||
return $this->aBindingsInputToInput;
|
||||
}
|
||||
|
||||
public function GetOutputToOutputs(): array
|
||||
{
|
||||
return $this->aOutputToOutputsMap;
|
||||
return $this->aBindingsOutputToOutputs;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Form\DataMapperInterface;
|
||||
use Symfony\Component\Form\DataTransformerInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormConfigInterface;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
@@ -32,7 +31,7 @@ class FormBuilder implements FormBuilderInterface, IteratorAggregate
|
||||
private AbstractFormBlock $oFormBlock;
|
||||
|
||||
/** @var array sub blocks */
|
||||
private array $aSubFormBlocks = [];
|
||||
private array $aChildren = [];
|
||||
private readonly FormBuilderInterface $builder;
|
||||
|
||||
/**
|
||||
@@ -68,26 +67,26 @@ class FormBuilder implements FormBuilderInterface, IteratorAggregate
|
||||
return;
|
||||
}
|
||||
|
||||
$aDependentBlocks = [];
|
||||
$aBlocksWithDependencies = [];
|
||||
/** Iterate throw the form sub blocks... @var FormBlock $oSubFormBlock */
|
||||
foreach ($oFormBlock->GetChildren() as $oSubFormBlock) {
|
||||
foreach ($oFormBlock->GetChildren() as $sBlockName => $oChildBlock) {
|
||||
|
||||
// Add to the sub blocks array
|
||||
$this->aSubFormBlocks[$oSubFormBlock->getName()] = $oSubFormBlock;
|
||||
// Add to the children
|
||||
$this->aChildren[$sBlockName] = $oChildBlock;
|
||||
|
||||
// Handle sub block
|
||||
$bHasDependency = $this->HandleSubBlock($oSubFormBlock);
|
||||
// Handle block
|
||||
$bHasDependency = $this->HandleSubBlock($oChildBlock);
|
||||
|
||||
// Add to the dependencies array
|
||||
// Add to the array of blocks with dependencies
|
||||
if ($bHasDependency) {
|
||||
$aDependentBlocks[$oSubFormBlock->GetName()] = $oSubFormBlock;
|
||||
$aBlocksWithDependencies[$sBlockName] = $oChildBlock;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Create a dependency handler if needed
|
||||
if (count($aDependentBlocks) > 0) {
|
||||
$this->oDependencyHandler = new DependencyHandler($this->builder->getName(), $oFormBlock, $this, $this->aSubFormBlocks, $aDependentBlocks);
|
||||
if (count($aBlocksWithDependencies) > 0) {
|
||||
$this->oDependencyHandler = new DependencyHandler($this->builder->getName(), $oFormBlock, $this, $this->aChildren, $aBlocksWithDependencies);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,19 +103,19 @@ class FormBuilder implements FormBuilderInterface, IteratorAggregate
|
||||
// Has dependencies blocks
|
||||
if ($oSubFormBlock->HasDependenciesBlocks()) {
|
||||
|
||||
// Insert a hidden type to save the place
|
||||
$this->builder->add($oSubFormBlock->GetName(), HiddenType::class, [
|
||||
'form_block' => $oSubFormBlock,
|
||||
'prevent_form_build' => true,
|
||||
// 'mapped' => false,
|
||||
// 'disabled' => true,
|
||||
]);
|
||||
// // Insert a hidden type to save the place
|
||||
// $this->builder->add($oSubFormBlock->GetName(), HiddenType::class, [
|
||||
// 'form_block' => $oSubFormBlock,
|
||||
// 'prevent_form_build' => true,
|
||||
//// 'mapped' => false,
|
||||
//// 'disabled' => true,
|
||||
// ]);
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
// Directly insert the block corresponding form type
|
||||
$this->add($oSubFormBlock->GetName(), $oSubFormBlock->GetFormType(), $oSubFormBlock->UpdateOptions());
|
||||
$this->add($oSubFormBlock->GetName(), $oSubFormBlock->GetFormType(), $oSubFormBlock->GetOptions());
|
||||
$oSubFormBlock->SetAdded(true);
|
||||
|
||||
return false;
|
||||
@@ -125,15 +124,15 @@ class FormBuilder implements FormBuilderInterface, IteratorAggregate
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a sub form block.
|
||||
* Get a child block.
|
||||
*
|
||||
* @param string $sName
|
||||
*
|
||||
* @return AbstractFormBlock|null
|
||||
*/
|
||||
public function GetSubFormBlock(string $sName): ?AbstractFormBlock
|
||||
public function GetChild(string $sName): ?AbstractFormBlock
|
||||
{
|
||||
return $this->aSubFormBlocks[$sName] ?? null;
|
||||
return $this->aChildren[$sName] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
8
sources/Forms/IFormBlock.php
Normal file
8
sources/Forms/IFormBlock.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Forms;
|
||||
|
||||
interface IFormBlock
|
||||
{
|
||||
|
||||
}
|
||||
@@ -3,13 +3,28 @@
|
||||
{# Widgets #}
|
||||
|
||||
{%- block widget_attributes -%}
|
||||
{{- parent() -}}
|
||||
{% if trigger_form_submit_on_modify %}
|
||||
onChange="this.form.setAttribute('novalidate', true); this.form.requestSubmit();console.log('Auto submitting form due to change in field {{ full_name }}');"
|
||||
{% endif %}
|
||||
{%- endblock widget_attributes -%}
|
||||
|
||||
{%- block form_widget_simple -%}
|
||||
{% if type == 'text' %}{% set ibo_class='ibo-input-string' %}{% else %}{% set ibo_class='ibo-input-' ~ type %}{% endif %}
|
||||
{% set attr = attr|merge({class: (attr.class|default('') ~ ' ibo-input ' ~ ibo_class)|trim}) %}
|
||||
{{- parent() -}}
|
||||
{% if trigger_form_submit_on_modify %}
|
||||
onChange="this.form.requestSubmit();console.log('Auto submitting form due to change in field {{ full_name }}');"
|
||||
{% endif %}
|
||||
{%- endblock widget_attributes -%}
|
||||
{%- endblock form_widget_simple -%}
|
||||
|
||||
{%- block textarea_widget -%}
|
||||
{% if type == 'text' %}{% set ibo_class='ibo-input-string' %}{% else %}{% set ibo_class='ibo-input-' ~ type %}{% endif %}
|
||||
{% set attr = attr|merge({class: (attr.class|default('') ~ ' ibo-input ' ~ ibo_class)|trim}) %}
|
||||
{{- parent() -}}
|
||||
{%- endblock textarea_widget -%}
|
||||
|
||||
{%- block choice_widget_collapsed -%}
|
||||
{% set attr = attr|merge({class: (attr.class|default('') ~ ' ibo-input')|trim}) %}
|
||||
{{- parent() -}}
|
||||
{%- endblock choice_widget_collapsed -%}
|
||||
|
||||
{%- block form_label -%}
|
||||
{%- if compound is defined and compound -%}
|
||||
@@ -20,13 +35,31 @@
|
||||
{{- parent() -}}
|
||||
{%- endblock form_label -%}
|
||||
|
||||
{%- block form_rows -%}
|
||||
{% for sId,child in form|filter(child => not child.rendered) %}
|
||||
<div id="block_{{ sId }}" class="ibo-field ibo-content-block ibo-block ibo-field-small">
|
||||
{{ form_row(child) }}
|
||||
{#{%- block form_rows -%}#}
|
||||
|
||||
{# {% for block in blocks %}#}
|
||||
{# <div id="block_{{ block.name }}" class="ibo-field ibo-content-block ibo-block ibo-field-small">#}
|
||||
{# {{ block.name }} {{ block.added }}#}
|
||||
{# {% if block.added == 1 %}#}
|
||||
{# {{ form_row(form[block.name]) }}#}
|
||||
{# {% endif %}#}
|
||||
{# </div>#}
|
||||
{# {% endfor %}#}
|
||||
|
||||
{#{%- endblock form_rows -%}#}
|
||||
|
||||
{%- block collection_widget -%}
|
||||
{% if prototype is defined and not prototype.rendered %}
|
||||
{%- set attr = attr|merge({'data-prototype': form_row(prototype), 'class': name, 'data-index': form|length > 0 ? form|last.vars.name + 1 : 0 }) -%}
|
||||
{% endif %}
|
||||
{{- block('form_widget') -}}
|
||||
{% if allow_add %}
|
||||
<div style="margin-top: 20px;">
|
||||
<button type="button" class="add_item_link ibo-button ibo-button ibo-is-regular " data-collection-holder-class="{{ name }}">{{ button_label|dict_s }}</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{%- endblock form_rows -%}
|
||||
{% endif %}
|
||||
{%- endblock collection_widget -%}
|
||||
|
||||
|
||||
{%- block form_label_content -%}
|
||||
{{- parent() -}}
|
||||
|
||||
15
tests/php-unit-tests/unitary-tests/sources/Forms/Binding.php
Normal file
15
tests/php-unit-tests/unitary-tests/sources/Forms/Binding.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Forms;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
|
||||
class Binding extends ItopDataTestCase
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
92
tests/php-unit-tests/unitary-tests/sources/Forms/Block.php
Normal file
92
tests/php-unit-tests/unitary-tests/sources/Forms/Block.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Forms;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
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;
|
||||
use Combodo\iTop\Forms\Forms;
|
||||
use Combodo\iTop\Forms\IFormBlock;
|
||||
use Combodo\iTop\Service\InterfaceDiscovery\InterfaceDiscovery;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use OutOfBoundsException;
|
||||
use ReflectionException;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
|
||||
class Block extends ItopDataTestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function testBlockFormType()
|
||||
{
|
||||
$oChoiceBlock = new ChoiceFormBlock('choiceBlock');
|
||||
$test = new \ReflectionClass($oChoiceBlock->GetFormType());
|
||||
$this->assertTrue($test->isSubclassOf(AbstractType::class));
|
||||
|
||||
$oFormBlock = new ChoiceFormBlock('formBlock');
|
||||
$test = new \ReflectionClass($oFormBlock->GetFormType());
|
||||
$this->assertTrue($test->isSubclassOf(AbstractType::class));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass a Symfony type instead of a FormBlock type will raise an exception
|
||||
*
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function testAddBlockFromSymfonyType()
|
||||
{
|
||||
$oFormBlock = new FormBlock('formBlock');
|
||||
$this->expectException(FormBlockException::class);
|
||||
$oFormBlock->Add('wrong', TextType::class, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* All block may contain a reference to themselves in their options
|
||||
*/
|
||||
public function testBlockOptionsContainsBlockReference()
|
||||
{
|
||||
$aFormBlocks = InterfaceDiscovery::GetInstance()->FindItopClasses(iFormBlock::class);
|
||||
foreach ($aFormBlocks as $sFormBlock) {
|
||||
$oChoiceBlock = new($sFormBlock)($sFormBlock);
|
||||
$this->assertTrue($oChoiceBlock->GetOptions()['form_block'] === $oChoiceBlock);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Dependent fields are not added to the form directly.
|
||||
*
|
||||
* @return void
|
||||
* @throws FormBlockException
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function testFormBlockNotContainsDependentFields()
|
||||
{
|
||||
// form with a dependent field
|
||||
$oFormBlock = new FormBlock('formBlock');
|
||||
$oFormBlock->Add('firstname', TextFormBlock::class, []);
|
||||
$oFormBlock->Add('lastname', TextFormBlock::class, []);
|
||||
$oFormBlock->Add('allow_age', CheckboxFormBlock::class, []);
|
||||
$oFormBlock->Add('birthdate', TextFormBlock::class, [])
|
||||
->DependsOn(AbstractFormBlock::INPUT_VISIBLE, 'allow_age', CheckboxFormBlock::OUTPUT_CHECKED);
|
||||
|
||||
// form builder
|
||||
$oFormFactoryBuilder = Forms::createFormFactoryBuilder();
|
||||
$oForm = $oFormFactoryBuilder->getFormFactory()->createNamedBuilder($oFormBlock->GetName(), $oFormBlock->GetFormType(), [], $oFormBlock->GetOptions())->getForm();
|
||||
|
||||
// try to get the dependent field
|
||||
$this->expectException(OutOfBoundsException::class);
|
||||
$oForm->get('birthdate');
|
||||
}
|
||||
}
|
||||
23
tests/php-unit-tests/unitary-tests/sources/Forms/BlockIO.php
Normal file
23
tests/php-unit-tests/unitary-tests/sources/Forms/BlockIO.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Forms;
|
||||
|
||||
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;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use ReflectionException;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
|
||||
class BlockIO extends ItopDataTestCase
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
15
tests/php-unit-tests/unitary-tests/sources/Forms/Builder.php
Normal file
15
tests/php-unit-tests/unitary-tests/sources/Forms/Builder.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Forms;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
|
||||
class Builder extends ItopDataTestCase
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user