Passed
Push — master ( 12b7eb...57e7f6 )
by Bernardette
02:41
created

TracyBar::getPanel()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 13
nc 4
nop 0
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Rostenkowski\Doctrine\Debugger;
4
5
6
use Doctrine\DBAL\Logging\SQLLogger;
7
use Nette\Utils\Strings;
8
use Tracy\Dumper;
9
use Tracy\IBarPanel;
10
11
class TracyBar implements SQLLogger, IBarPanel
12
{
13
14
	/**
15
	 * @var float
16
	 */
17
	private $start;
18
19
	/**
20
	 * @var int
21
	 */
22
	private $current;
23
24
	/**
25
	 * @var array
26
	 */
27
	private $queries = [];
28
29
	private $totalTime;
30
31
32
	private function getTotalTime()
33
	{
34
		if ($this->totalTime === NULL) {
35
			foreach ($this->queries as $query) {
36
				$this->totalTime += $query['dur'];
37
			}
38
		}
39
40
		return $this->totalTime;
41
	}
42
43
44
	public function getPanel()
45
	{
46
		$count = count($this->queries);
47
		$color = $count ? 'green' : '#555555';
48
		$totalTime = $this->getTotalTime();
49
		$t = number_format($totalTime * 1000, 0, '.', '&nbsp;') . '&nbsp;ms';
50
		$template = $this->getTemplate('panel');
51
		$row = $this->getTemplate('query');
52
		$buffer = '';
53
		foreach ($this->queries as $i => $query) {
54
			$buffer .= sprintf($row,
55
				number_format(round($query['dur'] * 1000, 5), 1, '.', '&nbsp;'),
56
				$this->colorize($query['sql']),
57
				$this->dump($query['params'])
58
			);
59
		}
60
61
		return sprintf($template, $color, $t, $count, $buffer);
62
	}
63
64
65
	public function getTab()
66
	{
67
		$count = count($this->queries);
68
		$color = $count ? 'green' : '#555555';
69
		$totalTime = $this->getTotalTime();
70
		$time = number_format($totalTime * 1000, 0, '.', '&nbsp;') . ' ms';
71
		$template = $this->getTemplate('tab');
72
73
		return sprintf($template, $color, $time, $count);
74
	}
75
76
77
	private function getTemplate($name)
78
	{
79
		return file_get_contents(__DIR__ . "/templates/$name.html");
80
	}
81
82
83
	private function colorize($sql): string
84
	{
85
		$class = strtolower(substr($sql, 0, 6));
86
		if (!in_array($class, ['select', 'update', 'delete', 'insert'])) {
87
			$class = '';
88
		}
89
		$keywords = implode('|', [
90
			'DROP TABLE',
91
			'CREATE TABLE',
92
			'PRAGMA',
93
			'SELECT ',
94
			'FROM ',
95
			'WHERE ',
96
			'ORDER BY ',
97
			'GROUP BY ',
98
			'LEFT JOIN ',
99
			'INNER JOIN ',
100
			'UNION ALL',
101
			' AND ',
102
			' OR ',
103
			'UPDATE ',
104
			'INSERT ',
105
			'DELETE ',
106
			'START TRANSACTION',
107
			'COMMIT',
108
			'INTO ',
109
			'SET ',
110
			'VALUES ',
111
			'DEFAULT ',
112
			'PRIMARY KEY',
113
			'VARCHAR',
114
			'INTEGER',
115
			'TEXT',
116
			'NULL',
117
			'NOT NULL',
118
		]);
119
		$template = "<b>$1</b>";
120
		$sql = preg_replace("/($keywords)/i", $template, $sql);
121
122
		return "<div class='query $class'>$sql</div>";
123
	}
124
125
126
	private function dump($params)
127
	{
128
		if ($params) {
129
130
			return Dumper::toHtml($params, [Dumper::COLLAPSE => 1]);
131
		}
132
133
		return '';
134
	}
135
136
137
	public function startQuery($sql, array $params = NULL, array $types = NULL)
138
	{
139
		$this->start = microtime(true);
0 ignored issues
show
Documentation Bug introduced by
It seems like microtime(true) can also be of type string. However, the property $start is declared as type double. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
140
		$this->queries[++$this->current] = ['sql' => Strings::trim($sql), 'params' => $params, 'types' => $types, 'dur' => 0];
141
	}
142
143
144
	public function stopQuery()
145
	{
146
		$this->queries[$this->current]['dur'] = microtime(true) - $this->start;
147
	}
148
}
149