Passed
Push — master ( cbd324...1f5054 )
by Tomáš
03:54
created

ElasticsearchPanel::debug()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
ccs 0
cts 4
cp 0
cc 2
nc 2
nop 2
crap 6
1
<?php declare(strict_types=1);
2
3
namespace Portiny\Elasticsearch\Adapter\Nette\Tracy;
4
5
use Elastica\Client;
6
use Elastica\Request;
7
use Elastica\Response;
8
use Psr\Log\LoggerInterface;
9
use Tracy\Debugger;
10
use Tracy\Dumper;
11
use Tracy\IBarPanel;
12
13
final class ElasticsearchPanel implements IBarPanel, LoggerInterface
14
{
15
	/**
16
	 * @var int
17
	 */
18
	public const DATA_REQUEST_INDEX = 0;
19
20
	/**
21
	 * @var int
22
	 */
23
	public const DATA_TIME_INDEX = 1;
24
25
	/**
26
	 * @var int
27
	 */
28
	public const DATA_PATH_INDEX = 2;
29
30
	/**
31
	 * @var int
32
	 */
33
	public const DATA_TRACE_INDEX = 3;
34
35
	/**
36
	 * @var int
37
	 */
38
	public const DATA_METHOD_INDEX = 4;
39
40
	/**
41
	 * @var float
42
	 */
43
	private $totalTime = 0.0;
44
45
	/**
46
	 * @var array
47
	 */
48
	private $queries = [];
49
50
	/**
51
	 * @var Client
52
	 */
53
	private $client;
54
55 2
	public function __construct(Client $client)
56
	{
57 2
		$this->client = $client;
58 2
	}
59
60
	/**
61
	 * {@inheritdoc}
62
	 */
63 1
	public function getTab(): string
64
	{
65
		return '<span title="Elasticsearch">'
66
			. '<img style="padding-right: 2px;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/'
67
			. '9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUCDgIqW2pwhwAAAw1JREFUOE9tk11sk3UU'
68
			. 'xn//96PtC202xtwCc06Mc5PN8LFIpFnc/AjRLIQYF4M3i3qhS0xMQMONH9HEqDeSSLKQEOMlGqMgaAyiBnAzSmUEBqOgsLoO2maDru'
69
			. '3WtX3f/d/jhdsA8Xd1kpNznifPyUFEWEREDBGxAHxdWukXr7ztZQ5MeMl92pv8Lu672VdFl4LcglosfN+vc2Njz8ic22g1rfiVcGyX'
70
			. 'l9jdrQvDgIFCYayIErhv15dmTffLSqk8gLWgHCn9OPpR+ci5F3U6R+S1bmR6D37hjCgzfFMkH8MbH3gOw/lJRD5VSokBIK7X4A4nnn'
71
			. 'RjY+iJLEbYR+eHwXSWhv/1a+HnTyHFeA8QXnKgAvbyqp51TsAXSicTGKsnkbSHMkPcjkLmc4ieWw1YIoIxdWN242dfnIo98eEPte8Y'
72
			. 'NoM7esCdQmFwJ4Jy7sV12hpyJd0CKPXLybHTL7z+1YZg0MLXPvmZMl8P9BK1+5nLXULEA2WBaMxIGxdDr/DGt+d5rPVBdm7tfdw6G8'
73
			. '9sUApMQ+G6Pl0da0ghHK19n47IIDUzQ5SyQ4Tqn+bY3DbeOnCGePIiv/95lmjL2r1WU0N12nX1KhF4avP9dG5v5aBOkUpUaI08Smf4'
74
			. 'EZ69u5/95wp8cOQEmWyGkB2gjMvlTKrZ2tjesPP5bes+L0yX2dzXyv78ODm3gkJxPn+deMHgdKWOFi1cSY9T5SxDFvKItqwdVCKigO'
75
			. '1HM1f37f5rJFycn+f220FZawbWRxn67Rg/j45w4VqSd3v7in1dW9otpZSISCyWnUznXbfZNv4vfQiaZRrXHOK9jk7a6vsnQuY9XUqp'
76
			. 'v62Fvhux7WzQNPFv+Q0AAYKmRViSJKcvkJyO42vn+sONL+VEZOnY1zbV1B1fFXLuWFDRWtZX16L1LMvslTxw1xbqI+2HgFmlFEpEUE'
77
			. 'ohIvXHp1KHP740smmyUsJA4YlPe1UNO5of+qYpOLvH8ytbDWX+sTxQe9ixq4s3bS6oiogz41U+OXg1Udx7eVS+T43fyFbKb4qIzX9Y'
78
			. 'nPkHxAJ5Y3iFu8EAAAAASUVORK5CYII=" />'
79 1
			. count($this->queries) . ' queries'
80 1
			. ($this->totalTime ? ' / ' . sprintf('%0.1f', $this->totalTime * 1000) . 'ms' : '')
81 1
			. '</span>';
82
	}
83
84
	/**
85
	 * {@inheritdoc}
86
	 */
87 1
	public function getPanel(): string
88
	{
89 1
		$s = '';
90 1
		foreach ($this->queries as $query) {
91
			$s .= '<tr>';
92
93
			$s .= '<td>' . sprintf('%0.3f', $query[self::DATA_TIME_INDEX] * 1000) . '</td>';
94
95
			$s .= '<td class="nette-ElasticsearchPanel-request" style="min-width: 400px">' .
96
				Dumper::toHtml($query[self::DATA_REQUEST_INDEX], [Dumper::DEPTH => 6])
97
				. '</td>';
98
99
			$s .= '<td>' .
100
				$query[self::DATA_METHOD_INDEX] . ' ' . $query[self::DATA_PATH_INDEX] . '<br>' .
101
				($query[self::DATA_REQUEST_INDEX] ? json_encode($query[self::DATA_REQUEST_INDEX]) : '')
102
				. '</td>';
103
104
			$s .= '<td>' . Dumper::toHtml($query[self::DATA_TRACE_INDEX], [Dumper::COLLAPSE => 1]) . '</td>';
105
106
			$s .= '</tr>';
107
		}
108
109 1
		return $this->renderStyles() .
110 1
			'<h1>Queries: ' . count($this->queries) .
111 1
			($this->totalTime ? ', time: ' . sprintf('%0.3f', $this->totalTime * 1000) . ' ms' : '') .
112 1
			'</h1>
113
			<div class="tracy-inner nette-ElasticsearchPanel">
114
				<h2>Queries</h2>
115
				<table>
116
					<tr><th>Time&nbsp;ms</th><th>Request</th><th>JSON Request</th><th>Trace</th></tr>'
117 1
					. $s .
118 1
				'</table>
119
			</div>';
120
	}
121
122
	public function bindToBar(): void
123
	{
124
		$this->client->setLogger($this);
125
		Debugger::getBar()->addPanel($this);
126
	}
127
128
	/**
129
	 * {@inheritdoc}
130
	 */
131
	public function debug($message, array $context = []): void
132
	{
133
		if (! isset($context['request'], $context['response'], $context['responseStatus'])) {
134
			return;
135
		}
136
137
		$this->logRequest($this->client->getLastRequest(), $this->client->getLastResponse());
138
	}
139
140
	/**
141
	 * {@inheritdoc}
142
	 */
143
	public function emergency($message, array $context = []): void
144
	{
145
	}
146
147
	/**
148
	 * {@inheritdoc}
149
	 */
150
	public function alert($message, array $context = []): void
151
	{
152
	}
153
154
	/**
155
	 * {@inheritdoc}
156
	 */
157
	public function critical($message, array $context = []): void
158
	{
159
	}
160
161
	/**
162
	 * {@inheritdoc}
163
	 */
164
	public function error($message, array $context = []): void
165
	{
166
	}
167
168
	/**
169
	 * {@inheritdoc}
170
	 */
171
	public function warning($message, array $context = []): void
172
	{
173
	}
174
175
	/**
176
	 * {@inheritdoc}
177
	 */
178
	public function notice($message, array $context = []): void
179
	{
180
	}
181
182
	/**
183
	 * {@inheritdoc}
184
	 */
185
	public function info($message, array $context = []): void
186
	{
187
	}
188
189
	/**
190
	 * {@inheritdoc}
191
	 */
192
	public function log($level, $message, array $context = []): void
193
	{
194
	}
195
196 1
	private function renderStyles(): string
197
	{
198 1
		return '<style>
199
			#tracy-debug td.nette-ElasticsearchPanel-request { background: white !important; }
200
			#tracy-debug td.nette-ElasticsearchPanel-request pre.tracy-dump { background: white !important; }
201
			#tracy-debug div.tracy-inner.nette-ElasticsearchPanel { max-width: 1000px }
202
			#tracy-debug .nette-ElasticsearchPanel h2 { font-size: 23px; }
203
			#tracy-debug .nette-ElasticsearchPanel tr table { margin: 8px 0; max-height: 150px; overflow:auto }
204
			</style>';
205
	}
206
207
	private function logRequest(?Request $request, ?Response $response): void
208
	{
209
		if (! $request || ! $response) {
210
			return;
211
		}
212
213
		$this->totalTime += $response->getQueryTime();
214
215
		$this->queries[] = [
216
			self::DATA_REQUEST_INDEX => $request->getData(),
217
			self::DATA_PATH_INDEX => $request->getPath(),
218
			self::DATA_TIME_INDEX => $response->getQueryTime(),
219
			self::DATA_TRACE_INDEX => debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : false),
0 ignored issues
show
Bug introduced by
It seems like Portiny\Elasticsearch\Ad...ACE_IGNORE_ARGS : false can also be of type false; however, parameter $options of debug_backtrace() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

219
			self::DATA_TRACE_INDEX => debug_backtrace(/** @scrutinizer ignore-type */ PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : false),
Loading history...
220
			self::DATA_METHOD_INDEX => $request->getMethod(),
221
		];
222
	}
223
}
224