Helper   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Test Coverage

Coverage 41.3%

Importance

Changes 4
Bugs 2 Features 0
Metric Value
eloc 52
c 4
b 2
f 0
dl 0
loc 76
ccs 19
cts 46
cp 0.413
rs 10
wmc 14

1 Method

Rating   Name   Duplication   Size   Complexity  
C dumpSql() 0 70 14
1
<?php declare(strict_types = 1);
2
3
namespace Portiny\Doctrine\Adapter\Nette\Tracy;
4
5
use Doctrine\DBAL\Connection;
6
use Nette\Utils\Strings;
7
8
final class Helper
9
{
10
11
	/**
12
	 * Returns syntax highlighted SQL command.
13
	 */
14 2
	public static function dumpSql(string $sql, ?array $params = null, ?Connection $connection = null): string
15
	{
16 2
		static $keywords1 = 'SELECT|(?:ON\s+DUPLICATE\s+KEY)?UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|'
17
			. 'DELETE|CALL|UNION|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|SET|VALUES|LEFT\s+JOIN|'
18
			. 'INNER\s+JOIN|TRUNCATE';
19 2
		static $keywords2 = 'ALL|DISTINCT|DISTINCTROW|IGNORE|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|[RI]?LIKE|'
20
			. 'REGEXP|TRUE|FALSE';
21
22
		// insert new lines
23 2
		$sql = " ${sql} ";
24 2
		$sql = (string) preg_replace("#(?<=[\\s,(])(${keywords1})(?=[\\s,)])#i", "\n\$1", $sql);
25
		// reduce spaces
26 2
		$sql = (string) preg_replace('#[ \t]{2,}#', ' ', $sql);
27 2
		$sql = wordwrap($sql, 100);
28 2
		$sql = (string) preg_replace('#([ \t]*\r?\n){2,}#', "\n", $sql);
29
		// syntax highlight
30 2
		$sql = htmlspecialchars($sql, ENT_IGNORE, 'UTF-8');
31
		$closure = function ($matches) {
32 2
			if (! empty($matches[1])) { // comment
33
				return '<em style="color:gray">' . $matches[1] . '</em>';
34 2
			} elseif (! empty($matches[2])) { // error
35
				return '<strong style="color:red">' . $matches[2] . '</strong>';
36 2
			} elseif (! empty($matches[3])) { // most important keywords
37 2
				return '<strong style="color:blue">' . $matches[3] . '</strong>';
38
			} elseif (! empty($matches[4])) { // other keywords
39
				return '<strong style="color:green">' . $matches[4] . '</strong>';
40
			}
41 2
		};
42 2
		$sql = (string) preg_replace_callback(
43 2
			"#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|(?<=[\\s,(])(${keywords1})(?=[\\s,)])|'
44 2
			. '(?<=[\\s,(=])(${keywords2})(?=[\\s,)=])#is",
45
			$closure,
46
			$sql
47
		);
48
49
		// parameters
50
		$sql = (string) preg_replace_callback('#\?#', function () use ($params, $connection) {
51
			static $i = 0;
52
			if (! isset($params[$i])) {
53
				return '?';
54
			}
55
56
			$param = $params[$i++];
57
			if (is_string($param)
58
				&& (preg_match('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u', $param) || preg_last_error())
59
			) {
60
				return '<i title="Length ' . strlen($param) . ' bytes">&lt;binary&gt;</i>';
61
			} elseif (is_string($param)) {
62
				$length = Strings::length($param);
63
				$truncated = Strings::truncate($param, 120);
64
				$text = htmlspecialchars(
65
					$connection ? $connection->quote($truncated) : '\'' . $truncated . '\'',
66
					ENT_NOQUOTES,
67
					'UTF-8'
68
				);
69
				return '<span title="Length ' . $length . ' characters">' . $text . '</span>';
70
			} elseif (is_resource($param)) {
71
				$type = get_resource_type($param);
72
				if ($type === 'stream') {
73
					$info = stream_get_meta_data($param);
74
					return '<i' . (isset($info['uri']) ? ' title="' .
75
							htmlspecialchars($info['uri'], ENT_NOQUOTES, 'UTF-8') . '"' : null)
76
						. '>&lt;' . htmlspecialchars($type, ENT_NOQUOTES, 'UTF-8') . ' resource&gt;</i> ';
77
				}
78
			}
79
80
			return htmlspecialchars((string) $param, ENT_NOQUOTES, 'UTF-8');
81 2
		}, $sql);
82
83 2
		return '<pre class="dump">' . trim($sql) . "</pre>\n";
84
	}
85
86
}
87