mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-19 07:12:26 +02:00
N°5341 - refactoring to have a dedicated ormcase log service
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
//
|
//
|
||||||
// iTop is free software; you can redistribute it and/or modify
|
// iTop is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU Affero General Public License as published by
|
// it under the terms of the GNU Affero General Public License as published by
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
@@ -19,36 +19,34 @@
|
|||||||
define('CASELOG_VISIBLE_ITEMS', 2);
|
define('CASELOG_VISIBLE_ITEMS', 2);
|
||||||
define('CASELOG_SEPARATOR', "\n".'========== %1$s : %2$s (%3$d) ============'."\n\n");
|
define('CASELOG_SEPARATOR', "\n".'========== %1$s : %2$s (%3$d) ============'."\n\n");
|
||||||
|
|
||||||
|
require_once('ormcaselogservice.inc.php');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to store a "case log" in a structured way, keeping track of its successive entries
|
* Class to store a "case log" in a structured way, keeping track of its successive entries
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
class ormCaseLog {
|
class ormCaseLog {
|
||||||
const CASE_LOG_SEPARATOR_REGEX_FIND = "\r?\n?========== \w+-\d+-\d+ \d+:\d+:\d+ : .*\s\(\d+\) ============\r?\n\r?\n";
|
|
||||||
const CASE_LOG_SEPARATOR_REGEX_EXTRACT = "\r?\n?========== (?<date>\w+-\d+-\d+ \d+:\d+:\d+) : (?<user_name>.*)\s\((?<user_id>\d+)\) ============\r?\n\r?\n";
|
|
||||||
|
|
||||||
protected $m_sLog;
|
protected $m_sLog;
|
||||||
protected $m_aIndex;
|
protected $m_aIndex;
|
||||||
protected $m_bModified;
|
protected $m_bModified;
|
||||||
|
protected \ormCaseLogService $oOrmCaseLogService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the log with the first (initial) entry
|
* Initializes the log with the first (initial) entry
|
||||||
* @param $sLog string The text of the whole case log
|
* @param $sLog string The text of the whole case log
|
||||||
* @param $aIndex array The case log index
|
* @param $aIndex array The case log index
|
||||||
*/
|
*/
|
||||||
public function __construct($sLog = '', $aIndex = array())
|
public function __construct($sLog = '', $aIndex = [], \ormCaseLogService $oOrmCaseLogService=null)
|
||||||
{
|
{
|
||||||
$this->m_sLog = $sLog;
|
$this->m_sLog = $sLog;
|
||||||
$this->m_aIndex = $this->RebuildIndex($sLog);
|
$this->m_aIndex = $aIndex;
|
||||||
if (count($this->m_aIndex) === 0 && count($aIndex) !== 0) {
|
|
||||||
$this->m_aIndex = $aIndex;
|
|
||||||
}
|
|
||||||
$this->m_bModified = false;
|
$this->m_bModified = false;
|
||||||
|
$this->oOrmCaseLogService = (is_null($oOrmCaseLogService)) ? new \ormCaseLogService() : $oOrmCaseLogService;
|
||||||
|
$this->RebuildIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetText($bConvertToPlainText = false)
|
public function GetText($bConvertToPlainText = false)
|
||||||
{
|
{
|
||||||
if ($bConvertToPlainText)
|
if ($bConvertToPlainText)
|
||||||
@@ -61,7 +59,7 @@ class ormCaseLog {
|
|||||||
return $this->m_sLog;
|
return $this->m_sLog;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FromJSON($oJson)
|
public static function FromJSON($oJson)
|
||||||
{
|
{
|
||||||
if (!isset($oJson->items))
|
if (!isset($oJson->items))
|
||||||
@@ -77,8 +75,8 @@ class ormCaseLog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a value that will be further JSON encoded
|
* Return a value that will be further JSON encoded
|
||||||
*/
|
*/
|
||||||
public function GetForJSON()
|
public function GetForJSON()
|
||||||
{
|
{
|
||||||
// Order by ascending date
|
// Order by ascending date
|
||||||
@@ -188,9 +186,9 @@ class ormCaseLog {
|
|||||||
$sSeparator = sprintf(CASELOG_SEPARATOR, $aData['date'], $aData['user_login'], $aData['user_id']);
|
$sSeparator = sprintf(CASELOG_SEPARATOR, $aData['date'], $aData['user_login'], $aData['user_id']);
|
||||||
$sPlainText .= $sSeparator.$aData['message'];
|
$sPlainText .= $sSeparator.$aData['message'];
|
||||||
}
|
}
|
||||||
return $sPlainText;
|
return $sPlainText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetIndex()
|
public function GetIndex()
|
||||||
{
|
{
|
||||||
return $this->m_aIndex;
|
return $this->m_aIndex;
|
||||||
@@ -207,7 +205,7 @@ class ormCaseLog {
|
|||||||
{
|
{
|
||||||
return ($this->m_sLog === null);
|
return ($this->m_sLog === null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ClearModifiedFlag()
|
public function ClearModifiedFlag()
|
||||||
{
|
{
|
||||||
$this->m_bModified = false;
|
$this->m_bModified = false;
|
||||||
@@ -215,7 +213,7 @@ class ormCaseLog {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Produces an HTML representation, aimed at being used within an email
|
* Produces an HTML representation, aimed at being used within an email
|
||||||
*/
|
*/
|
||||||
public function GetAsEmailHtml()
|
public function GetAsEmailHtml()
|
||||||
{
|
{
|
||||||
$sStyleCaseLogHeader = '';
|
$sStyleCaseLogHeader = '';
|
||||||
@@ -296,10 +294,10 @@ class ormCaseLog {
|
|||||||
$sHtml .= '</td></tr></table>';
|
$sHtml .= '</td></tr></table>';
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produces an HTML representation, aimed at being used to produce a PDF with TCPDF (no table)
|
* Produces an HTML representation, aimed at being used to produce a PDF with TCPDF (no table)
|
||||||
*/
|
*/
|
||||||
public function GetAsSimpleHtml($aTransfoHandler = null)
|
public function GetAsSimpleHtml($aTransfoHandler = null)
|
||||||
{
|
{
|
||||||
$sStyleCaseLogEntry = '';
|
$sStyleCaseLogEntry = '';
|
||||||
@@ -328,7 +326,7 @@ class ormCaseLog {
|
|||||||
$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry, true /* wiki "links" only */);
|
$sTextEntry = call_user_func($aTransfoHandler, $sTextEntry, true /* wiki "links" only */);
|
||||||
}
|
}
|
||||||
$sTextEntry = InlineImage::FixUrls($sTextEntry);
|
$sTextEntry = InlineImage::FixUrls($sTextEntry);
|
||||||
}
|
}
|
||||||
$iPos += $aIndex[$index]['text_length'];
|
$iPos += $aIndex[$index]['text_length'];
|
||||||
|
|
||||||
$sEntry = '<li>';
|
$sEntry = '<li>';
|
||||||
@@ -390,7 +388,7 @@ class ormCaseLog {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Produces an HTML representation, aimed at being used within the iTop framework
|
* Produces an HTML representation, aimed at being used within the iTop framework
|
||||||
*/
|
*/
|
||||||
public function GetAsHTML(WebPage $oP = null, $bEditMode = false, $aTransfoHandler = null)
|
public function GetAsHTML(WebPage $oP = null, $bEditMode = false, $aTransfoHandler = null)
|
||||||
{
|
{
|
||||||
$bPrintableVersion = (utils::ReadParam('printable', '0') == '1');
|
$bPrintableVersion = (utils::ReadParam('printable', '0') == '1');
|
||||||
@@ -510,11 +508,11 @@ class ormCaseLog {
|
|||||||
$sHtml .= '</td></tr></table>';
|
$sHtml .= '</td></tr></table>';
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new entry to the log or merge the given text into the currently modified entry
|
* Add a new entry to the log or merge the given text into the currently modified entry
|
||||||
* and updates the internal index
|
* and updates the internal index
|
||||||
* @param $sText string The text of the new entry
|
* @param $sText string The text of the new entry
|
||||||
*/
|
*/
|
||||||
public function AddLogEntry($sText, $sOnBehalfOf = '')
|
public function AddLogEntry($sText, $sOnBehalfOf = '')
|
||||||
{
|
{
|
||||||
@@ -546,23 +544,18 @@ class ormCaseLog {
|
|||||||
|
|
||||||
$sSeparator = sprintf(CASELOG_SEPARATOR, $sDate, $sOnBehalfOf, $iUserId);
|
$sSeparator = sprintf(CASELOG_SEPARATOR, $sDate, $sOnBehalfOf, $iUserId);
|
||||||
$this->m_sLog = $sSeparator.$sText.$this->m_sLog; // Latest entry printed first
|
$this->m_sLog = $sSeparator.$sText.$this->m_sLog; // Latest entry printed first
|
||||||
$aIndex = $this->RebuildIndex($this->m_sLog);
|
// Rebuild failed
|
||||||
if (count($aIndex) === 0) {
|
$iSepLength = strlen($sSeparator);
|
||||||
// Rebuild failed
|
$iTextLength = strlen($sText);
|
||||||
$iSepLength = strlen($sSeparator);
|
$this->m_aIndex[] = array(
|
||||||
$iTextLength = strlen($sText);
|
'user_name' => $sOnBehalfOf,
|
||||||
$this->m_aIndex[] = array(
|
'user_id' => $iUserId,
|
||||||
'user_name' => $sOnBehalfOf,
|
'date' => time(),
|
||||||
'user_id' => $iUserId,
|
'text_length' => $iTextLength,
|
||||||
'date' => time(),
|
'separator_length' => $iSepLength,
|
||||||
'text_length' => $iTextLength,
|
'format' => 'html',
|
||||||
'separator_length' => $iSepLength,
|
);
|
||||||
'format' => 'html',
|
$this->RebuildIndex();
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$this->m_aIndex = $aIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->m_bModified = true;
|
$this->m_bModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,7 +592,7 @@ class ormCaseLog {
|
|||||||
$iUserId = UserRights::GetUserId();
|
$iUserId = UserRights::GetUserId();
|
||||||
$sOnBehalfOf = UserRights::GetUserFriendlyName();
|
$sOnBehalfOf = UserRights::GetUserFriendlyName();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($oJson->date))
|
if (isset($oJson->date))
|
||||||
{
|
{
|
||||||
$oDate = new DateTime($oJson->date);
|
$oDate = new DateTime($oJson->date);
|
||||||
@@ -629,23 +622,18 @@ class ormCaseLog {
|
|||||||
|
|
||||||
$sSeparator = sprintf(CASELOG_SEPARATOR, $sDate, $sOnBehalfOf, $iUserId);
|
$sSeparator = sprintf(CASELOG_SEPARATOR, $sDate, $sOnBehalfOf, $iUserId);
|
||||||
$this->m_sLog = $sSeparator.$sText.$this->m_sLog; // Latest entry printed first
|
$this->m_sLog = $sSeparator.$sText.$this->m_sLog; // Latest entry printed first
|
||||||
$aIndex = $this->RebuildIndex($this->m_sLog);
|
// Rebuild failed
|
||||||
if (count($aIndex) === 0) {
|
$iSepLength = strlen($sSeparator);
|
||||||
// Rebuild failed
|
$iTextLength = strlen($sText);
|
||||||
$iSepLength = strlen($sSeparator);
|
$this->m_aIndex[] = array(
|
||||||
$iTextLength = strlen($sText);
|
'user_name' => $sOnBehalfOf,
|
||||||
$this->m_aIndex[] = array(
|
'user_id' => $iUserId,
|
||||||
'user_name' => $sOnBehalfOf,
|
'date' => time(),
|
||||||
'user_id' => $iUserId,
|
'text_length' => $iTextLength,
|
||||||
'date' => time(),
|
'separator_length' => $iSepLength,
|
||||||
'text_length' => $iTextLength,
|
'format' => 'html',
|
||||||
'separator_length' => $iSepLength,
|
);
|
||||||
'format' => 'html',
|
$this->RebuildIndex();
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$this->m_aIndex = $aIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->m_bModified = true;
|
$this->m_bModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,7 +670,7 @@ class ormCaseLog {
|
|||||||
$sRes = utils::HtmlToText($sRaw);
|
$sRes = utils::HtmlToText($sRaw);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'html':
|
case 'html':
|
||||||
if ($aLastEntry['format'] == 'text')
|
if ($aLastEntry['format'] == 'text')
|
||||||
{
|
{
|
||||||
@@ -707,7 +695,7 @@ class ormCaseLog {
|
|||||||
$iLast = end($aKeys); // Strict standards: the parameter passed to 'end' must be a variable since it is passed by reference
|
$iLast = end($aKeys); // Strict standards: the parameter passed to 'end' must be a variable since it is passed by reference
|
||||||
return $iLast;
|
return $iLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the text string corresponding to the given entry in the log (zero based index, older entries first)
|
* Get the text string corresponding to the given entry in the log (zero based index, older entries first)
|
||||||
* @param integer $iIndex
|
* @param integer $iIndex
|
||||||
@@ -728,39 +716,12 @@ class ormCaseLog {
|
|||||||
return $sText;
|
return $sText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function RebuildIndex($sLog): array
|
public function RebuildIndex(): void
|
||||||
{
|
{
|
||||||
$aTexts = preg_split('/'.self::CASE_LOG_SEPARATOR_REGEX_FIND.'/', $sLog, 0, PREG_SPLIT_NO_EMPTY);
|
$aIndex = $this->oOrmCaseLogService->RebuildIndex($this->m_sLog, $this->m_aIndex);
|
||||||
preg_match_all('/'.self::CASE_LOG_SEPARATOR_REGEX_FIND.'/', $sLog, $aMatches);
|
if (count($aIndex) !== 0) {
|
||||||
|
//index rebuild required
|
||||||
if (count($aTexts) != count($aMatches[0])) {
|
$this->m_aIndex = $aIndex;
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$aIndex = [];
|
|
||||||
$iPrevDate = 0;
|
|
||||||
for ($index = count($aTexts) - 1; $index >= 0; $index--) {
|
|
||||||
$sSeparator = $aMatches[0][$index];
|
|
||||||
preg_match('/'.self::CASE_LOG_SEPARATOR_REGEX_EXTRACT.'/', $sSeparator, $aSeparatorParts);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$iDate = (int)AttributeDateTime::GetAsUnixSeconds($aSeparatorParts['date']);
|
|
||||||
$iPrevDate = $iDate + 1;
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
$iDate = $iPrevDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
$aIndex[] = array(
|
|
||||||
'user_name' => $aSeparatorParts['user_name'],
|
|
||||||
'user_id' => $aSeparatorParts['user_id'],
|
|
||||||
'date' => $iDate,
|
|
||||||
'text_length' => strlen($aTexts[$index]),
|
|
||||||
'separator_length' => strlen($sSeparator),
|
|
||||||
'format' => 'html',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $aIndex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
57
core/ormcaselogservice.inc.php
Normal file
57
core/ormcaselogservice.inc.php
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ormCaseLogService
|
||||||
|
{
|
||||||
|
const CASE_LOG_SEPARATOR_REGEX_FIND = "\n?========== \w+-\d+-\d+ \d+:\d+:\d+ : .*\s\(\d+\) ============\n\n";
|
||||||
|
const CASE_LOG_SEPARATOR_REGEX_EXTRACT = "\n?========== (?<date>\w+-\d+-\d+ \d+:\d+:\d+) : (?<user_name>.*)\s\((?<user_id>\d+)\) ============\n\n";
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $sLog
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function RebuildIndex(string $sLog, array $aIndex)
|
||||||
|
{
|
||||||
|
$aTexts = preg_split('/'.self::CASE_LOG_SEPARATOR_REGEX_FIND.'/', $sLog, 0, PREG_SPLIT_NO_EMPTY);
|
||||||
|
preg_match_all('/'.self::CASE_LOG_SEPARATOR_REGEX_FIND.'/', $sLog, $aMatches);
|
||||||
|
|
||||||
|
if (count($aTexts) != count($aMatches[0])) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$aRebuiltIndex = [];
|
||||||
|
$iPrevDate = 0;
|
||||||
|
for ($index = count($aTexts) - 1; $index >= 0; $index--) {
|
||||||
|
$sSeparator = $aMatches[0][$index];
|
||||||
|
preg_match('/'.self::CASE_LOG_SEPARATOR_REGEX_EXTRACT.'/', $sSeparator, $aSeparatorParts);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$iDate = (int)AttributeDateTime::GetAsUnixSeconds($aSeparatorParts['date']);
|
||||||
|
$iPrevDate = $iDate + 1;
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
$iDate = $iPrevDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_id = $aSeparatorParts['user_id'];
|
||||||
|
$aRebuiltIndex[] = array(
|
||||||
|
'user_name' => $aSeparatorParts['user_name'],
|
||||||
|
'user_id' => $user_id ==='0' ? null : $user_id,
|
||||||
|
'date' => $iDate,
|
||||||
|
'text_length' => strlen($aTexts[$index]),
|
||||||
|
'separator_length' => strlen($sSeparator),
|
||||||
|
'format' => 'html',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aRebuiltIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2740,6 +2740,7 @@ return array(
|
|||||||
'iWorkingTimeComputer' => $baseDir . '/core/computing.inc.php',
|
'iWorkingTimeComputer' => $baseDir . '/core/computing.inc.php',
|
||||||
'lnkTriggerAction' => $baseDir . '/core/trigger.class.inc.php',
|
'lnkTriggerAction' => $baseDir . '/core/trigger.class.inc.php',
|
||||||
'ormCaseLog' => $baseDir . '/core/ormcaselog.class.inc.php',
|
'ormCaseLog' => $baseDir . '/core/ormcaselog.class.inc.php',
|
||||||
|
'ormCaseLogService' => $baseDir . '/core/ormcaselogservice.class.inc.php',
|
||||||
'ormCustomFieldsValue' => $baseDir . '/core/ormcustomfieldsvalue.class.inc.php',
|
'ormCustomFieldsValue' => $baseDir . '/core/ormcustomfieldsvalue.class.inc.php',
|
||||||
'ormDocument' => $baseDir . '/core/ormdocument.class.inc.php',
|
'ormDocument' => $baseDir . '/core/ormdocument.class.inc.php',
|
||||||
'ormLinkSet' => $baseDir . '/core/ormlinkset.class.inc.php',
|
'ormLinkSet' => $baseDir . '/core/ormlinkset.class.inc.php',
|
||||||
|
|||||||
@@ -3108,6 +3108,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
|||||||
'iWorkingTimeComputer' => __DIR__ . '/../..' . '/core/computing.inc.php',
|
'iWorkingTimeComputer' => __DIR__ . '/../..' . '/core/computing.inc.php',
|
||||||
'lnkTriggerAction' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
'lnkTriggerAction' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',
|
||||||
'ormCaseLog' => __DIR__ . '/../..' . '/core/ormcaselog.class.inc.php',
|
'ormCaseLog' => __DIR__ . '/../..' . '/core/ormcaselog.class.inc.php',
|
||||||
|
'ormCaseLogService' => __DIR__ . '/../..' . '/core/ormcaselogservice.class.inc.php',
|
||||||
'ormCustomFieldsValue' => __DIR__ . '/../..' . '/core/ormcustomfieldsvalue.class.inc.php',
|
'ormCustomFieldsValue' => __DIR__ . '/../..' . '/core/ormcustomfieldsvalue.class.inc.php',
|
||||||
'ormDocument' => __DIR__ . '/../..' . '/core/ormdocument.class.inc.php',
|
'ormDocument' => __DIR__ . '/../..' . '/core/ormdocument.class.inc.php',
|
||||||
'ormLinkSet' => __DIR__ . '/../..' . '/core/ormlinkset.class.inc.php',
|
'ormLinkSet' => __DIR__ . '/../..' . '/core/ormlinkset.class.inc.php',
|
||||||
|
|||||||
Reference in New Issue
Block a user