Skip to content

Commit 11e9d80

Browse files
committed
Merge branch '4.next' into 4.x
2 parents a13bbd6 + 2f944f9 commit 11e9d80

5 files changed

Lines changed: 61 additions & 57 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ jobs:
1717
strategy:
1818
fail-fast: false
1919
matrix:
20-
php-version: ['7.2', '8.0']
20+
php-version: ['7.4', '8.0']
2121
db-type: [mysql, pgsql, sqlite]
2222
prefer-lowest: ['']
2323
include:
2424
- php-version: '8.1'
2525
db-type: 'sqlite'
26-
- php-version: '7.2'
26+
- php-version: '7.4'
2727
db-type: 'sqlite'
2828
prefer-lowest: 'prefer-lowest'
2929

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
},
2525
"require": {
2626
"php": ">=7.2",
27-
"cakephp/cakephp": "^4.3.0",
27+
"cakephp/cakephp": "dev-4.next as 4.4.0",
2828
"cakephp/chronos": "^2.0",
2929
"composer/composer": "^1.3 | ^2.0",
3030
"jdorn/sql-formatter": "^1.2"

src/Panel/DeprecationsPanel.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,6 @@ protected function _prepare()
5959
foreach ($errors as $error) {
6060
$file = $error['file'];
6161
$line = $error['line'];
62-
if (isset($error['context']['frame'])) {
63-
$file = $error['context']['frame']['file'];
64-
$line = $error['context']['frame']['line'];
65-
}
6662

6763
$errorData = [
6864
'file' => $file,

src/Plugin.php

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
use Cake\Core\BasePlugin;
2020
use Cake\Core\Configure;
2121
use Cake\Core\PluginApplicationInterface;
22+
use Cake\Error\PhpError;
23+
use Cake\Event\EventInterface;
2224
use Cake\Event\EventManager;
2325
use Cake\Http\MiddlewareQueue;
2426
use DebugKit\Command\BenchmarkCommand;
@@ -50,7 +52,6 @@ public function bootstrap(PluginApplicationInterface $app): void
5052
}
5153

5254
$this->service = $service;
53-
5455
$this->setDeprecationHandler($service);
5556

5657
// will load `config/bootstrap.php`.
@@ -90,40 +91,30 @@ public function console(CommandCollection $commands): CommandCollection
9091
public function setDeprecationHandler($service)
9192
{
9293
if (!empty($service->getConfig('panels')['DebugKit.Deprecations'])) {
93-
$previousHandler = set_error_handler(
94-
function ($code, $message, $file, $line, $context = null) use (&$previousHandler) {
95-
if ($code == E_USER_DEPRECATED || $code == E_DEPRECATED) {
96-
// In PHP 8.0+ the $context variable has been removed from the set_error_handler callback
97-
// Therefore we need to fetch the correct file and line string ourselves
98-
if (PHP_VERSION_ID >= 80000) {
99-
$trace = debug_backtrace();
100-
foreach ($trace as $idx => $traceEntry) {
101-
if ($traceEntry['function'] !== 'deprecationWarning') {
102-
continue;
103-
}
104-
$offset = 1;
105-
// ['args'][1] refers to index of $stackFrame argument in deprecationWarning()
106-
if (isset($traceEntry['args'][1])) {
107-
$offset = $traceEntry['args'][1];
108-
}
109-
$file = $trace[$idx + $offset]['file'];
110-
$line = $trace[$idx + $offset]['line'];
111-
break;
112-
}
113-
}
114-
DeprecationsPanel::addDeprecatedError(compact('code', 'message', 'file', 'line', 'context'));
115-
116-
return;
117-
}
118-
if ($previousHandler) {
119-
$context['_trace_frame_offset'] = 1;
120-
121-
return $previousHandler($code, $message, $file, $line, $context);
122-
}
94+
EventManager::instance()->on('Error.beforeRender', function (EventInterface $event, PhpError $error) {
95+
$code = $error->getCode();
96+
if ($code !== E_USER_DEPRECATED && $code !== E_DEPRECATED) {
97+
return;
98+
}
99+
$file = $error->getFile();
100+
$line = $error->getLine();
123101

124-
return false;
102+
// Extract the line/file from the message as deprecationWarning
103+
// will calculate the application frame when generating the message.
104+
preg_match('/\\n([^\n,]+?), line: (\d+)\\n/', $error->getMessage(), $matches);
105+
if ($matches) {
106+
$file = $matches[1];
107+
$line = $matches[2];
125108
}
126-
);
109+
110+
DeprecationsPanel::addDeprecatedError([
111+
'code' => $code,
112+
'message' => $error->getMessage(),
113+
'file' => $file,
114+
'line' => $line,
115+
]);
116+
$event->stopPropagation();
117+
});
127118
}
128119
}
129120
}

tests/TestCase/PluginTest.php

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515
namespace DebugKit\Test\TestCase;
1616

17+
use Cake\Error\PhpError;
1718
use Cake\Event\Event;
1819
use Cake\Event\EventManager;
1920
use Cake\TestSuite\TestCase;
@@ -37,28 +38,44 @@ public function testSetDeprecationHandler()
3738
$service = new ToolbarService(new EventManager(), []);
3839
$plugin = new Plugin();
3940
$plugin->setDeprecationHandler($service);
40-
$event = new Event('');
4141
$panel = new DeprecationsPanel();
4242

43-
//Without setting the $stackFrame
44-
deprecationWarning('setDeprecationHandler');
45-
//Setting the $stackFrame
46-
deprecationWarning('setDeprecationHandler_2', 2);
47-
//Raw error
48-
$line = __LINE__ + 1;
49-
trigger_error('raw_error', E_USER_DEPRECATED);
43+
$error = new PhpError(E_USER_WARNING, 'ignored', __FILE__, __LINE__, []);
44+
$event = new Event('Error.beforeRender', null, ['error' => $error]);
45+
EventManager::instance()->dispatch($event);
46+
47+
// No file/line in message.
48+
$error = new PhpError(E_USER_DEPRECATED, 'going away', __FILE__, __LINE__, []);
49+
$event = new Event('Error.beforeRender', null, ['error' => $error]);
50+
EventManager::instance()->dispatch($event);
51+
52+
// Formatted like deprecationWarning()
53+
$message = <<<TEXT
54+
Something deprecated happened.
55+
Don't use that thing.
56+
src/Plugin.php, line: 51
57+
You can disable all deprecation warnings by setting `Error.errorLevel` to `E_ALL & ~E_USER_DEPRECATED`.
58+
TEXT;
59+
$error = new PhpError(E_USER_DEPRECATED, $message, __FILE__, __LINE__, []);
60+
$event = new Event('Error.beforeRender', null, ['error' => $error]);
61+
EventManager::instance()->dispatch($event);
5062

5163
$panel->shutdown($event);
52-
$data = $panel->data()['plugins']['DebugKit'];
64+
$data = $panel->data();
65+
66+
$this->assertArrayHasKey('plugins', $data);
67+
$this->assertArrayHasKey('DebugKit', $data['plugins']);
68+
$this->assertCount(1, $data['plugins']['DebugKit']);
5369

54-
$this->assertCount(3, $data);
70+
$first = $data['plugins']['DebugKit'][0];
71+
$this->assertEquals($first['message'], 'going away');
72+
$this->assertEquals($first['file'], __FILE__);
73+
$this->assertEquals($first['line'], 48);
5574

56-
//test first two deprecationWarning()
57-
foreach ([$data[0], $data[1]] as $value) {
58-
$this->assertStringContainsString($value['file'], $value['message']);
59-
$this->assertStringContainsString("line: {$value['line']}", $value['message']);
60-
}
61-
//test raw error
62-
$this->assertSame($line, $data[2]['line']);
75+
$this->assertArrayHasKey('other', $data);
76+
$parsed = $data['other'][0];
77+
$this->assertEquals($parsed['message'], $message);
78+
$this->assertEquals($parsed['file'], 'src/Plugin.php');
79+
$this->assertEquals($parsed['line'], 51);
6380
}
6481
}

0 commit comments

Comments
 (0)