diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 637aee863..1b18299cd 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -284,6 +284,11 @@ abstract class AttributeDefinition } // table, key field, name field + + /** + * @return string + * @deprecated never used + */ public function ListDBJoins() { return ""; @@ -710,7 +715,11 @@ abstract class AttributeDefinition { return null; } - + + /** + * @return mixed|null + * @deprecated never used + */ public function MakeValue() { $sComputeFunc = $this->Get("compute_func"); @@ -5898,9 +5907,15 @@ class AttributeExternalField extends AttributeDefinition * @see TagSetFieldData * @since 2.6 N°931 tag fields */ -class AttributeTagSet extends AttributeDBField +class AttributeTagSet extends AttributeDBFieldVoid { const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_STRING; + static public function ListExpectedParams() + { + return array_merge(parent::ListExpectedParams(), array("is_null_allowed")); + } + public function GetDefaultValue(DBObject $oHostObject = null) {return null;} + public function IsNullAllowed() {return $this->Get("is_null_allowed");} public function GetEditClass() { return "String"; @@ -5968,6 +5983,24 @@ class AttributeTagSet extends AttributeDBField return $oTagSet; } + /** + * Get the value from a given string (plain text, CSV import) + * + * @param string $sProposedValue + * @param bool $bLocalizedValue + * @param string $sSepItem + * @param string $sSepAttribute + * @param string $sSepValue + * @param string $sAttributeQualifier + * + * @return mixed null if no match could be found + * @throws \Exception + */ + public function MakeValueFromString($sProposedValue, $bLocalizedValue = false, $sSepItem = null, $sSepAttribute = null, $sSepValue = null, $sAttributeQualifier = null) + { + // TODO $bLocalizedValue + return $this->MakeRealValue($sProposedValue, null); + } public function GetNullValue() { return new ormTagSet(MetaModel::GetAttributeOrigin($this->GetHostClass(), $this->GetCode()), $this->GetCode()); @@ -6023,7 +6056,7 @@ class AttributeTagSet extends AttributeDBField */ public function GetAsHTML($value, $oHostObject = null, $bLocalize = true) { - if (is_object($value) && ($value instanceof ormTagSet)) + if ($value instanceof ormTagSet) { if ($bLocalize) { @@ -6033,9 +6066,19 @@ class AttributeTagSet extends AttributeDBField { $aValues = $value->GetValue(); } - return implode(' ', $aValues); + if (empty($aValues)) + { + return ''; + } + return ''.implode('', $aValues).''; } - return null; + if (is_string($value)) + { + $oValue = $this->MakeRealValue($value, $oHostObject); + return $this->GetAsHTML($oValue, $oHostObject, $bLocalize); + } + return parent::GetAsHTML($value, $oHostObject, $bLocalize); + } /** @@ -6094,7 +6137,7 @@ class AttributeTagSet extends AttributeDBField { $aValues = $value->GetValue(); } - $sRes = implode(' ', $aValues); + $sRes = implode('|', $aValues); } else { diff --git a/core/cmdbchangeop.class.inc.php b/core/cmdbchangeop.class.inc.php index f6145083d..dae48b873 100644 --- a/core/cmdbchangeop.class.inc.php +++ b/core/cmdbchangeop.class.inc.php @@ -242,6 +242,64 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute return $sResult; } } + +/** + * Record the modification of a tag set attribute + * + * @package iTopORM + */ +class CMDBChangeOpSetAttributeTagSet extends CMDBChangeOpSetAttribute +{ + public static function Init() + { + $aParams = array + ( + "category" => "core/cmdb", + "key_type" => "", + "name_attcode" => "change", + "state_attcode" => "", + "reconc_keys" => array(), + "db_table" => "priv_changeop_setatt_tagset", + "db_key_field" => "id", + "db_finalclass_field" => "", + ); + MetaModel::Init_Params($aParams); + MetaModel::Init_InheritAttributes(); + MetaModel::Init_AddAttribute(new AttributeString("oldvalue", array("allowed_values"=>null, "sql"=>"oldvalue", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeString("newvalue", array("allowed_values"=>null, "sql"=>"newvalue", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); + + // Display lists + MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for the complete details + MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode', 'oldvalue', 'newvalue')); // Attributes to be displayed for a list + } + + /** + * Describe (as a text string) the modifications corresponding to this change + */ + public function GetDescription() + { + $sResult = ''; + $sTargetObjectClass = $this->Get('objclass'); + $oTargetObjectKey = $this->Get('objkey'); + $sAttCode = $this->Get('attcode'); + $oTargetSearch = new DBObjectSearch($sTargetObjectClass); + $oTargetSearch->AddCondition('id', $oTargetObjectKey, '='); + + $oMonoObjectSet = new DBObjectSet($oTargetSearch); + if (UserRights::IsActionAllowedOnAttribute($sTargetObjectClass, $sAttCode, UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES) + { + if (!MetaModel::IsValidAttCode($this->Get('objclass'), $this->Get('attcode'))) return ''; // Protects against renamed attributes... + + $oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode')); + $sAttName = $oAttDef->GetLabel(); + $sNewValue = $this->Get('newvalue'); + $sOldValue = $this->Get('oldvalue'); + $sResult = $oAttDef->DescribeChangeAsHTML($sOldValue, $sNewValue); + } + return $sResult; + } +} + /** * Record the modification of an URL * diff --git a/core/cmdbobject.class.inc.php b/core/cmdbobject.class.inc.php index 7089057bf..b75559c6d 100644 --- a/core/cmdbobject.class.inc.php +++ b/core/cmdbobject.class.inc.php @@ -409,7 +409,19 @@ abstract class CMDBObject extends DBObject $oMyChangeOp->Set("newvalue", $value); $iId = $oMyChangeOp->DBInsertNoReload(); } - else + elseif ($oAttDef instanceOf AttributeTagSet) + { + // Tag Set + // + $oMyChangeOp = MetaModel::NewObject("CMDBChangeOpSetAttributeTagSet"); + $oMyChangeOp->Set("objclass", get_class($this)); + $oMyChangeOp->Set("objkey", $this->GetKey()); + $oMyChangeOp->Set("attcode", $sAttCode); + $oMyChangeOp->Set("oldvalue", implode(' ', $original->GetValue())); + $oMyChangeOp->Set("newvalue", implode(' ', $value->GetValue())); + $iId = $oMyChangeOp->DBInsertNoReload(); + } + else { // Scalars // diff --git a/core/excelbulkexport.class.inc.php b/core/excelbulkexport.class.inc.php index ed15c9465..0a93193b4 100644 --- a/core/excelbulkexport.class.inc.php +++ b/core/excelbulkexport.class.inc.php @@ -188,11 +188,16 @@ EOF $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); $sRet = $oAttDef->GetAsCSV($value, '', '', $oObj); } - else if ($value instanceOf ormDocument) - { - $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); - $sRet = $oAttDef->GetAsCSV($value, '', '', $oObj); - } + else if ($value instanceOf ormDocument) + { + $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); + $sRet = $oAttDef->GetAsCSV($value, '', '', $oObj); + } + else if ($value instanceOf ormTagSet) + { + $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); + $sRet = $oAttDef->GetAsCSV($value, '', '', $oObj); + } else { $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); diff --git a/core/metamodel.class.php b/core/metamodel.class.php index 3c5b06e41..711074b43 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -1024,7 +1024,7 @@ abstract class MetaModel /** * array of ("classname" => array of attributes) * - * @var array + * @var \AttributeDefinition[] */ private static $m_aAttribDefs = array(); /** diff --git a/core/tagsetfield.class.inc.php b/core/tagsetfield.class.inc.php index 5a583de36..0947b7190 100644 --- a/core/tagsetfield.class.inc.php +++ b/core/tagsetfield.class.inc.php @@ -83,12 +83,12 @@ abstract class TagSetFieldData extends cmdbAbstractObject "allowed_values" => null, "sql" => "is_default", "default_value" => false, - "is_null_allowed" => false, + "is_null_allowed" => true, "depends_on" => array() ))); - MetaModel::Init_SetZListItems('details', array('tag_code', 'tag_label', 'tag_description', 'is_default')); + MetaModel::Init_SetZListItems('details', array('tag_code', 'tag_label', 'tag_description', 'tag_class', 'tag_attcode')); MetaModel::Init_SetZListItems('standard_search', array('tag_code', 'tag_label', 'tag_description', 'is_default')); MetaModel::Init_SetZListItems('list', array('tag_code', 'tag_label', 'tag_description', 'is_default')); } diff --git a/css/light-grey.css b/css/light-grey.css index 465e5821b..dead22504 100644 --- a/css/light-grey.css +++ b/css/light-grey.css @@ -2862,3 +2862,11 @@ table.listResults .originColor { .menu-icon-select > .ui-menu-item { padding: 0.3em 3%; } +.attribute-tagset { + display: inline-block; + padding: 3px; + background-color: grey; + color: white; + margin-right: 3px; + border-radius: 4px; +} diff --git a/css/light-grey.scss b/css/light-grey.scss index 00fb6f8da..677e46e95 100644 --- a/css/light-grey.scss +++ b/css/light-grey.scss @@ -3259,4 +3259,13 @@ table.listResults .originColor{ } .menu-icon-select > .ui-menu-item{ padding: .3em 3%; +} + +.attribute-tagset{ + display: inline-block; + padding: 3px; + background-color: grey; + color: white; + margin-right: 3px; + border-radius: 4px; } \ No newline at end of file diff --git a/setup/compiler.class.inc.php b/setup/compiler.class.inc.php index e64074cb0..e45518fbd 100644 --- a/setup/compiler.class.inc.php +++ b/setup/compiler.class.inc.php @@ -1395,7 +1395,6 @@ EOF $aParameters['sql'] = $this->GetMandatoryPropString($oField, 'sql'); $aParameters['is_null_allowed'] = $this->GetPropBoolean($oField, 'is_null_allowed', false); $aParameters['depends_on'] = $sDependencies; - $aParameters['default_value'] = ''; } else { diff --git a/setup/xmldataloader.class.inc.php b/setup/xmldataloader.class.inc.php index d5f82a06c..da22e8712 100644 --- a/setup/xmldataloader.class.inc.php +++ b/setup/xmldataloader.class.inc.php @@ -273,6 +273,10 @@ class XMLDataLoader $oDoc = new ormDocument($data, $sMimeType, $sFileName); $oTargetObj->Set($sAttCode, $oDoc); } + elseif ($oAttDef instanceof AttributeTagSet) + { + // TODO + } else { $value = (string)$oSubNode;