diff --git a/core/datamodel.core.xml b/core/datamodel.core.xml
index e5a43f20b..189dbb0de 100644
--- a/core/datamodel.core.xml
+++ b/core/datamodel.core.xml
@@ -1285,6 +1285,17 @@
+
+ Dashlet
+
+
+
+
+ bizmodel
+
+
+
+
diff --git a/core/modelreflection.class.inc.php b/core/modelreflection.class.inc.php
index 04966dbb7..2103e0081 100644
--- a/core/modelreflection.class.inc.php
+++ b/core/modelreflection.class.inc.php
@@ -55,6 +55,11 @@ abstract class ModelReflection
abstract public function GetFiltersList($sClass);
abstract public function IsValidFilterCode($sClass, $sFilterCode);
+ /**
+ * @since 3.3.0
+ */
+ abstract public function IsAbstract($sClass): bool;
+
/**
* @param string $sOQL
*
@@ -230,6 +235,11 @@ class ModelReflectionRuntime extends ModelReflection
return MetaModel::IsValidFilterCode($sClass, $sFilterCode);
}
+ public function IsAbstract($sClass): bool
+ {
+ return MetaModel::IsAbstract($sClass);
+ }
+
public function GetQuery($sOQL)
{
return new QueryReflectionRuntime($sOQL, $this);
diff --git a/sources/PropertyTree/ValueType/ValueTypeClass.php b/sources/PropertyTree/ValueType/ValueTypeClass.php
index ad749bb58..ca0a1e00d 100644
--- a/sources/PropertyTree/ValueType/ValueTypeClass.php
+++ b/sources/PropertyTree/ValueType/ValueTypeClass.php
@@ -7,13 +7,44 @@
namespace Combodo\iTop\PropertyTree\ValueType;
+use Combodo\iTop\DesignElement;
+use Combodo\iTop\Forms\Block\Base\ChoiceFormBlock;
use Combodo\iTop\Forms\Block\Base\TextFormBlock;
use Combodo\iTop\PropertyTree\ValueType\AbstractValueType;
+use Combodo\iTop\Service\DependencyInjection\DIService;
+use utils;
class ValueTypeClass extends AbstractValueType
{
+ protected array $aCategories = [];
+
public function GetFormBlockClass(): string
{
- return TextFormBlock::class;
+ return ChoiceFormBlock::class;
}
+
+ public function InitFromDomNode(DesignElement $oDomNode): void
+ {
+ parent::InitFromDomNode($oDomNode);
+
+ $sCategories = $oDomNode->GetChildText('categories-csv');
+ /** @var \ModelReflection $oModelReflection */
+ $oModelReflection = DIService::GetInstance()->GetService('ModelReflection');
+
+ $sChoices = "[\n";
+ foreach ($oModelReflection->GetClasses($sCategories, true) as $sClass) {
+ if ($oModelReflection->IsAbstract($sClass)) {
+ continue;
+ }
+ $sValue = utils::QuoteForPHP($sClass);
+ $sChoices .= << $sValue,
+
+PHP;
+ }
+ $sChoices .= "\t\t\t]";
+
+ $this->aFormBlockOptionsForPHP['choices'] = $sChoices;
+ }
+
}
diff --git a/tests/php-unit-tests/unitary-tests/sources/Forms/Compiler/FormsCompilerTest.php b/tests/php-unit-tests/unitary-tests/sources/Forms/Compiler/FormsCompilerTest.php
index ea1863181..8b1ef6f41 100644
--- a/tests/php-unit-tests/unitary-tests/sources/Forms/Compiler/FormsCompilerTest.php
+++ b/tests/php-unit-tests/unitary-tests/sources/Forms/Compiler/FormsCompilerTest.php
@@ -6,6 +6,7 @@
*/
use Combodo\iTop\Forms\Compiler\FormsCompiler;
+use Combodo\iTop\Service\DependencyInjection\DIService;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
class FormsCompilerTest extends ItopDataTestCase
@@ -23,6 +24,8 @@ class FormsCompilerTest extends ItopDataTestCase
*/
public function testCompileFormFromXML(string $sXMLContent, string $sExpectedPHP)
{
+ DIService::GetInstance()->RegisterService('ModelReflection', new ModelReflectionRuntime());
+
$sProducedPHP = FormsCompiler::GetInstance()->CompileFormFromXML($sXMLContent);
$this->AssertPHPCodeIsValid($sProducedPHP);
@@ -46,6 +49,7 @@ class FormsCompilerTest extends ItopDataTestCase
+ test
@@ -60,8 +64,10 @@ class FormFor__basic_test extends Combodo\iTop\Forms\Block\Base\FormBlock
'label' => 'UI:BasicTest:Prop-Title',
]);
- \$this->Add('class_property', 'Combodo\iTop\Forms\Block\Base\TextFormBlock', [
+ \$this->Add('class_property', 'Combodo\iTop\Forms\Block\Base\ChoiceFormBlock', [
'label' => 'UI:BasicTest:Prop-Class',
+ 'choices' => [
+ ],
]);
}
}
@@ -128,6 +134,7 @@ PHP,
+ test
@@ -198,8 +205,10 @@ class FormFor__AllValueTypesTest extends Combodo\iTop\Forms\Block\Base\FormBlock
],
]);
- \$this->Add('class_property', 'Combodo\iTop\Forms\Block\Base\TextFormBlock', [
+ \$this->Add('class_property', 'Combodo\iTop\Forms\Block\Base\ChoiceFormBlock', [
'label' => 'UI:Class',
+ 'choices' => [
+ ],
]);
\$this->Add('class_attribute_property', 'Combodo\iTop\Forms\Block\DataModel\AttributeChoiceFormBlock', [
@@ -365,6 +374,7 @@ PHP,
+ test
@@ -381,8 +391,10 @@ class FormFor__input_binding_test extends Combodo\iTop\Forms\Block\Base\FormBloc
{
protected function BuildForm(): void
{
- \$this->Add('class_property', 'Combodo\iTop\Forms\Block\Base\TextFormBlock', [
+ \$this->Add('class_property', 'Combodo\iTop\Forms\Block\Base\ChoiceFormBlock', [
'label' => 'UI:Class',
+ 'choices' => [
+ ],
]);
\$this->Add('class_attribute_property', 'Combodo\iTop\Forms\Block\DataModel\AttributeChoiceFormBlock', [
@@ -402,12 +414,13 @@ PHP,
+ test
- {{IF(class_property.text = '', 'Person', class_property.text)}}
+ {{IF(class_property.value = '', 'Person', class_property.value)}}
@@ -418,14 +431,16 @@ class FormFor__input_binding_expression extends Combodo\iTop\Forms\Block\Base\Fo
{
protected function BuildForm(): void
{
- \$this->Add('class_property', 'Combodo\iTop\Forms\Block\Base\TextFormBlock', [
+ \$this->Add('class_property', 'Combodo\iTop\Forms\Block\Base\ChoiceFormBlock', [
'label' => 'UI:Class',
+ 'choices' => [
+ ],
]);
\$this->Add('class_attribute_property_class_expression', 'Combodo\iTop\Forms\Block\Expression\StringExpressionFormBlock', [
- 'expression' => 'IF(class_property.text = \'\', \'Person\', class_property.text)',
+ 'expression' => 'IF(class_property.value = \'\', \'Person\', class_property.value)',
])
- ->AddInputDependsOn('class_property.text', 'class_property', 'text');
+ ->AddInputDependsOn('class_property.value', 'class_property', 'value');
\$this->Add('class_attribute_property', 'Combodo\iTop\Forms\Block\DataModel\AttributeChoiceFormBlock', [
'label' => 'UI:ClassAttribute',
@@ -527,6 +542,65 @@ class FormFor__ComplexRelevanceCondition extends Combodo\iTop\Forms\Block\Base\F
->InputDependsOn('visible', 'dependant_property_visible_expression', 'result');
}
}
+PHP,
+ ],
+ 'Class category for value type class' => [
+ 'sXMLContent' => <<
+
+
+
+
+
+ addon/authentication,grant_by_profile,silo
+
+
+
+
+XML,
+ 'sExpectedPHP' => <<Add('class_property', 'Combodo\iTop\Forms\Block\Base\ChoiceFormBlock', [
+ 'label' => 'UI:Class',
+ 'choices' => [
+ \Dict::S('Class:UserExternal') => 'UserExternal',
+ \Dict::S('Class:UserLDAP') => 'UserLDAP',
+ \Dict::S('Class:UserLocal') => 'UserLocal',
+ \Dict::S('Class:AuditRule') => 'AuditRule',
+ \Dict::S('Class:AuditCategory') => 'AuditCategory',
+ \Dict::S('Class:AuditDomain') => 'AuditDomain',
+ \Dict::S('Class:QueryOQL') => 'QueryOQL',
+ \Dict::S('Class:ActionEmail') => 'ActionEmail',
+ \Dict::S('Class:TriggerOnPortalUpdate') => 'TriggerOnPortalUpdate',
+ \Dict::S('Class:TriggerOnStateEnter') => 'TriggerOnStateEnter',
+ \Dict::S('Class:TriggerOnStateLeave') => 'TriggerOnStateLeave',
+ \Dict::S('Class:TriggerOnObjectCreate') => 'TriggerOnObjectCreate',
+ \Dict::S('Class:TriggerOnObjectDelete') => 'TriggerOnObjectDelete',
+ \Dict::S('Class:TriggerOnObjectUpdate') => 'TriggerOnObjectUpdate',
+ \Dict::S('Class:TriggerOnObjectMention') => 'TriggerOnObjectMention',
+ \Dict::S('Class:TriggerOnAttributeBlobDownload') => 'TriggerOnAttributeBlobDownload',
+ \Dict::S('Class:TriggerOnThresholdReached') => 'TriggerOnThresholdReached',
+ \Dict::S('Class:SynchroDataSource') => 'SynchroDataSource',
+ \Dict::S('Class:SynchroAttribute') => 'SynchroAttribute',
+ \Dict::S('Class:SynchroAttExtKey') => 'SynchroAttExtKey',
+ \Dict::S('Class:SynchroAttLinkSet') => 'SynchroAttLinkSet',
+ \Dict::S('Class:SynchroLog') => 'SynchroLog',
+ \Dict::S('Class:SynchroReplica') => 'SynchroReplica',
+ \Dict::S('Class:ActionNewsroom') => 'ActionNewsroom',
+ \Dict::S('Class:TriggerOnAttachmentCreate') => 'TriggerOnAttachmentCreate',
+ \Dict::S('Class:TriggerOnAttachmentDelete') => 'TriggerOnAttachmentDelete',
+ \Dict::S('Class:TriggerOnAttachmentDownload') => 'TriggerOnAttachmentDownload',
+ \Dict::S('Class:OAuthClientAzure') => 'OAuthClientAzure',
+ \Dict::S('Class:OAuthClientGoogle') => 'OAuthClientGoogle',
+ \Dict::S('Class:URP_Profiles') => 'URP_Profiles',
+ \Dict::S('Class:URP_UserOrg') => 'URP_UserOrg',
+ ],
+ ]);
+ }
+}
PHP,
],
'test' => [