Parcourir la source

AttributeCaseLog finalized (history, easy migration of AttributeText, wiki formatting)

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1173 a333f486-631f-4898-b8df-5754b55c2be0
romainq il y a 14 ans
Parent
commit
cc14b9793a

+ 184 - 212
core/attributedef.class.inc.php

@@ -274,11 +274,6 @@ abstract class AttributeDefinition
 
 	public function GetAsHTML($sValue, $oHostObject = null)
 	{
-		if ($sValue instanceof ormCaseLog)
-		{
-			echo "<p>AttributeCode: ".$this->GetCode()."</p>";
-			echo debug_print_backtrace();
-		}
 		return Str::pure2html((string)$sValue);
 	}
 
@@ -1124,206 +1119,6 @@ class AttributeClass extends AttributeString
 }
 
 /**
- * An attibute that stores a case log (i.e journal) 
- *
- * @package     iTopORM
- */
-class AttributeCaseLog extends AttributeText
-{
-	public function GetBasicFilterOperators()
-	{
-		return array(
-			"="=>"equals",
-			"!="=>"differs from",
-			"Like"=>"equals (no case)",
-			"NotLike"=>"differs from (no case)",
-			"Contains"=>"contains",
-			"Begins with"=>"begins with",
-			"Finishes with"=>"finishes with"
-		);
-	}
-	public function GetBasicFilterLooseOperator()
-	{
-		return "Contains";
-	}
-
-	public function GetBasicFilterSQLExpr($sOpCode, $value)
-	{
-		$sQValue = CMDBSource::Quote($value);
-		switch ($sOpCode)
-		{
-		case '=':
-		case '!=':
-			return $this->GetSQLExpr()." $sOpCode $sQValue";
-		case 'Begins with':
-			return $this->GetSQLExpr()." LIKE ".CMDBSource::Quote("$value%");
-		case 'Finishes with':
-			return $this->GetSQLExpr()." LIKE ".CMDBSource::Quote("%$value");
-		case 'Contains':
-			return $this->GetSQLExpr()." LIKE ".CMDBSource::Quote("%$value%");
-		case 'NotLike':
-			return $this->GetSQLExpr()." NOT LIKE $sQValue";
-		case 'Like':
-		default:
-			return $this->GetSQLExpr()." LIKE $sQValue";
-		}
-	} 
-
-	public function GetNullValue()
-	{
-		return '';
-	} 
-
-	public function IsNull($proposedValue)
-	{
-		if (!($proposedValue instanceof ormCaseLog))
-		{
-			return ($proposedValue == '');
-		}
-		return ($proposedValue->GetText() == '');
-	} 
-
-	public function ScalarToSQL($value)
-	{
-		if (!is_string($value) && !is_null($value))
-		{
-			throw new CoreWarning('Expected the attribute value to be a string', array('found_type' => gettype($value), 'value' => $value, 'class' => $this->GetCode(), 'attribute' => $this->GetHostClass()));
-		}
-		return $value;
-	}
-	public function GetEditClass() {return "CaseLog";}
-	public function GetEditValue($sValue) { return ''; } // New 'edit' value is always blank since it will be appended to the existing log	
-	public function IsDirectField() {return true;} 
-	public function IsScalar() {return true;} 
-	public function IsWritable() {return true;} 
-	public function GetDefaultValue() {return new ormCaseLog();}
-	public function IsNullAllowed() {return $this->GetOptional("is_null_allowed", false);}
-	public function RequiresIndex() { return false; }
-	public function Equals($val1, $val2) {return (count($val1->GetIndex()) == count($val2->GetIndex()));}
-	public function GetMaxSize() { return null; }
-	public function CheckFormat($value) { return true; }
-	
-
-
-	// Facilitate things: allow the user to Set the value from a string
-	public function MakeRealValue($proposedValue, $oHostObj)
-	{
-		if (!($proposedValue instanceof ormCaseLog))
-		{
-			// Append the new value if an instance of the object is supplied
-			if ($oHostObj != null)
-			{
-				$oCaseLog = clone($oHostObj->GetOriginal($this->GetCode()));
-			}
-			else
-			{
-				$oCaseLog = new ormCaseLog();
-			}
-			echo "Added log entry: $proposedValue";
-			$oCaseLog->AddLogEntry(parent::MakeRealValue($proposedValue, $oHostObj));
-			return $oCaseLog;
-		}
-		return $proposedValue;
-	}
-
-	public function GetSQLExpressions($sPrefix = '')
-	{
-		if ($sPrefix == '')
-		{
-			$sPrefix = $this->GetCode();
-		}
-		$aColumns = array();
-		// Note: to optimize things, the existence of the attribute is determined by the existence of one column with an empty suffix
-		$aColumns[''] = $sPrefix;
-		$aColumns['_index'] = $sPrefix.'_index';
-		return $aColumns;
-	}
-
-	public function FromSQLToValue($aCols, $sPrefix = '')
-	{
-		if (!isset($aCols[$sPrefix]))
-		{
-			$sAvailable = implode(', ', array_keys($aCols));
-			throw new MissingColumnException("Missing column '$sPrefix' from {$sAvailable}");
-		} 
-		$sLog = $aCols[$sPrefix];
-
-		if (!isset($aCols[$sPrefix.'_index'])) 
-		{
-			$sAvailable = implode(', ', array_keys($aCols));
-			throw new MissingColumnException("Missing column '".$sPrefix."_index' from {$sAvailable}");
-		} 
-		$aIndex = unserialize($aCols[$sPrefix.'_index']);
-
-		$value = new ormCaseLog($sLog, $aIndex);
-		return $value;
-	}
-
-	public function GetSQLValues($value)
-	{
-		if (!($value instanceOf ormCaseLog))
-		{
-			$value = new ormCaseLog('');
-		}
-		$aValues = array();
-		$aValues[$this->GetCode()] = $value->GetText();
-		$aValues[$this->GetCode().'_index'] = serialize($value->GetIndex());
-
-		return $aValues;
-	}
-
-	public function GetSQLColumns()
-	{
-		$aColumns = array();
-		$aColumns[$this->GetCode()] = 'LONGTEXT'; // 2^32 (4 Gb)
-		$aColumns[$this->GetCode().'_index'] = 'BLOB';
-		return $aColumns;
-	}
-
-	public function GetFilterDefinitions()
-	{
-		return array($this->GetCode() => new FilterFromAttribute($this));
-	}
-
-	public function GetAsHTML($value, $oHostObject = null)
-	{
-		if ($value instanceOf ormCaseLog)
-		{
-			return $value->GetAsHTML(null, false);
-		}
-		else
-		{
-			return '';
-		}
-	}
-
-
-	public function GetAsCSV($value, $sSeparator = ',', $sTextQualifier = '"', $oHostObject = null)
-	{
-		if ($value instanceOf ormCaseLog)
-		{
-			return parent::GetAsCSV($value->GetText(), $sSeparator, $sTextQualifier, $oHostObject);
-		}
-		else
-		{
-			return '';
-		}
-	}
-	
-	public function GetAsXML($value, $oHostObject = null)
-	{
-		if ($value instanceOf ormCaseLog)
-		{
-			return parent::GetAsXML($value->GetText(), $oHostObject);
-		}
-		else
-		{
-			return '';
-		}
-	}
-}
-
-/**
  * An attibute that matches one of the language codes availables in the dictionnary 
  *
  * @package     iTopORM
@@ -1532,11 +1327,9 @@ class AttributeText extends AttributeString
 		return 65535;
 	}
 
-	public function GetAsHTML($sValue, $oHostObject = null)
+	static public function RenderWikiHtml($sText)
 	{
-		$sValue = parent::GetAsHTML($sValue);
-
-		if (preg_match_all(WIKI_OBJECT_REGEXP, $sValue, $aAllMatches, PREG_SET_ORDER))
+		if (preg_match_all(WIKI_OBJECT_REGEXP, $sText, $aAllMatches, PREG_SET_ORDER))
 		{
 			foreach($aAllMatches as $iPos => $aMatches)
 			{
@@ -1549,20 +1342,27 @@ class AttributeText extends AttributeString
 					if (is_object($oObj))
 					{
 						// Propose a std link to the object
-						$sValue = str_replace($aMatches[0], $oObj->GetHyperlink(), $sValue);
+						$sText = str_replace($aMatches[0], $oObj->GetHyperlink(), $sText);
 					}
 					else
 					{
 						// Propose a std link to the object
 						$sClassLabel = MetaModel::GetName($sClass);
-						$sValue = str_replace($aMatches[0], "<span class=\"wiki_broken_link\">$sClassLabel:$sName</span>", $sValue);
+						$sText = str_replace($aMatches[0], "<span class=\"wiki_broken_link\">$sClassLabel:$sName</span>", $sText);
 						// Later: propose a link to create a new object
 						// Anyhow... there is no easy way to suggest default values based on the given FRIENDLY name
-						//$sValue = preg_replace('/\[\[(.+):(.+)\]\]/', '<a href="./UI.php?operation=new&class='.$sClass.'&default[att1]=xxx&default[att2]=yyy">'.$sName.'</a>', $sValue);
+						//$sText = preg_replace('/\[\[(.+):(.+)\]\]/', '<a href="./UI.php?operation=new&class='.$sClass.'&default[att1]=xxx&default[att2]=yyy">'.$sName.'</a>', $sText);
 					}
 				}
 			}
 		}
+		return $sText;
+	}
+
+	public function GetAsHTML($sValue, $oHostObject = null)
+	{
+		$sValue = parent::GetAsHTML($sValue);
+		$sValue = self::RenderWikiHtml($sValue);
 		return str_replace("\n", "<br>\n", $sValue);
 	}
 
@@ -1632,6 +1432,178 @@ class AttributeLongText extends AttributeText
 }
 
 /**
+ * An attibute that stores a case log (i.e journal) 
+ *
+ * @package     iTopORM
+ */
+class AttributeCaseLog extends AttributeText
+{
+	public function GetNullValue()
+	{
+		return '';
+	} 
+
+	public function IsNull($proposedValue)
+	{
+		if (!($proposedValue instanceof ormCaseLog))
+		{
+			return ($proposedValue == '');
+		}
+		return ($proposedValue->GetText() == '');
+	} 
+
+	public function ScalarToSQL($value)
+	{
+		if (!is_string($value) && !is_null($value))
+		{
+			throw new CoreWarning('Expected the attribute value to be a string', array('found_type' => gettype($value), 'value' => $value, 'class' => $this->GetCode(), 'attribute' => $this->GetHostClass()));
+		}
+		return $value;
+	}
+	public function GetEditClass() {return "CaseLog";}
+	public function GetEditValue($sValue) { return ''; } // New 'edit' value is always blank since it will be appended to the existing log	
+	public function GetDefaultValue() {return new ormCaseLog();}
+	public function Equals($val1, $val2) {return ($val1->GetText() == $val2->GetText());}
+	
+
+	// Facilitate things: allow the user to Set the value from a string
+	public function MakeRealValue($proposedValue, $oHostObj)
+	{
+		if (!($proposedValue instanceof ormCaseLog))
+		{
+			// Append the new value if an instance of the object is supplied
+			//
+			$oPreviousLog = null;
+			if ($oHostObj != null)
+			{
+				$oPreviousLog = $oHostObj->Get($this->GetCode());
+				if (!is_object($oPreviousLog))
+				{
+					$oPreviousLog = $oHostObj->GetOriginal($this->GetCode());;
+				}
+				
+			}
+			if (is_object($oPreviousLog))
+			{
+				$oCaseLog = clone($oPreviousLog);
+			}
+			else
+			{
+				$oCaseLog = new ormCaseLog();
+			}
+			if (strlen($proposedValue) > 0)
+			{
+				$oCaseLog->AddLogEntry(parent::MakeRealValue($proposedValue, $oHostObj));
+			}
+			return $oCaseLog;
+		}
+		return $proposedValue;
+	}
+
+	public function GetSQLExpressions($sPrefix = '')
+	{
+		if ($sPrefix == '')
+		{
+			$sPrefix = $this->GetCode();
+		}
+		$aColumns = array();
+		// Note: to optimize things, the existence of the attribute is determined by the existence of one column with an empty suffix
+		$aColumns[''] = $sPrefix;
+		$aColumns['_index'] = $sPrefix.'_index';
+		return $aColumns;
+	}
+
+	public function FromSQLToValue($aCols, $sPrefix = '')
+	{
+		if (!isset($aCols[$sPrefix]))
+		{
+			$sAvailable = implode(', ', array_keys($aCols));
+			throw new MissingColumnException("Missing column '$sPrefix' from {$sAvailable}");
+		} 
+		$sLog = $aCols[$sPrefix];
+
+		if (isset($aCols[$sPrefix.'_index'])) 
+		{
+			$sIndex = $aCols[$sPrefix.'_index'];
+		}
+		else
+		{
+			// For backward compatibility, allow the current state to be: 1 log, no index
+			$sIndex = '';
+		}
+
+		if (strlen($sIndex) > 0)
+		{ 
+			$aIndex = unserialize($sIndex);
+			$value = new ormCaseLog($sLog, $aIndex);
+		}
+		else
+		{
+			$value = new ormCaseLog($sLog);
+		}
+		return $value;
+	}
+
+	public function GetSQLValues($value)
+	{
+		if (!($value instanceOf ormCaseLog))
+		{
+			$value = new ormCaseLog('');
+		}
+		$aValues = array();
+		$aValues[$this->GetCode()] = $value->GetText();
+		$aValues[$this->GetCode().'_index'] = serialize($value->GetIndex());
+
+		return $aValues;
+	}
+
+	public function GetSQLColumns()
+	{
+		$aColumns = array();
+		$aColumns[$this->GetCode()] = 'LONGTEXT'; // 2^32 (4 Gb)
+		$aColumns[$this->GetCode().'_index'] = 'BLOB';
+		return $aColumns;
+	}
+
+	public function GetAsHTML($value, $oHostObject = null)
+	{
+		if ($value instanceOf ormCaseLog)
+		{
+			return $value->GetAsHTML(null, false, array(__class__, 'RenderWikiHtml'));
+		}
+		else
+		{
+			return '';
+		}
+	}
+
+
+	public function GetAsCSV($value, $sSeparator = ',', $sTextQualifier = '"', $oHostObject = null)
+	{
+		if ($value instanceOf ormCaseLog)
+		{
+			return parent::GetAsCSV($value->GetText(), $sSeparator, $sTextQualifier, $oHostObject);
+		}
+		else
+		{
+			return '';
+		}
+	}
+	
+	public function GetAsXML($value, $oHostObject = null)
+	{
+		if ($value instanceOf ormCaseLog)
+		{
+			return parent::GetAsXML($value->GetText(), $oHostObject);
+		}
+		else
+		{
+			return '';
+		}
+	}
+}
+
+/**
  * Map a text column (size > ?), containing HTML code, to an attribute 
  *
  * @package     iTopORM

+ 24 - 2
core/cmdbchangeop.class.inc.php

@@ -232,7 +232,14 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
 				}
 				else
 				{
-					$sResult = Dict::Format('Change:AttName_SetTo_NewValue_PreviousValue_OldValue', $sAttName, $sNewValue, $sOldValue);
+					if (strlen($sOldValue) == 0)
+					{
+						$sResult = Dict::Format('Change:AttName_SetTo', $sAttName, $sNewValue);
+					}
+					else
+					{
+						$sResult = Dict::Format('Change:AttName_SetTo_NewValue_PreviousValue_OldValue', $sAttName, $sNewValue, $sOldValue);
+					}
 				}
 			}
 			elseif($bIsHtml && $oAttDef->IsExternalKey())
@@ -241,6 +248,14 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
 				$sFrom = MetaModel::GetHyperLink($sTargetClass, $sOldValue);
 				$sTo = MetaModel::GetHyperLink($sTargetClass, $sNewValue);
 				$sResult = "$sAttName set to $sTo (previous: $sFrom)";
+				if (strlen($sFrom) == 0)
+				{
+					$sResult = Dict::Format('Change:AttName_SetTo', $sAttName, $sTo);
+				}
+				else
+				{
+					$sResult = Dict::Format('Change:AttName_SetTo_NewValue_PreviousValue_OldValue', $sAttName, $sTo, $sFrom);
+				}
 			}
 			elseif ($oAttDef instanceOf AttributeBlob)
 			{
@@ -248,7 +263,14 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
 			}
 			else
 			{
-				$sResult = Dict::Format('Change:AttName_SetTo_NewValue_PreviousValue_OldValue', $sAttName, $sNewValue, $sOldValue);
+				if (strlen($sOldValue) == 0)
+				{
+					$sResult = Dict::Format('Change:AttName_SetTo', $sAttName, $sNewValue);
+				}
+				else
+				{
+					$sResult = Dict::Format('Change:AttName_SetTo_NewValue_PreviousValue_OldValue', $sAttName, $sNewValue, $sOldValue);
+				}
 			}
 		}
 		return $sResult;

+ 12 - 0
core/cmdbobject.class.inc.php

@@ -177,6 +177,18 @@ abstract class CMDBObject extends DBObject
 				$oMyChangeOp->Set("prevdata", $original);
 				$iId = $oMyChangeOp->DBInsertNoReload();
 			}
+			elseif ($oAttDef instanceOf AttributeCaseLog)
+			{
+				$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpSetAttributeScalar");
+				$oMyChangeOp->Set("change", $oChange->GetKey());
+				$oMyChangeOp->Set("objclass", get_class($this));
+				$oMyChangeOp->Set("objkey", $this->GetKey());
+				$oMyChangeOp->Set("attcode", $sAttCode);
+
+				$oMyChangeOp->Set("oldvalue", '');
+				$oMyChangeOp->Set("newvalue", $value->GetLatestEntry());
+				$iId = $oMyChangeOp->DBInsertNoReload();
+			}
 			elseif ($oAttDef instanceOf AttributeText)
 			{
 				// Data blobs

+ 65 - 8
core/ormcaselog.class.inc.php

@@ -49,12 +49,17 @@ class ormCaseLog {
 	{
 		return $this->m_aIndex;
 	}
+
+	public function __toString()
+	{
+		return $this->m_sLog;
+	}
 	
-	public function GetAsHTML(WebPage $oP = null, $bEditMode = false)
+	public function GetAsHTML(WebPage $oP = null, $bEditMode = false, $aTransfoHandler = null)
 	{
 		$sHtml = '';
-		$iPos = strlen($this->m_sLog);
-		for($index=0; $index < count($this->m_aIndex); $index++)
+		$iPos = 0;
+		for($index=count($this->m_aIndex)-1 ; $index >= 0 ; $index--)
 		{
 			if ($index < count($this->m_aIndex) - CASELOG_VISIBLE_ITEMS)
 			{
@@ -66,16 +71,57 @@ class ormCaseLog {
 				$sOpen = ' open';
 				$sDisplay = '';
 			}
-			$iStart = $iPos - $this->m_aIndex[$index]['text_length'];
-			$sTextEntry = substr($this->m_sLog, $iStart, $this->m_aIndex[$index]['text_length']);
-			$iPos = $iStart - $this->m_aIndex[$index]['separator_length'];
+			$iPos += $this->m_aIndex[$index]['separator_length'];
+			$sTextEntry = substr($this->m_sLog, $iPos, $this->m_aIndex[$index]['text_length']);
+			$sTextEntry = str_replace("\n", "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
+			if (!is_null($aTransfoHandler))
+			{
+				$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry);
+			}
+			$iPos += $this->m_aIndex[$index]['text_length'];
+
 			$sEntry = '<div class="caselog_header'.$sOpen.'">';
 			$sEntry .= sprintf(CASELOG_HEADER_FORMAT, $this->m_aIndex[$index]['date']->format(CASELOG_DATE_FORMAT), $this->m_aIndex[$index]['user_name']);
 			$sEntry .= '</div>';
 			$sEntry .= '<div class="caselog_entry"'.$sDisplay.'>';
-			$sEntry .= str_replace("\n", "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
+			$sEntry .= $sTextEntry;
 			$sEntry .= '</div>';
-			$sHtml = $sEntry . $sHtml;
+			$sHtml = $sHtml.$sEntry;
+		}
+
+		// Process the case of an eventual remainder (quick migration of AttributeText fields)
+		if ($iPos < (strlen($this->m_sLog) - 1))
+		{
+			$sTextEntry = substr($this->m_sLog, $iPos);
+			$sTextEntry = str_replace("\n", "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
+			if (!is_null($aTransfoHandler))
+			{
+				$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry);
+			}
+
+			if (count($this->m_aIndex) == 0)
+			{
+				$sHtml .= "<div>$sTextEntry</div>\n";
+			}
+			else
+			{
+				if (count($this->m_aIndex) - CASELOG_VISIBLE_ITEMS > 0)
+				{
+					$sOpen = '';
+					$sDisplay = 'style="display:none;"';
+				}
+				else
+				{
+					$sOpen = ' open';
+					$sDisplay = '';
+				}
+				$sHtml .= '<div class="caselog_header'.$sOpen.'">';
+				$sHtml .= '&nbsp;';
+				$sHtml .= '</div>';
+				$sHtml .= '<div class="caselog_entry"'.$sDisplay.'>';
+				$sHtml .= $sTextEntry;
+				$sHtml .= '</div>';
+			}
 		}
 		$sHtml = '<div class="caselog">'.$sHtml.'</div>';
 		return $sHtml;
@@ -100,5 +146,16 @@ class ormCaseLog {
 			'separator_length' => $iSepLength,	
 		);
 	}
+
+	/**
+	 * Get the latest entry from the log
+	 */
+	public function GetLatestEntry()
+	{
+		$iLast = count($this->m_aIndex) - 1;
+		$aLastEntry = $this->m_aIndex[$iLast];
+		$sRes = substr($this->m_sLog, $aLastEntry['separator_length'], $aLastEntry['text_length']);
+		return $sRes;
+	}
 }
 ?>

+ 1 - 0
dictionaries/de.dictionary.itop.core.php

@@ -203,6 +203,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
 	'Change:ObjectDeleted' => 'Object deleted',
 	'Change:ObjectModified' => 'Object modified',
 	'Change:AttName_SetTo_NewValue_PreviousValue_OldValue' => '%1$s geändert zu %2$s (vorheriger Wert: %3$s)',
+	'Change:AttName_SetTo' => '%1$s geändert zu %2$s',
 	'Change:Text_AppendedTo_AttName' => '%1$s zugefügt an %2$s',
 	'Change:AttName_Changed_PreviousValue_OldValue' => '%1$s modifiziert, vorheriger Wert: %2$s',
 	'Change:AttName_Changed' => '%1$s modifiziert',

+ 1 - 0
dictionaries/dictionary.itop.core.php

@@ -202,6 +202,7 @@ Dict::Add('EN US', 'English', 'English', array(
 	'Change:ObjectDeleted' => 'Object deleted',
 	'Change:ObjectModified' => 'Object modified',
 	'Change:AttName_SetTo_NewValue_PreviousValue_OldValue' => '%1$s set to %2$s (previous value: %3$s)',
+	'Change:AttName_SetTo' => '%1$s set to %2$s',
 	'Change:Text_AppendedTo_AttName' => '%1$s appended to %2$s',
 	'Change:AttName_Changed_PreviousValue_OldValue' => '%1$s modified, previous value: %2$s',
 	'Change:AttName_Changed' => '%1$s modified',

+ 1 - 0
dictionaries/es_cr.dictionary.itop.core.php

@@ -200,6 +200,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
 // Used by CMDBChangeOp... & derived classes
 Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
 	'Change:AttName_SetTo_NewValue_PreviousValue_OldValue' => '%1$s modificado en %2$s (valor anterior: %3$s)',
+	'Change:AttName_SetTo' => '%1$s modificado en %2$s',
 	'Change:Text_AppendedTo_AttName' => '%1$s añadido a %2$s',
 	'Change:AttName_Changed_PreviousValue_OldValue' => '%1$s modificado, valor anterior: %2$s',
 	'Change:AttName_Changed' => '%1$s modificado',

+ 1 - 0
dictionaries/fr.dictionary.itop.core.php

@@ -203,6 +203,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
 	'Change:ObjectDeleted' => 'Elément effacé',
 	'Change:ObjectModified' => 'Elément modifié',
 	'Change:AttName_SetTo_NewValue_PreviousValue_OldValue' => '%1$s modifié en %2$s (ancienne valeur: %3$s)',
+	'Change:AttName_SetTo' => '%1$s modifié en %2$s',
 	'Change:Text_AppendedTo_AttName' => '%1$s ajouté à %2$s',
 	'Change:AttName_Changed_PreviousValue_OldValue' => '%1$s modifié, ancienne valeur: %2$s',
 	'Change:AttName_Changed' => '%1$s modifié',

+ 1 - 0
dictionaries/ru.dictionary.itop.core.php

@@ -107,6 +107,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
 	'Change:ObjectCreated' => 'Объект создан',
 	'Change:ObjectDeleted' => 'Объект удалён',
 	'Change:AttName_SetTo_NewValue_PreviousValue_OldValue' => '%1$s установлено в %2$s (предыдущее значение: %3$s)',
+	'Change:AttName_SetTo' => '%1$s установлено в %2$s',
 	'Change:Text_AppendedTo_AttName' => '%1$s добавлено к %2$s',
 	'Change:AttName_Changed_PreviousValue_OldValue' => '%1$s изменено, предыдущее значение: %2$s',
 	'Change:AttName_Changed' => '%1$s изменено',

+ 1 - 0
dictionaries/tr.dictionary.itop.core.php

@@ -108,6 +108,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
 	'Change:ObjectCreated' => 'Nesne yaratıldı',
 	'Change:ObjectDeleted' => 'Nesne silindi',
 	'Change:AttName_SetTo_NewValue_PreviousValue_OldValue' => '%1$s\'nin değeri %2$s olarak atandı (önceki değer: %3$s)',
+	'Change:AttName_SetTo' => '%1$s\'nin değeri %2$s olarak atandı',
 	'Change:Text_AppendedTo_AttName' => '%2$s\'ye %1$s eklendi',
 	'Change:AttName_Changed_PreviousValue_OldValue' => '%1$\'nin değeri deiştirildi, önceki değer: %2$s',
 	'Change:AttName_Changed' => '%1$s değiştirildi',

+ 1 - 0
dictionaries/zh.dictionary.itop.core.php

@@ -107,6 +107,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
 	'Change:ObjectCreated' => 'Object created',
 	'Change:ObjectDeleted' => 'Object deleted',
 	'Change:AttName_SetTo_NewValue_PreviousValue_OldValue' => '%1$s set to %2$s (previous value: %3$s)',
+	'Change:AttName_SetTo' => '%1$s set to %2$s',
 	'Change:Text_AppendedTo_AttName' => '%1$s appended to %2$s',
 	'Change:AttName_Changed_PreviousValue_OldValue' => '%1$s modified, previous value: %2$s',
 	'Change:AttName_Changed' => '%1$s modified',