N°9065 - XML Definition for Dashlet properties

This commit is contained in:
Eric Espie
2026-01-06 15:59:46 +01:00
parent 904cd0b518
commit efb1bd765b
56 changed files with 2433 additions and 1270 deletions

View File

@@ -94,60 +94,83 @@ class AttributeChoiceFormBlock extends ChoiceFormBlock
public static function ListAttributeCodesByCategory(string $sClass, string $sCategory = ''): array
{
$oModelReflection = ServiceLocator::GetInstance()->get('ModelReflection');
$aNonGroupableAttributes = [
'AttributeLinkedSet',
'AttributeFriendlyName',
'iAttributeNoGroupBy', //we cannot only use iAttributeNoGroupBy since this method is also used by the designer who do not have access to the classes' PHP reflection API. So the known classes has to be listed altogether
'AttributeOneWayPassword',
'AttributeEncryptedString',
'AttributePassword',
];
$aAttributeCodes = [];
switch ($sCategory) {
case 'numeric':
foreach ($oModelReflection->ListAttributes($sClass, 'AttributeDecimal,AttributeDuration,AttributeInteger,AttributePercentage,AttributeSubItem') as $sAttCode => $sAttType) {
$sLabel = $oModelReflection->GetLabel($sClass, $sAttCode);
$aAttributeCodes[$sLabel] = $sAttCode;
}
break;
foreach ($oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType) {
$sLabel = $oModelReflection->GetLabel($sClass, $sAttCode);
case 'groupable':
$aForbiddenAttType = [
'AttributeLinkedSet',
'AttributeFriendlyName',
'iAttributeNoGroupBy', //we cannot only use iAttributeNoGroupBy since this method is also used by the designer who do not have access to the classes' PHP reflection API. So the known classes has to be listed altogether
'AttributeOneWayPassword',
'AttributeEncryptedString',
'AttributePassword',
];
foreach ($oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType) {
foreach ($aForbiddenAttType as $sForbiddenAttType) {
if (is_a($sAttType, $sForbiddenAttType, true)) {
continue 2;
// For external fields, find the real type of the target
$sExtFieldAttCode = $sAttCode;
$sTargetClass = $sClass;
while (is_a($sAttType, 'AttributeExternalField', true)) {
$sExtKeyAttCode = $oModelReflection->GetAttributeProperty($sTargetClass, $sExtFieldAttCode, 'extkey_attcode');
$sTargetAttCode = $oModelReflection->GetAttributeProperty($sTargetClass, $sExtFieldAttCode, 'target_attcode');
$sTargetClass = $oModelReflection->GetAttributeProperty($sTargetClass, $sExtKeyAttCode, 'targetclass');
$aTargetAttCodes = $oModelReflection->ListAttributes($sTargetClass);
$sAttType = $aTargetAttCodes[$sTargetAttCode];
$sExtFieldAttCode = $sTargetAttCode;
}
switch ($sCategory) {
case 'numeric':
if (is_a($sAttType, 'AttributeDecimal', true) ||
is_a($sAttType, 'AttributeDuration', true) ||
is_a($sAttType, 'AttributeInteger', true) ||
is_a($sAttType, 'AttributePercentage', true) ||
is_a($sAttType, 'AttributeSubItem', true)) {
$aAttributeCodes[$sLabel] = $sAttCode;
}
break;
case 'groupable':
foreach ($aNonGroupableAttributes as $sNonGroupableAttribute) {
if (is_a($sAttType, $sNonGroupableAttribute, true)) {
break;
}
}
$sLabel = $oModelReflection->GetLabel($sClass, $sAttCode);
$aAttributeCodes[$sLabel] = $sAttCode;
}
break;
break;
case 'enum':
foreach ($oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType) {
case 'enum':
if (is_a($sAttType, 'AttributeEnum', true)) {
$sLabel = $oModelReflection->GetLabel($sClass, $sAttCode);
$aAttributeCodes[$sLabel] = $sAttCode;
}
}
break;
break;
case 'date':
foreach ($oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType) {
case 'date':
if (is_a($sAttType, 'AttributeDateTime', true)) {
$sLabel = $oModelReflection->GetLabel($sClass, $sAttCode);
$aAttributeCodes[$sLabel] = $sAttCode;
}
}
break;
break;
case '':
foreach ($oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType) {
$sLabel = $oModelReflection->GetLabel($sClass, $sAttCode);
case 'link':
if (is_a($sAttType, 'AttributeLinkedSet', true) ||
is_a($sAttType, 'AttributeLinkedSetIndirect', true) ||
is_a($sAttType, 'AttributeExternalKey', true) ||
is_a($sAttType, 'AttributeHierarchicalKey', true)) {
$aAttributeCodes[$sLabel] = $sAttCode;
}
break;
case 'string':
if (is_a($sAttType, 'AttributeString', true)) {
$aAttributeCodes[$sLabel] = $sAttCode;
}
break;
case 'all':
case '':
$aAttributeCodes[$sLabel] = $sAttCode;
}
break;
break;
}
}
return $aAttributeCodes;

View File

@@ -32,7 +32,6 @@ class AttributeValueChoiceFormBlock extends ChoiceFormBlock
protected function RegisterOptions(OptionsRegister $oOptionsRegister): void
{
parent::RegisterOptions($oOptionsRegister);
$oOptionsRegister->SetOption('multiple', true);
$oOptionsRegister->SetOptionArrayValue('attr', 'size', 5);
$oOptionsRegister->SetOptionArrayValue('attr', 'style', 'height: auto;');
}

View File

@@ -8,7 +8,8 @@
namespace Combodo\iTop\Forms\Block;
use Combodo\iTop\Forms\Block\Base\FormBlock;
use Combodo\iTop\Forms\Compiler\FormsCompiler;
use Combodo\iTop\PropertyType\Compiler\PropertyTypeCompiler;
use Combodo\iTop\PropertyType\PropertyTypeService;
use Combodo\iTop\Service\Cache\DataModelDependantCache;
use Combodo\iTop\Service\DependencyInjection\ServiceLocator;
use ModelReflection;
@@ -17,14 +18,11 @@ use utils;
class FormBlockService
{
public const CACHE_POOL = 'Forms';
private static FormBlockService $oInstance;
private DataModelDependantCache $oCacheService;
protected function __construct(ModelReflection $oModelReflection = null)
{
ServiceLocator::GetInstance()->RegisterService('ModelReflection', $oModelReflection ?? new ModelReflectionRuntime());
$this->oCacheService = DataModelDependantCache::GetInstance();
}
final public static function GetInstance(ModelReflection $oModelReflection = null): FormBlockService
@@ -42,26 +40,13 @@ class FormBlockService
*
* @return \Combodo\iTop\Forms\Block\Base\FormBlock
* @throws \Combodo\iTop\Forms\Block\FormBlockException
* @throws \Combodo\iTop\Forms\Compiler\FormsCompilerException
* @throws \Combodo\iTop\PropertyTree\PropertyTreeException
* @throws \Combodo\iTop\PropertyType\Compiler\PropertyTypeCompilerException
* @throws \Combodo\iTop\PropertyType\PropertyTypeException
* @throws \DOMFormatException
*/
public function GetFormBlockById(string $sId, string $sType): FormBlock
{
$sFilteredId = preg_replace('/[^0-9a-zA-Z_]/', '', $sId);
if (strlen($sFilteredId) === 0 || $sFilteredId !== $sId) {
throw new FormBlockException('Malformed name for block: '.json_encode($sId));
}
$sCacheKey = $sType.'/'.$sFilteredId;
if (!$this->oCacheService->HasEntry(self::CACHE_POOL, $sCacheKey) || utils::IsDevelopmentEnvironment()) {
// Cache not found, compile the form
$sPHPContent = FormsCompiler::GetInstance()->CompileForm($sFilteredId, $sType);
$this->oCacheService->StorePhpContent(FormBlockService::CACHE_POOL, $sCacheKey, "<?php\n\n$sPHPContent");
}
$this->oCacheService->FetchPHP(self::CACHE_POOL, $sCacheKey);
$sFormBlockClass = 'FormFor__'.$sFilteredId;
return new $sFormBlockClass($sFilteredId);
return PropertyTypeService::GetInstance()->GetFormBlockById($sId, $sType);
}
}