Skip to content

Commit 65918d0

Browse files
authored
Merge pull request #968 from cakephp/4.next
merge 4.next => 4.x
2 parents 4ffcdd2 + 92cbfa9 commit 65918d0

File tree

7 files changed

+141
-54
lines changed

7 files changed

+141
-54
lines changed

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
},
2525
"require": {
2626
"php": ">=7.4",
27-
"cakephp/cakephp": "^4.4.0",
27+
"cakephp/cakephp": "^4.5.0",
2828
"cakephp/chronos": "^2.0",
2929
"composer/composer": "^1.3 | ^2.0",
30-
"jdorn/sql-formatter": "^1.2"
30+
"doctrine/sql-formatter": "^1.1.3"
3131
},
3232
"require-dev": {
3333
"cakephp/cakephp-codesniffer": "^4.0",

src/DebugSql.php

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
use Cake\Core\Configure;
1919
use Cake\Database\Query;
2020
use Cake\Error\Debugger;
21-
use SqlFormatter;
21+
use Doctrine\SqlFormatter\CliHighlighter;
22+
use Doctrine\SqlFormatter\HtmlHighlighter;
23+
use Doctrine\SqlFormatter\NullHighlighter;
24+
use Doctrine\SqlFormatter\SqlFormatter;
2225

2326
/**
2427
* Contains methods for dumping well formatted SQL queries.
@@ -77,7 +80,7 @@ public static function sql(Query $query, $showValues = true, $showHtml = null, $
7780
}
7881

7982
/** @var array $trace */
80-
$trace = Debugger::trace(['start' => 1, 'depth' => $stackDepth + 2, 'format' => 'array']);
83+
$trace = Debugger::trace(['start' => 0, 'depth' => $stackDepth + 2, 'format' => 'array']);
8184
$file = isset($trace[$stackDepth]) ? $trace[$stackDepth]['file'] : 'n/a';
8285
$line = isset($trace[$stackDepth]) ? $trace[$stackDepth]['line'] : 0;
8386
$lineInfo = '';
@@ -93,10 +96,8 @@ public static function sql(Query $query, $showValues = true, $showHtml = null, $
9396
}
9497

9598
$template = self::$templateHtml;
96-
$sqlHighlight = true;
97-
if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') || $showHtml === false) {
99+
if (static::isCli() || $showHtml === false) {
98100
$template = self::$templateText;
99-
$sqlHighlight = false;
100101
if ($file && $line) {
101102
$lineInfo = sprintf('%s (line %s)', $file, $line);
102103
}
@@ -105,12 +106,29 @@ public static function sql(Query $query, $showValues = true, $showHtml = null, $
105106
$showHtml = true;
106107
}
107108

108-
$var = $showHtml ? SqlFormatter::format($sql, $sqlHighlight) : $sql;
109-
$var = str_replace(
110-
'<span >:</span> <span style="color: #333;">',
111-
'<span >:</span><span style="color: #333;">',
112-
$var
113-
);
109+
if (static::isCli() && !$showHtml) {
110+
$highlighter = new CliHighlighter([
111+
CliHighlighter::HIGHLIGHT_QUOTE => "\x1b[33;1m",
112+
CliHighlighter::HIGHLIGHT_WORD => "\x1b[36;1m",
113+
CliHighlighter::HIGHLIGHT_VARIABLE => "\x1b[33;1m",
114+
]);
115+
} elseif ($showHtml) {
116+
$highlighter = new HtmlHighlighter(
117+
[
118+
HtmlHighlighter::HIGHLIGHT_QUOTE => 'style="color: #004d40;"',
119+
HtmlHighlighter::HIGHLIGHT_BACKTICK_QUOTE => 'style="color: #26a69a;"',
120+
HtmlHighlighter::HIGHLIGHT_NUMBER => 'style="color: #ec407a;"',
121+
HtmlHighlighter::HIGHLIGHT_WORD => 'style="color: #9c27b0;"',
122+
HtmlHighlighter::HIGHLIGHT_PRE => 'style="color: #222; background-color: transparent;"',
123+
],
124+
false
125+
);
126+
} else {
127+
$highlighter = new NullHighlighter();
128+
}
129+
130+
$var = (new SqlFormatter($highlighter))->format($sql);
131+
$var = trim($var);
114132

115133
if ($showHtml) {
116134
$template = self::$templateHtml;
@@ -143,6 +161,16 @@ public static function sqld(Query $query, $showValues = true, $showHtml = null,
143161
die(1);
144162
}
145163

164+
/**
165+
* Checks whether the current environment is CLI based.
166+
*
167+
* @return bool
168+
*/
169+
protected static function isCli()
170+
{
171+
return PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg';
172+
}
173+
146174
/**
147175
* Helper function used to replace query placeholders by the real
148176
* params used to execute the query.

src/Model/Table/RequestsTable.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,12 @@ public function gc()
118118
return;
119119
}
120120

121-
$query = $this->Panels->query()
122-
->delete()
121+
$query = $this->Panels->deleteQuery()
123122
->where(['request_id NOT IN' => $noPurge]);
124123
$statement = $query->execute();
125124
$statement->closeCursor();
126125

127-
$query = $this->query()
128-
->delete()
126+
$query = $this->deleteQuery()
129127
->where(['id NOT IN' => $noPurge]);
130128

131129
$statement = $query->execute();

templates/element/sql_log_panel.php

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,11 @@
2121
* @var array $tables
2222
* @var \DebugKit\Database\Log\DebugLog[] $loggers
2323
*/
24-
$noOutput = true;
2524

26-
// Configure sqlformatter colours.
27-
SqlFormatter::$quote_attributes = 'style="color: #004d40;"';
28-
SqlFormatter::$backtick_quote_attributes = 'style="color: #26a69a;"';
29-
SqlFormatter::$number_attributes = 'style="color: #ec407a;"';
30-
SqlFormatter::$word_attributes = 'style="color: #9c27b0;"';
31-
SqlFormatter::$pre_attributes = 'style="color: #222; background-color: transparent;"';
25+
use Doctrine\SqlFormatter\HtmlHighlighter;
26+
use Doctrine\SqlFormatter\SqlFormatter;
27+
28+
$noOutput = true;
3229
?>
3330

3431
<div class="c-sql-log-panel">
@@ -77,7 +74,20 @@
7774
<tbody>
7875
<?php foreach ($queries as $query) : ?>
7976
<tr>
80-
<td><?= SqlFormatter::format($query['query']) ?></td>
77+
<td>
78+
<?=
79+
(new SqlFormatter(
80+
new HtmlHighlighter([
81+
HtmlHighlighter::HIGHLIGHT_QUOTE => 'style="color: #004d40;"',
82+
HtmlHighlighter::HIGHLIGHT_BACKTICK_QUOTE => 'style="color: #26a69a;"',
83+
HtmlHighlighter::HIGHLIGHT_NUMBER => 'style="color: #ec407a;"',
84+
HtmlHighlighter::HIGHLIGHT_WORD => 'style="color: #9c27b0;"',
85+
HtmlHighlighter::HIGHLIGHT_PRE => 'style="color: #222; background-color: transparent;"',
86+
])
87+
))
88+
->format($query['query'])
89+
?>
90+
</td>
8191
<td><?= h($query['rows']) ?></td>
8292
<td><?= h($query['took']) ?></td>
8393
</tr>

tests/TestCase/DebugSqlTest.php

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
*/
1515
namespace DebugKit\Test\TestCase;
1616

17-
use Cake\Database\Driver\Postgres;
1817
use Cake\Datasource\ConnectionManager;
1918
use Cake\TestSuite\TestCase;
2019
use DebugKit\DebugSql;
20+
use DebugKit\TestApp\Stub\DebugSqlStub;
2121

2222
/**
2323
* Test the debugging SQL
@@ -41,62 +41,100 @@ public function setUp(): void
4141
}
4242

4343
/**
44-
* Tests that a SQL string is outputted as text on the CLI.
44+
* Tests that a SQL string is outputted in a formatted and
45+
* highlighted fashion in a CLI environment.
4546
*/
46-
public function testSqlText()
47+
public function testSqlCli()
4748
{
4849
$query = $this->newQuery()->select(['panels.id']);
4950

5051
ob_start();
5152
$this->assertSame($query, DebugSql::sql($query));
5253
$result = ob_get_clean();
5354

54-
$expectedText = <<<EXPECTED
55+
$expected = <<<EXPECTED
5556
%s (line %d)
5657
########## DEBUG ##########
57-
SELECT panels.id AS %s FROM panels panels
58-
###########################
59-
58+
SELECT
6059
EXPECTED;
61-
$fieldName = $this->connection->getDriver() instanceof Postgres ? '"panels__id"' : 'panels__id';
62-
$expected = sprintf($expectedText, str_replace(ROOT, '', __FILE__), __LINE__ - 11, $fieldName);
63-
$this->assertSame($expected, $result);
60+
$expected = sprintf($expected, str_replace(ROOT, '', __FILE__), __LINE__ - 8);
61+
$this->assertTextContains($expected, $result);
6462
}
6563

6664
/**
67-
* Tests that a SQL string is outputted as HTML.
65+
* Tests that a SQL string is outputted as HTML in a CLI
66+
* environment.
6867
*/
69-
public function testSqlHtml()
68+
public function testSqlHtmlOnCli()
7069
{
7170
$query = $this->newQuery()->select(['panels.id']);
7271

7372
ob_start();
7473
$this->assertSame($query, DebugSql::sql($query, true, true));
74+
$result = strip_tags(ob_get_clean());
75+
$result = preg_replace("/[\n\r]/", '', $result);
76+
77+
$this->assertStringContainsString(sprintf('%s (line %s)', str_replace(ROOT, '', __FILE__), __LINE__ - 4), $result);
78+
$this->assertStringContainsString('SELECT panels.id AS', $result);
79+
$this->assertStringContainsString('panels__id', $result);
80+
$this->assertStringContainsString('FROM panels panels', $result);
81+
}
82+
83+
/**
84+
* Tests that a SQL string is outputted as HTML in a non-CLI
85+
* environment.
86+
*/
87+
public function testSqlHtml()
88+
{
89+
$query = $this->newQuery()->select(['panels.id']);
90+
91+
ob_start();
92+
DebugSqlStub::$isCli = false;
93+
$this->assertSame($query, DebugSqlStub::sql($query, true, true));
94+
DebugSqlStub::$isCli = true;
7595
$result = ob_get_clean();
7696

77-
$expectedHtml = <<<EXPECTED
97+
$expected = <<<EXPECTED
7898
<div class="cake-debug-output">
7999
<span><strong>%s</strong> (line <strong>%d</strong>)</span>
80100
<pre class="cake-debug">
81-
SELECT
82-
panels.id AS %s
83-
FROM
84-
panels panels
85-
</pre>
86-
</div>
101+
<span style="font-weight:bold;">SELECT</span>
87102
EXPECTED;
88-
$fieldName = $this->connection->getDriver() instanceof Postgres ? '"panels__id"' : 'panels__id';
89-
$expected = sprintf($expectedHtml, str_replace(ROOT, '', __FILE__), __LINE__ - 15, $fieldName);
90-
$this->assertSame(str_replace("\r", '', $expected), str_replace("\r", '', $result));
103+
$expected = sprintf($expected, str_replace(ROOT, '', __FILE__), __LINE__ - 10);
104+
$this->assertTextContains(str_replace("\r", '', $expected), str_replace("\r", '', $result));
105+
}
106+
107+
/**
108+
* Tests that a SQL string is outputted as plain text in a non-CLI
109+
* environment.
110+
*/
111+
public function testSqlPlain()
112+
{
113+
$query = $this->newQuery()->select(['panels.id']);
114+
115+
ob_start();
116+
DebugSqlStub::$isCli = false;
117+
$this->assertSame($query, DebugSqlStub::sql($query, true, false));
118+
DebugSqlStub::$isCli = true;
119+
$result = ob_get_clean();
120+
121+
$expectedHtml = <<<EXPECTED
122+
%s (line %s)
123+
########## DEBUG ##########
124+
SELECT
125+
EXPECTED;
126+
127+
$expected = sprintf($expectedHtml, str_replace(ROOT, '', __FILE__), __LINE__ - 10);
128+
$this->assertTextContains(str_replace("\r", '', $expected), str_replace("\r", '', $result));
91129
}
92130

93131
/**
94132
* Creates a Query object for testing.
95133
*
96-
* @return Query
134+
* @return \Cake\ORM\Query
97135
*/
98136
private function newQuery()
99137
{
100-
return $this->getTableLocator()->get('panels')->query();
138+
return $this->getTableLocator()->get('panels')->selectQuery();
101139
}
102140
}

tests/TestCase/Panel/VariablesPanelTest.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,8 @@ public function testShutdown()
6262
$requests = $this->getTableLocator()->get('Requests');
6363
$query = $requests->find('all');
6464
$result = $requests->find()->all();
65-
$unbufferedQuery = $requests->find('all')->enableBufferedResults(false);
66-
$unbufferedQuery->toArray(); //toArray call would normally happen somewhere in View, usually implicitly
67-
$update = $requests->query()->update();
68-
$debugInfoException = $requests->query()->contain('NonExistentAssociation');
65+
$update = $requests->updateQuery();
66+
$debugInfoException = $requests->selectQuery()->contain('NonExistentAssociation');
6967

7068
$unserializable = new \stdClass();
7169
$unserializable->pdo = $requests->getConnection()->getDriver()->getConnection();
@@ -89,7 +87,6 @@ public function testShutdown()
8987
'debugInfoException' => $debugInfoException,
9088
'updateQuery' => $update,
9189
'query' => $query,
92-
'unbufferedQuery' => $unbufferedQuery,
9390
'result set' => $result,
9491
'string' => 'yes',
9592
'array' => ['some' => 'key'],

tests/test_app/Stub/DebugSqlStub.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace DebugKit\TestApp\Stub;
5+
6+
use DebugKit\DebugSql;
7+
8+
class DebugSqlStub extends DebugSql
9+
{
10+
public static $isCli = true;
11+
12+
protected static function isCli()
13+
{
14+
return static::$isCli;
15+
}
16+
}

0 commit comments

Comments
 (0)