mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°962: TagSet Attribute definition and values (with unit tests on values)
SVN:b931[6024]
This commit is contained in:
committed by
Pierre Goiffon
parent
157193c831
commit
9631021f84
@@ -1165,6 +1165,14 @@ class RestUtils
|
||||
}
|
||||
$value = DBObjectSet::FromArray($sLnkClass, $aLinks);
|
||||
}
|
||||
elseif ($oAttDef instanceof AttributeTagSet)
|
||||
{
|
||||
if (!is_array($value))
|
||||
{
|
||||
throw new Exception("A tag set must be defined by an array of objects");
|
||||
}
|
||||
$value = $oAttDef->FromJSONToValue($value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = $oAttDef->FromJSONToValue($value);
|
||||
|
||||
@@ -31,6 +31,7 @@ require_once('ormstopwatch.class.inc.php');
|
||||
require_once('ormpassword.class.inc.php');
|
||||
require_once('ormcaselog.class.inc.php');
|
||||
require_once('ormlinkset.class.inc.php');
|
||||
require_once('ormtagset.class.inc.php');
|
||||
require_once('htmlsanitizer.class.inc.php');
|
||||
require_once(APPROOT.'sources/autoload.php');
|
||||
require_once('customfieldshandler.class.inc.php');
|
||||
@@ -4210,7 +4211,7 @@ class AttributeEnum extends AttributeString
|
||||
{
|
||||
if ($oFormField === null)
|
||||
{
|
||||
// TODO : We should check $this->Get('display_style') and create a Radio / Select / ... regarding its value
|
||||
// Later : We should check $this->Get('display_style') and create a Radio / Select / ... regarding its value
|
||||
$sFormFieldClass = static::GetFormFieldClass();
|
||||
$oFormField = new $sFormFieldClass($this->GetCode());
|
||||
}
|
||||
@@ -5297,7 +5298,7 @@ class AttributeExternalKey extends AttributeDBFieldVoid
|
||||
{
|
||||
if ($oFormField === null)
|
||||
{
|
||||
// TODO : We should check $this->Get('display_style') and create a Radio / Select / ... regarding its value
|
||||
// Later : We should check $this->Get('display_style') and create a Radio / Select / ... regarding its value
|
||||
$sFormFieldClass = static::GetFormFieldClass();
|
||||
$oFormField = new $sFormFieldClass($this->GetCode());
|
||||
}
|
||||
@@ -5363,7 +5364,7 @@ class AttributeHierarchicalKey extends AttributeExternalKey
|
||||
unset($aParams[$idx]);
|
||||
$idx = array_search('jointype', $aParams);
|
||||
unset($aParams[$idx]);
|
||||
return $aParams; // TODO: mettre les bons parametres ici !!
|
||||
return $aParams; // Later: mettre les bons parametres ici !!
|
||||
}
|
||||
|
||||
public function GetEditClass() {return "ExtKey";}
|
||||
@@ -5899,23 +5900,216 @@ class AttributeExternalField extends AttributeDefinition
|
||||
*/
|
||||
class AttributeTagSet extends AttributeString
|
||||
{
|
||||
//TODO SQL type length (nb of tags per record, max tag length)
|
||||
//TODO implement ??
|
||||
//TODO specific filters
|
||||
public function RequiresIndex()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public function GetEditClass() {return "TagSet";}
|
||||
|
||||
public function RequiresFullTextIndex()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
protected function GetSQLCol($bFullSpec = false)
|
||||
{
|
||||
return 'VARCHAR(1024)'
|
||||
.CMDBSource::GetSqlStringColumnDefinition()
|
||||
.($bFullSpec ? $this->GetSQLColSpec() : '');
|
||||
}
|
||||
|
||||
public function RequiresIndex() {return true;}
|
||||
|
||||
public function RequiresFullTextIndex() {return true;}
|
||||
|
||||
public function Equals($val1, $val2) {
|
||||
if (($val1 instanceof ormTagSet) && ($val2 instanceof ormTagSet))
|
||||
{
|
||||
return $val1->Equals($val2);
|
||||
}
|
||||
return ($val1 == $val2);
|
||||
}
|
||||
|
||||
/**
|
||||
* force an allowed value (type conversion and possibly forces a value as mySQL would do upon writing!
|
||||
*
|
||||
* @param $proposedValue
|
||||
* @param $oHostObj
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function MakeRealValue($proposedValue, $oHostObj)
|
||||
{
|
||||
$oTagSet = new ormTagSet($this->GetHostClass(), $this->GetCode());
|
||||
if (is_string($proposedValue) && !empty($proposedValue))
|
||||
{
|
||||
$aTagCodes = explode(' ', "$proposedValue");
|
||||
$oTagSet->SetValue($aTagCodes);
|
||||
}
|
||||
return $oTagSet;
|
||||
}
|
||||
|
||||
public function ScalarToSQL($value)
|
||||
{
|
||||
if (empty($value))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
if ($value instanceof ormTagSet)
|
||||
{
|
||||
$aValues = $value->GetValue();
|
||||
return implode(' ', $aValues);
|
||||
}
|
||||
throw new CoreWarning('Expected the attribute value to be a string', array('found_type' => gettype($value), 'value' => $value, 'class' => $this->GetHostClass(), 'attribute' => $this->GetCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param \DBObject $oHostObject
|
||||
* @param bool $bLocalize
|
||||
*
|
||||
* @return string|null
|
||||
*
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function GetAsHTML($value, $oHostObject = null, $bLocalize = true)
|
||||
{
|
||||
if (is_object($value) && ($value instanceof ormTagSet))
|
||||
{
|
||||
$aValues = $value->GetValue();
|
||||
return implode(' ', $aValues);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param \DBObject $oHostObject
|
||||
* @param bool $bLocalize
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function GetAsXML($value, $oHostObject = null, $bLocalize = true)
|
||||
{
|
||||
if (is_object($value) && ($value instanceof ormTagSet))
|
||||
{
|
||||
$sRes = "<Set>\n";
|
||||
$aValues = $value->GetValue();
|
||||
if (!empty($aValuess))
|
||||
{
|
||||
$sRes .= '<Tag>'.implode('</Tag><Tag>', $aValues).'</Tag>';
|
||||
}
|
||||
$sRes .= "</Set>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sRes = '';
|
||||
}
|
||||
return $sRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param string $sSeparator
|
||||
* @param string $sTextQualifier
|
||||
* @param \DBObject $oHostObject
|
||||
* @param bool $bLocalize
|
||||
* @param bool $bConvertToPlainText
|
||||
*
|
||||
* @return mixed|string
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function GetAsCSV($value, $sSeparator = ',', $sTextQualifier = '"', $oHostObject = null, $bLocalize = true, $bConvertToPlainText = false)
|
||||
{
|
||||
$sSepItem = MetaModel::GetConfig()->Get('link_set_item_separator');
|
||||
|
||||
if (is_object($value) && ($value instanceof ormTagSet))
|
||||
{
|
||||
$aValues = $value->GetValue();
|
||||
$sRes = implode($sSepItem, $aValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sRes = '';
|
||||
}
|
||||
$sRes = str_replace($sTextQualifier, $sTextQualifier.$sTextQualifier, $sRes);
|
||||
$sRes = $sTextQualifier.$sRes.$sTextQualifier;
|
||||
return $sRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the available verbs for 'GetForTemplate'
|
||||
*/
|
||||
public function EnumTemplateVerbs()
|
||||
{
|
||||
return array(
|
||||
'' => 'Plain text (unlocalized) representation',
|
||||
'html' => 'HTML representation (unordered list)',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get various representations of the value, for insertion into a template (e.g. in Notifications)
|
||||
*
|
||||
* @param mixed $value The current value of the field
|
||||
* @param string $sVerb The verb specifying the representation of the value
|
||||
* @param DBObject $oHostObject The object
|
||||
* @param bool $bLocalize Whether or not to localize the value
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetForTemplate($value, $sVerb, $oHostObject = null, $bLocalize = true)
|
||||
{
|
||||
if (is_object($value) && ($value instanceof ormTagSet))
|
||||
{
|
||||
$aValues = $value->GetValue();
|
||||
|
||||
switch ($sVerb)
|
||||
{
|
||||
case '':
|
||||
return implode("\n", $aValues);
|
||||
|
||||
case 'html':
|
||||
return '<ul><li>'.implode("</li><li>", $aValues).'</li></ul>';
|
||||
|
||||
default:
|
||||
throw new Exception("Unknown verb '$sVerb' for attribute ".$this->GetCode().' in class '.get_class($oHostObject));
|
||||
}
|
||||
}
|
||||
throw new CoreUnexpectedValue("Bad value '$value' for attribute ".$this->GetCode().' in class '.get_class($oHostObject));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get a value that will be JSON encoded
|
||||
* The operation is the opposite to FromJSONToValue
|
||||
*
|
||||
* @param \ormTagSet $value
|
||||
*
|
||||
* @return array
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function GetForJSON($value)
|
||||
{
|
||||
$aRet = array();
|
||||
if (is_object($value) && ($value instanceof ormTagSet))
|
||||
{
|
||||
$aRet = $value->GetValue();
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to form a value, given JSON decoded data
|
||||
* The operation is the opposite to GetForJSON
|
||||
*
|
||||
* @param $json
|
||||
*
|
||||
* @return \ormTagSet
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function FromJSONToValue($json)
|
||||
{
|
||||
$oSet = new ormTagSet($this->GetHostClass(), $this->GetCode());
|
||||
$oSet->SetValue($json);
|
||||
return $oSet;
|
||||
}
|
||||
|
||||
public function IsNullAllowed()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7105,6 +7105,12 @@ abstract class MetaModel
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
public static function GetTagDataClass($sClass, $sAttCode)
|
||||
{
|
||||
$sTagSuffix = $sClass.'_'.$sAttCode;
|
||||
return 'TagSetFieldDataFor_'.$sTagSuffix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
294
core/ormtagset.class.inc.php
Normal file
294
core/ormtagset.class.inc.php
Normal file
@@ -0,0 +1,294 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2010-2018 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* Date: 24/08/2018
|
||||
* Time: 14:35
|
||||
*/
|
||||
|
||||
require_once('dbobjectiterator.php');
|
||||
|
||||
final class ormTagSet
|
||||
{
|
||||
private $sClass; // class of the tag
|
||||
private $sAttCode; // attcode of the tag
|
||||
|
||||
private $aAllowedTags;
|
||||
private $oOriginalSet;
|
||||
private $aOriginalObjects = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bHasDelta = false;
|
||||
|
||||
/**
|
||||
* Object from the original set, minus the removed objects
|
||||
* @var DBObject[] array of iObjectId => DBObject
|
||||
*/
|
||||
private $aPreserved = array();
|
||||
|
||||
/**
|
||||
* @var DBObject[] New items
|
||||
*/
|
||||
private $aAdded = array();
|
||||
|
||||
/**
|
||||
* @var int[] Removed items
|
||||
*/
|
||||
private $aRemoved = array();
|
||||
|
||||
/**
|
||||
* __toString magical function overload.
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* ormTagSet constructor.
|
||||
*
|
||||
* @param string $sClass
|
||||
* @param string $sAttCode
|
||||
* @param DBObjectSet|null $oOriginalSet
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct($sClass, $sAttCode, DBObjectSet $oOriginalSet = null)
|
||||
{
|
||||
$this->sAttCode = $sAttCode;
|
||||
$this->oOriginalSet = $oOriginalSet ? clone $oOriginalSet : null;
|
||||
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if (!$oAttDef instanceof AttributeTagSet)
|
||||
{
|
||||
throw new Exception("ormTagSet: field {$sClass}:{$sAttCode} is not a tag");
|
||||
}
|
||||
$this->sClass = $sClass;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $aTagCodes
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue when a code is invalid
|
||||
*/
|
||||
public function SetValue($aTagCodes)
|
||||
{
|
||||
if (!is_array($aTagCodes))
|
||||
{
|
||||
throw new CoreUnexpectedValue("Wrong value {$aTagCodes} for {$this->sClass}:{$this->sAttCode}");
|
||||
}
|
||||
|
||||
$oTags = array();
|
||||
foreach($aTagCodes as $sTagCode)
|
||||
{
|
||||
$oTag = $this->GetTagFromCode($sTagCode);
|
||||
$oTags[$oTag->GetKey()] = $oTag;
|
||||
}
|
||||
|
||||
$this->aPreserved = &$oTags;
|
||||
$this->aRemoved = array();
|
||||
$this->aAdded = array();
|
||||
$this->aOriginalObjects = $oTags;
|
||||
$this->bHasDelta = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array of tag codes
|
||||
*/
|
||||
public function GetValue()
|
||||
{
|
||||
$aValue = array();
|
||||
foreach ($this->aPreserved as $oTag)
|
||||
{
|
||||
try
|
||||
{
|
||||
$aValue[] = $oTag->Get('tag_code');
|
||||
} catch (CoreException $e)
|
||||
{
|
||||
IssueLog::Error($e->getMessage());
|
||||
}
|
||||
}
|
||||
foreach ($this->aAdded as $oTag)
|
||||
{
|
||||
try
|
||||
{
|
||||
$aValue[] = $oTag->Get('tag_code');
|
||||
} catch (CoreException $e)
|
||||
{
|
||||
IssueLog::Error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
sort($aValue);
|
||||
|
||||
return $aValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sTagCode
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
*/
|
||||
public function AddTag($sTagCode)
|
||||
{
|
||||
if ($this->IsTagInList($this->aPreserved, $sTagCode) || $this->IsTagInList($this->aAdded, $sTagCode))
|
||||
{
|
||||
// nothing to do, already existing tag
|
||||
return;
|
||||
}
|
||||
// if removed then added again
|
||||
if (($oTag = $this->RemoveTagFromList($this->aRemoved, $sTagCode)) !== false)
|
||||
{
|
||||
// put it back into preserved
|
||||
$this->aPreserved[] = $oTag;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->aAdded[] = $this->GetTagFromCode($sTagCode);
|
||||
}
|
||||
$this->UpdateHasDeltaFlag();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sTagCode
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
*/
|
||||
public function RemoveTag($sTagCode)
|
||||
{
|
||||
if ($this->IsTagInList($this->aRemoved, $sTagCode))
|
||||
{
|
||||
// nothing to do, already removed tag
|
||||
return;
|
||||
}
|
||||
// if added then remove it
|
||||
if (($oTag = $this->RemoveTagFromList($this->aAdded, $sTagCode)) === false)
|
||||
{
|
||||
// if present then remove it
|
||||
if (($oTag = $this->RemoveTagFromList($this->aPreserved, $sTagCode)) !== false)
|
||||
{
|
||||
$this->aRemoved[] = $oTag;
|
||||
}
|
||||
}
|
||||
$this->UpdateHasDeltaFlag();
|
||||
}
|
||||
|
||||
private function IsTagInList($aTagList, $sTagCode)
|
||||
{
|
||||
foreach ($aTagList as $oTag)
|
||||
{
|
||||
$sCode = $oTag->Get('tag_code');
|
||||
if ($sCode === $sTagCode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function RemoveTagFromList(&$aTagList, $sTagCode)
|
||||
{
|
||||
foreach ($aTagList as $index => $oTag)
|
||||
{
|
||||
$sCode = $oTag->Get('tag_code');
|
||||
if ($sCode === $sTagCode)
|
||||
{
|
||||
unset($aTagList[$index]);
|
||||
return $oTag;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function UpdateHasDeltaFlag()
|
||||
{
|
||||
if ((count($this->aAdded) == 0) && (count($this->aRemoved) == 0))
|
||||
{
|
||||
$this->bHasDelta = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->bHasDelta = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sTagCode
|
||||
*
|
||||
* @return DBObject tag
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreException
|
||||
*/
|
||||
private function GetTagFromCode($sTagCode)
|
||||
{
|
||||
$aAllowedTags = $this->GetAllowedTags();
|
||||
foreach($aAllowedTags as $oAllowedTag)
|
||||
{
|
||||
if ($oAllowedTag->Get('tag_code') === $sTagCode)
|
||||
{
|
||||
return $oAllowedTag;
|
||||
}
|
||||
}
|
||||
throw new CoreUnexpectedValue("{$sTagCode} is not defined as a valid tag for {$this->sClass}:{$this->sAttCode}");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function GetAllowedTags()
|
||||
{
|
||||
if (!$this->aAllowedTags)
|
||||
{
|
||||
$oSearch = new DBObjectSearch($this->GetTagDataClass());
|
||||
$oSearch->AddCondition('tag_class', $this->sClass);
|
||||
$oSearch->AddCondition('tag_attcode', $this->sAttCode);
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$this->aAllowedTags = $oSet->ToArray();
|
||||
}
|
||||
return $this->aAllowedTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare Tag Set
|
||||
*
|
||||
* @param \ormTagSet $other
|
||||
*
|
||||
* @return bool true if same tag set
|
||||
*/
|
||||
public function Equals(ormTagSet $other)
|
||||
{
|
||||
if ($this->GetTagDataClass() !== $other->GetTagDataClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return implode(' ',$this->GetValue()) === implode(' ', $other->GetValue());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,55 +27,69 @@
|
||||
*/
|
||||
abstract class TagSetFieldData extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
'category' => 'bizmodel',
|
||||
'key_type' => 'autoincrement',
|
||||
'name_attcode' => array('tag_label'),
|
||||
'state_attcode' => '',
|
||||
'reconc_keys' => array('tag_code'),
|
||||
'db_table' => 'priv_tagfielddata',
|
||||
'db_key_field' => 'id',
|
||||
'db_finalclass_field' => 'finalclass',
|
||||
);
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
'category' => 'bizmodel',
|
||||
'key_type' => 'autoincrement',
|
||||
'name_attcode' => array('tag_label'),
|
||||
'state_attcode' => '',
|
||||
'reconc_keys' => array('tag_code'),
|
||||
'db_table' => 'priv_tagfielddata',
|
||||
'db_key_field' => 'id',
|
||||
'db_finalclass_field' => 'finalclass',
|
||||
);
|
||||
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("tag_code", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => 'tag_code',
|
||||
"default_value" => '',
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array()
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("tag_label", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => 'tag_label',
|
||||
"default_value" => '',
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array()
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("tag_description", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => 'tag_description',
|
||||
"default_value" => '',
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array()
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeBoolean("is_default", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => "is_default",
|
||||
"default_value" => false,
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array()
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("tag_code", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => 'tag_code',
|
||||
"default_value" => '',
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array()
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("tag_label", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => 'tag_label',
|
||||
"default_value" => '',
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array()
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("tag_description", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => 'tag_description',
|
||||
"default_value" => '',
|
||||
"is_null_allowed" => true,
|
||||
"depends_on" => array()
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("tag_class", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => 'tag_class',
|
||||
"default_value" => '',
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array()
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("tag_attcode", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => 'tag_attcode',
|
||||
"default_value" => '',
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array()
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeBoolean("is_default", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => "is_default",
|
||||
"default_value" => false,
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array()
|
||||
)));
|
||||
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array('tag_code', 'tag_label', 'tag_description', 'is_default'));
|
||||
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'));
|
||||
}
|
||||
MetaModel::Init_SetZListItems('details', array('tag_code', 'tag_label', 'tag_description', 'is_default'));
|
||||
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'));
|
||||
}
|
||||
}
|
||||
@@ -198,6 +198,8 @@
|
||||
</field>
|
||||
<field id="tagfield" xsi:type="AttributeTagSet">
|
||||
<sql>tagfield</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
</fields>
|
||||
<methods>
|
||||
|
||||
@@ -74,8 +74,9 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Class:Ticket/Attribute:close_date+' => '',
|
||||
'Class:Ticket/Attribute:private_log' => 'Private log',
|
||||
'Class:Ticket/Attribute:private_log+' => '',
|
||||
'Class:Ticket/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:Ticket/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:Ticket/Attribute:contacts_list+' => 'All the contacts linked to this ticket',
|
||||
'Class:Ticket/Attribute:tagfield' => 'Tag Test',
|
||||
'Class:Ticket/Attribute:functionalcis_list' => 'CIs',
|
||||
'Class:Ticket/Attribute:functionalcis_list+' => 'All the configuration items impacted by this ticket. Items marked as "Computed" have been automatically marked as impacted. Items marked as "Not impacted" are excluded from the impact.',
|
||||
'Class:Ticket/Attribute:workorders_list' => 'Work orders',
|
||||
|
||||
@@ -34,7 +34,10 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Core:AttributeLinkedSet' => 'Array of objects',
|
||||
'Core:AttributeLinkedSet+' => 'Any kind of objects of the same class or subclass',
|
||||
|
||||
'Core:AttributeLinkedSetIndirect' => 'Array of objects (N-N)',
|
||||
'Core:AttributeTagSet' => 'List of tags',
|
||||
'Core:AttributeTagSet+' => '',
|
||||
|
||||
'Core:AttributeLinkedSetIndirect' => 'Array of objects (N-N)',
|
||||
'Core:AttributeLinkedSetIndirect+' => 'Any kind of objects [subclass] of the same class',
|
||||
|
||||
'Core:AttributeInteger' => 'Integer',
|
||||
|
||||
@@ -426,7 +426,9 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:appUserPreferences/Attribute:preferences+' => '',
|
||||
'Core:AttributeLinkedSet' => 'Objets liés (1-n)',
|
||||
'Core:AttributeLinkedSet+' => 'Liste d\'objets d\'une classe donnée et pointant sur l\'objet courant',
|
||||
'Core:AttributeLinkedSetIndirect' => 'Objets liés (1-n)',
|
||||
'Core:AttributeTagSet' => 'Liste d\'étiquettes',
|
||||
'Core:AttributeTagSet+' => '',
|
||||
'Core:AttributeLinkedSetIndirect' => 'Objets liés (1-n)',
|
||||
'Core:AttributeLinkedSetIndirect+' => 'Liste d\'objets d\'une classe donnée et liés à l\'objet courant via une classe intermédiaire',
|
||||
'Core:AttributeInteger' => 'Nombre entier',
|
||||
'Core:AttributeInteger+' => 'Valeur numérique entière',
|
||||
|
||||
@@ -1388,19 +1388,25 @@ EOF
|
||||
{
|
||||
$aParameters['handler_class'] = $this->GetMandatoryPropString($oField, 'handler_class');
|
||||
}
|
||||
else
|
||||
elseif ($sAttType == 'AttributeTagSet')
|
||||
{
|
||||
$aTagFieldsInfo[] = $sAttCode;
|
||||
$aParameters['allowed_values'] = 'null'; // or "new ValueSetEnum('SELECT xxxx')"
|
||||
$aParameters['sql'] = $this->GetMandatoryPropString($oField, 'sql');
|
||||
$aParameters['is_null_allowed'] = $this->GetPropBoolean($oField, 'is_null_allowed', false);
|
||||
$aParameters['depends_on'] = $sDependencies;
|
||||
$aParameters['default_value'] = $this->GetPropString($oField, 'default_value', '');
|
||||
}
|
||||
else
|
||||
{
|
||||
$aParameters['allowed_values'] = 'null'; // or "new ValueSetEnum('SELECT xxxx')"
|
||||
$aParameters['sql'] = $this->GetMandatoryPropString($oField, 'sql');
|
||||
$aParameters['default_value'] = $this->GetPropString($oField, 'default_value', '');
|
||||
$aParameters['is_null_allowed'] = $this->GetPropBoolean($oField, 'is_null_allowed', false);
|
||||
$aParameters['depends_on'] = $sDependencies;
|
||||
$aParameters['allowed_values'] = 'null'; // or "new ValueSetEnum('SELECT xxxx')"
|
||||
$aParameters['sql'] = $this->GetMandatoryPropString($oField, 'sql');
|
||||
$aParameters['default_value'] = $this->GetPropString($oField, 'default_value', '');
|
||||
$aParameters['is_null_allowed'] = $this->GetPropBoolean($oField, 'is_null_allowed', false);
|
||||
$aParameters['depends_on'] = $sDependencies;
|
||||
}
|
||||
|
||||
if ($sAttType == 'AttributeTagSet')
|
||||
{
|
||||
$aTagFieldsInfo[] = $sAttCode;
|
||||
}
|
||||
|
||||
|
||||
// Optional parameters (more for historical reasons)
|
||||
// Added if present...
|
||||
|
||||
@@ -171,7 +171,35 @@ class ItopDataTestCase extends ItopTestCase
|
||||
return $oTicket;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Create a Ticket in database
|
||||
*
|
||||
* @param string $sClass
|
||||
* @param string $sAttCode
|
||||
* @param string $sTagCode
|
||||
* @param string $sTagLabel
|
||||
* @param string $sTagDescription
|
||||
*
|
||||
* @return \TagSetFieldData
|
||||
* @throws \CoreException
|
||||
*/
|
||||
protected function CreateTagData($sClass, $sAttCode, $sTagCode, $sTagLabel, $sTagDescription = '')
|
||||
{
|
||||
$sTagClass = MetaModel::GetTagDataClass($sClass, $sAttCode);
|
||||
$oTagData = self::createObject($sTagClass, array(
|
||||
'tag_code' => $sTagCode,
|
||||
'tag_label' => $sTagLabel,
|
||||
'tag_class' => $sClass,
|
||||
'tag_attcode' => $sAttCode,
|
||||
'tag_description' => $sTagDescription,
|
||||
));
|
||||
$this->debug("\nCreated {$oTagData->Get('tag_code')} ({$oTagData->Get('tag_label')})");
|
||||
|
||||
/** @var \TagSetFieldData $oTagData */
|
||||
return $oTagData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a UserRequest in database
|
||||
*
|
||||
* @param int $iNum
|
||||
|
||||
155
test/core/ormTagSetTest.php
Normal file
155
test/core/ormTagSetTest.php
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2010-2018 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Eric
|
||||
* Date: 27/08/2018
|
||||
* Time: 17:26
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use Exception;
|
||||
use ormTagSet;
|
||||
|
||||
/**
|
||||
* Tests of the ormTagSet class
|
||||
*
|
||||
* @runTestsInSeparateProcesses
|
||||
* @preserveGlobalState disabled
|
||||
* @backupGlobals disabled
|
||||
*/class ormTagSetTest extends ItopDataTestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testGetTagDataClass()
|
||||
{
|
||||
$oTagSet = new ormTagSet('Ticket', 'tagfield');
|
||||
static::assertEquals($oTagSet->GetTagDataClass(), 'TagSetFieldDataFor_Ticket_tagfield');
|
||||
}
|
||||
|
||||
public function testGetValue()
|
||||
{
|
||||
$this->CreateTagData('Ticket', 'tagfield', 'tag1', 'First');
|
||||
$this->CreateTagData('Ticket', 'tagfield', 'tag2', 'Second');
|
||||
|
||||
$oTagSet = new ormTagSet('Ticket', 'tagfield');
|
||||
static::assertEquals($oTagSet->GetValue(), array());
|
||||
|
||||
$oTagSet->AddTag('tag1');
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag1'));
|
||||
|
||||
$oTagSet->AddTag('tag2');
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag1', 'tag2'));
|
||||
}
|
||||
|
||||
public function testAddTag()
|
||||
{
|
||||
$this->CreateTagData('Ticket', 'tagfield', 'tag1', 'First');
|
||||
$this->CreateTagData('Ticket', 'tagfield', 'tag2', 'Second');
|
||||
|
||||
$oTagSet = new ormTagSet('Ticket', 'tagfield');
|
||||
|
||||
$oTagSet->AddTag('tag1');
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag1'));
|
||||
|
||||
$oTagSet->SetValue(array('tag1', 'tag2'));
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag1', 'tag2'));
|
||||
|
||||
$oTagSet->RemoveTag('tag1');
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag2'));
|
||||
|
||||
$oTagSet->AddTag('tag1');
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag1', 'tag2'));
|
||||
}
|
||||
|
||||
public function testEquals()
|
||||
{
|
||||
$this->CreateTagData('Ticket', 'tagfield', 'tag1', 'First');
|
||||
$this->CreateTagData('Ticket', 'tagfield', 'tag2', 'Second');
|
||||
|
||||
$oTagSet1 = new ormTagSet('Ticket', 'tagfield');
|
||||
$oTagSet1->AddTag('tag1');
|
||||
static::assertTrue($oTagSet1->Equals($oTagSet1));
|
||||
|
||||
$oTagSet2 = new ormTagSet('Ticket', 'tagfield');
|
||||
$oTagSet2->SetValue(array('tag1'));
|
||||
|
||||
static::assertTrue($oTagSet1->Equals($oTagSet2));
|
||||
|
||||
$oTagSet1->AddTag('tag2');
|
||||
static::assertFalse($oTagSet1->Equals($oTagSet2));
|
||||
}
|
||||
|
||||
public function testSetValue()
|
||||
{
|
||||
$this->CreateTagData('Ticket', 'tagfield', 'tag1', 'First');
|
||||
$this->CreateTagData('Ticket', 'tagfield', 'tag2', 'Second');
|
||||
|
||||
$oTagSet = new ormTagSet('Ticket', 'tagfield');
|
||||
|
||||
$oTagSet->SetValue(array('tag1'));
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag1'));
|
||||
|
||||
$oTagSet->SetValue(array('tag1', 'tag2'));
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag1', 'tag2'));
|
||||
|
||||
}
|
||||
|
||||
public function testRemoveTag()
|
||||
{
|
||||
$this->CreateTagData('Ticket', 'tagfield', 'tag1', 'First');
|
||||
$this->CreateTagData('Ticket', 'tagfield', 'tag2', 'Second');
|
||||
|
||||
$oTagSet = new ormTagSet('Ticket', 'tagfield');
|
||||
$oTagSet->RemoveTag('tag_unknown');
|
||||
static::assertEquals($oTagSet->GetValue(), array());
|
||||
|
||||
$oTagSet->SetValue(array('tag1'));
|
||||
$oTagSet->RemoveTag('tag_unknown');
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag1'));
|
||||
|
||||
$oTagSet->SetValue(array('tag1', 'tag2'));
|
||||
$oTagSet->RemoveTag('tag1');
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag2'));
|
||||
|
||||
$oTagSet->AddTag('tag1');
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag1', 'tag2'));
|
||||
|
||||
$oTagSet->RemoveTag('tag1');
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag2'));
|
||||
|
||||
$oTagSet->RemoveTag('tag1');
|
||||
static::assertEquals($oTagSet->GetValue(), array('tag2'));
|
||||
|
||||
$oTagSet->RemoveTag('tag2');
|
||||
static::assertEquals($oTagSet->GetValue(), array());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user