123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695 |
- <?php
- // Copyright (C) 2010-2016 Combodo SARL
- //
- // This file is part of iTop.
- //
- // 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
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // iTop is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with iTop. If not, see <http://www.gnu.org/licenses/>
- define('CASELOG_VISIBLE_ITEMS', 2);
- define('CASELOG_SEPARATOR', "\n".'========== %1$s : %2$s (%3$d) ============'."\n\n");
- /**
- * Class to store a "case log" in a structured way, keeping track of its successive entries
- *
- * @copyright Copyright (C) 2010-2016 Combodo SARL
- * @license http://opensource.org/licenses/AGPL-3.0
- */
- class ormCaseLog {
- protected $m_sLog;
- protected $m_aIndex;
- protected $m_bModified;
-
- /**
- * Initializes the log with the first (initial) entry
- * @param $sLog string The text of the whole case log
- * @param $aIndex hash The case log index
- */
- public function __construct($sLog = '', $aIndex = array())
- {
- $this->m_sLog = $sLog;
- $this->m_aIndex = $aIndex;
- $this->m_bModified = false;
- }
-
- public function GetText($bConvertToPlainText = false)
- {
- if ($bConvertToPlainText)
- {
- // Rebuild the log, but filtering any HTML markup for the all 'html' entries in the log
- return $this->GetAsPlainText();
- }
- else
- {
- return $this->m_sLog;
- }
- }
-
- public static function FromJSON($oJson)
- {
- if (!isset($oJson->items))
- {
- throw new Exception("Missing 'items' elements");
- }
- $oCaseLog = new ormCaseLog();
- foreach($oJson->items as $oItem)
- {
- $oCaseLog->AddLogEntryFromJSON($oItem);
- }
- return $oCaseLog;
- }
- /**
- * Return a value that will be further JSON encoded
- */
- public function GetForJSON()
- {
- // Order by ascending date
- $aRet = array('entries' => array_reverse($this->GetAsArray()));
- return $aRet;
- }
- /**
- * Return all the data, in a format that is suitable for programmatic usages:
- * -> dates not formatted
- * -> to preserve backward compatibility, to the returned structure must grow (new array entries)
- *
- * Format:
- * array (
- * array (
- * 'date' => <yyyy-mm-dd hh:mm:ss>,
- * 'user_login' => <user friendly name>
- * 'user_id' => OPTIONAL <id of the user account (caution: the object might have been deleted since)>
- * 'message' => <message as plain text (CR/LF), empty if message_html is given>
- * 'message_html' => <message with HTML markup, empty if message is given>
- * )
- *
- * @return array
- * @throws DictExceptionMissingString
- */
- public function GetAsArray()
- {
- $aEntries = array();
- $iPos = 0;
- for($index=count($this->m_aIndex)-1 ; $index >= 0 ; $index--)
- {
- $iPos += $this->m_aIndex[$index]['separator_length'];
- $sTextEntry = substr($this->m_sLog, $iPos, $this->m_aIndex[$index]['text_length']);
- $iPos += $this->m_aIndex[$index]['text_length'];
- // Workaround: PHP < 5.3 cannot unserialize correctly DateTime objects,
- // therefore we have changed the format. To preserve the compatibility with existing
- // installations of iTop, both format are allowed:
- // the 'date' item is either a DateTime object, or a unix timestamp
- if (is_int($this->m_aIndex[$index]['date']))
- {
- // Unix timestamp
- $sDate = date(AttributeDateTime::GetInternalFormat(),$this->m_aIndex[$index]['date']);
- }
- elseif (is_object($this->m_aIndex[$index]['date']))
- {
- if (version_compare(phpversion(), '5.3.0', '>='))
- {
- // DateTime
- $sDate = $this->m_aIndex[$index]['date']->format(AttributeDateTime::GetInternalFormat());
- }
- else
- {
- // No Warning... but the date is unknown
- $sDate = '';
- }
- }
- $sFormat = array_key_exists('format', $this->m_aIndex[$index]) ? $this->m_aIndex[$index]['format'] : 'text';
- switch($sFormat)
- {
- case 'text':
- $sHtmlEntry = utils::TextToHtml($sTextEntry);
- break;
- case 'html':
- $sHtmlEntry = $sTextEntry;
- $sTextEntry = utils::HtmlToText($sHtmlEntry);
- break;
- }
- $aEntries[] = array(
- 'date' => $sDate,
- 'user_login' => $this->m_aIndex[$index]['user_name'],
- 'user_id' => $this->m_aIndex[$index]['user_id'],
- 'message' => $sTextEntry,
- 'message_html' => $sHtmlEntry,
- );
- }
- // 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);
- $aEntries[] = array(
- 'date' => '',
- 'user_login' => '',
- 'message' => $sTextEntry,
- 'message_html' => utils::TextToHtml($sTextEntry),
- );
- }
- return $aEntries;
- }
- /**
- * Returns a "plain text" version of the log (equivalent to $this->m_sLog) where all the HTML markup from the 'html' entries have been removed
- * @return string
- */
- public function GetAsPlainText()
- {
- $sPlainText = '';
- $aJSON = $this->GetForJSON();
- foreach($aJSON['entries'] as $aData)
- {
- $sSeparator = sprintf(CASELOG_SEPARATOR, $aData['date'], $aData['user_login'], $aData['user_id']);
- $sPlainText .= $sSeparator.$aData['message'];
- }
- return $sPlainText;
- }
-
- public function GetIndex()
- {
- return $this->m_aIndex;
- }
- public function __toString()
- {
- return $this->m_sLog;
- }
-
- public function ClearModifiedFlag()
- {
- $this->m_bModified = false;
- }
- /**
- * Produces an HTML representation, aimed at being used within an email
- */
- public function GetAsEmailHtml()
- {
- $sStyleCaseLogHeader = '';
- $sStyleCaseLogEntry = '';
- $sHtml = '<table style="width:100%;table-layout:fixed"><tr><td>'; // Use table-layout:fixed to force the with to be independent from the actual content
- $iPos = 0;
- $aIndex = $this->m_aIndex;
- for($index=count($aIndex)-1 ; $index >= 0 ; $index--)
- {
- $iPos += $aIndex[$index]['separator_length'];
- $sTextEntry = substr($this->m_sLog, $iPos, $aIndex[$index]['text_length']);
- $sCSSClass = 'caselog_entry_html';
- if (!array_key_exists('format', $aIndex[$index]) || ($aIndex[$index]['format'] == 'text'))
- {
- $sCSSClass = 'caselog_entry';
- $sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
- }
- else
- {
- $sTextEntry = InlineImage::FixUrls($sTextEntry);
- }
- $iPos += $aIndex[$index]['text_length'];
- $sEntry = '<div class="caselog_header" style="'.$sStyleCaseLogHeader.'">';
- // Workaround: PHP < 5.3 cannot unserialize correctly DateTime objects,
- // therefore we have changed the format. To preserve the compatibility with existing
- // installations of iTop, both format are allowed:
- // the 'date' item is either a DateTime object, or a unix timestamp
- if (is_int($aIndex[$index]['date']))
- {
- // Unix timestamp
- $sDate = date((string)AttributeDateTime::GetFormat(), $aIndex[$index]['date']);
- }
- elseif (is_object($aIndex[$index]['date']))
- {
- if (version_compare(phpversion(), '5.3.0', '>='))
- {
- // DateTime
- $sDate = $aIndex[$index]['date']->format((string)AttributeDateTime::GetFormat());
- }
- else
- {
- // No Warning... but the date is unknown
- $sDate = '';
- }
- }
- $sEntry .= sprintf(Dict::S('UI:CaseLog:Header_Date_UserName'), '<span class="caselog_header_date">'.$sDate.'</span>', '<span class="caselog_header_user">'.$aIndex[$index]['user_name'].'</span>');
- $sEntry .= '</div>';
- $sEntry .= '<div class="'.$sCSSClass.'" style="'.$sStyleCaseLogEntry.'">';
- $sEntry .= $sTextEntry;
- $sEntry .= '</div>';
- $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(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
- if (count($this->m_aIndex) == 0)
- {
- $sHtml .= '<div class="caselog_entry" style="'.$sStyleCaseLogEntry.'"">';
- $sHtml .= $sTextEntry;
- $sHtml .= '</div>';
- }
- else
- {
- $sHtml .= '<div class="caselog_header" style="'.$sStyleCaseLogHeader.'">';
- $sHtml .= Dict::S('UI:CaseLog:InitialValue');
- $sHtml .= '</div>';
- $sHtml .= '<div class="caselog_entry" style="'.$sStyleCaseLogEntry.'">';
- $sHtml .= $sTextEntry;
- $sHtml .= '</div>';
- }
- }
- $sHtml .= '</td></tr></table>';
- return $sHtml;
- }
-
- /**
- * Produces an HTML representation, aimed at being used to produce a PDF with TCPDF (no table)
- */
- public function GetAsSimpleHtml($aTransfoHandler = null)
- {
- $sStyleCaseLogHeader = '';
- $sStyleCaseLogEntry = '';
- $sHtml = '<ul class="case_log_simple_html">';
- $iPos = 0;
- $aIndex = $this->m_aIndex;
- for($index=count($aIndex)-1 ; $index >= 0 ; $index--)
- {
- $iPos += $aIndex[$index]['separator_length'];
- $sTextEntry = substr($this->m_sLog, $iPos, $aIndex[$index]['text_length']);
- $sCSSClass = 'case_log_simple_html_entry_html';
- if (!array_key_exists('format', $aIndex[$index]) || ($aIndex[$index]['format'] == 'text'))
- {
- $sCSSClass = 'case_log_simple_html_entry';
- $sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
- if (!is_null($aTransfoHandler))
- {
- $sTextEntry = call_user_func($aTransfoHandler, $sTextEntry);
- }
- }
- else
- {
- if (!is_null($aTransfoHandler))
- {
- $sTextEntry = call_user_func($aTransfoHandler, $sTextEntry, true /* wiki "links" only */);
- }
- $sTextEntry = InlineImage::FixUrls($sTextEntry);
- }
- $iPos += $aIndex[$index]['text_length'];
- $sEntry = '<li>';
- // Workaround: PHP < 5.3 cannot unserialize correctly DateTime objects,
- // therefore we have changed the format. To preserve the compatibility with existing
- // installations of iTop, both format are allowed:
- // the 'date' item is either a DateTime object, or a unix timestamp
- if (is_int($aIndex[$index]['date']))
- {
- // Unix timestamp
- $sDate = date((string)AttributeDateTime::GetFormat(),$aIndex[$index]['date']);
- }
- elseif (is_object($aIndex[$index]['date']))
- {
- if (version_compare(phpversion(), '5.3.0', '>='))
- {
- // DateTime
- $sDate = $aIndex[$index]['date']->format((string)AttributeDateTime::GetFormat());
- }
- else
- {
- // No Warning... but the date is unknown
- $sDate = '';
- }
- }
- $sEntry .= sprintf(Dict::S('UI:CaseLog:Header_Date_UserName'), '<span class="caselog_header_date">'.$sDate.'</span>', '<span class="caselog_header_user">'.$aIndex[$index]['user_name'].'</span>');
- $sEntry .= '<div class="'.$sCSSClass.'" style="'.$sStyleCaseLogEntry.'">';
- $sEntry .= $sTextEntry;
- $sEntry .= '</div>';
- $sEntry .= '</li>';
- $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(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
- if (count($this->m_aIndex) == 0)
- {
- $sHtml .= '<li>';
- $sHtml .= $sTextEntry;
- $sHtml .= '</li>';
- }
- else
- {
- $sHtml .= '<li>';
- $sHtml .= Dict::S('UI:CaseLog:InitialValue');
- $sHtml .= '<div class="case_log_simple_html_entry" style="'.$sStyleCaseLogEntry.'">';
- $sHtml .= $sTextEntry;
- $sHtml .= '</div>';
- $sHtml .= '</li>';
- }
- }
- $sHtml .= '</ul>';
- return $sHtml;
- }
- /**
- * Produces an HTML representation, aimed at being used within the iTop framework
- */
- public function GetAsHTML(WebPage $oP = null, $bEditMode = false, $aTransfoHandler = null)
- {
- $bPrintableVersion = (utils::ReadParam('printable', '0') == '1');
- $sHtml = '<table style="width:100%;table-layout:fixed"><tr><td>'; // Use table-layout:fixed to force the with to be independent from the actual content
- $iPos = 0;
- $aIndex = $this->m_aIndex;
- if (($bEditMode) && (count($aIndex) > 0) && $this->m_bModified)
- {
- // Don't display the first element, that is still considered as editable
- $iPos = $aIndex[0]['separator_length'] + $aIndex[0]['text_length'];
- array_shift($aIndex);
- }
- for($index=count($aIndex)-1 ; $index >= 0 ; $index--)
- {
- if (!$bPrintableVersion && ($index < count($aIndex) - CASELOG_VISIBLE_ITEMS))
- {
- $sOpen = '';
- $sDisplay = 'style="display:none;"';
- }
- else
- {
- $sOpen = ' open';
- $sDisplay = '';
- }
- $iPos += $aIndex[$index]['separator_length'];
- $sTextEntry = substr($this->m_sLog, $iPos, $aIndex[$index]['text_length']);
- $sCSSClass= 'caselog_entry_html';
- if (!array_key_exists('format', $aIndex[$index]) || ($aIndex[$index]['format'] == 'text'))
- {
- $sCSSClass= 'caselog_entry';
- $sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
- if (!is_null($aTransfoHandler))
- {
- $sTextEntry = call_user_func($aTransfoHandler, $sTextEntry);
- }
- }
- else
- {
- if (!is_null($aTransfoHandler))
- {
- $sTextEntry = call_user_func($aTransfoHandler, $sTextEntry, true /* wiki "links" only */);
- }
- $sTextEntry = InlineImage::FixUrls($sTextEntry);
- }
- $iPos += $aIndex[$index]['text_length'];
- $sEntry = '<div class="caselog_header'.$sOpen.'">';
- // Workaround: PHP < 5.3 cannot unserialize correctly DateTime objects,
- // therefore we have changed the format. To preserve the compatibility with existing
- // installations of iTop, both format are allowed:
- // the 'date' item is either a DateTime object, or a unix timestamp
- if (is_int($aIndex[$index]['date']))
- {
- // Unix timestamp
- $sDate = date((string)AttributeDateTime::GetFormat(),$aIndex[$index]['date']);
- }
- elseif (is_object($aIndex[$index]['date']))
- {
- if (version_compare(phpversion(), '5.3.0', '>='))
- {
- // DateTime
- $sDate = $aIndex[$index]['date']->format((string)AttributeDateTime::GetFormat());
- }
- else
- {
- // No Warning... but the date is unknown
- $sDate = '';
- }
- }
- $sEntry .= sprintf(Dict::S('UI:CaseLog:Header_Date_UserName'), $sDate, $aIndex[$index]['user_name']);
- $sEntry .= '</div>';
- $sEntry .= '<div class="'.$sCSSClass.'"'.$sDisplay.'>';
- $sEntry .= $sTextEntry;
- $sEntry .= '</div>';
- $sHtml = $sHtml.$sEntry;
- }
- // Process the case of an eventual remainder (quick migration of AttributeText fields)
- if ($iPos < (strlen($this->m_sLog) - 1))
- {
- // In this case the format is always "text"
- $sTextEntry = substr($this->m_sLog, $iPos);
- $sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<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 class="caselog_entry open">';
- $sHtml .= $sTextEntry;
- $sHtml .= '</div>';
- }
- else
- {
- if (!$bPrintableVersion && (count($this->m_aIndex) - CASELOG_VISIBLE_ITEMS > 0))
- {
- $sOpen = '';
- $sDisplay = 'style="display:none;"';
- }
- else
- {
- $sOpen = ' open';
- $sDisplay = '';
- }
- $sHtml .= '<div class="caselog_header'.$sOpen.'">';
- $sHtml .= Dict::S('UI:CaseLog:InitialValue');
- $sHtml .= '</div>';
- $sHtml .= '<div class="caselog_entry"'.$sDisplay.'>';
- $sHtml .= $sTextEntry;
- $sHtml .= '</div>';
- }
- }
- $sHtml .= '</td></tr></table>';
- return $sHtml;
- }
-
- /**
- * Add a new entry to the log or merge the given text into the currently modified entry
- * and updates the internal index
- * @param $sText string The text of the new entry
- */
- public function AddLogEntry($sText, $sOnBehalfOf = '')
- {
- $sText = HTMLSanitizer::Sanitize($sText);
- $bMergeEntries = false;
- $sDate = date(AttributeDateTime::GetInternalFormat());
- if ($sOnBehalfOf == '')
- {
- $sOnBehalfOf = UserRights::GetUserFriendlyName();
- $iUserId = UserRights::GetUserId();
- }
- else
- {
- $iUserId = null;
- }
- if ($this->m_bModified)
- {
- $aLatestEntry = end($this->m_aIndex);
- if ($aLatestEntry['user_name'] != $sOnBehalfOf)
- {
- $bMergeEntries = false;
- }
- else
- {
- $bMergeEntries = true;
- }
- }
-
- if ($bMergeEntries)
- {
- $aLatestEntry = end($this->m_aIndex);
- $this->m_sLog = substr($this->m_sLog, $aLatestEntry['separator_length']);
- $sSeparator = sprintf(CASELOG_SEPARATOR, $sDate, $sOnBehalfOf, $iUserId);
- $iSepLength = strlen($sSeparator);
- $iTextlength = strlen($sText."\n");
- $this->m_sLog = $sSeparator.$sText.$this->m_sLog; // Latest entry printed first
- $this->m_aIndex[] = array(
- 'user_name' => $sOnBehalfOf,
- 'user_id' => $iUserId,
- 'date' => time(),
- 'text_length' => $aLatestEntry['text_length'] + $iTextlength,
- 'separator_length' => $iSepLength,
- 'format' => 'html',
- );
-
- }
- else
- {
- $sSeparator = sprintf(CASELOG_SEPARATOR, $sDate, $sOnBehalfOf, $iUserId);
- $iSepLength = strlen($sSeparator);
- $iTextlength = strlen($sText);
- $this->m_sLog = $sSeparator.$sText.$this->m_sLog; // Latest entry printed first
- $this->m_aIndex[] = array(
- 'user_name' => $sOnBehalfOf,
- 'user_id' => $iUserId,
- 'date' => time(),
- 'text_length' => $iTextlength,
- 'separator_length' => $iSepLength,
- 'format' => 'html',
- );
- }
- $this->m_bModified = true;
- }
- public function AddLogEntryFromJSON($oJson, $bCheckUserId = true)
- {
- $sText = HTMLSanitizer::Sanitize(isset($oJson->message) ? $oJson->message : '');
- if (isset($oJson->user_id))
- {
- if (!UserRights::IsAdministrator())
- {
- throw new Exception("Only administrators can set the user id", RestResult::UNAUTHORIZED);
- }
- if ($bCheckUserId && ($oJson->user_id != 0))
- {
- try
- {
- $oUser = RestUtils::FindObjectFromKey('User', $oJson->user_id);
- }
- catch(Exception $e)
- {
- throw new Exception('user_id: '.$e->getMessage(), $e->getCode());
- }
- $iUserId = $oUser->GetKey();
- $sOnBehalfOf = $oUser->GetFriendlyName();
- }
- else
- {
- $iUserId = $oJson->user_id;
- $sOnBehalfOf = $oJson->user_login;
- }
- }
- else
- {
- $iUserId = UserRights::GetUserId();
- $sOnBehalfOf = UserRights::GetUserFriendlyName();
- }
-
- if (isset($oJson->date))
- {
- $oDate = new DateTime($oJson->date);
- $iDate = (int) $oDate->format('U');
- }
- else
- {
- $iDate = time();
- }
- if (isset($oJson->format))
- {
- $sFormat = $oJson->format;
- }
- else
- {
- // TODO: what is the default format ? text ?
- $sFormat = 'html';
- }
-
- $sDate = date(AttributeDateTime::GetInternalFormat(), $iDate);
- $sSeparator = sprintf(CASELOG_SEPARATOR, $sDate, $sOnBehalfOf, $iUserId);
- $iSepLength = strlen($sSeparator);
- $iTextlength = strlen($sText);
- $this->m_sLog = $sSeparator.$sText.$this->m_sLog; // Latest entry printed first
- $this->m_aIndex[] = array(
- 'user_name' => $sOnBehalfOf,
- 'user_id' => $iUserId,
- 'date' => $iDate,
- 'text_length' => $iTextlength,
- 'separator_length' => $iSepLength,
- 'format' => $sFormat,
- );
- $this->m_bModified = true;
- }
- public function GetModifiedEntry()
- {
- $sModifiedEntry = '';
- if ($this->m_bModified)
- {
- $sModifiedEntry = $this->GetLatestEntry();
- }
- return $sModifiedEntry;
- }
- /**
- * Get the latest entry from the log
- * @return string
- */
- public function GetLatestEntry()
- {
- $aLastEntry = end($this->m_aIndex);
- $sRes = substr($this->m_sLog, $aLastEntry['separator_length'], $aLastEntry['text_length']);
- return $sRes;
- }
- /**
- * Get the index of the latest entry from the log
- * @return integer
- */
- public function GetLatestEntryIndex()
- {
- $aKeys = array_keys($this->m_aIndex);
- $iLast = end($aKeys); // Strict standards: the parameter passed to 'end' must be a variable since it is passed by reference
- return $iLast;
- }
-
- /**
- * Get the text string corresponding to the given entry in the log (zero based index, older entries first)
- * @param integer $iIndex
- * @return string The text of the entry
- */
- public function GetEntryAt($iIndex)
- {
- $iPos = 0;
- $index = count($this->m_aIndex) - 1;
- $aIndex = $this->m_aIndex;
- while($index > $iIndex)
- {
- $iPos += $this->m_aIndex[$index]['separator_length'];
- $iPos += $this->m_aIndex[$index]['text_length'];
- $index--;
- }
- $iPos += $this->m_aIndex[$index]['separator_length'];
- $sText = substr($this->m_sLog, $iPos, $this->m_aIndex[$index]['text_length']);
- return $sText;
- }
- }
- ?>
|