GetText() == ''); } /** * @inheritDoc * * @param ormCaseLog $proposedValue */ public function HasAValue($proposedValue): bool { // Protection against wrong value type if (false === ($proposedValue instanceof ormCaseLog)) { return parent::HasAValue($proposedValue); } // We test if there is at least 1 entry in the log, not if the user is adding one return $proposedValue->GetEntryCount() > 0; } public function ScalarToSQL($value) { if (!is_string($value) && !is_null($value)) { throw new CoreWarning('Expected the attribute value to be a string', [ 'found_type' => gettype($value), 'value' => $value, 'class' => $this->GetCode(), 'attribute' => $this->GetHostClass(), ]); } return $value; } public function GetEditClass() { return "CaseLog"; } public function GetEditValue($sValue, $oHostObj = null) { if (!($sValue instanceof ormCaseLog)) { return ''; } return $sValue->GetModifiedEntry(); } /** * For fields containing a potential markup, return the value without this markup * * @param mixed $value * @param \DBObject $oHostObj * * @return string */ public function GetAsPlainText($value, $oHostObj = null) { if ($value instanceof ormCaseLog) { /** ormCaseLog $value */ return $value->GetAsPlainText(); } else { return (string)$value; } } public function GetDefaultValue(DBObject $oHostObject = null) { 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 * * @param $proposedValue * @param DBObject $oHostObj * * @return mixed|null|ormCaseLog|string * @throws Exception */ public function MakeRealValue($proposedValue, $oHostObj) { if ($proposedValue instanceof ormCaseLog) { // Passthrough $ret = clone $proposedValue; } else { // 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 ($proposedValue instanceof stdClass) { $oCaseLog->AddLogEntryFromJSON($proposedValue); } else { if (utils::StrLen($proposedValue) > 0) { //N°5135 - add impersonation information in caselog if (UserRights::IsImpersonated()) { $sOnBehalfOf = Dict::Format('UI:Archive_User_OnBehalfOf_User', UserRights::GetRealUserFriendlyName(), UserRights::GetUserFriendlyName()); $oCaseLog->AddLogEntry($proposedValue, $sOnBehalfOf, UserRights::GetConnectedUserId()); } else { $oCaseLog->AddLogEntry($proposedValue); } } } $ret = $oCaseLog; } return $ret; } public function GetSQLExpressions($sPrefix = '') { if ($sPrefix == '') { $sPrefix = $this->Get('sql'); } $aColumns = []; // 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; } /** * @param array $aCols * @param string $sPrefix * * @return ormCaseLog * @throws MissingColumnException */ public function FromSQLToValue($aCols, $sPrefix = '') { if (!array_key_exists($sPrefix, $aCols)) { $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 = []; $aValues[$this->GetCode()] = $value->GetText(); $aValues[$this->GetCode().'_index'] = serialize($value->GetIndex()); return $aValues; } public function GetSQLColumns($bFullSpec = false) { $aColumns = []; $aColumns[$this->GetCode()] = 'LONGTEXT' // 2^32 (4 Gb) .CMDBSource::GetSqlStringColumnDefinition(); $aColumns[$this->GetCode().'_index'] = 'BLOB'; return $aColumns; } public function GetAsHTML($value, $oHostObject = null, $bLocalize = true) { if ($value instanceof ormCaseLog) { $sContent = $value->GetAsHTML(null, false, [__class__, 'RenderWikiHtml']); } else { $sContent = ''; } $aStyles = []; if ($this->GetWidth() != '') { $aStyles[] = 'width:'.$this->GetWidth(); } if ($this->GetHeight() != '') { $aStyles[] = 'height:'.$this->GetHeight(); } $sStyle = ''; if (count($aStyles) > 0) { $sStyle = 'style="'.implode(';', $aStyles).'"'; } return "
".$sContent.'
'; } public function GetAsCSV( $value, $sSeparator = ',', $sTextQualifier = '"', $oHostObject = null, $bLocalize = true, $bConvertToPlainText = false ) { if ($value instanceof ormCaseLog) { return parent::GetAsCSV( $value->GetText($bConvertToPlainText), $sSeparator, $sTextQualifier, $oHostObject, $bLocalize, $bConvertToPlainText ); } else { return ''; } } public function GetAsXML($value, $oHostObject = null, $bLocalize = true) { if ($value instanceof ormCaseLog) { return parent::GetAsXML($value->GetText(), $oHostObject, $bLocalize); } else { return ''; } } /** * List the available verbs for 'GetForTemplate' */ public function EnumTemplateVerbs() { return [ '' => 'Plain text representation of all the log entries', 'head' => 'Plain text representation of the latest entry', 'head_html' => 'HTML representation of the latest entry', 'html' => 'HTML representation of all the log entries', ]; } /** * Get various representations of the value, for insertion into a template (e.g. in Notifications) * * @param $value mixed The current value of the field * @param $sVerb string The verb specifying the representation of the value * @param $oHostObject DBObject The object * @param $bLocalize bool Whether or not to localize the value * * @return mixed * @throws \Exception */ public function GetForTemplate($value, $sVerb, $oHostObject = null, $bLocalize = true) { switch ($sVerb) { case '': return $value->GetText(true); case 'head': return $value->GetLatestEntry('text'); case 'head_html': return $value->GetLatestEntry('html'); case 'html': return $value->GetAsEmailHtml(); default: throw new \Exception("Unknown verb '$sVerb' for attribute ".$this->GetCode().' in class '.get_class($oHostObject)); } } public function GetForJSON($value) { return $value->GetForJSON(); } public function FromJSONToValue($json) { if (is_string($json)) { // Will be correctly handled in MakeRealValue $ret = $json; } else { if (isset($json->add_item)) { // Will be correctly handled in MakeRealValue $ret = $json->add_item; if (!isset($ret->message)) { throw new Exception("Missing mandatory entry: 'message'"); } } else { $ret = ormCaseLog::FromJSON($json); } } return $ret; } public function Fingerprint($value) { $sFingerprint = ''; if ($value instanceof ormCaseLog) { $sFingerprint = $value->GetText(); } return $sFingerprint; } /** * The actual formatting of the text: either text (=plain text) or html (= text with HTML markup) * * @return string */ public function GetFormat() { return $this->GetOptional('format', 'html'); // default format for case logs is now HTML } public static function GetFormFieldClass() { return '\\Combodo\\iTop\\Form\\Field\\CaseLogField'; } public function MakeFormField(DBObject $oObject, $oFormField = null) { // First we call the parent so the field is build $oFormField = parent::MakeFormField($oObject, $oFormField); // Then only we set the value $oFormField->SetCurrentValue($this->GetEditValue($oObject->Get($this->GetCode()))); // And we set the entries $oFormField->SetEntries($oObject->Get($this->GetCode())->GetAsArray()); return $oFormField; } protected function GetChangeRecordAdditionalData(CMDBChangeOp $oMyChangeOp, DBObject $oObject, $original, $value): void { /** @var ormCaseLog $value */ $oMyChangeOp->Set("lastentry", $value->GetLatestEntryIndex()); } protected function GetChangeRecordClassName(): string { return CMDBChangeOpSetAttributeCaseLog::class; } }