浏览代码

- Special handling (using some custom code - temporary solution) of the 'ticket_log' attribute: the attribute is displayed at the bottom of the "Properties" page and takes the whole width of the page.

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1193 a333f486-631f-4898-b8df-5754b55c2be0
dflaven 14 年之前
父节点
当前提交
f3a9f15672

+ 81 - 3
application/cmdbabstract.class.inc.php

@@ -175,6 +175,16 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
 	{
 	{
 		$oPage->add($this->GetBareProperties($oPage, $bEditMode));		
 		$oPage->add($this->GetBareProperties($oPage, $bEditMode));		
 
 
+		// Special case to display the case log, if any...
+		if (MetaModel::IsValidAttCode(get_class($this), 'ticket_log'))
+		{
+			$oAttDef = MetaModel::GetAttributeDef(get_class($this), 'ticket_log');
+			if ($oAttDef instanceof AttributeCaseLog)
+			{
+				$this->DisplayCaseLog($oPage, 'ticket_log', '', '', false);
+			}
+		}
+
 		foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
 		foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
 		{
 		{
 			$oExtensionInstance->OnDisplayProperties($this, $oPage, $bEditMode);
 			$oExtensionInstance->OnDisplayProperties($this, $oPage, $bEditMode);
@@ -1298,7 +1308,7 @@ EOF
 					$aEventsList[] ='validate';
 					$aEventsList[] ='validate';
 					$aEventsList[] ='keyup';
 					$aEventsList[] ='keyup';
 					$aEventsList[] ='change';
 					$aEventsList[] ='change';
-					$aStyles = array("overflow:auto;border:1px #999 solid; background:#fff");
+					$aStyles = array();
 					$sStyle = '';
 					$sStyle = '';
 					$sWidth = $oAttDef->GetWidth('width', '');
 					$sWidth = $oAttDef->GetWidth('width', '');
 					if (!empty($sWidth))
 					if (!empty($sWidth))
@@ -1316,8 +1326,8 @@ EOF
 					}
 					}
 					$sHeader = '<div class="caselog_input_header">&nbsp;'.Dict::S('UI:CaseLogTypeYourTextHere').'</div>';
 					$sHeader = '<div class="caselog_input_header">&nbsp;'.Dict::S('UI:CaseLogTypeYourTextHere').'</div>';
 					$sEditValue = $oAttDef->GetEditValue($value);
 					$sEditValue = $oAttDef->GetEditValue($value);
-					$sPreviousLog = $oAttDef->GetAsHTML($value);
-					$sHTMLValue = "<div $sStyle><table style=\"width:100%\"><tr><td>$sHeader<textarea style=\"border:0;width:100%\" title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" rows=\"8\" cols=\"40\" id=\"$iId\">$sEditValue</textarea>$sPreviousLog</td><td>{$sValidationField}</td></tr></table></div>";
+					$sPreviousLog = $value->GetAsHTML();
+					$sHTMLValue = "<div class=\"caselog\" $sStyle><table style=\"width:100%;\"><tr><td>$sHeader<textarea style=\"border:0;width:100%\" title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" rows=\"8\" cols=\"40\" id=\"$iId\">$sEditValue</textarea>$sPreviousLog</td><td>{$sValidationField}</td></tr></table></div>";
 				break;
 				break;
 
 
 				case 'HTML':
 				case 'HTML':
@@ -1606,6 +1616,18 @@ EOF
 			$oPage->add('</tr></table>');
 			$oPage->add('</tr></table>');
 		}
 		}
 
 
+		// Special case to display the case log, if any...
+		if (MetaModel::IsValidAttCode($sClass, 'ticket_log'))
+		{
+			$oAttDef = MetaModel::GetAttributeDef($sClass, 'ticket_log');
+			if ($oAttDef instanceof AttributeCaseLog)
+			{
+				$sComments = isset($aFieldsComments['ticket_log']) ? $aFieldsComments['ticket_log'] : '&nbsp;';
+				$this->DisplayCaseLog($oPage, 'ticket_log', $sComments, $sPrefix, true);
+				$sInputId = $this->m_iFormId.'_ticket_log';
+				$aFieldsMap['ticket_log'] = $sInputId;
+			}
+		}
 		// Now display the relations, one tab per relation
 		// Now display the relations, one tab per relation
 		if (!isset($aExtraParams['noRelations']))
 		if (!isset($aExtraParams['noRelations']))
 		{
 		{
@@ -2223,5 +2245,61 @@ EOF
 			}
 			}
 		}
 		}
 	}
 	}
+
+	/**
+	 * Special display where the case log uses the whole "screen" at the bottom of the "Properties" tab
+	 */
+	public function DisplayCaseLog(WebPage $oPage, $sAttCode, $sComment = '', $sPrefix = '', $bEditMode = false)
+	{
+		$oPage->SetCurrentTab(Dict::S('UI:PropertiesTab'));
+		$sClass = get_class($this);
+		$iFlags = $this->GetAttributeFlags($sAttCode);
+		if ( $iFlags & OPT_ATT_HIDDEN)
+		{
+			// The case log is hidden do nothing
+		}
+		else
+		{
+			$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
+			$sInputId = $this->m_iFormId.'_'.$sAttCode;
+			
+			if ((!$bEditMode) || ($iFlags & (OPT_ATT_READONLY|OPT_ATT_SLAVE)))
+			{
+				// Check if the attribute is not read-only becuase of a synchro...
+				$aReasons = array();
+				$sSynchroIcon = '';
+				if ($iFlags & OPT_ATT_SLAVE)
+				{
+					$iSynchroFlags = $this->GetSynchroReplicaFlags($sAttCode, $aReasons);
+					$sSynchroIcon = "&nbsp;<img id=\"synchro_$sInputId\" src=\"../images/transp-lock.png\" style=\"vertical-align:middle\"/>";
+					$sTip = '';
+					foreach($aReasons as $aRow)
+					{
+						$sTip .= "<p>Synchronized with {$aRow['name']} - {$aRow['description']}</p>";
+					}
+					$oPage->add_ready_script("$('#synchro_$sInputId').qtip( { content: '$sTip', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );");
+				}
+
+				// Attribute is read-only
+				$sHTMLValue = $this->GetAsHTML($sAttCode);
+				$sHTMLValue .= '<input type="hidden" id="'.$sInputId.'" name="attr_'.$sPrefix.$sAttCode.'" value="'.htmlentities($this->Get($sAttCode), ENT_QUOTES, 'UTF-8').'"/>';
+				$aFieldsMap[$sAttCode] = $sInputId;
+				$sComment .= $sSynchroIcon;
+			}
+			else
+			{
+				$sValue = $this->Get($sAttCode);
+				$sDisplayValue = $this->GetEditValue($sAttCode);
+				$aArgs = array('this' => $this, 'formPrefix' => $sPrefix);
+				$sHTMLValue = "<span id=\"field_{$sInputId}\">".self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).'</span>';
+				$aFieldsMap[$sAttCode] = $sInputId;
+				
+			}
+			//$aVal = array('label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().'</span>', 'value' => $sHTMLValue, 'comments' => $sComments, 'infos' => $sInfos);
+			$oPage->add('<fieldset><legend>'.$oAttDef->GetLabel().'&nbsp<span>'.$sComment.'</span></legend>');
+			$oPage->add($sHTMLValue);
+			$oPage->add('</fieldset>');
+		}
+	}
 }
 }
 ?>
 ?>

+ 33 - 4
core/attributedef.class.inc.php

@@ -1363,7 +1363,22 @@ class AttributeText extends AttributeString
 	{
 	{
 		$sValue = parent::GetAsHTML($sValue);
 		$sValue = parent::GetAsHTML($sValue);
 		$sValue = self::RenderWikiHtml($sValue);
 		$sValue = self::RenderWikiHtml($sValue);
-		return str_replace("\n", "<br>\n", $sValue);
+		$aStyles = array();
+		if ($this->GetWidth() != '')
+		{
+			$aStyles[] = 'width:'.$this->GetWidth();
+		}
+		if ($this->GetHeight() != '')
+		{
+			$aStyles[] = 'height:'.$this->GetHeight();
+		}
+		$sStyle = '';
+		if (count($aStyles) > 0)
+		{
+			$aStyles[] = 'overflow:auto';
+			$sStyle = 'style="'.implode(';', $aStyles).'"';
+		}
+		return "<div $sStyle>".str_replace("\n", "<br>\n", $sValue).'</div>';
 	}
 	}
 
 
 	public function GetEditValue($sValue)
 	public function GetEditValue($sValue)
@@ -1579,13 +1594,27 @@ class AttributeCaseLog extends AttributeText
 	{
 	{
 		if ($value instanceOf ormCaseLog)
 		if ($value instanceOf ormCaseLog)
 		{
 		{
-			return $value->GetAsHTML(null, false, array(__class__, 'RenderWikiHtml'));
+			$sContent = $value->GetAsHTML(null, false, array(__class__, 'RenderWikiHtml'));
 		}
 		}
 		else
 		else
 		{
 		{
-			return '';
+			$sContent = '';
 		}
 		}
-	}
+		$aStyles = array();
+		if ($this->GetWidth() != '')
+		{
+			$aStyles[] = 'width:'.$this->GetWidth();
+		}
+		if ($this->GetHeight() != '')
+		{
+			$aStyles[] = 'height:'.$this->GetHeight();
+		}
+		$sStyle = '';
+		if (count($aStyles) > 0)
+		{
+			$sStyle = 'style="'.implode(';', $aStyles).'"';
+		}
+		return "<div class=\"caselog\" $sStyle>".str_replace("\n", "<br>\n", $sContent).'</div>';	}
 
 
 
 
 	public function GetAsCSV($value, $sSeparator = ',', $sTextQualifier = '"', $oHostObject = null)
 	public function GetAsCSV($value, $sSeparator = ',', $sTextQualifier = '"', $oHostObject = null)

+ 57 - 0
core/cmdbchangeop.class.inc.php

@@ -497,4 +497,61 @@ class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
 	}
 	}
 }
 }
 
 
+/**
+ * Record the modification of a caselog (text)
+ * since the caselog itself stores the history
+ * of its entries, there is no need to duplicate
+ * the text here
+ *
+ * @package     iTopORM
+ */
+class CMDBChangeOpSetAttributeCaseLog 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_log",
+			"db_key_field" => "id",
+			"db_finalclass_field" => "",
+		);
+		MetaModel::Init_Params($aParams);
+		MetaModel::Init_InheritAttributes();
+		MetaModel::Init_AddAttribute(new AttributeInteger("lastentry", array("allowed_values"=>null, "sql"=>"lastentry", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
+
+		// Display lists
+		MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for the complete details
+		MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'attcode')); // Attributes to be displayed for a list
+	}
+	
+	/**
+	 * Describe (as a text string) the modifications corresponding to this change
+	 */	 
+	public function GetDescription()
+	{
+		// Temporary, until we change the options of GetDescription() -needs a more global revision
+		$bIsHtml = true;
+		
+		$sResult = '';
+		$oTargetObjectClass = $this->Get('objclass');
+		$oTargetObjectKey = $this->Get('objkey');
+		$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
+		$oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
+
+		$oMonoObjectSet = new DBObjectSet($oTargetSearch);
+		if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
+		{
+			$oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode'));
+			$sAttName = $oAttDef->GetLabel();
+			$sResult = Dict::Format('Change:AttName_EntryAdded', $sAttName);
+		}
+		return $sResult;
+	}
+}
+
 ?>
 ?>

+ 2 - 3
core/cmdbobject.class.inc.php

@@ -179,14 +179,13 @@ abstract class CMDBObject extends DBObject
 			}
 			}
 			elseif ($oAttDef instanceOf AttributeCaseLog)
 			elseif ($oAttDef instanceOf AttributeCaseLog)
 			{
 			{
-				$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpSetAttributeScalar");
+				$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpSetAttributeCaseLog");
 				$oMyChangeOp->Set("change", $oChange->GetKey());
 				$oMyChangeOp->Set("change", $oChange->GetKey());
 				$oMyChangeOp->Set("objclass", get_class($this));
 				$oMyChangeOp->Set("objclass", get_class($this));
 				$oMyChangeOp->Set("objkey", $this->GetKey());
 				$oMyChangeOp->Set("objkey", $this->GetKey());
 				$oMyChangeOp->Set("attcode", $sAttCode);
 				$oMyChangeOp->Set("attcode", $sAttCode);
 
 
-				$oMyChangeOp->Set("oldvalue", '');
-				$oMyChangeOp->Set("newvalue", $value->GetLatestEntry());
+				$oMyChangeOp->Set("lastentry", $value->GetLatestEntryIndex());
 				$iId = $oMyChangeOp->DBInsertNoReload();
 				$iId = $oMyChangeOp->DBInsertNoReload();
 			}
 			}
 			elseif ($oAttDef instanceOf AttributeText)
 			elseif ($oAttDef instanceOf AttributeText)

+ 4 - 7
core/dbobjectset.class.php

@@ -537,11 +537,10 @@ class DBObjectSet
 	public function ComputeCommonObject(&$aValues)
 	public function ComputeCommonObject(&$aValues)
 	{
 	{
 		$sClass = $this->GetClass();
 		$sClass = $this->GetClass();
-		$aList = MetaModel::FlattenZlist(MetaModel::GetZListItems($sClass, 'details'));
+		$aList = MetaModel::ListAttributeDefs($sClass);
 		$aValues = array();
 		$aValues = array();
-		foreach($aList as $sAttCode)
+		foreach($aList as $sAttCode => $oAttDef)
 		{
 		{
-			$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
 			if ($oAttDef->IsScalar())
 			if ($oAttDef->IsScalar())
 			{
 			{
 				$aValues[$sAttCode] = array();
 				$aValues[$sAttCode] = array();
@@ -550,9 +549,8 @@ class DBObjectSet
 		$this->Rewind();
 		$this->Rewind();
 		while($oObj = $this->Fetch())
 		while($oObj = $this->Fetch())
 		{
 		{
-			foreach($aList as $sAttCode)
+			foreach($aList as $sAttCode => $oAttDef)
 			{
 			{
-				$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
 				if ($oAttDef->IsScalar() && $oAttDef->IsWritable())
 				if ($oAttDef->IsScalar() && $oAttDef->IsWritable())
 				{
 				{
 					$currValue = $oObj->Get($sAttCode);
 					$currValue = $oObj->Get($sAttCode);
@@ -586,9 +584,8 @@ class DBObjectSet
 		$sReadyScript = '';
 		$sReadyScript = '';
 		$aDependsOn = array();
 		$aDependsOn = array();
 		$sFormPrefix = '2_';
 		$sFormPrefix = '2_';
-		foreach($aList as $sAttCode)
+		foreach($aList as $sAttCode => $oAttDef)
 		{
 		{
-			$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
 			if ($oAttDef->IsScalar() && $oAttDef->IsWritable())
 			if ($oAttDef->IsScalar() && $oAttDef->IsWritable())
 			{
 			{
 				if ($oAttDef->GetEditClass() == 'One Way Password')
 				if ($oAttDef->GetEditClass() == 'One Way Password')

+ 11 - 1
core/ormcaselog.class.inc.php

@@ -121,7 +121,6 @@ class ormCaseLog {
 				$sHtml .= '</div>';
 				$sHtml .= '</div>';
 			}
 			}
 		}
 		}
-		$sHtml = '<div class="caselog">'.$sHtml.'</div>';
 		return $sHtml;
 		return $sHtml;
 	}
 	}
 	
 	
@@ -147,6 +146,7 @@ class ormCaseLog {
 
 
 	/**
 	/**
 	 * Get the latest entry from the log
 	 * Get the latest entry from the log
+	 * @return string
 	 */
 	 */
 	public function GetLatestEntry()
 	public function GetLatestEntry()
 	{
 	{
@@ -155,5 +155,15 @@ class ormCaseLog {
 		$sRes = substr($this->m_sLog, $aLastEntry['separator_length'], $aLastEntry['text_length']);
 		$sRes = substr($this->m_sLog, $aLastEntry['separator_length'], $aLastEntry['text_length']);
 		return $sRes;
 		return $sRes;
 	}
 	}
+
+	/**
+	 * Get the index of the latest entry from the log
+	 * @return integer
+	 */
+	public function GetLatestEntryIndex()
+	{
+		$iLast = count($this->m_aIndex) - 1;
+		return $iLast;
+	}
 }
 }
 ?>
 ?>

+ 11 - 3
css/light-grey.css

@@ -1,6 +1,6 @@
 /* CSS Document */
 /* CSS Document */
 body {
 body {
-    font-family: Tahoma, Verdana, Arial, Helevtica;
+    font-family: Tahoma, Verdana, Arial, Helvetica;
     font-size: 10pt;
     font-size: 10pt;
     background-color: #fff;
     background-color: #fff;
     color:#000000;
     color:#000000;
@@ -10,7 +10,7 @@ body {
 }
 }
 
 
 .raw_output {
 .raw_output {
-    font-family: Courier-New, Courier, Arial, Helevtica;
+    font-family: Courier-New, Courier, Arial, Helvetica;
     font-size: 8pt;
     font-size: 8pt;
     background-color: #eeeeee;
     background-color: #eeeeee;
     color: #000000;
     color: #000000;
@@ -166,6 +166,8 @@ fieldset {
 }
 }
 
 
 legend {
 legend {
+    font-family: Tahoma, Verdana, Arial, Helvetica;
+    font-size: 12px;
 	padding:8px;
 	padding:8px;
 	color: #fff;
 	color: #fff;
 	background-color: #1C94C4;
 	background-color: #1C94C4;
@@ -993,6 +995,11 @@ span.form_validation {
 }
 }
 .caselog {
 .caselog {
 	overflow-x: hidden;
 	overflow-x: hidden;
+	display: block;
+	overflow-y: auto;
+	border: 1px #ddd solid;
+    font-family: Tahoma, Verdana, Arial, Helvetica;
+    font-size: 12px;
 }
 }
 .caselog_input_header {
 .caselog_input_header {
 	padding-top:3px;
 	padding-top:3px;
@@ -1016,7 +1023,8 @@ span.form_validation {
 	padding:3px;
 	padding:3px;
 	padding-left: 16px;
 	padding-left: 16px;
 	border-bottom:1px #999 solid;
 	border-bottom:1px #999 solid;
-	width:100%;
+	margin-left:0;
+	margin-right:0;
 }
 }
 table.details {
 table.details {
   border-collapse: collapse;
   border-collapse: collapse;

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

@@ -206,6 +206,7 @@ Dict::Add('EN US', 'English', 'English', array(
 	'Change:Text_AppendedTo_AttName' => '%1$s appended 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_PreviousValue_OldValue' => '%1$s modified, previous value: %2$s',
 	'Change:AttName_Changed' => '%1$s modified',
 	'Change:AttName_Changed' => '%1$s modified',
+	'Change:AttName_EntryAdded' => '%1$s modified, new entry added.',
 ));
 ));
 
 
 //
 //

+ 3 - 3
modules/itop-change-mgmt-1.0.0/model.itop-change-mgmt.php

@@ -376,7 +376,7 @@ class RoutineChange extends Change
 			'col:col1' => array(
 			'col:col1' => array(
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','reason','impact','description', ),
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','reason','impact','description', ),
 				'fieldset:Ticket:moreinfo' => array('outage', 'fallback',),
 				'fieldset:Ticket:moreinfo' => array('outage', 'fallback',),
-				'fieldset:Ticket:log' => array('ticket_log'),),
+				),
 			'col:col2' => array(
 			'col:col2' => array(
 				'fieldset:Ticket:date' => array('creation_date','start_date','last_update','close_date',),
 				'fieldset:Ticket:date' => array('creation_date','start_date','last_update','close_date',),
 				'fieldset:Ticket:contact' => array('requestor_id','workgroup_id','agent_id','supervisor_group_id', 'supervisor_id', 'manager_group_id', 'manager_id',),
 				'fieldset:Ticket:contact' => array('requestor_id','workgroup_id','agent_id','supervisor_group_id', 'supervisor_id', 'manager_group_id', 'manager_id',),
@@ -477,7 +477,7 @@ class NormalChange extends ApprovedChange
 			'col:col1' => array(
 			'col:col1' => array(
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','reason','impact','description', ),
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','reason','impact','description', ),
 				'fieldset:Ticket:moreinfo' => array('acceptance_comment','approval_comment','outage', 'fallback',),
 				'fieldset:Ticket:moreinfo' => array('acceptance_comment','approval_comment','outage', 'fallback',),
-				'fieldset:Ticket:log' => array('ticket_log'),),
+				),
 			'col:col2' => array(
 			'col:col2' => array(
 				'fieldset:Ticket:date' => array('creation_date','start_date','last_update','acceptance_date','approval_date','close_date',),
 				'fieldset:Ticket:date' => array('creation_date','start_date','last_update','acceptance_date','approval_date','close_date',),
 				'fieldset:Ticket:contact' => array('requestor_id','workgroup_id','agent_id','supervisor_group_id', 'supervisor_id', 'manager_group_id', 'manager_id',),
 				'fieldset:Ticket:contact' => array('requestor_id','workgroup_id','agent_id','supervisor_group_id', 'supervisor_id', 'manager_group_id', 'manager_id',),
@@ -548,7 +548,7 @@ class EmergencyChange extends ApprovedChange
 			'col:col1' => array(
 			'col:col1' => array(
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','reason','impact','description', ),
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','reason','impact','description', ),
 				'fieldset:Ticket:moreinfo' => array('approval_comment','outage', 'fallback',),
 				'fieldset:Ticket:moreinfo' => array('approval_comment','outage', 'fallback',),
-				'fieldset:Ticket:log' => array('ticket_log'),),
+				),
 			'col:col2' => array(
 			'col:col2' => array(
 				'fieldset:Ticket:date' => array('creation_date','start_date','last_update','approval_date','close_date',),
 				'fieldset:Ticket:date' => array('creation_date','start_date','last_update','approval_date','close_date',),
 				'fieldset:Ticket:contact' => array('requestor_id','workgroup_id','agent_id','supervisor_group_id', 'supervisor_id', 'manager_group_id', 'manager_id',),
 				'fieldset:Ticket:contact' => array('requestor_id','workgroup_id','agent_id','supervisor_group_id', 'supervisor_id', 'manager_group_id', 'manager_id',),

+ 1 - 1
modules/itop-incident-mgmt-1.0.0/model.itop-incident-mgmt.php

@@ -50,7 +50,7 @@ class Incident extends ResponseTicket
 			'col:col1' => array(
 			'col:col1' => array(
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','priority','service_id','servicesubcategory_id','product' ),
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','priority','service_id','servicesubcategory_id','product' ),
 				'fieldset:Ticket:moreinfo' => array('impact','urgency','description','resolution_code', 'solution', 'user_satisfaction', 'user_commment',),
 				'fieldset:Ticket:moreinfo' => array('impact','urgency','description','resolution_code', 'solution', 'user_satisfaction', 'user_commment',),
-				'fieldset:Ticket:log' => array('ticket_log'),),
+				),
 			'col:col2' => array(
 			'col:col2' => array(
 				'fieldset:Ticket:date' => array('start_date','last_update','assignment_date','tto_escalation_deadline', 'ttr_escalation_deadline', 'close_date','closure_deadline',),
 				'fieldset:Ticket:date' => array('start_date','last_update','assignment_date','tto_escalation_deadline', 'ttr_escalation_deadline', 'close_date','closure_deadline',),
 				'fieldset:Ticket:contact' => array('caller_id','workgroup_id','agent_id',),
 				'fieldset:Ticket:contact' => array('caller_id','workgroup_id','agent_id',),

+ 1 - 1
modules/itop-problem-mgmt-1.0.0/model.itop-problem-mgmt.php

@@ -72,7 +72,7 @@ class Problem extends Ticket
 			'col:col1' => array(
 			'col:col1' => array(
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','priority','service_id','servicesubcategory_id','product' ),
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','priority','service_id','servicesubcategory_id','product' ),
 				'fieldset:Ticket:moreinfo' => array('impact','urgency','description',),
 				'fieldset:Ticket:moreinfo' => array('impact','urgency','description',),
-				'fieldset:Ticket:log' => array('ticket_log'),),
+				),
 			'col:col2' => array(
 			'col:col2' => array(
 				'fieldset:Ticket:date' => array('start_date','last_update','assignment_date','close_date',),
 				'fieldset:Ticket:date' => array('start_date','last_update','assignment_date','close_date',),
 				'fieldset:Ticket:contact' => array('workgroup_id','agent_id',),
 				'fieldset:Ticket:contact' => array('workgroup_id','agent_id',),

+ 2 - 2
modules/itop-request-mgmt-1.0.0/model.itop-request-mgmt.php

@@ -52,11 +52,11 @@ class UserRequest extends ResponseTicket
 			'col:col1' => array(
 			'col:col1' => array(
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','priority','service_id','servicesubcategory_id','product' ),
 				'fieldset:Ticket:baseinfo' => array('ref','title','org_id','status','priority','service_id','servicesubcategory_id','product' ),
 				'fieldset:Ticket:moreinfo' => array('impact','urgency','description','resolution_code', 'solution', 'user_satisfaction', 'user_commment','freeze_reason'),
 				'fieldset:Ticket:moreinfo' => array('impact','urgency','description','resolution_code', 'solution', 'user_satisfaction', 'user_commment','freeze_reason'),
-				'fieldset:Ticket:log' => array('ticket_log'),),
+				),
 			'col:col2' => array(
 			'col:col2' => array(
 				'fieldset:Ticket:date' => array('start_date','last_update','assignment_date','tto_escalation_deadline', 'ttr_escalation_deadline', 'close_date',  'closure_deadline',),
 				'fieldset:Ticket:date' => array('start_date','last_update','assignment_date','tto_escalation_deadline', 'ttr_escalation_deadline', 'close_date',  'closure_deadline',),
 				'fieldset:Ticket:contact' => array('caller_id','workgroup_id','agent_id',),
 				'fieldset:Ticket:contact' => array('caller_id','workgroup_id','agent_id',),
-				'fieldset:Ticket:relation' => array('related_problem_id', 'related_change_id',),
+				'fieldset:Ticket:relation' => array('related_problem_id', 'related_change_id'),
 				)
 				)
 
 
 		));
 		));

+ 2 - 2
modules/itop-tickets-1.0.0/model.itop-tickets.php

@@ -53,7 +53,7 @@ abstract class Ticket extends cmdbAbstractObject
 		MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("contact_list", array("linked_class"=>"lnkTicketToContact", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"contact_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("contact_list", array("linked_class"=>"lnkTicketToContact", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"contact_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("incident_list", array("linked_class"=>"lnkTicketToIncident", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"incident_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("incident_list", array("linked_class"=>"lnkTicketToIncident", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"incident_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array())));
 
 
-		MetaModel::Init_SetZListItems('details', array('ref', 'title', 'description',  'start_date','ticket_log', 'document_list', 'ci_list', 'contact_list','incident_list'));
+		MetaModel::Init_SetZListItems('details', array('ref', 'title', 'description',  'start_date', 'document_list', 'ci_list', 'contact_list','incident_list'));
 		MetaModel::Init_SetZListItems('advanced_search', array('finalclass', 'ref', 'title',  'start_date'));
 		MetaModel::Init_SetZListItems('advanced_search', array('finalclass', 'ref', 'title',  'start_date'));
 		MetaModel::Init_SetZListItems('standard_search', array('finalclass', 'ref', 'title',  'start_date'));
 		MetaModel::Init_SetZListItems('standard_search', array('finalclass', 'ref', 'title',  'start_date'));
 		MetaModel::Init_SetZListItems('list', array('finalclass', 'ref', 'title', 'ticket_log', 'start_date'));
 		MetaModel::Init_SetZListItems('list', array('finalclass', 'ref', 'title', 'ticket_log', 'start_date'));
@@ -212,7 +212,7 @@ abstract class ResponseTicket extends Ticket
 		MetaModel::Init_AddAttribute(new AttributeEnum("user_satisfaction", array("allowed_values"=>new ValueSetEnum('1,2,3,4'), "sql"=>"user_satisfaction", "default_value"=>"1", "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("user_satisfaction", array("allowed_values"=>new ValueSetEnum('1,2,3,4'), "sql"=>"user_satisfaction", "default_value"=>"1", "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeText("user_commment", array("allowed_values"=>null, "sql"=>"user_commment", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeText("user_commment", array("allowed_values"=>null, "sql"=>"user_commment", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 
 
-		MetaModel::Init_SetZListItems('details', array('ref', 'title', 'org_id', 'ticket_log', 'start_date', 'tto_escalation_deadline', 'ttr_escalation_deadline', 'closure_deadline', 'document_list', 'ci_list', 'contact_list', 'status', 'caller_id', 'service_id', 'servicesubcategory_id', 'product', 'impact', 'urgency', 'priority', 'workgroup_id', 'agent_id', 'agent_email', 'related_problem_id', 'related_change_id', 'close_date', 'last_update', 'assignment_date', 'resolution_code', 'solution', 'user_satisfaction', 'user_commment'));
+		MetaModel::Init_SetZListItems('details', array('ref', 'title', 'org_id', 'start_date', 'tto_escalation_deadline', 'ttr_escalation_deadline', 'closure_deadline', 'document_list', 'ci_list', 'contact_list', 'status', 'caller_id', 'service_id', 'servicesubcategory_id', 'product', 'impact', 'urgency', 'priority', 'workgroup_id', 'agent_id', 'agent_email', 'related_problem_id', 'related_change_id', 'close_date', 'last_update', 'assignment_date', 'resolution_code', 'solution', 'user_satisfaction', 'user_commment'));
 		MetaModel::Init_SetZListItems('advanced_search', array('finalclass', 'ref', 'title', 'org_id', 'start_date', 'status', 'caller_id', 'service_id', 'servicesubcategory_id', 'product', 'impact', 'urgency', 'priority', 'workgroup_id', 'agent_id', 'agent_email', 'related_problem_id', 'related_change_id', 'close_date', 'last_update', 'assignment_date', 'tto_escalation_deadline', 'ttr_escalation_deadline', 'closure_deadline', 'resolution_code', 'solution', 'user_satisfaction', 'user_commment'));
 		MetaModel::Init_SetZListItems('advanced_search', array('finalclass', 'ref', 'title', 'org_id', 'start_date', 'status', 'caller_id', 'service_id', 'servicesubcategory_id', 'product', 'impact', 'urgency', 'priority', 'workgroup_id', 'agent_id', 'agent_email', 'related_problem_id', 'related_change_id', 'close_date', 'last_update', 'assignment_date', 'tto_escalation_deadline', 'ttr_escalation_deadline', 'closure_deadline', 'resolution_code', 'solution', 'user_satisfaction', 'user_commment'));
 		MetaModel::Init_SetZListItems('standard_search', array('finalclass', 'ref', 'title', 'org_id', 'start_date', 'status', 'caller_id', 'service_id', 'servicesubcategory_id', 'product', 'impact', 'urgency', 'priority', 'workgroup_id', 'agent_id', 'agent_email', 'close_date', 'resolution_code', 'solution', 'user_satisfaction', 'user_commment'));
 		MetaModel::Init_SetZListItems('standard_search', array('finalclass', 'ref', 'title', 'org_id', 'start_date', 'status', 'caller_id', 'service_id', 'servicesubcategory_id', 'product', 'impact', 'urgency', 'priority', 'workgroup_id', 'agent_id', 'agent_email', 'close_date', 'resolution_code', 'solution', 'user_satisfaction', 'user_commment'));
 		MetaModel::Init_SetZListItems('list', array('finalclass', 'title', 'org_id', 'start_date', 'status', 'caller_id', 'service_id', 'priority', 'workgroup_id', 'agent_id', 'last_update'));
 		MetaModel::Init_SetZListItems('list', array('finalclass', 'title', 'org_id', 'start_date', 'status', 'caller_id', 'service_id', 'priority', 'workgroup_id', 'agent_id', 'last_update'));

+ 4 - 7
pages/UI.php

@@ -818,11 +818,10 @@ try
 			$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL));
 			$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL));
 			
 			
 			// Compute the distribution of the values for each field to determine which of the "scalar" fields are homogenous
 			// Compute the distribution of the values for each field to determine which of the "scalar" fields are homogenous
-			$aList = MetaModel::FlattenZlist(MetaModel::GetZListItems($sClass, 'details'));
+			$aList = MetaModel::ListAttributeDefs($sClass);
 			$aValues = array();
 			$aValues = array();
-			foreach($aList as $sAttCode)
+			foreach($aList as $sAttCode => $oAttDef)
 			{
 			{
-				$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
 				if ($oAttDef->IsScalar())
 				if ($oAttDef->IsScalar())
 				{
 				{
 					$aValues[$sAttCode] = array();
 					$aValues[$sAttCode] = array();
@@ -830,9 +829,8 @@ try
 			}
 			}
 			while($oObj = $oSet->Fetch())
 			while($oObj = $oSet->Fetch())
 			{
 			{
-				foreach($aList as $sAttCode)
+				foreach($aList as $sAttCode => $oAttDef)
 				{
 				{
-					$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
 					if ($oAttDef->IsScalar() && $oAttDef->IsWritable())
 					if ($oAttDef->IsScalar() && $oAttDef->IsWritable())
 					{
 					{
 						$currValue = $oObj->Get($sAttCode);
 						$currValue = $oObj->Get($sAttCode);
@@ -864,9 +862,8 @@ try
 			$sReadyScript = '';
 			$sReadyScript = '';
 			$aDependsOn = array();
 			$aDependsOn = array();
 			$sFormPrefix = '2_';
 			$sFormPrefix = '2_';
-			foreach($aList as $sAttCode)
+			foreach($aList as $sAttCode => $oAttDef)
 			{
 			{
-				$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
 				$aPrerequisites = MetaModel::GetPrequisiteAttributes($sClass, $sAttCode); // List of attributes that are needed for the current one
 				$aPrerequisites = MetaModel::GetPrequisiteAttributes($sClass, $sAttCode); // List of attributes that are needed for the current one
 				if (count($aPrerequisites) > 0)
 				if (count($aPrerequisites) > 0)
 				{
 				{