1: | <?php
|
2: | |
3: | |
4: | |
5: | |
6: | |
7: | |
8: | |
9: | |
10: | |
11: | |
12: | |
13: | |
14: | |
15: | |
16: | |
17: | |
18: | |
19: | |
20: | |
21: | |
22: |
|
23: | defined('XOOPS_ROOT_PATH') || exit('Restricted access');
|
24: |
|
25: | |
26: | |
27: | |
28: | |
29: | |
30: | |
31: | |
32: |
|
33: | class XoopsLogger
|
34: | {
|
35: | |
36: | |
37: | |
38: | |
39: |
|
40: | public $queries = array();
|
41: | public $blocks = array();
|
42: | public $extra = array();
|
43: | public $logstart = array();
|
44: | public $logend = array();
|
45: | public $errors = array();
|
46: | public $deprecated = array();
|
47: | |
48: | |
49: |
|
50: |
|
51: | public $usePopup = false;
|
52: | public $activated = true;
|
53: |
|
54: | |
55: | |
56: |
|
57: | public $renderingEnabled = false;
|
58: |
|
59: | |
60: | |
61: |
|
62: | public function __construct()
|
63: | {
|
64: | }
|
65: |
|
66: | |
67: | |
68: |
|
69: | public function instance()
|
70: | {
|
71: | return XoopsLogger::getInstance();
|
72: | }
|
73: |
|
74: | |
75: | |
76: | |
77: | |
78: |
|
79: | public static function getInstance()
|
80: | {
|
81: | static $instance;
|
82: | if (!isset($instance)) {
|
83: | $instance = new XoopsLogger();
|
84: |
|
85: | set_error_handler('XoopsErrorHandler_HandleError');
|
86: |
|
87: | set_exception_handler(array($instance, 'handleException'));
|
88: | }
|
89: |
|
90: | return $instance;
|
91: | }
|
92: |
|
93: | |
94: | |
95: | |
96: | |
97: | |
98: |
|
99: | public function enableRendering()
|
100: | {
|
101: | if (!$this->renderingEnabled) {
|
102: | ob_start(array(&$this, 'render'));
|
103: | $this->renderingEnabled = true;
|
104: | }
|
105: | }
|
106: |
|
107: | |
108: | |
109: | |
110: | |
111: |
|
112: | public function microtime()
|
113: | {
|
114: |
|
115: | $now = explode(' ', microtime());
|
116: |
|
117: | return (float)$now[0] + (float)$now[1];
|
118: | }
|
119: |
|
120: | |
121: | |
122: | |
123: | |
124: |
|
125: | public function startTime($name = 'XOOPS')
|
126: | {
|
127: | if ($this->activated) {
|
128: | $this->logstart[$name] = $this->microtime();
|
129: | }
|
130: | }
|
131: |
|
132: | |
133: | |
134: | |
135: | |
136: |
|
137: | public function stopTime($name = 'XOOPS')
|
138: | {
|
139: | if ($this->activated) {
|
140: | $this->logend[$name] = $this->microtime();
|
141: | }
|
142: | }
|
143: |
|
144: | |
145: | |
146: | |
147: | |
148: | |
149: | |
150: | |
151: |
|
152: | public function addQuery($sql, $error = null, $errno = null, $query_time = null)
|
153: | {
|
154: | if ($this->activated) {
|
155: | $this->queries[] = array('sql' => $sql, 'error' => $error, 'errno' => $errno, 'query_time' => $query_time);
|
156: | }
|
157: | }
|
158: |
|
159: | |
160: | |
161: | |
162: | |
163: | |
164: | |
165: |
|
166: | public function addBlock($name, $cached = false, $cachetime = 0)
|
167: | {
|
168: | if ($this->activated) {
|
169: | $this->blocks[] = array('name' => $name, 'cached' => $cached, 'cachetime' => $cachetime);
|
170: | }
|
171: | }
|
172: |
|
173: | |
174: | |
175: | |
176: | |
177: | |
178: |
|
179: | public function addExtra($name, $msg)
|
180: | {
|
181: | if ($this->activated) {
|
182: | $this->extra[] = array('name' => $name, 'msg' => $msg);
|
183: | }
|
184: | }
|
185: |
|
186: | |
187: | |
188: | |
189: | |
190: | |
191: | |
192: | |
193: |
|
194: | public function addDeprecated($msg)
|
195: | {
|
196: | if ($this->activated) {
|
197: | $backTrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
198: | $miniTrace = ' trace: ';
|
199: | foreach ($backTrace as $i => $trace) {
|
200: | $miniTrace .= $trace['file'] . ':' . $trace['line'] . ' ';
|
201: | }
|
202: | $miniTrace = str_replace(XOOPS_VAR_PATH, '', $miniTrace);
|
203: | $miniTrace = str_replace(XOOPS_PATH, '', $miniTrace);
|
204: | $miniTrace = str_replace(XOOPS_ROOT_PATH, '', $miniTrace);
|
205: |
|
206: | $this->deprecated[] = $msg . $miniTrace;
|
207: | }
|
208: | }
|
209: |
|
210: | |
211: | |
212: | |
213: | |
214: | |
215: | |
216: | |
217: | |
218: |
|
219: | public function handleError($errno, $errstr, $errfile, $errline,$trace=null)
|
220: | {
|
221: | if ($this->activated && ($errno & error_reporting())) {
|
222: |
|
223: | $this->errors[] = compact('errno', 'errstr', 'errfile', 'errline');
|
224: | }
|
225: | if ($errno == E_USER_ERROR) {
|
226: | $includeTrace = true;
|
227: | if (substr($errstr, 0, '8') === 'notrace:') {
|
228: | $includeTrace = false;
|
229: | $errstr = substr($errstr, 8);
|
230: | }
|
231: | echo sprintf(_XOOPS_FATAL_MESSAGE, $errstr);
|
232: | if ($includeTrace) {
|
233: | echo "<div style='color:#f0f0f0;background-color:#f0f0f0;'>" . _XOOPS_FATAL_BACKTRACE . ':<br>';
|
234: | if ($trace === null && function_exists('debug_backtrace')) {
|
235: | $trace = \debug_backtrace();
|
236: | array_shift($trace);
|
237: | }
|
238: | foreach ($trace as $step) {
|
239: | if (isset($step['file'])) {
|
240: | echo $this->sanitizePath($step['file']);
|
241: | echo ' (' . $step['line'] . ")\n<br>";
|
242: | }
|
243: | }
|
244: | echo '</div>';
|
245: | }
|
246: | exit();
|
247: | }
|
248: | }
|
249: |
|
250: | |
251: | |
252: | |
253: | |
254: | |
255: | |
256: |
|
257: | public function handleException($e)
|
258: | {
|
259: | if ($this->isThrowable($e)) {
|
260: | $msg = get_class($e) . ': ' . $this->sanitizePath($this->sanitizeDbMessage($e->getMessage()));
|
261: | $this->handleError(E_USER_ERROR, $msg, $e->getFile(), $e->getLine(), $e->getTrace());
|
262: | }
|
263: | }
|
264: |
|
265: | |
266: | |
267: | |
268: | |
269: | |
270: | |
271: |
|
272: | protected function isThrowable($e)
|
273: | {
|
274: | $type = interface_exists('\Throwable', false) ? '\Throwable' : '\Exception';
|
275: | return $e instanceof $type;
|
276: | }
|
277: |
|
278: | |
279: | |
280: | |
281: | |
282: | |
283: | |
284: | |
285: |
|
286: | public function sanitizePath($path)
|
287: | {
|
288: | $path = str_replace(array('\\', XOOPS_ROOT_PATH, str_replace('\\', '/', realpath(XOOPS_ROOT_PATH))), array('/', '', ''), $path);
|
289: |
|
290: | return $path;
|
291: | }
|
292: |
|
293: | |
294: | |
295: | |
296: | |
297: | |
298: | |
299: | |
300: |
|
301: | protected function sanitizeDbMessage($message)
|
302: | {
|
303: |
|
304: | $message = str_replace(XOOPS_DB_PREFIX.'_', '', $message);
|
305: | $message = str_replace(XOOPS_DB_NAME.'.', '', $message);
|
306: |
|
307: | return $message;
|
308: | }
|
309: |
|
310: | |
311: | |
312: | |
313: | |
314: |
|
315: | public function render($output)
|
316: | {
|
317: | global $xoopsUser;
|
318: | if (!$this->activated) {
|
319: | return $output;
|
320: | }
|
321: |
|
322: | $log = $this->dump($this->usePopup ? 'popup' : '');
|
323: | $this->renderingEnabled = $this->activated = false;
|
324: | $pattern = '<!--{xo-logger-output}-->';
|
325: | $pos = strpos($output, $pattern);
|
326: | if ($pos !== false) {
|
327: | return substr($output, 0, $pos) . $log . substr($output, $pos + strlen($pattern));
|
328: | } else {
|
329: | return $output . $log;
|
330: | }
|
331: | }
|
332: |
|
333: | |
334: | |
335: | |
336: | |
337: | |
338: | |
339: |
|
340: | public function dump($mode = '')
|
341: | {
|
342: | include XOOPS_ROOT_PATH . '/class/logger/render.php';
|
343: |
|
344: | return $ret;
|
345: | }
|
346: |
|
347: | |
348: | |
349: | |
350: | |
351: | |
352: | |
353: |
|
354: | public function dumpTime($name = 'XOOPS', $unset = false)
|
355: | {
|
356: | if (!$this->activated) {
|
357: | return null;
|
358: | }
|
359: |
|
360: | if (!isset($this->logstart[$name])) {
|
361: | return 0;
|
362: | }
|
363: | $stop = isset($this->logend[$name]) ? $this->logend[$name] : $this->microtime();
|
364: | $start = $this->logstart[$name];
|
365: |
|
366: | if ($unset) {
|
367: | unset($this->logstart[$name]);
|
368: | }
|
369: |
|
370: | return $stop - $start;
|
371: | }
|
372: |
|
373: | |
374: | |
375: | |
376: | |
377: | |
378: | |
379: | |
380: | |
381: | |
382: | |
383: |
|
384: | public function triggerError($errkey = 0, $errStr = '', $errFile = '', $errLine = '', $errNo = 0)
|
385: | {
|
386: | $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated since XOOPS 2.5.4');
|
387: |
|
388: | if (!empty($errStr)) {
|
389: | $errStr = sprintf($errStr, $errkey);
|
390: | }
|
391: | $errFile = $this->sanitizePath($errFile);
|
392: | $this->handleError($errNo, $errStr, $errFile, $errLine);
|
393: | }
|
394: |
|
395: | |
396: | |
397: | |
398: | |
399: |
|
400: | public function dumpAll()
|
401: | {
|
402: | $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated since XOOPS 2.5.4, please use \'$xoopsLogger->dump(\'\');\' instead.');
|
403: |
|
404: | return $this->dump('');
|
405: | }
|
406: |
|
407: | |
408: | |
409: | |
410: | |
411: |
|
412: | public function dumpBlocks()
|
413: | {
|
414: | $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated since XOOPS 2.5.4, please use \'$xoopsLogger->dump(\'blocks\');\' instead.');
|
415: |
|
416: | return $this->dump('blocks');
|
417: | }
|
418: |
|
419: | |
420: | |
421: | |
422: | |
423: |
|
424: | public function dumpExtra()
|
425: | {
|
426: | $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated since XOOPS 2.5.4, please use \'$xoopsLogger->dump(\'extra\');\' instead.');
|
427: |
|
428: | return $this->dump('extra');
|
429: | }
|
430: |
|
431: | |
432: | |
433: | |
434: | |
435: |
|
436: | public function dumpQueries()
|
437: | {
|
438: | $GLOBALS['xoopsLogger']->addDeprecated(__METHOD__ . ' is deprecated since XOOPS 2.5.4, please use \'$xoopsLogger->dump(\'queries\');\' instead.');
|
439: |
|
440: | return $this->dump('queries');
|
441: | }
|
442: | |
443: | |
444: |
|
445: | }
|
446: |
|
447: | |
448: | |
449: | |
450: | |
451: | |
452: | |
453: | |
454: | |
455: | |
456: | |
457: | |
458: | |
459: | |
460: | |
461: |
|
462: | function XoopsErrorHandler_HandleError($errNo, $errStr, $errFile, $errLine, $errContext = null)
|
463: | {
|
464: | |
465: | |
466: | |
467: | |
468: | |
469: | |
470: |
|
471: | $logger = XoopsLogger::getInstance();
|
472: | $logger->handleError($errNo, $errStr, $errFile, $errLine, $errContext);
|
473: | return null;
|
474: | }
|
475: | |