mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 10:38:45 +02:00
N°931: Limit the number of tags in the widget
This commit is contained in:
@@ -2189,6 +2189,11 @@ EOF
|
||||
$aJson['added'] = array();
|
||||
$aJson['removed'] = array();
|
||||
|
||||
/** @var \AttributeTagSet $oAttDef */
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$iMaxTags = $oAttDef->GetTagMaxNb();
|
||||
$aJson['max_tags_allowed'] = $iMaxTags;
|
||||
|
||||
return json_encode($aJson);
|
||||
}
|
||||
|
||||
|
||||
@@ -6869,7 +6869,8 @@ class AttributeTagSet extends AttributeDBFieldVoid
|
||||
$oTagSet = new ormTagSet(MetaModel::GetAttributeOrigin($this->GetHostClass(), $this->GetCode()), $this->GetCode(), $this->GetTagMaxNb());
|
||||
if (is_string($proposedValue) && !empty($proposedValue))
|
||||
{
|
||||
$aTagCodes = explode(' ', "$proposedValue");
|
||||
$proposedValue = trim("$proposedValue");
|
||||
$aTagCodes = explode(' ', $proposedValue);
|
||||
$oTagSet->SetValue($aTagCodes);
|
||||
}
|
||||
elseif ($proposedValue instanceof ormTagSet)
|
||||
|
||||
@@ -142,15 +142,13 @@ abstract class TagSetFieldData extends cmdbAbstractObject
|
||||
parent::DoCheckToDelete($oDeletionPlan);
|
||||
|
||||
$sTagCode = $this->Get('code');
|
||||
$sClass = $this->Get('obj_class');
|
||||
$sAttCode = $this->Get('obj_attcode');
|
||||
$oSearch = DBSearch::FromOQL("SELECT $sClass WHERE $sAttCode MATCHES '$sTagCode'");
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
if ($oSet->CountExceeds(0))
|
||||
if ($this->IsCodeUsed($sTagCode))
|
||||
{
|
||||
$this->m_aDeleteIssues[] = Dict::S('Core:TagSetFieldData:ErrorDeleteUsedTag');
|
||||
}
|
||||
// Clear cache
|
||||
$sClass = $this->Get('obj_class');
|
||||
$sAttCode = $this->Get('obj_attcode');
|
||||
$sTagDataClass = self::GetTagDataClassName($sClass, $sAttCode);
|
||||
unset(self::$m_aAllowedValues[$sTagDataClass]);
|
||||
}
|
||||
@@ -222,10 +220,43 @@ abstract class TagSetFieldData extends cmdbAbstractObject
|
||||
$aChanges = $this->ListChanges();
|
||||
if (array_key_exists('code', $aChanges))
|
||||
{
|
||||
throw new CoreException(Dict::S('Core:TagSetFieldData:ErrorCodeUpdateNotAllowed'));
|
||||
$sTagCode = $this->GetOriginal('code');
|
||||
if ($this->IsCodeUsed($sTagCode))
|
||||
{
|
||||
throw new CoreException(Dict::S('Core:TagSetFieldData:ErrorCodeUpdateNotAllowed'));
|
||||
}
|
||||
}
|
||||
if (array_key_exists('obj_class', $aChanges))
|
||||
{
|
||||
throw new CoreException(Dict::S('Core:TagSetFieldData:ErrorClassUpdateNotAllowed'));
|
||||
}
|
||||
if (array_key_exists('obj_attcode', $aChanges))
|
||||
{
|
||||
throw new CoreException(Dict::S('Core:TagSetFieldData:ErrorAttCodeUpdateNotAllowed'));
|
||||
}
|
||||
}
|
||||
|
||||
private function IsCodeUsed($sTagCode)
|
||||
{
|
||||
try
|
||||
{
|
||||
$sClass = $this->Get('obj_class');
|
||||
$sAttCode = $this->Get('obj_attcode');
|
||||
$oSearch = DBSearch::FromOQL("SELECT $sClass WHERE $sAttCode MATCHES '$sTagCode'");
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
if ($oSet->CountExceeds(0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
IssueLog::Warning($e->getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display Tag Usage
|
||||
*
|
||||
|
||||
@@ -921,7 +921,9 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Core:TagSetFieldData:ErrorDuplicateTagCodeOrLabel' => 'Tags codes or labels must be unique',
|
||||
'Core:TagSetFieldData:ErrorTagCodeSyntax' => 'Tags code should contain between 3 and %1$d alphanumeric characters',
|
||||
'Core:TagSetFieldData:ErrorTagLabelSyntax' => 'Tags label should not contain \'%1$s\' nor be empty',
|
||||
'Core:TagSetFieldData:ErrorCodeUpdateNotAllowed' => 'Tags code cannot be changed',
|
||||
'Core:TagSetFieldData:ErrorCodeUpdateNotAllowed' => 'Tags "Code" cannot be changed',
|
||||
'Core:TagSetFieldData:ErrorClassUpdateNotAllowed' => 'Tags "Object Class" cannot be changed',
|
||||
'Core:TagSetFieldData:ErrorAttCodeUpdateNotAllowed' => 'Tags "Attribute Code" cannot be changed',
|
||||
'Core:TagSetFieldData:WhereIsThisTagTab' => 'Tag usage (%1$d)',
|
||||
'Core:TagSetFieldData:NoEntryFound' => 'No entry found for this tag',
|
||||
));
|
||||
|
||||
@@ -773,6 +773,8 @@ Opérateurs :<br/>
|
||||
'Core:TagSetFieldData:ErrorTagCodeSyntax' => 'Le code de l\'étiquette doit contenir entre 3 et %1$d caractères alphanumériques.',
|
||||
'Core:TagSetFieldData:ErrorTagLabelSyntax' => 'Le nom de l\'étiquette ne doit pas être vide ni contenir le caractère \'%1$s\'',
|
||||
'Core:TagSetFieldData:ErrorCodeUpdateNotAllowed' => 'Le code de l\'étiquette ne peut pas être changé',
|
||||
'Core:TagSetFieldData:ErrorClassUpdateNotAllowed' => 'La classe de l\'étiquette ne peut pas être changée',
|
||||
'Core:TagSetFieldData:ErrorAttCodeUpdateNotAllowed' => 'L\'attribut de l\'étiquette ne peut pas être changé',
|
||||
'Core:TagSetFieldData:WhereIsThisTagTab' => 'Utilisation (%1$d)',
|
||||
'Core:TagSetFieldData:NoEntryFound' => 'Pas d\'utilisation de cette étiquette',
|
||||
|
||||
|
||||
@@ -70,7 +70,8 @@ $.widget('itop.tagset_widget',
|
||||
REMOVED_VAL_KEY: "removed",
|
||||
STATUS_ADDED: "added",
|
||||
STATUS_REMOVED: "removed",
|
||||
STATUS_NEUTRAL: "unchanged",
|
||||
STATUS_NEUTRAL: "unchanged",
|
||||
MAX_TAGS_ALLOWED: "max_tags_allowed",
|
||||
|
||||
possibleValues: null,
|
||||
partialValues: null,
|
||||
@@ -79,6 +80,7 @@ $.widget('itop.tagset_widget',
|
||||
tagSetCodesStatus: null,
|
||||
|
||||
selectizeWidget: null,
|
||||
maxTagsAllowed: null,
|
||||
|
||||
// the constructor
|
||||
_create: function () {
|
||||
@@ -100,6 +102,7 @@ $.widget('itop.tagset_widget',
|
||||
this.possibleValues = dataArray[this.POSSIBLE_VAL_KEY];
|
||||
this.partialValues = ($.isArray(dataArray[this.PARTIAL_VAL_KEY])) ? dataArray[this.PARTIAL_VAL_KEY] : [];
|
||||
this.originalValue = dataArray[this.ORIG_VAL_KEY];
|
||||
this.maxTagsAllowed = dataArray[this.MAX_TAGS_ALLOWED];
|
||||
this.tagSetCodesStatus = {};
|
||||
},
|
||||
|
||||
@@ -118,7 +121,7 @@ $.widget('itop.tagset_widget',
|
||||
$inputWidget.selectize({
|
||||
plugins: ['remove_button'],
|
||||
delimiter: ' ',
|
||||
maxItems: null,
|
||||
maxItems: this.maxTagsAllowed,
|
||||
hideSelected: true,
|
||||
valueField: 'code',
|
||||
labelField: 'label',
|
||||
|
||||
@@ -185,16 +185,37 @@ class TagSetFieldDataTest extends ItopDataTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that tag code cannot be modified
|
||||
* @expectedException \CoreException
|
||||
* Test that tag code cannot be modified if used
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function testUpdateCode()
|
||||
{
|
||||
$oTagData = $this->CreateTagData(TAG_CLASS, TAG_ATTCODE, 'tag1', 'First');
|
||||
$oTagData->Set('code', 'tag2');
|
||||
$oTagData->DBWrite();
|
||||
|
||||
//Use it
|
||||
$oTicket = $this->CreateTicket(1);
|
||||
$oTicket->Set(TAG_ATTCODE, 'tag2');
|
||||
$oTicket->DBWrite();
|
||||
|
||||
// Try to change the code of the tag, must complain !
|
||||
try
|
||||
{
|
||||
$oTagData->Set('code', 'tag1');
|
||||
$oTagData->DBWrite();
|
||||
|
||||
} catch (\CoreException $e)
|
||||
{
|
||||
static::assertTrue(true);
|
||||
|
||||
return;
|
||||
}
|
||||
// Should not pass here
|
||||
static::assertFalse(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,4 +248,38 @@ class TagSetFieldDataTest extends ItopDataTestCase
|
||||
// Failed
|
||||
static::assertFalse(true);
|
||||
}
|
||||
|
||||
public function testMaxTagsAllowed()
|
||||
{
|
||||
/** @var \AttributeTagSet $oAttDef */
|
||||
$oAttDef = \MetaModel::GetAttributeDef(TAG_CLASS, TAG_ATTCODE);
|
||||
$iMaxTags = $oAttDef->GetTagMaxNb();
|
||||
for ($i = 0; $i < $iMaxTags; $i++)
|
||||
{
|
||||
$sTagCode = 'MaxTag'.$i;
|
||||
$this->CreateTagData(TAG_CLASS, TAG_ATTCODE, $sTagCode, $sTagCode);
|
||||
}
|
||||
$oTicket = $this->CreateTicket(1);
|
||||
$this->debug("Max number of tags is $iMaxTags");
|
||||
$sValue = '';
|
||||
for ($i = 0; $i < ($iMaxTags + 1); $i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
$sTagCode = 'MaxTag'.$i;
|
||||
$sValue .= "$sTagCode ";
|
||||
$oTicket->Set(TAG_ATTCODE, $sValue);
|
||||
$oTicket->DBWrite();
|
||||
} catch (\Exception $e)
|
||||
{
|
||||
// Should fail on the last iteration
|
||||
static::assertEquals($iMaxTags, $i);
|
||||
$this->debug("Setting (".($i+1).") tag(s) failed");
|
||||
return;
|
||||
}
|
||||
$this->debug("Setting (".($i+1).") tag(s) worked");
|
||||
}
|
||||
|
||||
static::assertFalse(true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user