PluginProbe
Debug Log Viewer / 1.2
Debug Log Viewer v1.2
2.5 2.5.1 2.5.2 2.4 trunk 1.0.2 1.0.3 1.1 1.1.1 1.2 1.2.1 1.3 1.4 1.4.1 1.4.2 1.4.3 2.0.1 2.0.3 2.0.4 2.0.5 2.1 2.2.3
debug-log-viewer / admin / models / LogModel.php

LogModel.php in Debug Log Viewer 1.2, at admin/models/LogModel.php

232 lines 7.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) {
4 exit; // Exit if accessed directly
5 }
6
7 class DBG_LV_LogModel
8 {
9 const DBG_LV_LAST_POSITION_OPTION_NAME = 'dbg_lv_log_last_position';
10 const DBG_LV_LOG_UPDATES_MODE_OPTION_NAME = 'dbg_lv_log_updates_mode';
11
12 public static function dbg_lv_is_log_file_exists()
13 {
14 $path = DBG_LV_LogController::dbg_lv_get_debug_file_path();
15
16 return $path && file_exists($path) && is_file($path);
17 }
18
19 public static function dbg_lv_get_actual_log_limit()
20 {
21 return defined('DBG_LV_USER_DEFINED_LOG_FILE_LIMIT') ? constant('DBG_LV_USER_DEFINED_LOG_FILE_LIMIT') : DBG_LV_LOG_FILE_LIMIT;
22 }
23
24 public static function dbg_lv_is_debug_log_too_big()
25 {
26 return self::dbg_lv_get_log_filesize(['raw' => true]) > self::dbg_lv_get_actual_log_limit();
27 }
28
29 public static function dbg_lv_get_log_content($filename)
30 {
31 if (self::dbg_lv_is_debug_log_too_big()) {
32 $actual_limit = self::dbg_lv_get_actual_log_limit();
33 $file_handle = fopen($filename, 'r');
34 fseek($file_handle, -$actual_limit, SEEK_END);
35 $content = fread($file_handle, $actual_limit);
36 fclose($file_handle);
37 return $content;
38 } else {
39 return file_get_contents($filename);
40 }
41 }
42
43 public static function getNewLogEntries()
44 {
45 $filename = DBG_LV_LogController::dbg_lv_get_debug_file_path();
46 // Handle missing file
47 if (!file_exists($filename)) {
48 return self::resetLog('File does not exist');
49 }
50
51 $file_size = filesize($filename);
52 // Handle empty file
53 if ($file_size === 0) {
54 return self::resetLog();
55 }
56
57 $file_handle = fopen($filename, 'r');
58 if (!$file_handle) {
59 return self::resetLog();
60 }
61 $last_position = get_option(self::DBG_LV_LAST_POSITION_OPTION_NAME, 0);
62
63 // Handle new or truncated content
64 if ($last_position === 0 || $file_size > $last_position) {
65 fseek($file_handle, $last_position, SEEK_SET);
66 $content = fread($file_handle, $file_size - $last_position);
67 $new_position = ftell($file_handle);
68 fclose($file_handle);
69
70 update_option(self::DBG_LV_LAST_POSITION_OPTION_NAME, $new_position);
71
72 return [
73 'action' => [],
74 'data' => self::splitLogToRows($content),
75 ];
76 }
77
78 // Handle file truncation
79 if ($file_size < $last_position) {
80 fclose($file_handle);
81 return self::resetLog();
82 }
83
84 fclose($file_handle);
85 }
86
87 private static function resetLog()
88 {
89 update_option(self::DBG_LV_LAST_POSITION_OPTION_NAME, 0);
90 return ['action' => 'clear', 'data' => []];
91 }
92
93 public static function parseWholeLogFile()
94 {
95 $path = DBG_LV_LogController::dbg_lv_get_debug_file_path();
96
97 if (!file_exists($path) || !is_file($path)) {
98 return false;
99 }
100
101 $content = self::dbg_lv_get_log_content($path);
102 return self::splitLogToRows($content);
103 }
104
105 private static function splitLogToRows($content)
106 {
107 $pattern = '/\[[^\]]+\].*? on line \d+/s';
108 $count = preg_match_all($pattern, $content, $matches);
109
110 if (!$count) {
111 return [];
112 }
113
114 return $matches[0];
115 }
116
117 public static function dbg_lv_get_datetime_from_row($row)
118 {
119 preg_match_all('/\[(.*?)\]/m', $row, $matches, PREG_SET_ORDER, 0);
120 return isset($matches[0][1]) ? $matches[0][1] : __('N/A', 'debug-log-viewer');
121 }
122
123 public static function dbg_lv_get_line_from_log_row($row)
124 {
125 preg_match_all('/(on line |php:)(\d{1,})/m', $row, $matches, PREG_SET_ORDER, 0);
126 return isset($matches[0][2]) ? $matches[0][2] : __('N/A', 'debug-log-viewer');
127 }
128
129 public static function dbg_lv_get_file_from_log_row($row)
130 {
131 preg_match_all('/ in ' . preg_quote(dbg_lv_get_document_root(), '/') . '(.*?)( on line |:)\d{1,}/m', $row, $matches, PREG_SET_ORDER, 0);
132 return isset($matches[0][1]) ? $matches[0][1] : __('N/A', 'debug-log-viewer');
133 }
134
135 public static function dbg_lv_get_type_from_row($row)
136 {
137 if (strpos($row, 'PHP Notice:') !== false) {
138 return DBG_LV_LogLevelStatuses::NOTICE;
139 } elseif (strpos($row, 'PHP Warning:') !== false) {
140 return DBG_LV_LogLevelStatuses::WARNING;
141 } elseif (strpos($row, 'PHP Fatal error:') !== false) {
142 return DBG_LV_LogLevelStatuses::FATAL;
143 } elseif (strpos($row, 'WordPress database error') !== false) {
144 return DBG_LV_LogLevelStatuses::DATABASE;
145 } elseif (strpos($row, 'PHP Parse error:') !== false) {
146 return DBG_LV_LogLevelStatuses::PARSE;
147 } elseif (strpos($row, 'PHP Deprecated:') !== false) {
148 return DBG_LV_LogLevelStatuses::DEPRECATED;
149 }
150 }
151
152 public static function dbg_lv_get_stack_trace_for_row($row)
153 {
154 $re = '/Stack trace:\n(.*?)thrown in/s';
155 preg_match_all($re, $row, $matches, PREG_SET_ORDER, 0);
156 if (isset($matches[0])) {
157 return $matches[0][1];
158 }
159 return null;
160 }
161
162 public static function dbg_lv_get_description_from_row($row)
163 {
164 if (self::dbg_lv_get_type_from_row($row) === 'Database') {
165
166 $re = '/WordPress database error (.*)/m';
167 preg_match_all($re, $row, $matches, PREG_SET_ORDER, 0);
168 return isset($matches[0]) && $matches[0][1] ? $matches[0][1] : __('N/A', 'debug-log-viewer');
169 }
170
171 $re = '/ (PHP Notice:|PHP Warning:|PHP Fatal error:|PHP Parse error:|PHP Deprecated:)(.*?)(\[ | in |on line)/m';
172 preg_match_all($re, $row, $matches, PREG_SET_ORDER, 0);
173 return isset($matches[0]) && $matches[0][2] ? $matches[0][2] : __('N/A', 'debug-log-viewer');
174 }
175
176 public static function dbg_lv_get_log_filesize($params)
177 {
178 $with_measure_units = isset($params['with_measure_units']) ? $params['with_measure_units'] : null;
179 $raw = isset($params['raw']) ? $params['raw'] : null;
180
181 $debug_filepath = DBG_LV_LogController::dbg_lv_get_debug_file_path();
182
183 if (is_file($debug_filepath) && filesize($debug_filepath)) {
184 $filesize_in_bytes = filesize($debug_filepath);
185 if ($raw) {
186 return $filesize_in_bytes;
187 }
188 $filesize_in_mb = $filesize_in_bytes / 1024 / 1024;
189 return $with_measure_units
190 ? round($filesize_in_mb, 2) . ' ' . __('Mb', 'debug-log-viewer')
191 : round($filesize_in_mb, 2);
192 } else {
193 return 0;
194 }
195 }
196
197 public static function render_log_viewer_errors($errors)
198 {
199 global $DBG_LV_LOG_VIEWER_EMAIL_LEVELS;
200
201 $body = "" .
202 "<tr>" .
203 " <td>#</td>" .
204 " <td>Type</td>" .
205 " <td>Description</td>" .
206 " <td>File</td>" .
207 " <td>Line</td>" .
208 " <td>Hits</td>" .
209 "</tr>";
210
211 $row = "" .
212 "<tr>" .
213 " <td>%s</td>" .
214 " <td>%s</td>" .
215 " <td>%s</td>" .
216 " <td>%s</td>" .
217 " <td>%s</td>" .
218 " <td>%d</td>" .
219 "</tr>";
220
221 $index = 1;
222 foreach ($DBG_LV_LOG_VIEWER_EMAIL_LEVELS as $level) {
223 foreach ($errors[$level] as $hash => $error) {
224 $body .= sprintf($row, $index, $error['type'], $error['description']['text'], $error['file'], $error['line'], $error['hits']);
225 $index += 1;
226 }
227 }
228
229 return $body;
230 }
231 }
232