Issues (1474)

framework/Util/TFirebugLogRoute.php (1 issue)

Severity
1
<?php
2
3
/**
4
 * TLogRouter, TLogRoute, TFileLogRoute, TEmailLogRoute class file
5
 *
6
 * @author Qiang Xue <[email protected]>
7
 * @link https://github.com/pradosoft/prado
8
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
9
 */
10
11
namespace Prado\Util;
12
13
use Prado\Web\Javascripts\TJavaScript;
14
use Prado\Web\UI\ActiveControls\TActivePageAdapter;
15
16
/**
17
 * TFirebugLogRoute class.
18
 *
19
 * TFirebugLogRoute prints selected log messages in the firebug log console.
20
 *
21
 * {@see http://www.getfirebug.com/ FireBug Website}
22
 *
23
 * @author Enrico Stahn <[email protected]>, Christophe Boulain <[email protected]>
24
 * @since 3.1.2
25
 * @method \Prado\Web\Services\TPageService getService()
26
 */
27
class TFirebugLogRoute extends TBrowserLogRoute
28
{
29
	/**
30
	 * Logs via Firebug.
31
	 * @param array $logs list of log messages
32
	 * @param bool $final is the final flush
33
	 * @param array $meta the meta data for the logs.
34
	 */
35
	protected function processLogs(array $logs, bool $final, array $meta)
36
	{
37
		$page = $this->getService()->getRequestedPage();
38
		if (empty($logs) || $this->getApplication()->getMode() === \Prado\TApplicationMode::Performance) {
39
			return;
40
		}
41
		$even = false;
42
43
		$blocks = [['info', 'Tot Time', 'Time    ', '[Level] [Category] [Message]']];
44
		for ($i = 0, $n = count($logs); $i < $n; ++$i) {
45
			$logs[$i]['even'] = ($even = !$even);
0 ignored issues
show
The condition $even is always false.
Loading history...
46
			$blocks[] = $this->renderMessageCallback($logs[$i]);
47
		}
48
49
		try {
50
			$blocks = TJavaScript::jsonEncode($blocks);
51
		} catch (\Exception $e) {
52
			// strip everythin not 7bit ascii
53
			$blocks = preg_replace('/[^(\x20-\x7F)]*/', '', serialize($blocks));
54
		}
55
56
		// the response has already been flushed
57
		$response = $this->getApplication()->getResponse();
58
		if ($page->getIsCallback()) {
59
			$content = $response->createHtmlWriter();
60
			$content->getWriter()->setBoundary(TActivePageAdapter::CALLBACK_DEBUG_HEADER);
61
			$content->write($blocks);
62
			$response->write($content->flush());
63
		}
64
	}
65
66
	protected function renderHeader()
67
	{
68
		$page = $this->getService()->getRequestedPage();
69
		if ($page->getIsCallback()) {
70
			return
71
<<<EOD
72
73
	<script>
74
	/*<![CDATA[*/
75
	if (typeof(console) == 'object')
76
	{
77
		var groupFunc = blocks.length < 10 ? 'group': 'groupCollapsed';
78
		if(typeof log[groupFunc] === "function")
79
			log[groupFunc]("Callback logs ("+blocks.length+" entries)");
80
81
		console.log ("[Tot Time] [Time    ] [Level] [Category] [Message]");
82
83
	EOD;
84
		}
85
		return '';
86
	}
87
88
	protected function renderMessage($log, $meta)
89
	{
90
		$logfunc = 'console.' . $this->getFirebugLoggingFunction($log[TLogger::LOG_LEVEL]);
91
		$total = sprintf('%0.6f', $log['total']);
92
		$delta = sprintf('%0.6f', $log['delta']);
93
		$msg = trim($this->formatFirebugLogMessage($log));
94
		$msg = preg_replace('/\(line[^\)]+\)$/', '', $msg); //remove line number info
95
		$msg = "[{$total}] [{$delta}] " . $msg; // Add time spent and cumulated time spent
96
		$string = $logfunc . '(\'' . addslashes($msg) . '\');' . "\n";
97
98
		return $string;
99
	}
100
101
	protected function renderMessageCallback($log)
102
	{
103
		$logfunc = $this->getFirebugLoggingFunction($log[TLogger::LOG_LEVEL]);
104
		$total = sprintf('%0.6f', $log['total']);
105
		$delta = sprintf('%0.6f', $log['delta']);
106
		$msg = trim($this->formatFirebugLogMessage($log));
107
		$msg = preg_replace('/\(line[^\)]+\)$/', '', $msg); //remove line number info
108
109
		return [$logfunc, $total, $delta, $msg];
110
	}
111
112
	protected function renderFooter()
113
	{
114
		$string =
115
<<<EOD
116
		if(typeof console.groupEnd === "function")
117
			console.groupEnd();
118
119
	}
120
	</script>
121
122
	EOD;
123
124
		return $string;
125
	}
126
127
128
	/**
129
	 * Formats a log message given different fields.
130
	 * @param array $log The log to format
131
	 * @return string formatted message
132
	 */
133
	public function formatFirebugLogMessage(array $log): string
134
	{
135
		$traces = [];
136
		if (!is_string($log[TLogger::LOG_MESSAGE])) {
137
			if ($log[TLogger::LOG_MESSAGE] instanceof \Exception || $log[TLogger::LOG_MESSAGE] instanceof \Throwable) {
138
				$log[TLogger::LOG_MESSAGE] = (string) $log[TLogger::LOG_MESSAGE];
139
			} else {
140
				$log[TLogger::LOG_MESSAGE] = \Prado\Util\TVarDumper::dump($log[TLogger::LOG_MESSAGE]);
141
			}
142
		}
143
		if (!is_string($log[TLogger::LOG_MESSAGE])) {
144
			if ($log[TLogger::LOG_MESSAGE] instanceof \Exception || $log[TLogger::LOG_MESSAGE] instanceof \Throwable) {
145
				$log[TLogger::LOG_MESSAGE] = (string) $log[TLogger::LOG_MESSAGE];
146
			} else {
147
				$log[TLogger::LOG_MESSAGE] = \Prado\Util\TVarDumper::dump($log[TLogger::LOG_MESSAGE]);
148
			}
149
		}
150
		if (isset($log[TLogger::LOG_TRACES])) {
151
			$traces = array_map(fn ($trace) => "in {$trace['file']}:{$trace['line']}", $log[TLogger::LOG_TRACES]);
152
		}
153
		return '[' . $this->getLevelName($log[TLogger::LOG_LEVEL]) . '] [' . $log[TLogger::LOG_CATEGORY] . '] ' . $log[TLogger::LOG_MESSAGE]
154
			. (empty($traces) ? '' : "\n    " . implode("\n    ", $traces));
155
	}
156
157
	protected function getFirebugLoggingFunction($level)
158
	{
159
		switch ($level) {
160
			case TLogger::PROFILE:
161
			case TLogger::PROFILE_BEGIN:
162
			case TLogger::PROFILE_END:
163
			case TLogger::DEBUG:
164
			case TLogger::INFO:
165
			case TLogger::NOTICE:
166
				return 'info';
167
			case TLogger::WARNING:
168
				return 'warn';
169
			case TLogger::ERROR:
170
			case TLogger::ALERT:
171
			case TLogger::FATAL:
172
				return 'error';
173
			default:
174
				return 'log';
175
		}
176
	}
177
}
178