diff --git a/admin/css/debug-toolbar/toolbar.scss b/admin/css/debug-toolbar/toolbar.scss index d9bc347c4b3b..23e0807fabfc 100644 --- a/admin/css/debug-toolbar/toolbar.scss +++ b/admin/css/debug-toolbar/toolbar.scss @@ -474,8 +474,8 @@ width: 70px; } -.debug-bar-width140p { - width: 140px; +.debug-bar-width190p { + width: 190px; } .debug-bar-width20e { diff --git a/system/Debug/Toolbar.php b/system/Debug/Toolbar.php index 72328e6c334f..c74b303d1476 100644 --- a/system/Debug/Toolbar.php +++ b/system/Debug/Toolbar.php @@ -378,8 +378,8 @@ public function prepare(?RequestInterface $request = null, ?ResponseInterface $r helper('filesystem'); - // Updated to time() so we can get history - $time = time(); + // Updated to microtime() so we can get history + $time = sprintf('%.6f', microtime(true)); if (! is_dir(WRITEPATH . 'debugbar')) { mkdir(WRITEPATH . 'debugbar', 0777); @@ -485,10 +485,10 @@ protected function format(string $data, string $format = 'html'): string { $data = json_decode($data, true); - if ($this->config->maxHistory !== 0) { + if ($this->config->maxHistory !== 0 && preg_match('/\d+\.\d{6}/s', (string) Services::request()->getGet('debugbar_time'), $debugbarTime)) { $history = new History(); $history->setFiles( - (int) Services::request()->getGet('debugbar_time'), + $debugbarTime[0], $this->config->maxHistory ); diff --git a/system/Debug/Toolbar/Collectors/History.php b/system/Debug/Toolbar/Collectors/History.php index 3c0f4268f65e..afc68ee85f2e 100644 --- a/system/Debug/Toolbar/Collectors/History.php +++ b/system/Debug/Toolbar/Collectors/History.php @@ -11,6 +11,8 @@ namespace CodeIgniter\Debug\Toolbar\Collectors; +use DateTime; + /** * History collector */ @@ -56,10 +58,10 @@ class History extends BaseCollector /** * Specify time limit & file count for debug history. * - * @param int $current Current history time - * @param int $limit Max history files + * @param string $current Current history time + * @param int $limit Max history files */ - public function setFiles(int $current, int $limit = 20) + public function setFiles(string $current, int $limit = 20) { $filenames = glob(WRITEPATH . 'debugbar/debugbar_*.json'); @@ -81,13 +83,13 @@ public function setFiles(int $current, int $limit = 20) $contents = @json_decode($contents); if (json_last_error() === JSON_ERROR_NONE) { - preg_match_all('/\d+/', $filename, $time); - $time = (int) end($time[0]); + preg_match('/debugbar_(.*)\.json$/s', $filename, $time); + $time = sprintf('%.6f', $time[1] ?? 0); // Debugbar files shown in History Collector $files[] = [ 'time' => $time, - 'datetime' => date('Y-m-d H:i:s', $time), + 'datetime' => DateTime::createFromFormat('U.u', $time)->format('Y-m-d H:i:s.u'), 'active' => $time === $current, 'status' => $contents->vars->response->statusCode, 'method' => $contents->method, diff --git a/system/Debug/Toolbar/Views/_history.tpl b/system/Debug/Toolbar/Views/_history.tpl index 9db00ecc4679..5763ff4d167f 100644 --- a/system/Debug/Toolbar/Views/_history.tpl +++ b/system/Debug/Toolbar/Views/_history.tpl @@ -16,7 +16,7 @@ - {datetime} + {datetime} {status} {method} {url} diff --git a/system/Debug/Toolbar/Views/toolbar.css b/system/Debug/Toolbar/Views/toolbar.css index 8fb9c15737c5..11a3301a954c 100644 --- a/system/Debug/Toolbar/Views/toolbar.css +++ b/system/Debug/Toolbar/Views/toolbar.css @@ -773,8 +773,8 @@ width: 70px; } -.debug-bar-width140p { - width: 140px; +.debug-bar-width190p { + width: 190px; } .debug-bar-width20e { diff --git a/tests/system/Debug/Toolbar/Collectors/HistoryTest.php b/tests/system/Debug/Toolbar/Collectors/HistoryTest.php new file mode 100644 index 000000000000..bcd3da49d541 --- /dev/null +++ b/tests/system/Debug/Toolbar/Collectors/HistoryTest.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Debug\Toolbar\Collectors; + +use CodeIgniter\Test\CIUnitTestCase; +use DateTime; + +/** + * @internal + */ +final class HistoryTest extends CIUnitTestCase +{ + private const STEP = 0.0001; + + private float $time; + + protected function setUp(): void + { + parent::setUp(); + $this->time = (float) sprintf('%.4f', microtime(true)); + } + + private function createDummyDebugbarJson() + { + $time = $this->time; + $path = WRITEPATH . 'debugbar' . DIRECTORY_SEPARATOR . "debugbar_{$time}.json"; + + $dummyData = [ + 'vars' => [ + 'response' => [ + 'statusCode' => 200, + 'contentType' => 'text/html; charset=UTF-8', + ], + ], + 'method' => 'get', + 'url' => 'localhost', + 'isAJAX' => false, + ]; + // create 20 dummy debugbar json files + for ($i = 0; $i < 20; $i++) { + $path = str_replace($time, sprintf('%.4f', $time - self::STEP), $path); + file_put_contents($path, json_encode($dummyData)); + $time = sprintf('%.4f', $time - self::STEP); + } + } + + protected function tearDown(): void + { + command('debugbar:clear'); + } + + public function testSetFiles() + { + $time = $this->time; + // test dir is now populated with json + $this->createDummyDebugbarJson(); + + $activeRowTime = $time = sprintf('%.4f', $time - self::STEP); + + $history = new History(); + $history->setFiles($time, 20); + $this->assertArrayHasKey('files', $history->display()); + $this->assertNotEmpty($history->display()['files'], 'Dummy Debugbar data is empty'); + + foreach ($history->display()['files'] as $request) { + $this->assertSame($request['time'], sprintf('%.4f', $time)); + $this->assertSame($request['datetime'], DateTime::createFromFormat('U.u', $time)->format('Y-m-d H:i:s.u')); + $this->assertSame($request['active'], ($time === $activeRowTime)); + + $time = sprintf('%.4f', $time - self::STEP); + } + } +} diff --git a/user_guide_src/source/changelogs/v4.2.0.rst b/user_guide_src/source/changelogs/v4.2.0.rst index f22ddae1aa17..099fac31a2b0 100644 --- a/user_guide_src/source/changelogs/v4.2.0.rst +++ b/user_guide_src/source/changelogs/v4.2.0.rst @@ -13,6 +13,7 @@ BREAKING ******** - The method signature of ``Validation::setRule()`` has been changed. The ``string`` typehint on the ``$rules`` parameter was removed. Extending classes should likewise remove the parameter so as not to break LSP. +- There is a possible backward compatibility break for those users extending the History Collector and they should probably update ``History::setFiles()`` method. Enhancements ************ @@ -30,6 +31,8 @@ Enhancements - The ``spark routes`` command now shows closure routes, auto routes, and filters. See :ref:`URI Routing `. - Exception information logged through ``log_message()`` has now improved. It now includes the file and line where the exception originated. It also does not truncate the message anymore. - The log format has also changed. If users are depending on the log format in their apps, the new log format is "<1-based count> (): " +- Debugbar enhancements + - Debug toolbar is now using ``microtime()`` instead of ``time()``. Changes *******