Issues (1474)

framework/Util/TBrowserLogRoute.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\TPropertyValue;
14
use Prado\Web\THttpUtility;
15
16
/**
17
 * TBrowserLogRoute class.
18
 *
19
 * TBrowserLogRoute prints selected log messages in the response.
20
 *
21
 * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>
22
 * @since 3.0
23
 */
24
class TBrowserLogRoute extends TLogRoute implements IOutputLogRoute
25
{
26
	/**
27
	 * @var string css class for identifying the table structure in the dom tree
28
	 */
29
	private $_cssClass;
30
	/**
31
	 * @var bool colorize the deltas.
32
	 * @since 4.3.0
33
	 */
34
	private bool $_colorizeDelta = true;
35
	/**
36
	 * @var bool add the prefix to the message
37
	 * @since 4.3.0
38
	 */
39
	private bool $_addPrefix = false;
40
41
	/**
42
	 * Renders the logs in HTML to the browser.
43
	 * @param array $logs list of log messages
44
	 * @param bool $final is the final flush
45
	 * @param array $meta the meta data for the logs.
46
	 */
47
	protected function processLogs(array $logs, bool $final, array $meta)
48
	{
49
		$app = $this->getApplication();
50
		if (empty($logs) || $app->getMode() === 'Performance' || $app instanceof \Prado\Shell\TShellApplication) {
51
			return;
52
		}
53
		$response = $this->getApplication()->getResponse();
54
		$response->write($this->renderHeader());
55
		$even = false;
56
		for ($i = 0, $n = count($logs); $i < $n; ++$i) {
57
			$logs[$i]['even'] = ($even = !$even);
0 ignored issues
show
The condition $even is always false.
Loading history...
58
			$response->write($this->renderMessage($logs[$i], $meta));
59
		}
60
		$response->write($this->renderFooter());
61
	}
62
63
	/**
64
	 * @return string the css class of the control
65
	 */
66
	public function getCssClass()
67
	{
68
		return $this->_cssClass;
69
	}
70
71
	/**
72
	 * @param string $value the css class of the control
73
	 */
74
	public function setCssClass($value): static
75
	{
76
		$this->_cssClass = TPropertyValue::ensureString($value);
77
		return $this;
78
	}
79
80
	/**
81
	 * @return bool Colorize the Deltas
82
	 * @since 4.3.0
83
	 */
84
	public function getColorizeDelta(): bool
85
	{
86
		return $this->_colorizeDelta;
87
	}
88
89
	/**
90
	 * @param bool|string $value Colorize the Deltas
91
	 * @since 4.3.0
92
	 */
93
	public function setColorizeDelta($value): static
94
	{
95
		$this->_colorizeDelta = TPropertyValue::ensureBoolean($value);
96
		return $this;
97
	}
98
99
	/**
100
	 * @return bool Adds the prefix to the message
101
	 * @since 4.3.0
102
	 */
103
	public function getAddPrefix(): bool
104
	{
105
		return $this->_addPrefix;
106
	}
107
108
	/**
109
	 * @param bool|string $value Adds the prefix to the message
110
	 * @since 4.3.0
111
	 */
112
	public function setAddPrefix($value): static
113
	{
114
		$this->_addPrefix = TPropertyValue::ensureBoolean($value);
115
		return $this;
116
	}
117
118
	/**
119
	 * @return string
120
	 */
121
	protected function renderHeader()
122
	{
123
		$string = '';
124
		if ($className = $this->getCssClass()) {
125
			$string =
126
<<<EOD
127
	<table class="$className">
128
		<tr class="header">
129
			<th colspan="5">
130
				Application Log
131
			</th>
132
		</tr><tr class="description">
133
		    <th>&nbsp;</th>
134
			<th>Category</th><th>Message</th><th>Time Spent (s)</th><th>Cumulated Time Spent (s)</th>
135
		</tr>
136
	EOD;
137
		} else {
138
			$string =
139
<<<EOD
140
	<table cellspacing="0" cellpadding="2" border="0" width="100%" style="table-layout:auto">
141
		<tr>
142
			<th style="background-color: black; color:white;" colspan="5">
143
				Application Log
144
			</th>
145
		</tr><tr style="background-color: #ccc; color:black">
146
		    <th style="width: 15px">&nbsp;</th>
147
			<th style="width: auto">Category</th><th style="width: auto">Message</th><th style="width: 120px">Time Spent (s)</th><th style="width: 150px">Cumulated Time Spent (s)</th>
148
		</tr>
149
	EOD;
150
		}
151
		return $string;
152
	}
153
154
	/**
155
	 * @param array $log
156
	 * @param array $meta
157
	 * @return string
158
	 * @author Brad Anderson <[email protected]> Colorization/weight of time deltas.
159
	 */
160
	protected function renderMessage($log, $meta)
161
	{
162
		$string = '';
163
		$total = sprintf('%0.6f', $log['total']);
164
		$delta = sprintf('%0.6f', $log['delta']);
165
		if ($this->_addPrefix) {
166
			$msg = $this->formatLogMessage($log);
167
		} else {
168
			$msg = $log[0];
169
		}
170
		$msg = preg_replace('/\(line[^\)]+\)$/', '', $msg); //remove line number info
171
172
		$msg = THttpUtility::htmlEncode($msg);
173
		if ($this->getCssClass()) {
174
			$colorCssClass = $log[TLogger::LOG_LEVEL];
175
			$messageCssClass = $log['even'] ? 'even' : 'odd';
176
			$category = $log[TLogger::LOG_CATEGORY];
177
			$string = <<<EOD
178
					<tr class="message level$colorCssClass $messageCssClass">
179
						<td class="code">&nbsp;</td>
180
						<td class="category">{$category}</td>
181
						<td class="message">{$msg}</td>
182
						<td class="time">{$delta}</td>
183
						<td class="cumulatedtime">{$total}</td>
184
					</tr>
185
				EOD;
186
		} else {
187
			$bgcolor = $log['even'] ? "#fff" : "#e8e8e8";
188
			if ($this->getColorizeDelta()) {
189
				$normalizedTime = $delta / ($meta['maxdelta'] === 0.0 ? 1 : $meta['maxdelta']);
190
				$textColor = 'color:' . TPropertyValue::ensureHexColor(static::getLogColor($normalizedTime));
191
				$weightCutOff = 0.75;
192
				$weightLightCutOff = 0.4;
193
				if ($normalizedTime > $weightCutOff) {
194
					$weight = '; font-weight: ' . round(400 + 500 * ($normalizedTime - $weightCutOff) / (1 - $weightCutOff));
195
				} elseif ($normalizedTime < $weightLightCutOff) {
196
					$weight = '; font-weight: ' . round(400 - 300 * ($weightLightCutOff - $normalizedTime) / ($weightLightCutOff));
197
				} else {
198
					$weight = '';
199
				}
200
			} else {
201
				$textColor = '';
202
				$weight = '';
203
			}
204
205
			$color = $this->getColorLevel($log[TLogger::LOG_LEVEL]);
206
			$category = $log[TLogger::LOG_CATEGORY];
207
			$string = <<<EOD
208
					<tr style="background-color: {$bgcolor}; color:#000">
209
						<td style="border:1px solid silver;background-color: {$color}">&nbsp;</td>
210
						<td>{$category}</td>
211
						<td>{$msg}</td>
212
						<td style="text-align:center; {$textColor}{$weight}">{$delta}</td>
213
						<td style="text-align:center">{$total}</td>
214
					</tr>
215
				EOD;
216
		}
217
		return $string;
218
	}
219
220
	protected function getColorLevel($level)
221
	{
222
		switch ($level) {
223
			case TLogger::PROFILE:
224
			case TLogger::PROFILE_BEGIN_SELECT:
225
			case TLogger::PROFILE_BEGIN:
226
			case TLogger::PROFILE_END_SELECT:
227
			case TLogger::PROFILE_END: return 'lime';
228
			case TLogger::DEBUG: return 'green';
229
			case TLogger::INFO: return 'black';
230
			case TLogger::NOTICE: return '#3333FF';
231
			case TLogger::WARNING: return '#33FFFF';
232
			case TLogger::ERROR: return '#ff9933';
233
			case TLogger::ALERT: return '#ff00ff';
234
			case TLogger::FATAL: return 'red';
235
		}
236
		return '';
237
	}
238
239
	protected function renderFooter()
240
	{
241
		$string = '';
242
		if ($this->getCssClass()) {
243
			$string .= '<tr class="footer"><td colspan="5">';
244
			foreach (self::$_levelValues as $name => $level) {
245
				$string .= '<span class="level' . $level . '">' . strtoupper($name) . "</span>";
246
			}
247
		} else {
248
			$string .= "<tr><td colspan=\"5\" style=\"text-align:center; background-color:black; border-top: 1px solid #ccc; padding:0.2em;\">";
249
			foreach (self::$_levelValues as $name => $level) {
250
				$string .= "<span style=\"color:white; border:1px solid white; background-color:" . $this->getColorLevel($level);
251
				$string .= ";margin: 0.5em; padding:0.01em;\">" . strtoupper($name) . "</span>";
252
			}
253
		}
254
		$string .= '</td></tr></table>';
255
		return $string;
256
	}
257
}
258