From 6817cfbeea110d7d350c9dc1562e0ecd0553a975 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 7 Sep 2018 17:49:00 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B0931:=20Integrity=20controls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/attributedef.class.inc.php | 34 ++++++++++++++++++++- core/ormtagset.class.inc.php | 25 ++++++++++++---- core/tagsetfield.class.inc.php | 38 ++++++++++++++++++++++++ dictionaries/en.dictionary.itop.core.php | 2 ++ dictionaries/fr.dictionary.itop.core.php | 2 ++ 5 files changed, 94 insertions(+), 7 deletions(-) diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 7c1dda2df..4493ade73 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -5959,7 +5959,39 @@ class AttributeTagSet extends AttributeDBFieldVoid return ($val1 == $val2); } - /** + /** + * @param array $aCols + * @param string $sPrefix + * + * @return mixed + * @throws \CoreException + * @throws \Exception + */ + public function FromSQLToValue($aCols, $sPrefix = '') + { + $sValue = $aCols["$sPrefix"]; + $aTagCodes = explode(' ', "$sValue"); + $sAttCode = $this->GetCode(); + $sClass = MetaModel::GetAttributeOrigin($this->GetHostClass(), $sAttCode); + $oTagSet = new ormTagSet($sClass, $sAttCode); + $aGoodTags = array(); + foreach($aTagCodes as $sTagCode) + { + if ($oTagSet->TagsExist($sTagCode)) + { + $aGoodTags[] = $sTagCode; + } + else + { + // Ignore bad tags from database + IssueLog::Warning("Unknown tag $sTagCode for $sClass::$sAttCode found in database, ignored."); + } + } + $oTagSet->SetValue($aGoodTags); + return $oTagSet; + } + + /** * force an allowed value (type conversion and possibly forces a value as mySQL would do upon writing! * * @param $proposedValue diff --git a/core/ormtagset.class.inc.php b/core/ormtagset.class.inc.php index 3b5c61655..6a8af77d7 100644 --- a/core/ormtagset.class.inc.php +++ b/core/ormtagset.class.inc.php @@ -30,9 +30,6 @@ final class ormTagSet { private $sClass; // class of the tag field private $sAttCode; // attcode of the tag field - - private $aAllowedTags; - private $oOriginalSet; private $aOriginalObjects = null; /** @@ -69,14 +66,12 @@ final class ormTagSet * * @param string $sClass * @param string $sAttCode - * @param DBObjectSet|null $oOriginalSet * * @throws \Exception */ - public function __construct($sClass, $sAttCode, DBObjectSet $oOriginalSet = null) + public function __construct($sClass, $sAttCode) { $this->sAttCode = $sAttCode; - $this->oOriginalSet = $oOriginalSet ? clone $oOriginalSet : null; $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); if (!$oAttDef instanceof AttributeTagSet) @@ -277,6 +272,24 @@ final class ormTagSet } } + /** + * @param string $sTagCode + * + * @return bool + * @throws \CoreException + */ + public function TagsExist($sTagCode) + { + try + { + $this->GetTagFromCode($sTagCode); + return true; + } catch (CoreUnexpectedValue $e) + { + return false; + } + } + /** * @param $sTagCode * diff --git a/core/tagsetfield.class.inc.php b/core/tagsetfield.class.inc.php index 66f3e9af0..b765bd7e3 100644 --- a/core/tagsetfield.class.inc.php +++ b/core/tagsetfield.class.inc.php @@ -99,6 +99,44 @@ abstract class TagSetFieldData extends cmdbAbstractObject } } + /** + * @param \DeletionPlan $oDeletionPlan + * + * @return bool + * @throws \CoreException + */ + public function DoCheckToDelete(&$oDeletionPlan) + { + $sTagCode = $this->Get('tag_code'); + $sClass = $this->Get('tag_class'); + $sAttCode = $this->Get('tag_attcode'); + $oSearch = DBSearch::FromOQL("SELECT $sClass WHERE $sAttCode MATCHES '$sTagCode'"); + $oSet = new DBObjectSet($oSearch); + if ($oSet->CountExceeds(1)) + { + $this->m_aDeleteIssues[] = Dict::S('Core:TagSetFieldData:ErrorDeleteUsedTag'); + } + + return parent::DoCheckToDelete($oDeletionPlan); + } + + public function DoCheckToWrite() + { + // Check that code and labels are uniques + $sTagCode = $this->Get('tag_code'); + $sTagLabel = $this->Get('tag_label'); + $id = $this->GetKey(); + $sClassName = get_class($this); + $oSearch = DBSearch::FromOQL("SELECT $sClassName WHERE id != $id AND (tag_code = '$sTagCode' OR tag_label = '$sTagLabel')"); + $oSet = new DBObjectSet($oSearch); + if ($oSet->CountExceeds(1)) + { + $this->m_aCheckIssues[] = Dict::S('Core:TagSetFieldData:ErrorDuplicateTagCodeOrLabel'); + } + + parent::DoCheckToWrite(); + } + public static function GetAllowedValues($sClass, $sAttCode) { $sTagDataClass = MetaModel::GetTagDataClass($sClass, $sAttCode); diff --git a/dictionaries/en.dictionary.itop.core.php b/dictionaries/en.dictionary.itop.core.php index 2583ba2ef..56776820f 100644 --- a/dictionaries/en.dictionary.itop.core.php +++ b/dictionaries/en.dictionary.itop.core.php @@ -916,4 +916,6 @@ Dict::Add('EN US', 'English', 'English', array( Dict::Add('EN US', 'English', 'English', array( 'Class:TagSetFieldData' => 'List of tags', 'Class:TagSetFieldData+' => '', + 'Core:TagSetFieldData:ErrorDeleteUsedTag' => 'Used tags cannot be deleted', + 'Core:TagSetFieldData:ErrorDuplicateTagCodeOrLabel' => 'Tags codes or labels must be unique', )); diff --git a/dictionaries/fr.dictionary.itop.core.php b/dictionaries/fr.dictionary.itop.core.php index f7cadc669..56c9eb98d 100644 --- a/dictionaries/fr.dictionary.itop.core.php +++ b/dictionaries/fr.dictionary.itop.core.php @@ -764,4 +764,6 @@ Opérateurs :
'Core:Validator:Mandatory' => 'Veuillez remplir ce champ', 'Core:Validator:MustBeInteger' => 'Ce champ ne peut contenir qu\'un nombre entier', 'Core:Validator:MustSelectOne' => 'Veuillez choisir une valeur', + 'Core:TagSetFieldData:ErrorDeleteUsedTag' => 'Impossible de supprimer une étiquette utilisée', + 'Core:TagSetFieldData:ErrorDuplicateTagCodeOrLabel' => 'Les codes et noms des étiquettes doivent être unique', ));