Polymorphic type

This commit is contained in:
Eric Espie
2026-01-13 18:00:19 +01:00
parent c075a5c145
commit 90729f84b6
14 changed files with 555 additions and 87 deletions

View File

@@ -308,7 +308,11 @@ abstract class Dashboard
public function Save()
{
}
public function PersistDashboard(string $sXml): bool
{
return true;
}
/**
@@ -771,6 +775,26 @@ class RuntimeDashboard extends Dashboard
public function Save()
{
$sXml = $this->ToXml();
return $this->PersistDashboard($sXml);
}
/**
* @param string $sXml
*
* @return bool
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \CoreWarning
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
*/
public function PersistDashboard(string $sXml): bool
{
$oUDSearch = new DBObjectSearch('UserDashboard');
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
$oUDSearch->AddCondition('menu_code', $this->sId, '=');

View File

@@ -852,6 +852,70 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
</class>
</classes>
<property_types _delta="define">
<property_type id="Dashboard" xsi:type="Combodo-AbstractPropertyType"/>
<property_type id="Combodo-Dashboard-Grid" xsi:type="Combodo-PropertyType">
<extends>Dashboard</extends>
<definition xsi:type="Combodo-ValueType-PropertyTree">
<label>Dashboard</label>
<nodes>
<node id="title" xsi:type="Combodo-ValueType-String">
<label>UI:DashboardEdit:DashboardTitle</label>
</node>
<node id="refresh" xsi:type="Combodo-ValueType-Choice"> <!-- Possible de le cacher, etc celui-ci nous met dedans -->
<label>UI:DashboardEdit:AutoReload</label>
<values>
<value id="0">
<label>No auto-refresh</label>
</value>
<value id="30">
<label>Every 30 seconds</label>
</value>
<value id="60">
<label>Every 1 minute</label>
</value>
<value id="300">
<label>Every 5 minutes</label>
</value>
<value id="600">
<label>Every 10 minutes</label>
</value>
<value id="1800">
<label>Every 30 minutes</label>
</value>
<value id="3600">
<label>Every 1 hour</label>
</value>
</values>
</node>
<node id="pos_dashlets" xsi:type="Combodo-ValueType-Collection">
<label>Dashlet List</label>
<xml-format xsi:type="Combodo-XMLFormat-CollectionWithId">
<tag-name>pos_dashlet</tag-name>
</xml-format>
<prototype>
<node id="position_x" xsi:type="Combodo-ValueType-Integer">
<label>X</label>
</node>
<node id="position_y" xsi:type="Combodo-ValueType-Integer">
<label>Y</label>
</node>
<node id="width" xsi:type="Combodo-ValueType-Integer">
<label>W</label>
</node>
<node id="height" xsi:type="Combodo-ValueType-Integer">
<label>H</label>
</node>
<node id="dashlet" xsi:type="Combodo-ValueType-Polymorphic">
<label>Dashlet</label>
<allowed-types>
<allowed-type>Dashlet</allowed-type>
</allowed-types>
</node>
</prototype>
</node>
</nodes>
</definition>
</property_type>
<property_type id="Dashlet" xsi:type="Combodo-AbstractPropertyType"/>
<property_type id="DashletGroupByTable" xsi:type="Combodo-PropertyType">
<extends>Dashlet</extends>

View File

@@ -500,6 +500,7 @@ return array(
'Combodo\\iTop\\Forms\\Block\\Base\\HiddenFormBlock' => $baseDir . '/sources/Forms/Block/Base/HiddenFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\IntegerFormBlock' => $baseDir . '/sources/Forms/Block/Base/IntegerFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\NumberFormBlock' => $baseDir . '/sources/Forms/Block/Base/NumberFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\PolymorphicFormBlock' => $baseDir . '/sources/Forms/Block/Base/PolymorphicFormBlock.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',
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
@@ -570,6 +571,7 @@ return array(
'Combodo\\iTop\\PropertyType\\Serializer\\XMLEncoder' => $baseDir . '/sources/PropertyType/Serializer/XMLEncoder.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\AbstractXMLFormat' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/AbstractXMLFormat.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCSV' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCSV.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCollectionWithId' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCollectionWithId.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFactory' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFactory.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFlatArray' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFlatArray.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatValueAsId' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatValueAsId.php',
@@ -578,6 +580,7 @@ return array(
'Combodo\\iTop\\PropertyType\\ValueType\\AbstractValueType' => $baseDir . '/sources/PropertyType/ValueType/AbstractValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\AbstractBranchValueType' => $baseDir . '/sources/PropertyType/ValueType/Branch/AbstractBranchValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypeCollection' => $baseDir . '/sources/PropertyType/ValueType/Branch/ValueTypeCollection.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePolymorphic' => $baseDir . '/sources/PropertyType/ValueType/Branch/ValueTypePolymorphic.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePropertyTree' => $baseDir . '/sources/PropertyType/ValueType/Branch/ValueTypePropertyTree.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\AbstractLeafValueType' => $baseDir . '/sources/PropertyType/ValueType/Leaf/AbstractLeafValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\ValueTypeAggregateFunction' => $baseDir . '/sources/PropertyType/ValueType/Leaf/ValueTypeAggregateFunction.php',

View File

@@ -28,12 +28,12 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
);
public static $prefixLengthsPsr4 = array (
'T' =>
'T' =>
array (
'Twig\\' => 5,
'TheNetworg\\OAuth2\\Client\\' => 25,
),
'S' =>
'S' =>
array (
'Symfony\\Polyfill\\Php83\\' => 23,
'Symfony\\Polyfill\\Mbstring\\' => 26,
@@ -82,7 +82,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'ScssPhp\\ScssPhp\\' => 16,
'Sabberworm\\CSS\\' => 15,
),
'P' =>
'P' =>
array (
'Psr\\Log\\' => 8,
'Psr\\Http\\Message\\' => 17,
@@ -93,298 +93,298 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'PhpParser\\' => 10,
'Pelago\\Emogrifier\\' => 18,
),
'L' =>
'L' =>
array (
'League\\OAuth2\\Client\\' => 21,
),
'G' =>
'G' =>
array (
'GuzzleHttp\\Psr7\\' => 16,
'GuzzleHttp\\Promise\\' => 19,
'GuzzleHttp\\' => 11,
),
'F' =>
'F' =>
array (
'Firebase\\JWT\\' => 13,
),
'E' =>
'E' =>
array (
'Egulias\\EmailValidator\\' => 23,
),
'D' =>
'D' =>
array (
'Doctrine\\Common\\Lexer\\' => 22,
),
);
public static $prefixDirsPsr4 = array (
'Twig\\' =>
'Twig\\' =>
array (
0 => __DIR__ . '/..' . '/twig/twig/src',
),
'TheNetworg\\OAuth2\\Client\\' =>
'TheNetworg\\OAuth2\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/thenetworg/oauth2-azure/src',
),
'Symfony\\Polyfill\\Php83\\' =>
'Symfony\\Polyfill\\Php83\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php83',
),
'Symfony\\Polyfill\\Mbstring\\' =>
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Polyfill\\Intl\\Normalizer\\' =>
'Symfony\\Polyfill\\Intl\\Normalizer\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer',
),
'Symfony\\Polyfill\\Intl\\Idn\\' =>
'Symfony\\Polyfill\\Intl\\Idn\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn',
),
'Symfony\\Polyfill\\Intl\\Icu\\' =>
'Symfony\\Polyfill\\Intl\\Icu\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-icu',
),
'Symfony\\Polyfill\\Intl\\Grapheme\\' =>
'Symfony\\Polyfill\\Intl\\Grapheme\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme',
),
'Symfony\\Polyfill\\Ctype\\' =>
'Symfony\\Polyfill\\Ctype\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
),
'Symfony\\Contracts\\Translation\\' =>
'Symfony\\Contracts\\Translation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/translation-contracts',
),
'Symfony\\Contracts\\Service\\' =>
'Symfony\\Contracts\\Service\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/service-contracts',
),
'Symfony\\Contracts\\EventDispatcher\\' =>
'Symfony\\Contracts\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/event-dispatcher-contracts',
),
'Symfony\\Contracts\\Cache\\' =>
'Symfony\\Contracts\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/cache-contracts',
),
'Symfony\\Component\\Yaml\\' =>
'Symfony\\Component\\Yaml\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/yaml',
),
'Symfony\\Component\\VarExporter\\' =>
'Symfony\\Component\\VarExporter\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/var-exporter',
),
'Symfony\\Component\\VarDumper\\' =>
'Symfony\\Component\\VarDumper\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/var-dumper',
),
'Symfony\\Component\\Validator\\' =>
'Symfony\\Component\\Validator\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/validator',
),
'Symfony\\Component\\String\\' =>
'Symfony\\Component\\String\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/string',
),
'Symfony\\Component\\Stopwatch\\' =>
'Symfony\\Component\\Stopwatch\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/stopwatch',
),
'Symfony\\Component\\Security\\Csrf\\' =>
'Symfony\\Component\\Security\\Csrf\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/security-csrf',
),
'Symfony\\Component\\Security\\Core\\' =>
'Symfony\\Component\\Security\\Core\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/security-core',
),
'Symfony\\Component\\Routing\\' =>
'Symfony\\Component\\Routing\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/routing',
),
'Symfony\\Component\\PropertyInfo\\' =>
'Symfony\\Component\\PropertyInfo\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/property-info',
),
'Symfony\\Component\\PropertyAccess\\' =>
'Symfony\\Component\\PropertyAccess\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/property-access',
),
'Symfony\\Component\\PasswordHasher\\' =>
'Symfony\\Component\\PasswordHasher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/password-hasher',
),
'Symfony\\Component\\OptionsResolver\\' =>
'Symfony\\Component\\OptionsResolver\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/options-resolver',
),
'Symfony\\Component\\Mime\\' =>
'Symfony\\Component\\Mime\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/mime',
),
'Symfony\\Component\\Mailer\\' =>
'Symfony\\Component\\Mailer\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/mailer',
),
'Symfony\\Component\\HttpKernel\\' =>
'Symfony\\Component\\HttpKernel\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/http-kernel',
),
'Symfony\\Component\\HttpFoundation\\' =>
'Symfony\\Component\\HttpFoundation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/http-foundation',
),
'Symfony\\Component\\Form\\' =>
'Symfony\\Component\\Form\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/form',
),
'Symfony\\Component\\Finder\\' =>
'Symfony\\Component\\Finder\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/finder',
),
'Symfony\\Component\\Filesystem\\' =>
'Symfony\\Component\\Filesystem\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/filesystem',
),
'Symfony\\Component\\EventDispatcher\\' =>
'Symfony\\Component\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/event-dispatcher',
),
'Symfony\\Component\\ErrorHandler\\' =>
'Symfony\\Component\\ErrorHandler\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/error-handler',
),
'Symfony\\Component\\Dotenv\\' =>
'Symfony\\Component\\Dotenv\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/dotenv',
),
'Symfony\\Component\\DependencyInjection\\' =>
'Symfony\\Component\\DependencyInjection\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/dependency-injection',
),
'Symfony\\Component\\CssSelector\\' =>
'Symfony\\Component\\CssSelector\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/css-selector',
),
'Symfony\\Component\\Console\\' =>
'Symfony\\Component\\Console\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/console',
),
'Symfony\\Component\\Config\\' =>
'Symfony\\Component\\Config\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/config',
),
'Symfony\\Component\\Cache\\' =>
'Symfony\\Component\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/cache',
),
'Symfony\\Bundle\\WebProfilerBundle\\' =>
'Symfony\\Bundle\\WebProfilerBundle\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/web-profiler-bundle',
),
'Symfony\\Bundle\\TwigBundle\\' =>
'Symfony\\Bundle\\TwigBundle\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/twig-bundle',
),
'Symfony\\Bundle\\FrameworkBundle\\' =>
'Symfony\\Bundle\\FrameworkBundle\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/framework-bundle',
),
'Symfony\\Bridge\\Twig\\' =>
'Symfony\\Bridge\\Twig\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/twig-bridge',
),
'Soundasleep\\' =>
'Soundasleep\\' =>
array (
0 => __DIR__ . '/..' . '/soundasleep/html2text/src',
),
'ScssPhp\\ScssPhp\\' =>
'ScssPhp\\ScssPhp\\' =>
array (
0 => __DIR__ . '/..' . '/scssphp/scssphp/src',
),
'Sabberworm\\CSS\\' =>
'Sabberworm\\CSS\\' =>
array (
0 => __DIR__ . '/..' . '/sabberworm/php-css-parser/src',
),
'Psr\\Log\\' =>
'Psr\\Log\\' =>
array (
0 => __DIR__ . '/..' . '/psr/log/src',
),
'Psr\\Http\\Message\\' =>
'Psr\\Http\\Message\\' =>
array (
0 => __DIR__ . '/..' . '/psr/http-factory/src',
1 => __DIR__ . '/..' . '/psr/http-message/src',
),
'Psr\\Http\\Client\\' =>
'Psr\\Http\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/psr/http-client/src',
),
'Psr\\EventDispatcher\\' =>
'Psr\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/psr/event-dispatcher/src',
),
'Psr\\Container\\' =>
'Psr\\Container\\' =>
array (
0 => __DIR__ . '/..' . '/psr/container/src',
),
'Psr\\Cache\\' =>
'Psr\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/psr/cache/src',
),
'PhpParser\\' =>
'PhpParser\\' =>
array (
0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser',
),
'Pelago\\Emogrifier\\' =>
'Pelago\\Emogrifier\\' =>
array (
0 => __DIR__ . '/..' . '/pelago/emogrifier/src',
),
'League\\OAuth2\\Client\\' =>
'League\\OAuth2\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/league/oauth2-google/src',
1 => __DIR__ . '/..' . '/league/oauth2-client/src',
),
'GuzzleHttp\\Psr7\\' =>
'GuzzleHttp\\Psr7\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
),
'GuzzleHttp\\Promise\\' =>
'GuzzleHttp\\Promise\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/promises/src',
),
'GuzzleHttp\\' =>
'GuzzleHttp\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
),
'Firebase\\JWT\\' =>
'Firebase\\JWT\\' =>
array (
0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
),
'Egulias\\EmailValidator\\' =>
'Egulias\\EmailValidator\\' =>
array (
0 => __DIR__ . '/..' . '/egulias/email-validator/src',
),
'Doctrine\\Common\\Lexer\\' =>
'Doctrine\\Common\\Lexer\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/lexer/src',
),
);
public static $prefixesPsr0 = array (
'C' =>
'C' =>
array (
'Console' =>
'Console' =>
array (
0 => __DIR__ . '/..' . '/pear/console_getopt',
),
),
'A' =>
'A' =>
array (
'Archive_Tar' =>
'Archive_Tar' =>
array (
0 => __DIR__ . '/..' . '/pear/archive_tar',
),
@@ -886,6 +886,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Forms\\Block\\Base\\HiddenFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/HiddenFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\IntegerFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/IntegerFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\NumberFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/NumberFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\PolymorphicFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/PolymorphicFormBlock.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',
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
@@ -956,6 +957,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\PropertyType\\Serializer\\XMLEncoder' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLEncoder.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\AbstractXMLFormat' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/AbstractXMLFormat.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCSV' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCSV.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCollectionWithId' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCollectionWithId.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFactory' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFactory.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFlatArray' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFlatArray.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatValueAsId' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatValueAsId.php',
@@ -964,6 +966,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\PropertyType\\ValueType\\AbstractValueType' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/AbstractValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\AbstractBranchValueType' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/AbstractBranchValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypeCollection' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/ValueTypeCollection.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePolymorphic' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/ValueTypePolymorphic.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePropertyTree' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/ValueTypePropertyTree.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\AbstractLeafValueType' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Leaf/AbstractLeafValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\ValueTypeAggregateFunction' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Leaf/ValueTypeAggregateFunction.php',

View File

@@ -10,7 +10,10 @@ use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\WebPage\AjaxPage;
use Combodo\iTop\Application\WebPage\JsonPage;
use Combodo\iTop\Controller\AbstractController;
use Combodo\iTop\Forms\Block\FormBlockService;
use Combodo\iTop\ItopSdkFormDemonstrator\Helper\ItopSdkFormDemonstratorLog;
use Combodo\iTop\Service\DependencyInjection\ServiceLocator;
use Exception;
use ModelReflectionRuntime;
use utils;
@@ -78,7 +81,30 @@ class DashboardController extends Controller
$sValues = utils::ReadParam('values', '', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
$aValues = !empty($sValues) ? json_decode($sValues, true, 20) : [];
// TODO 3.3 Consume the values and persist them
try {
// Get the form block from the service (and the compiler)
$oRequest = $this->getRequest();
$oFormBlock = FormBlockService::GetInstance()->GetFormBlockById('dashboard_type', 'Dashboard');
$oBuilder = $this->GetFormBuilder($oFormBlock, []);
$oForm = $oBuilder->getForm();
$oForm->handleRequest($oRequest);
if ($oForm->isSubmitted()) {
if ($oForm->isValid()) {
// Save XML
}
// Compute blocks to redraw
$this->HandleFormSubmitted($oFormBlock, $oForm);
}
} catch (Exception $e) {
ItopSdkFormDemonstratorLog::Exception($e->getMessage(), $e);
$this->DisplayPage([
'sControllerError' => $e->getMessage(),
], 'itop_error_update', Controller::ENUM_PAGE_TYPE_TURBO_FORM_AJAX);
return null;
}
$oPage = new JsonPage();
$oPage->SetData($aValues);

View File

@@ -0,0 +1,14 @@
<?php
/*
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Forms\Block\Base;
use Combodo\iTop\Forms\Block\AbstractFormBlock;
class PolymorphicFormBlock extends AbstractFormBlock
{
}

View File

@@ -46,12 +46,6 @@ class FormsController extends Controller
return;
}
// $this->DisplayPage([
// 'form' => $oForm->createView(),
// 'sAction' => utils::GetAbsoluteUrlAppRoot().'pages/UI.php?route=forms.dashlet_configuration&dashlet_code='.urlencode($sDashletId),
// ], 'itop_form');
} catch (Exception $e) {
ItopSdkFormDemonstratorLog::Exception($e->getMessage(), $e);
$this->DisplayPage([

View File

@@ -76,6 +76,13 @@ class PropertyTypeService
return PropertyTypeCompiler::GetInstance()->ListPropertyTypesByType($sType);
}
public function GetPropertyType(string $sId, string $sType = 'Dashlet'): PropertyType
{
$sXML = PropertyTypeCompiler::GetInstance()->GetXMLContent($sId, $sType);
return PropertyTypeCompiler::GetInstance()->CompilePropertyTypeFromXML($sXML);
}
/**
* @param string $sId
*

View File

@@ -0,0 +1,78 @@
<?php
/*
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\PropertyType\Serializer\XMLFormat;
use Combodo\iTop\DesignElement;
use Combodo\iTop\PropertyType\Serializer\SerializerException;
use Combodo\iTop\PropertyType\ValueType\AbstractValueType;
use Combodo\iTop\PropertyType\ValueType\Branch\ValueTypeCollection;
class XMLFormatCollectionWithId extends AbstractXMLFormat
{
private ?string $sTagName;
public function InitFromDomNode(DesignElement $oDomNode): void
{
parent::InitFromDomNode($oDomNode);
$this->sTagName = $oDomNode->GetChildText('tag-name');
}
public function Normalize($value, AbstractValueType $oValueType): mixed
{
return $value;
}
public function EncodeToDOMNode(mixed $normalizedValue, DesignElement $oDOMNode, AbstractValueType $oValueType): void
{
if (!$oValueType instanceof ValueTypeCollection) {
throw new SerializerException('XMLFormatFlatArray is allowed only in ValueTypeCollection nodes');
}
foreach ($normalizedValue as $sItemId => $aValues) {
/** @var DesignElement $oNode */
$oNode = $oDOMNode->ownerDocument->createElement($this->sTagName);
$oNode->setAttribute('id', $sItemId);
$oDOMNode->appendChild($oNode);
foreach ($oValueType->GetChildren() as $oChild) {
$sPropertyId = $oChild->GetId();
if (isset($aValues[$sPropertyId])) {
/** @var DesignElement $oSubNode */
$oSubNode = $oDOMNode->ownerDocument->createElement($sPropertyId);
$oNode->appendChild($oSubNode);
$oChild->EncodeToDOMNode($aValues[$sPropertyId], $oSubNode);
}
}
}
}
public function DecodeFromDOMNode(DesignElement $oDOMNode, AbstractValueType $oValueType): mixed
{
if (!$oValueType instanceof ValueTypeCollection) {
throw new SerializerException('XMLFormatFlatArray is allowed only in ValueTypeCollection nodes');
}
$aNormalizedValues = [];
/** @var DesignElement $oNode */
foreach ($oDOMNode->GetNodes($this->sTagName) as $oNode) {
$sItemId = $oNode->getAttribute('id');
$aSubArray = [];
foreach ($oValueType->GetChildren() as $oChild) {
$aSubArray[$oChild->GetId()] = $oChild->DecodeFromDomNode($oNode->GetUniqueElement($oChild->GetId()));
}
$aNormalizedValues[$sItemId] = $aSubArray;
}
return $aNormalizedValues;
}
public function Denormalize($normalizedValue, AbstractValueType $oValueType): mixed
{
return $normalizedValue;
}
}

View File

@@ -0,0 +1,53 @@
<?php
/*
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\PropertyType\ValueType\Branch;
use Combodo\iTop\DesignElement;
use Combodo\iTop\Forms\Block\Base\PolymorphicFormBlock;
use Combodo\iTop\PropertyType\PropertyTypeService;
use Combodo\iTop\PropertyType\ValueType\ValueTypeFactory;
class ValueTypePolymorphic extends AbstractBranchValueType
{
public function GetFormBlockClass(): string
{
return PolymorphicFormBlock::class;
}
public function InitFromDomNode(DesignElement $oDomNode, ?AbstractBranchValueType $oParent = null): void
{
parent::InitFromDomNode($oDomNode, $oParent);
}
public function ToPHPFormBlock(array &$aPHPFragments = []): string
{
return "// ValueTypePolymorphic Block\n";
}
public function EncodeToDOMNode(mixed $normalizedValue, DesignElement $oDOMNode): void
{
$sType = $normalizedValue['type'];
$oDOMNode->setAttribute('xsi:type', $sType);
$oPropertyType = PropertyTypeService::GetInstance()->GetPropertyType($sType);
$aProperties = $normalizedValue['properties'];
$oPropertyType->EncodeToDOMNode($aProperties, $oDOMNode);
}
public function DecodeFromDomNode(DesignElement $oDOMNode): mixed
{
$sType = $oDOMNode->getAttribute('xsi:type');
$oPropertyType = PropertyTypeService::GetInstance()->GetPropertyType($sType);
return [
'type' => $sType,
'properties' => $oPropertyType->DecodeFromDOMNode($oDOMNode),
];
}
}

View File

@@ -101,6 +101,7 @@ class_alias(\Combodo\iTop\PropertyType\PropertyType::class, 'Combodo-PropertyTyp
class_alias(\Combodo\iTop\PropertyType\ValueType\Branch\ValueTypeCollection::class, 'Combodo-ValueType-Collection');
class_alias(\Combodo\iTop\PropertyType\ValueType\Branch\ValueTypePropertyTree::class, 'Combodo-ValueType-PropertyTree');
class_alias(\Combodo\iTop\PropertyType\ValueType\Branch\ValueTypePolymorphic::class, 'Combodo-ValueType-Polymorphic');
class_alias(\Combodo\iTop\PropertyType\ValueType\Leaf\ValueTypeAggregateFunction::class, 'Combodo-ValueType-AggregateFunction');
class_alias(\Combodo\iTop\PropertyType\ValueType\Leaf\ValueTypeBoolean::class, 'Combodo-ValueType-Boolean');
@@ -121,3 +122,4 @@ class_alias(\Combodo\iTop\PropertyType\ValueType\Leaf\ValueTypeText::class, 'Com
class_alias(\Combodo\iTop\PropertyType\Serializer\XMLFormat\XMLFormatCSV::class, 'Combodo-XMLFormat-CSV');
class_alias(\Combodo\iTop\PropertyType\Serializer\XMLFormat\XMLFormatValueAsId::class, 'Combodo-XMLFormat-ValueAsId');
class_alias(\Combodo\iTop\PropertyType\Serializer\XMLFormat\XMLFormatFlatArray::class, 'Combodo-XMLFormat-FlatArray');
class_alias(\Combodo\iTop\PropertyType\Serializer\XMLFormat\XMLFormatCollectionWithId::class, 'Combodo-XMLFormat-CollectionWithId');

View File

@@ -0,0 +1,95 @@
<?php
/*
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\PropertyType\PropertyTypeDesign;
use Combodo\iTop\Service\DependencyInjection\ServiceLocator;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
/**
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
class DashboardSerializerTest extends ItopDataTestCase
{
/**
* @dataProvider XMLSerializerProvider
*
* @param $normalizedValue
* @param string $sPropertyTypeXML
* @param string $sXMLContent
*
* @return void
* @throws \DOMException
*/
public function testSerializeXML($normalizedValue, string $sXMLContent)
{
ServiceLocator::GetInstance()->RegisterService('ModelReflection', new ModelReflectionRuntime());
$oDOMDocument = new PropertyTypeDesign();
$oDOMDocument->preserveWhiteSpace = false;
$oDOMDocument->formatOutput = true;
/** @var \Combodo\iTop\DesignElement $oRootNode */
$oRootNode = $oDOMDocument->createElement('root');
$oDOMDocument->appendChild($oRootNode);
Combodo\iTop\PropertyType\Serializer\XMLSerializer::GetInstance()->Serialize($normalizedValue, $oRootNode, 'DashboardDefinition', 'Dashboard');
$sActualXML = $oDOMDocument->saveXML();
$this->AssertEqualiTopXML($sXMLContent, $sActualXML);
}
public function XMLSerializerProvider()
{
return [
'Basic test should serialize to XML' => [
'normalizedValue' => [
'schema_version' => 2,
'id' => 'WelcomeMenuPage',
'title' => 'Bienvenido al Panel de Control Panel',
'refresh' => '60',
'pos_dashlets' => [
'CUSTOM_WelcomeMenuPage_ID_row0_col0_1' => [
'position_x' => 1,
'position_y' => 2,
'width' => 3,
'height' => 1,
'dashlet' => [
'type' => 'DashletHeaderStatic',
'properties' => [
'title' => 'Menu:ConfigManagementCI',
'icon' => '../images/icons/icons8-database.svg',
],
],
],
],
],
'sXMLContent' => <<<XML
<?xml version="1.0"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Combodo-Dashboard-Grid">
<title>Bienvenido al Panel de Control Panel</title>
<refresh>60</refresh>
<pos_dashlets>
<pos_dashlet id="CUSTOM_WelcomeMenuPage_ID_row0_col0_1">
<position_x>1</position_x>
<position_y>2</position_y>
<width>3</width>
<height>1</height>
<dashlet xsi:type="DashletHeaderStatic">
<title>Menu:ConfigManagementCI</title>
<icon>../images/icons/icons8-database.svg</icon>
</dashlet>
</pos_dashlet>
</pos_dashlets>
</root>
XML,
],
];
}
}

View File

@@ -32,6 +32,8 @@ class XMLSerializerTest extends ItopDataTestCase
/** @var \Combodo\iTop\DesignElement $oRootNode */
$oRootNode = $oDOMDocument->createElement('root');
$oRootNode->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$oDOMDocument->appendChild($oRootNode);
Combodo\iTop\PropertyType\Serializer\XMLSerializer::GetInstance()->SerializeForPropertyType($normalizedValue, $oRootNode, $sPropertyTypeXML);
@@ -56,7 +58,7 @@ class XMLSerializerTest extends ItopDataTestCase
XML,
'sXMLContent' => <<<XML
<?xml version="1.0"?>
<root>text</root>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">text</root>
XML,
],
'Collection of values as CSV' => [
@@ -74,7 +76,7 @@ XML,
XML,
'sXMLContent' => <<<XML
<?xml version="1.0"?>
<root>Contact,Organization</root>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Contact,Organization</root>
XML,
],
'Collection of values as id attribute' => [
@@ -94,7 +96,7 @@ XML,
XML,
'sXMLContent' => <<<XML
<?xml version="1.0"?>
<root>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item id="Contact"/>
<item id="Organization"/>
</root>
@@ -134,7 +136,7 @@ XML,
XML,
'sXMLContent' => <<<XML
<?xml version="1.0"?>
<root>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item_count>2</item_count>
<item_0_title_property>title_a</item_0_title_property>
<item_0_class_property>class_a</item_0_class_property>
@@ -164,10 +166,83 @@ XML,
XML,
'sXMLContent' => <<<XML
<?xml version="1.0"?>
<root>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<title_property>title</title_property>
<class_property>class</class_property>
</root>
XML,
],
'Polymorphic tree' => [
'normalizedValue' => [
'type' => 'DashletHeaderStatic',
'properties' => [
'title' => 'Menu:ConfigManagementCI',
'icon' => '../images/icons/icons8-database.svg',
],
],
'sPropertyTypeXML' => <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<property_type id="property_tree_test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Combodo-PropertyType" xsi:noNamespaceSchemaLocation = "https://www.combodo.com/itop-schema/3.3">
<extends>Dashlet</extends>
<definition xsi:type="Combodo-ValueType-Polymorphic">
<label>Dashlet</label>
<allowed-types>
<allowed-type>Dashlet</allowed-type>
</allowed-types>
</definition>
</property_type>
XML,
'sXMLContent' => <<<XML
<?xml version="1.0"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="DashletHeaderStatic">
<title>Menu:ConfigManagementCI</title>
<icon>../images/icons/icons8-database.svg</icon>
</root>
XML,
],
'Collection of tree with id' => [
'normalizedValue' => [
'a' => [
'title_property' => 'title_a',
'class_property' => 'class_a',
],
'b' => [
'title_property' => 'title_b',
'class_property' => 'class_b',
],
],
'sPropertyTypeXML' => <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<property_type id="collection_test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Combodo-PropertyType" xsi:noNamespaceSchemaLocation = "https://www.combodo.com/itop-schema/3.3">
<extends>Dashlet</extends>
<definition xsi:type="Combodo-ValueType-Collection">
<xml-format xsi:type="Combodo-XMLFormat-CollectionWithId">
<tag-name>item</tag-name>
</xml-format>
<prototype>
<node id="title_property" xsi:type="Combodo-ValueType-Label">
<label>UI:BasicTest:Prop-Title</label>
</node>
<node id="class_property" xsi:type="Combodo-ValueType-Class">
<label>UI:BasicTest:Prop-Class</label>
<categories-csv>test</categories-csv>
</node>
</prototype>
</definition>
</property_type>
XML,
'sXMLContent' => <<<XML
<?xml version="1.0"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item id="a">
<title_property>title_a</title_property>
<class_property>class_a</class_property>
</item>
<item id="b">
<title_property>title_b</title_property>
<class_property>class_b</class_property>
</item>
</root>
XML,
],
];

View File

@@ -354,6 +354,26 @@
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Combodo-ValueType-Polymorphic">
<xsd:complexContent>
<xsd:extension base="Combodo-ValueType-Abstract">
<xsd:sequence>
<xsd:element name="xml-format" minOccurs="0" type="Combodo-XMLFormat-Abstract">
<xsd:annotation>
<xsd:documentation>Format of the property in the source XML</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="allowed-types">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="allowed-type" type="xsd:string" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<!--============================= XML Formats ===============================-->
<xsd:complexType name="Combodo-XMLFormat-Abstract">
@@ -396,5 +416,15 @@
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Combodo-XMLFormat-CollectionWithId">
<xsd:complexContent>
<xsd:extension base="Combodo-XMLFormat-Abstract">
<xsd:sequence>
<xsd:element name="tag-name" type="xsd:NCName">
</xsd:element>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>