diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php
index 4616438fd..93ffacaaa 100644
--- a/core/attributedef.class.inc.php
+++ b/core/attributedef.class.inc.php
@@ -9170,6 +9170,8 @@ class AttributeClassAttCodeSet extends AttributeSet
{
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_STRING;
+ const DEFAULT_PARAM_INCLUDE_CHILD_CLASSES_ATTRIBUTES = false;
+
public function __construct($sCode, array $aParams)
{
parent::__construct($sCode, $aParams);
@@ -9186,69 +9188,111 @@ class AttributeClassAttCodeSet extends AttributeSet
return max(255, 15 * $this->GetMaxItems());
}
+ /**
+ * @param array $aArgs
+ * @param string $sContains
+ *
+ * @return array|null
+ * @throws \CoreException
+ */
public function GetAllowedValues($aArgs = array(), $sContains = '')
{
- if (isset($aArgs['this']))
+ if (!isset($aArgs['this']))
{
- $oHostObj = $aArgs['this'];
- $sTargetClass = $this->Get('class_field');
- $sClass = $oHostObj->Get($sTargetClass);
-
- $aAllowedAttributes = array();
- if (empty($sClass))
- {
- $aAllAttributes = array();
- }
- else
- {
- $aAllAttributes = MetaModel::GetAttributesList($sClass);
- }
- $sAttDefExclusionList = $this->Get('attribute_definition_exclusion_list');
- $aExcludeDefs = array();
- if (!empty($sAttDefExclusionList))
- {
- foreach(explode(',', $sAttDefExclusionList) as $sAttDefName)
- {
- $sAttDefName = trim($sAttDefName);
- $aExcludeDefs[$sAttDefName] = $sAttDefName;
- }
- }
-
- $sAttDefList = $this->Get('attribute_definition_list');
- if (!empty($sAttDefList))
- {
- $aAllowedDefs = array();
- foreach(explode(',', $sAttDefList) as $sAttDefName)
- {
- $sAttDefName = trim($sAttDefName);
- $aAllowedDefs[$sAttDefName] = $sAttDefName;
- }
- foreach($aAllAttributes as $sAttCode)
- {
- $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
- $sAttDef = get_class($oAttDef);
- if (isset($aAllowedDefs[$sAttDef]) && !isset($aExcludeDefs[$sAttDef]))
- {
- $aAllowedAttributes[$sAttCode] = $sAttCode.' ('.MetaModel::GetLabel($sClass, $sAttCode).')';
- }
- }
- }
- else
- {
- foreach($aAllAttributes as $sAttCode)
- {
- $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
- $sAttDef = get_class($oAttDef);
- if (!isset($aExcludeDefs[$sAttDef]))
- {
- $aAllowedAttributes[$sAttCode] = $sAttCode.' ('.MetaModel::GetLabel($sClass, $sAttCode).')';
- }
- }
- }
- return $aAllowedAttributes;
+ return null;
}
- return null;
+ $oHostObj = $aArgs['this'];
+ $sTargetClass = $this->Get('class_field');
+ $sRootClass = $oHostObj->Get($sTargetClass);
+ $bIncludeChildClasses = $this->GetOptional('include_child_classes_attributes', static::DEFAULT_PARAM_INCLUDE_CHILD_CLASSES_ATTRIBUTES);
+
+ $aExcludeDefs = array();
+ $sAttDefExclusionList = $this->Get('attribute_definition_exclusion_list');
+ if (!empty($sAttDefExclusionList))
+ {
+ foreach(explode(',', $sAttDefExclusionList) as $sAttDefName)
+ {
+ $sAttDefName = trim($sAttDefName);
+ $aExcludeDefs[$sAttDefName] = $sAttDefName;
+ }
+ }
+
+ $aAllowedDefs = array();
+ $sAttDefList = $this->Get('attribute_definition_list');
+ if (!empty($sAttDefList))
+ {
+ foreach(explode(',', $sAttDefList) as $sAttDefName)
+ {
+ $sAttDefName = trim($sAttDefName);
+ $aAllowedDefs[$sAttDefName] = $sAttDefName;
+ }
+ }
+
+ $aAllAttributes = array();
+ if (!empty($sRootClass))
+ {
+ $aClasses = array($sRootClass);
+ if($bIncludeChildClasses === true)
+ {
+ $aClasses = $aClasses + MetaModel::EnumChildClasses($sRootClass, ENUM_CHILD_CLASSES_EXCLUDETOP);
+ }
+
+ foreach($aClasses as $sClass)
+ {
+ foreach(MetaModel::GetAttributesList($sClass) as $sAttCode)
+ {
+ // Add attribute only if not already there (can be in leaf classes but not the root)
+ if(!array_key_exists($sAttCode, $aAllAttributes))
+ {
+ $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
+ $sAttDefClass = get_class($oAttDef);
+
+ // Skip excluded attdefs
+ if(isset($aExcludeDefs[$sAttDefClass]))
+ {
+ continue;
+ }
+ // Skip not allowed attdefs only if list specified
+ if(!empty($aAllowedDefs) && !isset($aAllowedDefs[$sAttDefClass]))
+ {
+ continue;
+ }
+
+ $aAllAttributes[$sAttCode] = array(
+ 'classes' => array($sClass),
+ );
+ }
+ else
+ {
+ $aAllAttributes[$sAttCode]['classes'][] = $sClass;
+ }
+ }
+ }
+ }
+
+ $aAllowedAttributes = array();
+ foreach($aAllAttributes as $sAttCode => $aAttData)
+ {
+ $iAttClassesCount = count($aAttData['classes']);
+ $sAttFirstClass = $aAttData['classes'][0];
+ $sAttLabel = MetaModel::GetLabel($sAttFirstClass, $sAttCode);
+
+ if($sAttFirstClass === $sRootClass)
+ {
+ $sLabel = Dict::Format('Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass', $sAttCode, $sAttLabel);
+ }
+ elseif($iAttClassesCount === 1)
+ {
+ $sLabel = Dict::Format('Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass', $sAttCode, $sAttLabel, MetaModel::GetName($sAttFirstClass));
+ }
+ else
+ {
+ $sLabel = Dict::Format('Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses', $sAttCode, $sAttLabel);
+ }
+ $aAllowedAttributes[$sAttCode] = $sLabel;
+ }
+ return $aAllowedAttributes;
}
/**
@@ -9338,7 +9382,19 @@ class AttributeClassAttCodeSet extends AttributeSet
{
try
{
- $aLocalizedValues[] = ''.$sAttCode.'';
+ $sAttClass = $sClass;
+
+ // Look for the first class (current or children) that have this attcode
+ foreach(MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sChildClass)
+ {
+ if(MetaModel::IsValidAttCode($sChildClass, $sAttCode))
+ {
+ $sAttClass = $sChildClass;
+ break;
+ }
+ }
+
+ $aLocalizedValues[] = ''.$sAttCode.'';
} catch (Exception $e)
{
// Ignore bad values
diff --git a/core/trigger.class.inc.php b/core/trigger.class.inc.php
index b77bffa30..593115ece 100644
--- a/core/trigger.class.inc.php
+++ b/core/trigger.class.inc.php
@@ -595,7 +595,7 @@ class TriggerOnThresholdReached extends TriggerOnObject
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
- MetaModel::Init_AddAttribute(new AttributeString("stop_watch_code", array("allowed_values" => null, "sql" => "stop_watch_code", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
+ MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('stop_watch_code', array("allowed_values" => null, "class_field" => "target_class", "sql" => "stop_watch_code", "default_value" => null, "is_null_allowed" => false, "max_items" => 1, "min_items" => 1, "attribute_definition_exclusion_list" => null, "attribute_definition_list" => "AttributeStopWatch", "include_child_classes_attributes" => true, "depends_on" => array('target_class'))));
MetaModel::Init_AddAttribute(new AttributeString("threshold_index", array("allowed_values" => null, "sql" => "threshold_index", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
// Display lists
@@ -606,5 +606,3 @@ class TriggerOnThresholdReached extends TriggerOnObject
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
}
-
-?>
diff --git a/dictionaries/cs.dictionary.itop.core.php b/dictionaries/cs.dictionary.itop.core.php
index 496093c04..78fb4fd6e 100755
--- a/dictionaries/cs.dictionary.itop.core.php
+++ b/dictionaries/cs.dictionary.itop.core.php
@@ -47,6 +47,9 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
'Core:AttributeTagSet' => 'List of tags~~',
'Core:AttributeTagSet+' => '~~',
'Core:AttributeSet:placeholder' => 'click to add~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log~~',
'Core:AttributeCaseLog+' => '~~',
diff --git a/dictionaries/da.dictionary.itop.core.php b/dictionaries/da.dictionary.itop.core.php
index c8dabd9be..75fdd1c9d 100644
--- a/dictionaries/da.dictionary.itop.core.php
+++ b/dictionaries/da.dictionary.itop.core.php
@@ -45,6 +45,9 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
'Core:AttributeTagSet' => 'List of tags~~',
'Core:AttributeTagSet+' => '~~',
'Core:AttributeSet:placeholder' => 'click to add~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log~~',
'Core:AttributeCaseLog+' => '~~',
diff --git a/dictionaries/de.dictionary.itop.core.php b/dictionaries/de.dictionary.itop.core.php
index 6730fd19d..98707ee7a 100644
--- a/dictionaries/de.dictionary.itop.core.php
+++ b/dictionaries/de.dictionary.itop.core.php
@@ -44,6 +44,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Core:AttributeTagSet' => 'Liste von Tags',
'Core:AttributeTagSet+' => 'List von Tags',
'Core:AttributeSet:placeholder' => 'Zum Hinzufügen klicken',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log',
'Core:AttributeCaseLog+' => '',
diff --git a/dictionaries/en.dictionary.itop.core.php b/dictionaries/en.dictionary.itop.core.php
index c92869237..fbae83f62 100644
--- a/dictionaries/en.dictionary.itop.core.php
+++ b/dictionaries/en.dictionary.itop.core.php
@@ -45,6 +45,9 @@ Dict::Add('EN US', 'English', 'English', array(
'Core:AttributeTagSet' => 'List of tags',
'Core:AttributeTagSet+' => '',
'Core:AttributeSet:placeholder' => 'click to add',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)',
'Core:AttributeCaseLog' => 'Log',
'Core:AttributeCaseLog+' => '',
diff --git a/dictionaries/es_cr.dictionary.itop.core.php b/dictionaries/es_cr.dictionary.itop.core.php
index 7efa05a33..e5787e864 100644
--- a/dictionaries/es_cr.dictionary.itop.core.php
+++ b/dictionaries/es_cr.dictionary.itop.core.php
@@ -45,6 +45,9 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
'Core:AttributeTagSet' => 'List of tags~~',
'Core:AttributeTagSet+' => '~~',
'Core:AttributeSet:placeholder' => 'click to add~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log~~',
'Core:AttributeCaseLog+' => '~~',
diff --git a/dictionaries/fr.dictionary.itop.core.php b/dictionaries/fr.dictionary.itop.core.php
index 5d15648a1..c89c4ec0a 100644
--- a/dictionaries/fr.dictionary.itop.core.php
+++ b/dictionaries/fr.dictionary.itop.core.php
@@ -43,6 +43,9 @@ Dict::Add('FR FR', 'French', 'Français', array(
'Core:AttributeTagSet' => 'Liste d\'étiquettes',
'Core:AttributeTagSet+' => '',
'Core:AttributeSet:placeholder' => 'cliquer pour ajouter',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s de la classe %3$s)',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log~~',
'Core:AttributeCaseLog+' => '~~',
diff --git a/dictionaries/hu.dictionary.itop.core.php b/dictionaries/hu.dictionary.itop.core.php
index 073cced13..31d8ffdbf 100755
--- a/dictionaries/hu.dictionary.itop.core.php
+++ b/dictionaries/hu.dictionary.itop.core.php
@@ -43,6 +43,9 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
'Core:AttributeTagSet' => 'List of tags~~',
'Core:AttributeTagSet+' => '~~',
'Core:AttributeSet:placeholder' => 'click to add~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log~~',
'Core:AttributeCaseLog+' => '~~',
diff --git a/dictionaries/it.dictionary.itop.core.php b/dictionaries/it.dictionary.itop.core.php
index 4c723d46d..c39566c31 100644
--- a/dictionaries/it.dictionary.itop.core.php
+++ b/dictionaries/it.dictionary.itop.core.php
@@ -45,6 +45,9 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
'Core:AttributeTagSet' => 'List of tags~~',
'Core:AttributeTagSet+' => '~~',
'Core:AttributeSet:placeholder' => 'click to add~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log~~',
'Core:AttributeCaseLog+' => '~~',
diff --git a/dictionaries/ja.dictionary.itop.core.php b/dictionaries/ja.dictionary.itop.core.php
index 19a9b8dbb..cd94170ba 100644
--- a/dictionaries/ja.dictionary.itop.core.php
+++ b/dictionaries/ja.dictionary.itop.core.php
@@ -43,6 +43,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
'Core:AttributeTagSet' => 'List of tags~~',
'Core:AttributeTagSet+' => '~~',
'Core:AttributeSet:placeholder' => 'click to add~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log~~',
'Core:AttributeCaseLog+' => '~~',
diff --git a/dictionaries/nl.dictionary.itop.core.php b/dictionaries/nl.dictionary.itop.core.php
index bb57c0b84..4a0faa728 100644
--- a/dictionaries/nl.dictionary.itop.core.php
+++ b/dictionaries/nl.dictionary.itop.core.php
@@ -51,6 +51,9 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
'Core:AttributeTagSet' => 'Lijst van tags',
'Core:AttributeTagSet+' => '',
'Core:AttributeSet:placeholder' => 'klik om toe te voegen',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log',
'Core:AttributeCaseLog+' => '',
diff --git a/dictionaries/pt_br.dictionary.itop.core.php b/dictionaries/pt_br.dictionary.itop.core.php
index 5b8fabb2d..1dad95981 100644
--- a/dictionaries/pt_br.dictionary.itop.core.php
+++ b/dictionaries/pt_br.dictionary.itop.core.php
@@ -45,6 +45,9 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
'Core:AttributeTagSet' => 'List of tags~~',
'Core:AttributeTagSet+' => '~~',
'Core:AttributeSet:placeholder' => 'click to add~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log~~',
'Core:AttributeCaseLog+' => '~~',
diff --git a/dictionaries/ru.dictionary.itop.core.php b/dictionaries/ru.dictionary.itop.core.php
index f05f6c3ec..f6852ae1e 100644
--- a/dictionaries/ru.dictionary.itop.core.php
+++ b/dictionaries/ru.dictionary.itop.core.php
@@ -32,6 +32,9 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
'Core:AttributeTagSet' => 'Список тегов',
'Core:AttributeTagSet+' => '',
'Core:AttributeSet:placeholder' => 'нажмите, чтобы добавить',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Журнал',
'Core:AttributeCaseLog+' => '',
diff --git a/dictionaries/tr.dictionary.itop.core.php b/dictionaries/tr.dictionary.itop.core.php
index 70941ea4d..bd4737964 100644
--- a/dictionaries/tr.dictionary.itop.core.php
+++ b/dictionaries/tr.dictionary.itop.core.php
@@ -53,6 +53,9 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
'Core:AttributeTagSet' => 'List of tags~~',
'Core:AttributeTagSet+' => '~~',
'Core:AttributeSet:placeholder' => 'click to add~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log~~',
'Core:AttributeCaseLog+' => '~~',
diff --git a/dictionaries/zh.dictionary.itop.core.php b/dictionaries/zh.dictionary.itop.core.php
index 1fd4b9c61..805aa73f9 100644
--- a/dictionaries/zh.dictionary.itop.core.php
+++ b/dictionaries/zh.dictionary.itop.core.php
@@ -45,6 +45,9 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Core:AttributeTagSet' => 'List of tags~~',
'Core:AttributeTagSet+' => '~~',
'Core:AttributeSet:placeholder' => 'click to add~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromClass' => '%1$s (%2$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromOneChildClass' => '%1$s (%2$s from %3$s)~~',
+ 'Core:AttributeClassAttCodeSet:ItemLabel:AttributeFromSeveralChildClasses' => '%1$s (%2$s from child classes)~~',
'Core:AttributeCaseLog' => 'Log~~',
'Core:AttributeCaseLog+' => '~~',