| 1 | <?php
|
|---|
| 2 |
|
|---|
| 3 | class ModuleLog extends Module
|
|---|
| 4 | {
|
|---|
| 5 | var $Excludes;
|
|---|
| 6 |
|
|---|
| 7 | function __construct(System $System)
|
|---|
| 8 | {
|
|---|
| 9 | parent::__construct($System);
|
|---|
| 10 | $this->Name = 'Log';
|
|---|
| 11 | $this->Version = '1.0';
|
|---|
| 12 | $this->Creator = 'Chronos';
|
|---|
| 13 | $this->License = 'GNU/GPL';
|
|---|
| 14 | $this->Description = 'Log various application events';
|
|---|
| 15 | $this->Dependencies = array('Error', 'News', 'Translation');
|
|---|
| 16 |
|
|---|
| 17 | $this->Excludes = array();
|
|---|
| 18 | }
|
|---|
| 19 |
|
|---|
| 20 | function DoStart(): void
|
|---|
| 21 | {
|
|---|
| 22 | $this->System->RegisterPage(['log'], 'PageLog');
|
|---|
| 23 | $this->System->ModuleManager->Modules['Error']->OnError[] = array($this, 'DoAddItem');
|
|---|
| 24 | $this->System->ModuleManager->Modules['News']->RegisterRSS(array('Title' => T('Logs'),
|
|---|
| 25 | 'Channel' => 'log', 'Callback' => array('PageLog', 'ShowRSS'), 'Permission' => LICENCE_ADMIN));
|
|---|
| 26 | }
|
|---|
| 27 |
|
|---|
| 28 | function DoAddItem($Message)
|
|---|
| 29 | {
|
|---|
| 30 | $this->WriteLog($Message, LOG_TYPE_ERROR);
|
|---|
| 31 | }
|
|---|
| 32 |
|
|---|
| 33 | function WriteLog($Text, $Type)
|
|---|
| 34 | {
|
|---|
| 35 | $User = ModuleUser::Cast($this->System->GetModule('User'))->User;
|
|---|
| 36 | if (isset($User) and !is_null($User->Id))
|
|---|
| 37 | $UserId = $User->Id;
|
|---|
| 38 | else $UserId = 'NULL';
|
|---|
| 39 | $Query = 'INSERT INTO `Log` ( `User` , `Type` , `Text` , `Date` , `IP`, `URL` ) '.
|
|---|
| 40 | 'VALUES ('.$UserId.', '.$Type.', "'.addslashes($Text).'", NOW(), "'.
|
|---|
| 41 | GetRemoteAddress().'", "'.GetRequestURI().'")';
|
|---|
| 42 | $this->System->Database->query($Query);
|
|---|
| 43 | }
|
|---|
| 44 |
|
|---|
| 45 | static function Cast(Module $Module): ModuleLog
|
|---|
| 46 | {
|
|---|
| 47 | if ($Module instanceof ModuleLog)
|
|---|
| 48 | {
|
|---|
| 49 | return $Module;
|
|---|
| 50 | }
|
|---|
| 51 | throw new Exception('Expected '.ModuleLog::GetClassName().' type but got '.gettype($Module));
|
|---|
| 52 | }
|
|---|
| 53 | }
|
|---|
| 54 |
|
|---|
| 55 | // Log types
|
|---|
| 56 | define('LOG_TYPE_TRANSLATION', 1);
|
|---|
| 57 | define('LOG_TYPE_DOWNLOAD', 2);
|
|---|
| 58 | define('LOG_TYPE_USER', 3);
|
|---|
| 59 | define('LOG_TYPE_MODERATOR', 4);
|
|---|
| 60 | define('LOG_TYPE_ERROR', 10);
|
|---|
| 61 | define('LOG_TYPE_IMPORT', 11);
|
|---|
| 62 | define('LOG_TYPE_EXPORT', 12);
|
|---|
| 63 | define('LOG_TYPE_CZWOW', 13);
|
|---|
| 64 | define('LOG_TYPE_ADMINISTRATION', 14);
|
|---|
| 65 | define('LOG_TYPE_PAGE_NOT_FOUND', 15);
|
|---|
| 66 |
|
|---|
| 67 | // TODO: Change global function to module class local method
|
|---|
| 68 | function WriteLog($Text, $Type)
|
|---|
| 69 | {
|
|---|
| 70 | global $System, $User;
|
|---|
| 71 |
|
|---|
| 72 | if (isset($User) and !is_null($User->Id)) $UserId = $User->Id;
|
|---|
| 73 | else $UserId = 'NULL';
|
|---|
| 74 | $Query = 'INSERT INTO `Log` ( `User` , `Type` , `Text` , `Date` , `IP`, `URL` ) '.
|
|---|
| 75 | 'VALUES ('.$UserId.', '.$Type.', "'.addslashes($Text).'", NOW(), "'.
|
|---|
| 76 | GetRemoteAddress().'", "'.GetRequestURI().'")';
|
|---|
| 77 | $System->Database->query($Query);
|
|---|
| 78 | }
|
|---|
| 79 |
|
|---|
| 80 | class PageLog extends Page
|
|---|
| 81 | {
|
|---|
| 82 | function ShowRSS()
|
|---|
| 83 | {
|
|---|
| 84 | $this->RawPage = true;
|
|---|
| 85 | $Output = '';
|
|---|
| 86 | $Items = array();
|
|---|
| 87 | if (array_key_exists('type', $_GET)) $Where = ' WHERE `Type` = "'.($_GET['type'] * 1).'"';
|
|---|
| 88 | else $Where = '';
|
|---|
| 89 | $sql = 'SELECT *, UNIX_TIMESTAMP(`Date`) AS `TimeCreate`, (SELECT `User`.`Name` FROM `User` WHERE `User`.`ID` = `Log`.`User`) AS `UserName`, `Date` FROM `Log`'.
|
|---|
| 90 | $Where.' ORDER BY `Date` DESC LIMIT 100';
|
|---|
| 91 | $DbResult = $this->System->Database->query($sql);
|
|---|
| 92 | while ($Line = $DbResult->fetch_assoc())
|
|---|
| 93 | {
|
|---|
| 94 | $DbResult2 = $this->System->Database->query('SELECT * FROM `LogType` WHERE `Id`='.$Line['Type']);
|
|---|
| 95 | $LogType = $DbResult2->fetch_assoc();
|
|---|
| 96 |
|
|---|
| 97 | if ($Line['Type'] == LOG_TYPE_ERROR) $Line['Text'] = htmlspecialchars($Line['Text']);
|
|---|
| 98 | $Line['Text'] = str_replace("\n", '<br>', $Line['Text']);
|
|---|
| 99 |
|
|---|
| 100 | $Items[] = array
|
|---|
| 101 | (
|
|---|
| 102 | 'Title' => $LogType['Name'].' ('.$Line['UserName'].', '.$Line['IP'].')',
|
|---|
| 103 | 'Link' => 'https://'.Core::Cast($this->System)->Config['Web']['Host'].$this->System->Link('/log/'),
|
|---|
| 104 | 'Description' => $LogType['Name'].': '.$Line['Text'].' ('.$Line['UserName'].
|
|---|
| 105 | ', '.$Line['IP'].', '.HumanDate($Line['Date']).')',
|
|---|
| 106 | 'Time' => $Line['TimeCreate'],
|
|---|
| 107 | );
|
|---|
| 108 | }
|
|---|
| 109 |
|
|---|
| 110 | $Output .= GenerateRSS(array
|
|---|
| 111 | (
|
|---|
| 112 | 'Title' => Core::Cast($this->System)->Config['Web']['Title'].' - '.T('Logs'),
|
|---|
| 113 | 'Link' => 'https://'.Core::Cast($this->System)->Config['Web']['Host'].$this->System->Link('/'),
|
|---|
| 114 | 'Description' => Core::Cast($this->System)->Config['Web']['Description'],
|
|---|
| 115 | 'WebmasterEmail' => Core::Cast($this->System)->Config['Web']['AdminEmail'],
|
|---|
| 116 | 'Items' => $Items,
|
|---|
| 117 | ));
|
|---|
| 118 | return $Output;
|
|---|
| 119 | }
|
|---|
| 120 |
|
|---|
| 121 | function Show(): string
|
|---|
| 122 | {
|
|---|
| 123 | if (array_key_exists('a', $_POST)) $Action = $_POST['a'];
|
|---|
| 124 | else if (array_key_exists('a', $_GET)) $Action = $_GET['a'];
|
|---|
| 125 | else $Action = '';
|
|---|
| 126 | if ($Action == 'delerrlog') $Output = $this->DeleteErrorLog();
|
|---|
| 127 | else $Output = $this->ShowList();
|
|---|
| 128 | return $Output;
|
|---|
| 129 | }
|
|---|
| 130 |
|
|---|
| 131 | function ShowList()
|
|---|
| 132 | {
|
|---|
| 133 | $User = ModuleUser::Cast($this->System->GetModule('User'))->User;
|
|---|
| 134 | $TranslationTree = $this->System->ModuleManager->Modules['Translation']->GetTranslationTree();
|
|---|
| 135 |
|
|---|
| 136 | $this->Title = T('System log');
|
|---|
| 137 | $Output = '';
|
|---|
| 138 | if (array_key_exists('type', $_GET))
|
|---|
| 139 | {
|
|---|
| 140 | if (is_numeric($_GET['type'])) $_SESSION['type'] = $_GET['type'] * 1;
|
|---|
| 141 | else $_SESSION['type'] = '';
|
|---|
| 142 | } else if (!array_key_exists('type', $_SESSION)) $_SESSION['type'] = '';
|
|---|
| 143 |
|
|---|
| 144 | if (array_key_exists('group', $_GET)) $_SESSION['group'] = $_GET['group'];
|
|---|
| 145 |
|
|---|
| 146 | if ($_SESSION['type'] != '') $WhereType = ' (`Type`='.$_SESSION['type'].')';
|
|---|
| 147 | else $WhereType = '1=1';
|
|---|
| 148 |
|
|---|
| 149 | $RSSChannels = array(
|
|---|
| 150 | array('Title' => 'Záznamy změn', 'Channel' => 'log&type='.$_SESSION['type'])
|
|---|
| 151 | );
|
|---|
| 152 |
|
|---|
| 153 | // Show category filter
|
|---|
| 154 | if ($User->Licence(LICENCE_MODERATOR))
|
|---|
| 155 | {
|
|---|
| 156 | $Output = '<strong>'.T('Filter').':</strong>';
|
|---|
| 157 | $Item = '<a href="'.$this->System->Link('/log/?type=').'" title="Bez filtrování">'.T('All').'</a>';
|
|---|
| 158 | if ($_SESSION['type'] == '') $Item = '<strong>'.$Item.'</strong>';
|
|---|
| 159 | $Output .= ' '.$Item;
|
|---|
| 160 | $DbResult = $this->System->Database->query('SELECT * FROM `LogType`');
|
|---|
| 161 | while ($LogType = $DbResult->fetch_assoc())
|
|---|
| 162 | {
|
|---|
| 163 | $Item = '<a href="'.$this->System->Link('/log/?type='.$LogType['Id']).'" style="color:'.
|
|---|
| 164 | $LogType['Color'].'" title="'.$LogType['Name'].'">'.T($LogType['Name']).'</a>';
|
|---|
| 165 | if ($_SESSION['type'] == $LogType['Id']) $Item = '<strong>'.$Item.'</strong>';
|
|---|
| 166 | $Output .= ' '.$Item;
|
|---|
| 167 | }
|
|---|
| 168 | // echo ' Formát: datum: text zprávy (uživatel, IP)<br /><br />';
|
|---|
| 169 | $Output .= '<br /><br />';
|
|---|
| 170 |
|
|---|
| 171 | if (array_key_exists('type', $_SESSION)) $Where = ' WHERE '.$WhereType;
|
|---|
| 172 | else
|
|---|
| 173 | {
|
|---|
| 174 | if (array_key_exists('group', $_SESSION)) $Where = ' WHERE `Text` LIKE "%'.$TranslationTree[$_SESSION['group']]['Name'].'%"';
|
|---|
| 175 | else $Where = '';
|
|---|
| 176 | }
|
|---|
| 177 | //if (($Where != '') and (array_key_exists('group', $_SESSION))) $Where .= ' AND text LIKE "%'.$TranslationTree[$_SESSION['group']]['Name'].'%"';
|
|---|
| 178 |
|
|---|
| 179 | $DbResult = $this->System->Database->query('SELECT COUNT(*) FROM `Log` '.$Where);
|
|---|
| 180 | $DbRow = $DbResult->fetch_row();
|
|---|
| 181 | $PageList = GetPageList($DbRow[0]);
|
|---|
| 182 |
|
|---|
| 183 | $Output .= $PageList['Output'];
|
|---|
| 184 |
|
|---|
| 185 | $TableColumns = array(
|
|---|
| 186 | array('Name' => 'Date', 'Title' => T('Time')),
|
|---|
| 187 | );
|
|---|
| 188 | if ($_SESSION['type'] == '') $TableColumns[] =
|
|---|
| 189 | array('Name' => 'LogName', 'Title' => T('Type'));
|
|---|
| 190 | $TableColumns = array_merge($TableColumns, array(
|
|---|
| 191 | array('Name' => 'Text', 'Title' => T('Content')),
|
|---|
| 192 | array('Name' => 'UserName', 'Title' => T('User')),
|
|---|
| 193 | array('Name' => 'IP', 'Title' => T('Address')),
|
|---|
| 194 | array('Name' => 'URL', 'Title' => T('URL')),
|
|---|
| 195 | ));
|
|---|
| 196 | $Order = GetOrderTableHeader($TableColumns, 'date', 1);
|
|---|
| 197 | $Output .= '<table width="98%" class="BaseTable">'.
|
|---|
| 198 | $Order['Output'];
|
|---|
| 199 |
|
|---|
| 200 | $sql = 'SELECT *, `LogType`.`Color` AS `LogColor`, `LogType`.`Name` AS `LogName`, '.
|
|---|
| 201 | '(SELECT `User`.`Name` FROM `User` WHERE `User`.`ID` = `Log`.`User`) AS `UserName` FROM `Log` LEFT JOIN `LogType` ON `LogType`.`Id`=`Log`.`Type` '.$Where.$Order['SQL'].$PageList['SQLLimit'];
|
|---|
| 202 | $DbResult = $this->System->Database->query($sql);
|
|---|
| 203 | while ($Line = $DbResult->fetch_assoc())
|
|---|
| 204 | {
|
|---|
| 205 | if ($Line['Type'] == LOG_TYPE_ERROR) $Line['Text'] = htmlspecialchars($Line['Text']);
|
|---|
| 206 | $Line['Text'] = str_replace("\n", '<br/>', $Line['Text']);
|
|---|
| 207 | $Output .= '<tr><td>'.$Line['Date'].'</td>';
|
|---|
| 208 | if ($_SESSION['type'] == '') $Output .= '<td>'.T($Line['LogName']).'</td>';
|
|---|
| 209 | $Output .= '<td><span style="color: '.$Line['LogColor'].'">'.$Line['Text'].'</span></td>'.
|
|---|
| 210 | '<td><a href="'.$this->System->Link('/user/?user='.$Line['User']).'">'.$Line['UserName'].'</a></td>'.
|
|---|
| 211 | '<td>'.$Line['IP'].'</td>'.
|
|---|
| 212 | '<td>'.$Line['URL'].'</td></tr>';
|
|---|
| 213 | }
|
|---|
| 214 | $Output .= '</table>'.
|
|---|
| 215 | $PageList['Output'];
|
|---|
| 216 | if ($User->Licence(LICENCE_ADMIN))
|
|---|
| 217 | {
|
|---|
| 218 | $Output .= '<div>'.T('Remove').': <a href="'.$this->System->Link('/log/?a=delerrlog&type='.LOG_TYPE_ERROR).'">'.T('Error logs').'</a> '.
|
|---|
| 219 | '<a href="'.$this->System->Link('/log/?a=delerrlog&type='.LOG_TYPE_PAGE_NOT_FOUND).'">'.T('Missing').'</a></div>';
|
|---|
| 220 | }
|
|---|
| 221 | } else $Output .= ShowMessage(T('Access denied'), MESSAGE_CRITICAL);
|
|---|
| 222 |
|
|---|
| 223 | return $Output;
|
|---|
| 224 | }
|
|---|
| 225 |
|
|---|
| 226 | function DeleteErrorLog()
|
|---|
| 227 | {
|
|---|
| 228 | $User = ModuleUser::Cast($this->System->GetModule('User'))->User;
|
|---|
| 229 | if ($User->Licence(LICENCE_ADMIN) and
|
|---|
| 230 | (($_GET['type'] == LOG_TYPE_ERROR) or ($_GET['type'] == LOG_TYPE_PAGE_NOT_FOUND)))
|
|---|
| 231 | {
|
|---|
| 232 | $DbResult = $this->System->Database->select('LogType', '*', 'Id='.$_GET['type']);
|
|---|
| 233 | $LogType = $DbResult->fetch_assoc();
|
|---|
| 234 | $DbResult = $this->System->Database->query('SELECT COUNT(*) FROM `Log` WHERE `Type`='.$_GET['type']);
|
|---|
| 235 | $DbRow = $DbResult->fetch_row();
|
|---|
| 236 | $this->System->Database->query('DELETE FROM `Log` WHERE `Type`='.$_GET['type']);
|
|---|
| 237 | $this->System->ModuleManager->Modules['Log']->WriteLog('Vymazáno záznamů z '.$LogType['Description'].'.', LOG_TYPE_ADMINISTRATION);
|
|---|
| 238 | $Output = ShowMessage('Smazáno všech '.$DbRow[0].' záznamů z '.$LogType['Description'].'.');
|
|---|
| 239 | $Output .= $this->ShowList();
|
|---|
| 240 | return $Output;
|
|---|
| 241 | } else $Output = ShowMessage(T('Access denied'), MESSAGE_CRITICAL);
|
|---|
| 242 | }
|
|---|
| 243 | }
|
|---|