diff --git a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php index a2a33fd89..02ee530a2 100644 --- a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php +++ b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php @@ -30,7 +30,7 @@ SetupWebPage::AddModule( // Identification // 'label' => 'Database maintenance tools', - 'category' => 'business', + 'category' => 'Application management', // Setup // diff --git a/datamodels/2.x/itop-core-update/module.itop-core-update.php b/datamodels/2.x/itop-core-update/module.itop-core-update.php index 9e4272e34..d243de687 100644 --- a/datamodels/2.x/itop-core-update/module.itop-core-update.php +++ b/datamodels/2.x/itop-core-update/module.itop-core-update.php @@ -30,7 +30,7 @@ SetupWebPage::AddModule( // Identification // 'label' => 'iTop Core Update', - 'category' => 'business', + 'category' => 'Application management', // Setup // diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index c3a3e74a4..d76a0e797 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -499,7 +499,11 @@ return array( 'Combodo\\iTop\\Forms\\Block\\Expression\\NumberExpressionFormBlock' => $baseDir . '/sources/Forms/Block/Expression/NumberExpressionFormBlock.php', 'Combodo\\iTop\\Forms\\Block\\FormBlockException' => $baseDir . '/sources/Forms/Block/FormBlockException.php', 'Combodo\\iTop\\Forms\\Block\\FormBlockHelper' => $baseDir . '/sources/Forms/Block/FormBlockHelper.php', + 'Combodo\\iTop\\Forms\\Block\\FormBlockService' => $baseDir . '/sources/Forms/Block/FormBlockService.php', 'Combodo\\iTop\\Forms\\Block\\IFormBlock' => $baseDir . '/sources/Forms/Block/IFormBlock.php', + 'Combodo\\iTop\\Forms\\Compiler\\FormsCompiler' => $baseDir . '/sources/Forms/Compiler/FormsCompiler.php', + 'Combodo\\iTop\\Forms\\Compiler\\FormsCompilerException' => $baseDir . '/sources/Forms/Compiler/FormsCompilerException.php', + 'Combodo\\iTop\\Forms\\Compiler\\FormsController' => $baseDir . '/sources/Forms/Compiler/FormsController.php', 'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => $baseDir . '/sources/Forms/FormBuilder/DependencyHandler.php', 'Combodo\\iTop\\Forms\\FormBuilder\\DependencyMap' => $baseDir . '/sources/Forms/FormBuilder/DependencyMap.php', 'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilder' => $baseDir . '/sources/Forms/FormBuilder/FormBuilder.php', @@ -537,6 +541,18 @@ return array( 'Combodo\\iTop\\Forms\\Validator\\AttributeExist' => $baseDir . '/sources/Forms/Validator/AttributeExist.php', 'Combodo\\iTop\\Forms\\Validator\\AttributeExistValidator' => $baseDir . '/sources/Forms/Validator/AttributeExistValidator.php', 'Combodo\\iTop\\PhpParser\\Evaluation\\PhpExpressionEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/PhpExpressionEvaluator.php', + 'Combodo\\iTop\\PropertyTree\\CollectionOfTrees' => $baseDir . '/sources/PropertyTree/CollectionOfTrees.php', + 'Combodo\\iTop\\PropertyTree\\CollectionOfValues' => $baseDir . '/sources/PropertyTree/CollectionOfValues.php', + 'Combodo\\iTop\\PropertyTree\\Property' => $baseDir . '/sources/PropertyTree/Property.php', + 'Combodo\\iTop\\PropertyTree\\PropertyTree' => $baseDir . '/sources/PropertyTree/PropertyTree.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeChoice' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeChoice.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttribute' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeClassAttribute.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttributeGroupBy' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeClassAttributeGroupBy.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttributeValue' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeClassAttributeValue.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeInteger' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeInteger.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeLabel' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeLabel.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeOQL' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeOQL.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeProfileName' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeProfileName.php', 'Combodo\\iTop\\Renderer\\BlockRenderer' => $baseDir . '/sources/Renderer/BlockRenderer.php', 'Combodo\\iTop\\Renderer\\Bootstrap\\BsFieldRendererMappings' => $baseDir . '/sources/Renderer/Bootstrap/BsFieldRendererMappings.php', 'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => $baseDir . '/sources/Renderer/Bootstrap/BsFormRenderer.php', @@ -3894,5 +3910,5 @@ return array( 'privUITransactionFile' => $baseDir . '/application/transaction.class.inc.php', 'privUITransactionSession' => $baseDir . '/application/transaction.class.inc.php', 'utils' => $baseDir . '/application/utils.inc.php', - '�' => $vendorDir . '/symfony/cache/Traits/ValueWrapper.php', + '©' => $vendorDir . '/symfony/cache/Traits/ValueWrapper.php', ); diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index 1c266fd0c..2c4e23ffe 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -885,7 +885,11 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Combodo\\iTop\\Forms\\Block\\Expression\\NumberExpressionFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Expression/NumberExpressionFormBlock.php', 'Combodo\\iTop\\Forms\\Block\\FormBlockException' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockException.php', 'Combodo\\iTop\\Forms\\Block\\FormBlockHelper' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockHelper.php', + 'Combodo\\iTop\\Forms\\Block\\FormBlockService' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockService.php', 'Combodo\\iTop\\Forms\\Block\\IFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/IFormBlock.php', + 'Combodo\\iTop\\Forms\\Compiler\\FormsCompiler' => __DIR__ . '/../..' . '/sources/Forms/Compiler/FormsCompiler.php', + 'Combodo\\iTop\\Forms\\Compiler\\FormsCompilerException' => __DIR__ . '/../..' . '/sources/Forms/Compiler/FormsCompilerException.php', + 'Combodo\\iTop\\Forms\\Compiler\\FormsController' => __DIR__ . '/../..' . '/sources/Forms/Compiler/FormsController.php', 'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/DependencyHandler.php', 'Combodo\\iTop\\Forms\\FormBuilder\\DependencyMap' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/DependencyMap.php', 'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilder' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/FormBuilder.php', @@ -923,6 +927,18 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Combodo\\iTop\\Forms\\Validator\\AttributeExist' => __DIR__ . '/../..' . '/sources/Forms/Validator/AttributeExist.php', 'Combodo\\iTop\\Forms\\Validator\\AttributeExistValidator' => __DIR__ . '/../..' . '/sources/Forms/Validator/AttributeExistValidator.php', 'Combodo\\iTop\\PhpParser\\Evaluation\\PhpExpressionEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/PhpExpressionEvaluator.php', + 'Combodo\\iTop\\PropertyTree\\CollectionOfTrees' => __DIR__ . '/../..' . '/sources/PropertyTree/CollectionOfTrees.php', + 'Combodo\\iTop\\PropertyTree\\CollectionOfValues' => __DIR__ . '/../..' . '/sources/PropertyTree/CollectionOfValues.php', + 'Combodo\\iTop\\PropertyTree\\Property' => __DIR__ . '/../..' . '/sources/PropertyTree/Property.php', + 'Combodo\\iTop\\PropertyTree\\PropertyTree' => __DIR__ . '/../..' . '/sources/PropertyTree/PropertyTree.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeChoice' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeChoice.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttribute' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeClassAttribute.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttributeGroupBy' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeClassAttributeGroupBy.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttributeValue' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeClassAttributeValue.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeInteger' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeInteger.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeLabel' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeLabel.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeOQL' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeOQL.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeProfileName' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeProfileName.php', 'Combodo\\iTop\\Renderer\\BlockRenderer' => __DIR__ . '/../..' . '/sources/Renderer/BlockRenderer.php', 'Combodo\\iTop\\Renderer\\Bootstrap\\BsFieldRendererMappings' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/BsFieldRendererMappings.php', 'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/BsFormRenderer.php', @@ -4280,7 +4296,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'privUITransactionFile' => __DIR__ . '/../..' . '/application/transaction.class.inc.php', 'privUITransactionSession' => __DIR__ . '/../..' . '/application/transaction.class.inc.php', 'utils' => __DIR__ . '/../..' . '/application/utils.inc.php', - '�' => __DIR__ . '/..' . '/symfony/cache/Traits/ValueWrapper.php', + '©' => __DIR__ . '/..' . '/symfony/cache/Traits/ValueWrapper.php', ); public static function getInitializer(ClassLoader $loader) diff --git a/sources/Application/UI/Base/Component/TurboForm/TurboFormUIBlockFactory.php b/sources/Application/UI/Base/Component/TurboForm/TurboFormUIBlockFactory.php index 691595e51..05ae68e5c 100644 --- a/sources/Application/UI/Base/Component/TurboForm/TurboFormUIBlockFactory.php +++ b/sources/Application/UI/Base/Component/TurboForm/TurboFormUIBlockFactory.php @@ -8,6 +8,9 @@ namespace Combodo\iTop\Application\UI\Base\Component\TurboForm; use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory; +use Combodo\iTop\Forms\Block\FormBlockService; +use Combodo\iTop\Forms\Compiler\FormsCompiler; +use Combodo\iTop\Forms\Compiler\FormsController; use Symfony\Component\Form\FormView; /** @@ -34,4 +37,26 @@ class TurboFormUIBlockFactory extends AbstractUIBlockFactory { return new TurboForm($oFormView, $sId); } + + /** + * @param string $sDashletId + * @param string|null $sAction + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\TurboForm\TurboForm + */ + public static function MakeForDashlet(string $sDashletId, string $sAction = null, string $sId = null): TurboForm + { + $oBlockForm = FormBlockService::GetInstance()->GetFormBlockById($sDashletId); + $oController = new FormsController(); + $oBuilder = $oController->GetFormBuilder($oBlockForm); + $oForm = $oBuilder->getForm(); + + $oTurboForm = new TurboForm($oForm->createView(), $sId); + if (!is_null($sAction)) { + $oTurboForm->SetAction($sAction); + } + + return $oTurboForm; + } } diff --git a/sources/Forms/Block/FormBlockService.php b/sources/Forms/Block/FormBlockService.php new file mode 100644 index 000000000..75753d5df --- /dev/null +++ b/sources/Forms/Block/FormBlockService.php @@ -0,0 +1,46 @@ +RegisterService('ModelReflection', $oModelReflection ?? new ModelReflectionRuntime()); + $this->oCacheService = DataModelDependantCache::GetInstance(); + } + + final public static function GetInstance(ModelReflection $oModelReflection = null): FormBlockService + { + if (!isset(static::$oInstance)) { + static::$oInstance = new FormBlockService($oModelReflection); + } + + return static::$oInstance; + } + + public function GetFormBlockById(string $sId): FormBlock + { + if ($this->oCacheService->HasEntry(FormsCompiler::CACHE_POOL, $sId)) { + $this->oCacheService->Fetch(FormsCompiler::CACHE_POOL, $sId); + } + + return new $sId($sId); + } + +} diff --git a/sources/Forms/Compiler/FormsCompiler.php b/sources/Forms/Compiler/FormsCompiler.php new file mode 100644 index 000000000..7e635c5af --- /dev/null +++ b/sources/Forms/Compiler/FormsCompiler.php @@ -0,0 +1,46 @@ +oCacheService = DataModelDependantCache::GetInstance(); + } + + final public static function GetInstance(): FormsCompiler + { + if (!isset(static::$oInstance)) { + static::$oInstance = new FormsCompiler(); + } + + return static::$oInstance; + } + + public function CompileFormFromFile(string $filePath): ?FormBlock + { + return null; + } + + public function StoreFormFromContent(string $sId, string $sPHPContent): void + { + $this->oCacheService->StorePhpContent(self::CACHE_POOL, $sId, $sPHPContent); + } +} diff --git a/sources/Forms/Compiler/FormsCompilerException.php b/sources/Forms/Compiler/FormsCompilerException.php new file mode 100644 index 000000000..9f7d6c101 --- /dev/null +++ b/sources/Forms/Compiler/FormsCompilerException.php @@ -0,0 +1,14 @@ +GetFormBlockById('VerySimpleForm'); + $oBuilder = $this->GetFormBuilder($oFormBlock, []); + $oForm = $oBuilder->getForm(); + $oForm->handleRequest($this->GetRequest()); + + if ($oForm->isSubmitted()) { + if ($oForm->isValid()) { + IssueLog::Info('form is valid'); + } + + // Retrieve form data + $aData = $oForm->getData(); + + // Compute blocks to redraw + $aBlocksToRedraw = FormTypeHelper::ComputeBlocksToRedraw($oFormBlock, $oForm, $aData['_turbo_trigger']); + + // Display turbo response + $this->DisplayTurboAjaxPage($aBlocksToRedraw); + + return; + } + + $this->DisplayPage([ + 'form' => $oForm->createView(), + ], 'BasicForm'); + + } catch (Exception $e) { + ItopSdkFormDemonstratorLog::Exception($e->getMessage(), $e); + $this->DisplayPage([ + 'sError' => $e->getMessage(), + ], 'BasicForm'); + + return; + } + } +} diff --git a/sources/PropertyTree/CollectionOfTrees.php b/sources/PropertyTree/CollectionOfTrees.php new file mode 100644 index 000000000..290b8832a --- /dev/null +++ b/sources/PropertyTree/CollectionOfTrees.php @@ -0,0 +1,12 @@ +MakeCacheFileName($sPool, $sKey); - SetupUtils::builddir(dirname($sCacheFileName)); $sMoreInfo = ''; foreach ($aMoreInfo as $sKey => $sValue) { $sMoreInfo .= "\n// $sKey: $sValue"; } - $sCacheContent = "StorePhpContent($sPool, $sKey, $sCacheContent); + } + + /** + * + * @param string $sPool + * @param string $sKey + * @param string $sPHPContent must include 'MakeCacheFileName($sPool, $sKey); + SetupUtils::builddir(dirname($sCacheFileName)); + + file_put_contents($sCacheFileName, $sPHPContent, LOCK_EX); } /** diff --git a/sources/Service/DependencyInjection/DIService.php b/sources/Service/DependencyInjection/DIService.php index 896223402..f5d0ad75c 100644 --- a/sources/Service/DependencyInjection/DIService.php +++ b/sources/Service/DependencyInjection/DIService.php @@ -46,14 +46,19 @@ class DIService * @api * * @param string $sName name of the service to get + * @param bool $bMustBeFound if true a DIException is thrown when the service is not found * - * @return mixed + * @return mixed The service or null when the service is not found and $bMustBeFound is false * @throws \Combodo\iTop\Service\DependencyInjection\DIException */ - final public function GetService(string $sName): mixed + final public function GetService(string $sName, bool $bMustBeFound = true): mixed { if (!isset($this->aServices[$sName])) { - throw new DIException("Service ".json_encode($sName)." not found"); + if ($bMustBeFound) { + throw new DIException("Service ".json_encode($sName)." not found"); + } + + return null; } return $this->aServices[$sName]; diff --git a/sources/alias.php b/sources/alias.php index 3dacb0d2e..7c5bdfd54 100644 --- a/sources/alias.php +++ b/sources/alias.php @@ -6,10 +6,14 @@ * All classes in sources directory needs to be PSR-4 compatible, this alias covers the namespaces corrections. * PSR-4 Exception with directory sources/Application/WebPage configured in \symfony\config\services.yaml */ + +use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryFormFactory; + class_alias(\Combodo\iTop\Application\UI\Hook\iKeyboardShortcut::class, 'iKeyboardShortcut'); class_alias(\Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableConfig\DataTableConfig::class, 'DataTableConfig'); -class_alias(\Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectUIBlockFactory::class, 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\SelectUIBlockFactory'); -class_alias(\Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryFormFactory::class, 'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\CaseLogEntryFormFactory\\CaseLogEntryFormFactory'); +class_alias(SelectUIBlockFactory::class, 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\SelectUIBlockFactory'); +class_alias(CaseLogEntryFormFactory::class, 'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\CaseLogEntryFormFactory\\CaseLogEntryFormFactory'); class_alias(\Combodo\iTop\Core\Email\EMailSymfony::class, 'EMailSymfony'); class_alias(\Combodo\iTop\Core\Email\Transport\SymfonyFileTransport::class, 'SymfonyFileTransport'); class_alias(\Combodo\iTop\Core\Email\Transport\SymfonyOAuthTransport::class, 'SymfonyOAuthTransport'); @@ -95,3 +99,15 @@ class_alias(\Combodo\iTop\Core\AttributeDefinition\AttributeText::class, 'Attrib class_alias(\Combodo\iTop\Core\AttributeDefinition\AttributeURL::class, 'AttributeURL'); class_alias(\Combodo\iTop\Core\AttributeDefinition\iAttributeNoGroupBy::class, 'iAttributeNoGroupBy'); class_alias(\Combodo\iTop\Core\AttributeDefinition\MissingColumnException::class, 'MissingColumnException'); + +class_alias(Combodo\iTop\PropertyTree\PropertyTree::class, 'Combodo-PropertyTree'); +class_alias(Combodo\iTop\PropertyTree\Property::class, 'Combodo-Property'); +class_alias(Combodo\iTop\PropertyTree\CollectionOfValues::class, 'Combodo-CollectionOfValues'); +class_alias(Combodo\iTop\PropertyTree\CollectionOfTrees::class, 'Combodo-CollectionOfTrees'); + +class_alias(Combodo\iTop\PropertyTree\ValueType\ValueTypeLabel::class, 'Combodo-ValueTypeLabel'); +class_alias(Combodo\iTop\PropertyTree\ValueType\ValueTypeOQL::class, 'Combodo-ValueTypeOQL'); +class_alias(Combodo\iTop\PropertyTree\ValueType\ValueTypeClassAttributeGroupBy::class, 'Combodo-ValueTypeClassAttributeGroupBy'); +class_alias(Combodo\iTop\PropertyTree\ValueType\ValueTypeChoice::class, 'Combodo-ValueTypeChoice'); +class_alias(Combodo\iTop\PropertyTree\ValueType\ValueTypeClassAttribute::class, 'Combodo-ValueTypeClassAttribute'); +class_alias(Combodo\iTop\PropertyTree\ValueType\ValueTypeInteger::class, 'Combodo-ValueTypeInteger'); diff --git a/templates/base/components/turbo-form/layout.html.twig b/templates/base/components/turbo-form/layout.html.twig index a0701953f..600be25b2 100644 --- a/templates/base/components/turbo-form/layout.html.twig +++ b/templates/base/components/turbo-form/layout.html.twig @@ -8,8 +8,8 @@ - {% if actionUrl is defined %} - {{ form_start(oUIBlock.GetFormView(), {'action': actionUrl}) }} + {% if oUIBlock.GetAction() %} + {{ form_start(oUIBlock.GetFormView(), {action: oUIBlock.GetAction()}) }} {% else %} {{ form_start(oUIBlock.GetFormView()) }} {% endif %}