From 0bb09ff5e29d87e7e8dceab07bb05c1ce461e4c5 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Fri, 7 Feb 2025 06:59:53 +0100 Subject: [PATCH 01/18] uses @nette/eslint-plugin --- eslint.config.js | 47 ++++++++++--------------------------- package.json | 10 ++++---- src/Tracy/Bar/assets/bar.js | 6 ++--- 3 files changed, 20 insertions(+), 43 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 228a52673..13e699e08 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,40 +1,19 @@ -import globals from 'globals'; -import pluginJs from '@eslint/js'; -import stylistic from '@stylistic/eslint-plugin'; +import nette from '@nette/eslint-plugin'; +import { defineConfig } from 'eslint/config'; -export default [ +export default defineConfig([ { - ignores: ['*/', '!src/'], + ignores: [ + 'vendor', 'tests', 'x', + ], }, - pluginJs.configs.recommended, - - stylistic.configs.customize({ - indent: 'tab', - braceStyle: '1tbs', - arrowParens: true, - semi: true, - jsx: false, - }), - { - languageOptions: { - ecmaVersion: 'latest', - globals: globals.browser, - }, - plugins: { - '@stylistic': stylistic, - }, - rules: { - '@stylistic/no-multiple-empty-lines': ['error', { max: 2, maxEOF: 0 }], - '@stylistic/new-parens': ['error', 'never'], - '@stylistic/padded-blocks': 'off', - 'func-style': ['error', 'declaration', { allowArrowFunctions: true }], - 'prefer-arrow-callback': 'error', - 'arrow-body-style': 'error', - 'eqeqeq': ['error', 'always', { null: 'ignore' }], - 'no-var': 'error', - 'prefer-const': 'off', - }, + files: [ + '*.js', + 'src/**/*.js', + ], + + extends: [nette.configs.recommended], }, -]; +]); diff --git a/package.json b/package.json index 0c8092127..038505b4b 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,11 @@ { "type": "module", "devDependencies": { - "@eslint/js": "^9.4.0", - "@stylistic/eslint-plugin": "^2.1.0", - "eslint": "^9.4.0", - "globals": "^15.3.0" + "@nette/eslint-plugin": "^0.2", + "eslint": "^9.26.0" }, "scripts": { - "lint": "eslint", - "lint:fix": "eslint --fix" + "lint": "eslint --cache", + "lint:fix": "eslint --cache --fix" } } diff --git a/src/Tracy/Bar/assets/bar.js b/src/Tracy/Bar/assets/bar.js index 403757350..56f237958 100644 --- a/src/Tracy/Bar/assets/bar.js +++ b/src/Tracy/Bar/assets/bar.js @@ -157,9 +157,9 @@ class Panel { let meta = this.elem.parentElement.lastElementChild; doc.body.innerHTML = '' - + '
' + this.elem.tracyContent + '
' - + meta.outerHTML - + '
'; + + '
' + this.elem.tracyContent + '
' + + meta.outerHTML + + ''; evalScripts(doc.body); if (this.elem.querySelector('h1')) { doc.title = this.elem.querySelector('h1').textContent; From 6ca296e418da39928bca854ae3b0134d85a42427 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Thu, 19 Jun 2025 04:00:15 +0200 Subject: [PATCH 02/18] tests: fixed compatibility --- tests/Tracy/Dumper.toText().specials.dom.php84.phpt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/Tracy/Dumper.toText().specials.dom.php84.phpt b/tests/Tracy/Dumper.toText().specials.dom.php84.phpt index 2df18400d..c0c19a59d 100644 --- a/tests/Tracy/Dumper.toText().specials.dom.php84.phpt +++ b/tests/Tracy/Dumper.toText().specials.dom.php84.phpt @@ -28,11 +28,6 @@ Assert::match( baseURI: 'about:blank' %A% doctype: Dom\DocumentType #%d% - | attributes: null - | baseURI: 'about:blank' - | childNodes: %a% - | entities: Dom\DtdNamedNodeMap #%d% ... - | firstChild: null %A% documentElement: Dom\Element #%d% %A% @@ -58,7 +53,6 @@ Assert::match( length: 1 items: array (1) | 'class' => Dom\Attr #%d% - | | attributes: null %A% XX, Dumper::toText($namedNodeMap, [Dumper::DEPTH => 3]), @@ -70,7 +64,7 @@ Assert::match( Dom\HTMLCollection #%d% length: 1 items: array (1) - | 'li' => Dom\Element #%d% ... + | %a% => Dom\Element #%d% ... XX, Dumper::toText($collection, [Dumper::DEPTH => 2]), ); From 1d951b0f9d3b864538cef713e54e983c1332acde Mon Sep 17 00:00:00 2001 From: schlndh Date: Thu, 19 Jun 2025 03:47:40 +0200 Subject: [PATCH 03/18] BlueScreen: fixed PHP 8.4 exception in generator [Closes: #595] (#596) --- src/Tracy/BlueScreen/BlueScreen.php | 7 +- .../Debugger.exception.in-generator.html.phpt | 37 ++++++ ...ebugger.exception.in-generator.html.expect | 119 ++++++++++++++++++ 3 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 tests/Tracy/Debugger.exception.in-generator.html.phpt create mode 100644 tests/Tracy/expected/Debugger.exception.in-generator.html.expect diff --git a/src/Tracy/BlueScreen/BlueScreen.php b/src/Tracy/BlueScreen/BlueScreen.php index acdae1e4a..cc1c51a4a 100644 --- a/src/Tracy/BlueScreen/BlueScreen.php +++ b/src/Tracy/BlueScreen/BlueScreen.php @@ -483,7 +483,12 @@ private function findGeneratorsAndFibers(object $object): array $add = function ($obj) use (&$generators, &$fibers) { if ($obj instanceof \Generator) { try { - new \ReflectionGenerator($obj); + $ref = new \ReflectionGenerator($obj); + // Before PHP 8.4 the ReflectionGenerator cannot be constructed from closed generator. + // Since PHP 8.4 it can, but getTrace throws ReflectionException. + if (PHP_VERSION_ID >= 80400 && $ref->isClosed()) { + return; + } $generators[spl_object_id($obj)] = $obj; } catch (\ReflectionException) { } diff --git a/tests/Tracy/Debugger.exception.in-generator.html.phpt b/tests/Tracy/Debugger.exception.in-generator.html.phpt new file mode 100644 index 000000000..9f1816a28 --- /dev/null +++ b/tests/Tracy/Debugger.exception.in-generator.html.phpt @@ -0,0 +1,37 @@ +

+ + + + + + + Exception: The my exception #123 + + + + %A% + + + + + +  +
+
+

Exception #123

+ +

The my exception + search► +

+ +
+ + + +
+ + +
+

File: %a%Debugger.exception.in-generator.html.phpt:%d%

+
%d%: +%d%: +%d%: Debugger::$productionMode = false; +%d%: setHtmlMode(); +%d%: +%d%: Debugger::enable(); +%d%: +%d%: +%d%: $generator = (function (): iterable { +%d%: yield 5; +%d%: throw new Exception('The my exception', 123); +%d%: })(); +%d%: $fn = function ($generator) { +%d%: foreach ($generator as $value) { +%d%: } +
+
+
+ +
+ + +
+
+ + + + + +
+
%d%: setHtmlMode(); +%d%: +%d%: Debugger::enable(); +%d%: +%d%: +%d%: $generator = (function (): iterable { +%d%: yield 5; +%d%: throw new Exception('The my exception', 123); +%d%: })(); +%d%: $fn = function ($generator) { +%d%: foreach ($generator as $value) { +%d%: } +%d%: }; +%d%: +%d%: $fn($generator); +
+ +
+ + + + + +
+
%d%: +%d%: $generator = (function (): iterable { +%d%: yield 5; +%d%: throw new Exception('The my exception', 123); +%d%: })(); +%d%: $fn = function ($generator) { +%d%: foreach ($generator as $value) { +%d%: } +%d%: }; +%d%: +%d%: $fn($generator); +
+ + + +
#0

+
+
+
+
+
+%A% From edaa7493e6a6092cb85d6599423ba75d6522077f Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 2 Aug 2025 04:00:13 +0200 Subject: [PATCH 04/18] opened 2.11-dev --- composer.json | 2 +- src/Tracy/Debugger/Debugger.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 4d974c5e7..b26c69271 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ }, "extra": { "branch-alias": { - "dev-master": "2.10-dev" + "dev-master": "2.11-dev" } } } diff --git a/src/Tracy/Debugger/Debugger.php b/src/Tracy/Debugger/Debugger.php index 0b608cbe3..e9ad04c90 100644 --- a/src/Tracy/Debugger/Debugger.php +++ b/src/Tracy/Debugger/Debugger.php @@ -17,7 +17,7 @@ */ class Debugger { - public const Version = '2.10.10'; + public const Version = '2.11.0'; /** server modes for Debugger::enable() */ public const From bdca3b0152d4e6b95dd5cdd090d49d6dc89ae5be Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 2 Aug 2025 04:01:14 +0200 Subject: [PATCH 05/18] requires PHP 8.1 --- .github/workflows/static-analysis.yml | 2 +- .github/workflows/tests.yml | 4 ++-- composer.json | 2 +- readme.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 1b855cdb7..396244b28 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: - php-version: 8.0 + php-version: 8.1 coverage: none - run: composer install --no-progress --prefer-dist diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 71bbf0ccf..9251d57c6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - php: ['8.0', '8.1', '8.2', '8.3', '8.4'] + php: ['8.1', '8.2', '8.3', '8.4'] sapi: ['php', 'php-cgi'] fail-fast: false @@ -41,7 +41,7 @@ jobs: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: - php-version: 8.0 + php-version: 8.1 extensions: ds coverage: none diff --git a/composer.json b/composer.json index b26c69271..e7bdd674f 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "php": "8.0 - 8.4", + "php": "8.1 - 8.4", "ext-session": "*", "ext-json": "*" }, diff --git a/readme.md b/readme.md index bacf2aee9..96e87069d 100644 --- a/readme.md +++ b/readme.md @@ -48,7 +48,7 @@ composer require tracy/tracy Alternatively, you can download the whole package or [tracy.phar](https://github.com/nette/tracy/releases) file. -Tracy is compatible with PHP 8.0 to 8.4. +Tracy is compatible with PHP 8.1 to 8.4.   From 7a3cf951cc1f6a4e7272f7e7be2d9a8693ceba75 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Tue, 11 Jun 2024 14:38:20 +0200 Subject: [PATCH 06/18] uses PHP 8.1 features --- src/Tracy/Logger/Logger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tracy/Logger/Logger.php b/src/Tracy/Logger/Logger.php index 0f9fd0c63..beb740629 100644 --- a/src/Tracy/Logger/Logger.php +++ b/src/Tracy/Logger/Logger.php @@ -127,7 +127,7 @@ public function getExceptionFile(\Throwable $exception, string $level = self::EX ]; } - $hash = substr(md5(serialize($data)), 0, 10); + $hash = substr(hash('xxh128', serialize($data)), 0, 10); $dir = strtr($this->directory . '/', '\/', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR); foreach (new \DirectoryIterator($this->directory) as $file) { if (strpos($file->getBasename(), $hash)) { From 1f9d2fe363d797e66000bc28604ba69857bd65d2 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Thu, 19 Jun 2025 20:47:32 +0200 Subject: [PATCH 07/18] optimized global function calls --- src/Bridges/Nette/Bridge.php | 2 ++ src/Bridges/Nette/TracyExtension.php | 1 + src/Bridges/Psr/PsrToTracyLoggerAdapter.php | 1 + src/Tracy/Bar/Bar.php | 2 ++ src/Tracy/BlueScreen/BlueScreen.php | 3 +++ src/Tracy/BlueScreen/CodeHighlighter.php | 3 +++ src/Tracy/Debugger/Debugger.php | 2 ++ src/Tracy/Debugger/DeferredContent.php | 3 +++ src/Tracy/Debugger/DevelopmentStrategy.php | 1 + src/Tracy/Debugger/ProductionStrategy.php | 2 ++ src/Tracy/Dumper/Describer.php | 1 + src/Tracy/Dumper/Dumper.php | 2 ++ src/Tracy/Dumper/Exposer.php | 1 + src/Tracy/Dumper/Renderer.php | 2 ++ src/Tracy/Helpers.php | 3 +++ src/Tracy/Logger/Logger.php | 3 +++ src/Tracy/OutputDebugger/OutputDebugger.php | 3 +++ src/Tracy/Session/FileSession.php | 3 +++ src/Tracy/Session/NativeSession.php | 2 ++ 19 files changed, 40 insertions(+) diff --git a/src/Bridges/Nette/Bridge.php b/src/Bridges/Nette/Bridge.php index b79624531..5e06f40ae 100644 --- a/src/Bridges/Nette/Bridge.php +++ b/src/Bridges/Nette/Bridge.php @@ -14,6 +14,8 @@ use Tracy; use Tracy\BlueScreen; use Tracy\Helpers; +use function array_slice; +use const ENT_IGNORE; /** diff --git a/src/Bridges/Nette/TracyExtension.php b/src/Bridges/Nette/TracyExtension.php index 3f0c6ac2b..d4244cc16 100644 --- a/src/Bridges/Nette/TracyExtension.php +++ b/src/Bridges/Nette/TracyExtension.php @@ -13,6 +13,7 @@ use Nette\DI\Definitions\Statement; use Nette\Schema\Expect; use Tracy; +use function is_array, is_string; /** diff --git a/src/Bridges/Psr/PsrToTracyLoggerAdapter.php b/src/Bridges/Psr/PsrToTracyLoggerAdapter.php index 5d8b0430b..8bf66781a 100644 --- a/src/Bridges/Psr/PsrToTracyLoggerAdapter.php +++ b/src/Bridges/Psr/PsrToTracyLoggerAdapter.php @@ -11,6 +11,7 @@ use Psr; use Tracy; +use function is_string; /** diff --git a/src/Tracy/Bar/Bar.php b/src/Tracy/Bar/Bar.php index 00d85b5c4..ddc3a47a8 100644 --- a/src/Tracy/Bar/Bar.php +++ b/src/Tracy/Bar/Bar.php @@ -9,6 +9,8 @@ namespace Tracy; +use function count; + /** * Debug Bar. diff --git a/src/Tracy/BlueScreen/BlueScreen.php b/src/Tracy/BlueScreen/BlueScreen.php index cc1c51a4a..6e13675c4 100644 --- a/src/Tracy/BlueScreen/BlueScreen.php +++ b/src/Tracy/BlueScreen/BlueScreen.php @@ -9,6 +9,9 @@ namespace Tracy; +use function in_array, strlen; +use const ARRAY_FILTER_USE_KEY, ENT_IGNORE; + /** * Red BlueScreen. diff --git a/src/Tracy/BlueScreen/CodeHighlighter.php b/src/Tracy/BlueScreen/CodeHighlighter.php index fb5ae0f3d..ec4c8c12e 100644 --- a/src/Tracy/BlueScreen/CodeHighlighter.php +++ b/src/Tracy/BlueScreen/CodeHighlighter.php @@ -9,6 +9,9 @@ namespace Tracy; +use function array_pop, array_shift, array_unshift, count, explode, floor, implode, max, min, preg_replace, preg_replace_callback, rtrim, sprintf, str_replace, strip_tags, strlen, strtr; +use const T_CLASS_C, T_CLOSE_TAG, T_COMMENT, T_CONSTANT_ENCAPSED_STRING, T_DIR, T_DNUMBER, T_DOC_COMMENT, T_ENCAPSED_AND_WHITESPACE, T_FILE, T_FUNC_C, T_INLINE_HTML, T_LINE, T_LNUMBER, T_METHOD_C, T_NAME_FULLY_QUALIFIED, T_NAME_QUALIFIED, T_NAME_RELATIVE, T_NS_C, T_OPEN_TAG, T_OPEN_TAG_WITH_ECHO, T_STRING, T_TRAIT_C, T_VARIABLE, T_WHITESPACE; + /** @internal */ final class CodeHighlighter diff --git a/src/Tracy/Debugger/Debugger.php b/src/Tracy/Debugger/Debugger.php index e9ad04c90..749ded408 100644 --- a/src/Tracy/Debugger/Debugger.php +++ b/src/Tracy/Debugger/Debugger.php @@ -10,6 +10,8 @@ namespace Tracy; use ErrorException; +use function in_array, is_bool, is_int, is_string; +use const PHP_VERSION; /** diff --git a/src/Tracy/Debugger/DeferredContent.php b/src/Tracy/Debugger/DeferredContent.php index 8f831fd52..57260a5ae 100644 --- a/src/Tracy/Debugger/DeferredContent.php +++ b/src/Tracy/Debugger/DeferredContent.php @@ -9,6 +9,9 @@ namespace Tracy; +use function array_slice, is_string, strlen; +use const JSON_INVALID_UTF8_SUBSTITUTE, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE; + /** * @internal diff --git a/src/Tracy/Debugger/DevelopmentStrategy.php b/src/Tracy/Debugger/DevelopmentStrategy.php index e53cb791d..dae2f60c2 100644 --- a/src/Tracy/Debugger/DevelopmentStrategy.php +++ b/src/Tracy/Debugger/DevelopmentStrategy.php @@ -10,6 +10,7 @@ namespace Tracy; use ErrorException; +use function is_bool; /** diff --git a/src/Tracy/Debugger/ProductionStrategy.php b/src/Tracy/Debugger/ProductionStrategy.php index fb8f6d398..64fbd02c3 100644 --- a/src/Tracy/Debugger/ProductionStrategy.php +++ b/src/Tracy/Debugger/ProductionStrategy.php @@ -10,6 +10,8 @@ namespace Tracy; use ErrorException; +use function is_resource; +use const STDERR; /** diff --git a/src/Tracy/Dumper/Describer.php b/src/Tracy/Dumper/Describer.php index f0c017b21..c482609c5 100644 --- a/src/Tracy/Dumper/Describer.php +++ b/src/Tracy/Dumper/Describer.php @@ -11,6 +11,7 @@ use Tracy; use Tracy\Helpers; +use function array_map, array_slice, class_exists, count, explode, file, get_debug_type, get_resource_type, gettype, htmlspecialchars, implode, is_bool, is_file, is_finite, is_int, is_resource, is_string, is_subclass_of, json_encode, method_exists, preg_match, spl_object_id, str_replace, strlen, strpos, strtolower, trim, uksort; /** diff --git a/src/Tracy/Dumper/Dumper.php b/src/Tracy/Dumper/Dumper.php index 4598a4f7f..ca7938f2a 100644 --- a/src/Tracy/Dumper/Dumper.php +++ b/src/Tracy/Dumper/Dumper.php @@ -14,6 +14,8 @@ use Tracy\Dumper\Describer; use Tracy\Dumper\Exposer; use Tracy\Dumper\Renderer; +use function array_flip, array_map, file_get_contents, fwrite, str_replace; +use const STDOUT; /** diff --git a/src/Tracy/Dumper/Exposer.php b/src/Tracy/Dumper/Exposer.php index eb14a504a..773f54124 100644 --- a/src/Tracy/Dumper/Exposer.php +++ b/src/Tracy/Dumper/Exposer.php @@ -10,6 +10,7 @@ namespace Tracy\Dumper; use Dom; use Ds; +use function array_diff_key, array_key_exists, array_key_last, count, end, explode, get_mangled_object_vars, implode, iterator_to_array, preg_match_all, sort; /** diff --git a/src/Tracy/Dumper/Renderer.php b/src/Tracy/Dumper/Renderer.php index edcff7498..96788fc77 100644 --- a/src/Tracy/Dumper/Renderer.php +++ b/src/Tracy/Dumper/Renderer.php @@ -10,6 +10,8 @@ namespace Tracy\Dumper; use Tracy\Helpers; +use function count, htmlspecialchars, ini_set, is_array, is_bool, is_float, is_int, is_object, is_string, json_encode, str_repeat, str_replace, strlen, strrpos, substr, substr_count; +use const JSON_HEX_AMP, JSON_HEX_APOS, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE; /** diff --git a/src/Tracy/Helpers.php b/src/Tracy/Helpers.php index 8c0e35876..df246be63 100644 --- a/src/Tracy/Helpers.php +++ b/src/Tracy/Helpers.php @@ -9,6 +9,9 @@ namespace Tracy; +use function array_filter, array_map, array_merge, array_pop, array_slice, array_unique, basename, bin2hex, class_exists, constant, count, dechex, defined, dirname, end, escapeshellarg, explode, extension_loaded, func_get_args, function_exists, get_class, get_class_methods, get_declared_classes, get_defined_functions, getenv, getmypid, headers_list, htmlspecialchars, htmlspecialchars_decode, iconv_strlen, implode, in_array, is_a, is_array, is_callable, is_file, is_object, is_string, levenshtein, ltrim, mb_strlen, mb_substr, method_exists, ob_end_clean, ob_get_clean, ob_start, ord, preg_match, preg_replace, preg_replace_callback, random_bytes, rawurlencode, rtrim, sapi_windows_vt100_support, spl_object_id, str_contains, str_pad, str_replace, strcasecmp, stream_isatty, strip_tags, strlen, strtoupper, strtr, substr, trait_exists, utf8_decode; +use const DIRECTORY_SEPARATOR, ENT_HTML5, ENT_QUOTES, ENT_SUBSTITUTE, PHP_EOL, PHP_SAPI, STDOUT, STR_PAD_LEFT; + /** * Rendering helpers for Debugger. diff --git a/src/Tracy/Logger/Logger.php b/src/Tracy/Logger/Logger.php index beb740629..43fd3d201 100644 --- a/src/Tracy/Logger/Logger.php +++ b/src/Tracy/Logger/Logger.php @@ -9,6 +9,9 @@ namespace Tracy; +use function in_array, is_string; +use const DIRECTORY_SEPARATOR, FILE_APPEND, LOCK_EX, PHP_EOL; + /** * Logger. diff --git a/src/Tracy/OutputDebugger/OutputDebugger.php b/src/Tracy/OutputDebugger/OutputDebugger.php index 4c8c74cf8..abd136a84 100644 --- a/src/Tracy/OutputDebugger/OutputDebugger.php +++ b/src/Tracy/OutputDebugger/OutputDebugger.php @@ -9,6 +9,9 @@ namespace Tracy; +use function array_slice, count; +use const PHP_OUTPUT_HANDLER_FINAL; + /** * Debugger for outputs. diff --git a/src/Tracy/Session/FileSession.php b/src/Tracy/Session/FileSession.php index 8aef83671..6dd85ce45 100644 --- a/src/Tracy/Session/FileSession.php +++ b/src/Tracy/Session/FileSession.php @@ -9,6 +9,9 @@ namespace Tracy; +use function is_string; +use const LOCK_EX, LOCK_UN; + class FileSession implements SessionStorage { diff --git a/src/Tracy/Session/NativeSession.php b/src/Tracy/Session/NativeSession.php index 5b6b2563f..9bec86090 100644 --- a/src/Tracy/Session/NativeSession.php +++ b/src/Tracy/Session/NativeSession.php @@ -9,6 +9,8 @@ namespace Tracy; +use const PHP_SESSION_ACTIVE; + class NativeSession implements SessionStorage { From a8b421e92021d06e32469df750596c2ef19a83e9 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Fri, 1 Aug 2025 03:35:46 +0200 Subject: [PATCH 08/18] output buffering handlers return string --- src/Tracy/BlueScreen/BlueScreen.php | 5 ++++- src/Tracy/Helpers.php | 2 +- src/Tracy/OutputDebugger/OutputDebugger.php | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Tracy/BlueScreen/BlueScreen.php b/src/Tracy/BlueScreen/BlueScreen.php index 6e13675c4..4596b7bb7 100644 --- a/src/Tracy/BlueScreen/BlueScreen.php +++ b/src/Tracy/BlueScreen/BlueScreen.php @@ -134,7 +134,10 @@ public function renderToFile(\Throwable $exception, string $file): bool { if ($handle = @fopen($file, 'x')) { ob_start(); // double buffer prevents sending HTTP headers in some PHP - ob_start(function ($buffer) use ($handle): void { fwrite($handle, $buffer); }, 4096); + ob_start(function ($buffer) use ($handle) { + fwrite($handle, $buffer); + return ''; + }, 4096); $this->renderTemplate($exception, __DIR__ . '/assets/page.phtml', toScreen: false); ob_end_flush(); ob_end_clean(); diff --git a/src/Tracy/Helpers.php b/src/Tracy/Helpers.php index df246be63..33a77ca8a 100644 --- a/src/Tracy/Helpers.php +++ b/src/Tracy/Helpers.php @@ -359,7 +359,7 @@ private static function escapeArg(string $s): string */ public static function capture(callable $func): string { - ob_start(fn() => null); + ob_start(fn() => ''); try { $func(); return ob_get_clean(); diff --git a/src/Tracy/OutputDebugger/OutputDebugger.php b/src/Tracy/OutputDebugger/OutputDebugger.php index abd136a84..fe9559086 100644 --- a/src/Tracy/OutputDebugger/OutputDebugger.php +++ b/src/Tracy/OutputDebugger/OutputDebugger.php @@ -44,7 +44,7 @@ public function start(): void /** @internal */ - public function handler(string $s, int $phase): ?string + public function handler(string $s, int $phase): string { $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); if (isset($trace[0]['file'], $trace[0]['line'])) { @@ -60,7 +60,7 @@ public function handler(string $s, int $phase): ?string return $phase === PHP_OUTPUT_HANDLER_FINAL ? $this->renderHtml() - : null; + : ''; } From a14cc6383b403fb931944ce62257710cda1c277b Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 6 Aug 2025 20:00:16 +0200 Subject: [PATCH 09/18] support for PHP 8.5 --- .github/workflows/tests.yml | 2 +- composer.json | 2 +- readme.md | 2 +- src/Tracy/Helpers.php | 1 - tests/Tracy/Dumper.toHtml().specials.phpt | 6 ++---- tests/Tracy/Dumper.toText().specials.phpt | 6 ++---- tools/create-phar/create-phar.php | 1 - 7 files changed, 7 insertions(+), 13 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9251d57c6..7f5a475e7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - php: ['8.1', '8.2', '8.3', '8.4'] + php: ['8.1', '8.2', '8.3', '8.4', '8.5'] sapi: ['php', 'php-cgi'] fail-fast: false diff --git a/composer.json b/composer.json index e7bdd674f..cfde91964 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "php": "8.1 - 8.4", + "php": "8.1 - 8.5", "ext-session": "*", "ext-json": "*" }, diff --git a/readme.md b/readme.md index 96e87069d..a541173b6 100644 --- a/readme.md +++ b/readme.md @@ -48,7 +48,7 @@ composer require tracy/tracy Alternatively, you can download the whole package or [tracy.phar](https://github.com/nette/tracy/releases) file. -Tracy is compatible with PHP 8.1 to 8.4. +Tracy is compatible with PHP 8.1 to 8.5.   diff --git a/src/Tracy/Helpers.php b/src/Tracy/Helpers.php index 33a77ca8a..8264fb6f1 100644 --- a/src/Tracy/Helpers.php +++ b/src/Tracy/Helpers.php @@ -218,7 +218,6 @@ public static function improveException(\Throwable $e): void if ($message !== $e->getMessage()) { $ref = new \ReflectionProperty($e, 'message'); - $ref->setAccessible(true); $ref->setValue($e, $message); } diff --git a/tests/Tracy/Dumper.toHtml().specials.phpt b/tests/Tracy/Dumper.toHtml().specials.phpt index ec2262dd9..13a676a85 100644 --- a/tests/Tracy/Dumper.toHtml().specials.phpt +++ b/tests/Tracy/Dumper.toHtml().specials.phpt @@ -87,10 +87,8 @@ Assert::match( // SplObjectStorage $objStorage = new SplObjectStorage; -$objStorage->attach($o1 = new stdClass); -$objStorage[$o1] = 'o1'; -$objStorage->attach($o2 = (object) ['foo' => 'bar']); -$objStorage[$o2] = 'o2'; +$objStorage[$o1 = new stdClass] = 'o1'; +$objStorage[$o2 = (object) ['foo' => 'bar']] = 'o2'; $objStorage->next(); $key = $objStorage->key(); diff --git a/tests/Tracy/Dumper.toText().specials.phpt b/tests/Tracy/Dumper.toText().specials.phpt index 3cb5f0615..750c3bdde 100644 --- a/tests/Tracy/Dumper.toText().specials.phpt +++ b/tests/Tracy/Dumper.toText().specials.phpt @@ -53,10 +53,8 @@ Assert::match("SplFileInfo #%d% // SplObjectStorage $objStorage = new SplObjectStorage; -$objStorage->attach($o1 = new stdClass); -$objStorage[$o1] = 'o1'; -$objStorage->attach($o2 = (object) ['foo' => 'bar']); -$objStorage[$o2] = 'o2'; +$objStorage[$o1 = new stdClass] = 'o1'; +$objStorage[$o2 = (object) ['foo' => 'bar']] = 'o2'; $objStorage->next(); $key = $objStorage->key(); diff --git a/tools/create-phar/create-phar.php b/tools/create-phar/create-phar.php index 58af56d35..44ce7a73c 100644 --- a/tools/create-phar/create-phar.php +++ b/tools/create-phar/create-phar.php @@ -17,7 +17,6 @@ function compressJs(string $s): string curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, 'output_info=compiled_code&js_code=' . urlencode($s)); $s = curl_exec($curl) ?: $s; - curl_close($curl); } return $s; } From cd5f67e68c31f13870d56a3c1c0485507a8afe30 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 2 Aug 2025 04:05:59 +0200 Subject: [PATCH 10/18] Bridge: removed support for Latte (is part of Latte) --- src/Bridges/Nette/Bridge.php | 73 +----------------------------------- 1 file changed, 1 insertion(+), 72 deletions(-) diff --git a/src/Bridges/Nette/Bridge.php b/src/Bridges/Nette/Bridge.php index 5e06f40ae..1f095716c 100644 --- a/src/Bridges/Nette/Bridge.php +++ b/src/Bridges/Nette/Bridge.php @@ -9,97 +9,26 @@ namespace Tracy\Bridges\Nette; -use Latte; use Nette; use Tracy; use Tracy\BlueScreen; use Tracy\Helpers; -use function array_slice; use const ENT_IGNORE; /** - * Bridge for NEON & Latte. + * Bridge for Utils & NEON. */ class Bridge { public static function initialize(): void { $blueScreen = Tracy\Debugger::getBlueScreen(); - if (!class_exists(Latte\Bridges\Tracy\BlueScreenPanel::class)) { - $blueScreen->addPanel([self::class, 'renderLatteError']); - $blueScreen->addAction([self::class, 'renderLatteUnknownMacro']); - $blueScreen->addFileGenerator(fn(string $file) => substr($file, -6) === '.latte' - ? "{block content}\n\$END\$" - : null); - Tracy\Debugger::addSourceMapper([self::class, 'mapLatteSourceCode']); - } - $blueScreen->addAction([self::class, 'renderMemberAccessException']); $blueScreen->addPanel([self::class, 'renderNeonError']); } - public static function renderLatteError(?\Throwable $e): ?array - { - if ($e instanceof Latte\CompileException && $e->sourceName) { - return [ - 'tab' => 'Template', - 'panel' => (preg_match('#\n|\?#', $e->sourceName) - ? '' - : '

' - . (@is_file($e->sourceName) // @ - may trigger error - ? 'File: ' . Helpers::editorLink($e->sourceName, $e->sourceLine) - : '' . htmlspecialchars($e->sourceName . ($e->sourceLine ? ':' . $e->sourceLine : '')) . '') - . '

') - . BlueScreen::highlightFile($e->sourceCode, $e->sourceLine, php: false), - ]; - } - - return null; - } - - - public static function renderLatteUnknownMacro(?\Throwable $e): ?array - { - if ( - $e instanceof Latte\CompileException - && $e->sourceName - && @is_file($e->sourceName) // @ - may trigger error - && (preg_match('#Unknown macro (\{\w+)\}, did you mean (\{\w+)\}\?#A', $e->getMessage(), $m) - || preg_match('#Unknown attribute (n:\w+), did you mean (n:\w+)\?#A', $e->getMessage(), $m)) - ) { - return [ - 'link' => Helpers::editorUri($e->sourceName, $e->sourceLine, 'fix', $m[1], $m[2]), - 'label' => 'fix it', - ]; - } - - return null; - } - - - /** @return array{file: string, line: int, label: string, active: bool} */ - public static function mapLatteSourceCode(string $file, int $line): ?array - { - if (!strpos($file, '.latte--')) { - return null; - } - - $lines = file($file); - if ( - !preg_match('#^/(?:\*\*|/) source: (\S+\.latte)#m', implode('', array_slice($lines, 0, 10)), $m) - || !@is_file($m[1]) // @ - may trigger error - ) { - return null; - } - - $file = $m[1]; - $line = $line && preg_match('#/\* line (\d+) \*/#', $lines[$line - 1], $m) ? (int) $m[1] : 0; - return ['file' => $file, 'line' => $line, 'label' => 'Latte', 'active' => true]; - } - - public static function renderMemberAccessException(?\Throwable $e): ?array { if (!$e instanceof Nette\MemberAccessException && !$e instanceof \LogicException) { From e4336b1b354b78ab6c02b3eee9317d27581fe371 Mon Sep 17 00:00:00 2001 From: n3t Date: Wed, 7 Aug 2024 03:21:38 +0200 Subject: [PATCH 11/18] readme: added link to Joomla integration (#583) Link to Joomla! integration. --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index a541173b6..162dab103 100644 --- a/readme.md +++ b/readme.md @@ -456,5 +456,6 @@ This is a list of unofficial integrations to other frameworks and CMS: - [Slim Framework](https://github.com/runcmf/runtracy) - Symfony framework: [kutny/tracy-bundle](https://github.com/kutny/tracy-bundle), [VasekPurchart/Tracy-Blue-Screen-Bundle](https://github.com/VasekPurchart/Tracy-Blue-Screen-Bundle) - [Wordpress](https://github.com/ktstudio/WP-Tracy) +- [Joomla! CMS](https://n3t.bitbucket.io/extension/n3t-debug/) ... feel free to be famous, create an integration for your favourite platform! From 9d0e1c5f28d60f08c92aedbd59a7b6dc4df03e60 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Fri, 10 Dec 2021 05:33:06 +0100 Subject: [PATCH 12/18] opened 3.0-dev --- composer.json | 2 +- src/Tracy/Debugger/Debugger.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index cfde91964..b1a1f38b3 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ }, "extra": { "branch-alias": { - "dev-master": "2.11-dev" + "dev-master": "3.0-dev" } } } diff --git a/src/Tracy/Debugger/Debugger.php b/src/Tracy/Debugger/Debugger.php index 749ded408..73ff11e42 100644 --- a/src/Tracy/Debugger/Debugger.php +++ b/src/Tracy/Debugger/Debugger.php @@ -19,7 +19,7 @@ */ class Debugger { - public const Version = '2.11.0'; + public const Version = '3.0-dev'; /** server modes for Debugger::enable() */ public const From 160312c16b5cbbef45c06fb0a350180d6a7be365 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Mon, 5 Dec 2022 01:21:34 +0100 Subject: [PATCH 13/18] uses PascalCase constants --- src/Bridges/Nette/TracyExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bridges/Nette/TracyExtension.php b/src/Bridges/Nette/TracyExtension.php index d4244cc16..e1ba09527 100644 --- a/src/Bridges/Nette/TracyExtension.php +++ b/src/Bridges/Nette/TracyExtension.php @@ -131,7 +131,7 @@ public function afterCompile(Nette\PhpGenerator\ClassType $class): void if ($this->debugMode) { foreach ($this->config->bar as $item) { if (is_string($item) && substr($item, 0, 1) === '@') { - $item = new Statement(['@' . $builder::THIS_CONTAINER, 'getService'], [substr($item, 1)]); + $item = new Statement(['@' . $builder::ThisContainer, 'getService'], [substr($item, 1)]); } elseif (is_string($item)) { $item = new Statement($item); } From 6b2db648c225fc3a0f73957a5336d1e3067f0e9d Mon Sep 17 00:00:00 2001 From: David Grudl Date: Thu, 3 Feb 2022 17:37:54 +0100 Subject: [PATCH 14/18] Logger: added typehints --- src/Tracy/Logger/Logger.php | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/src/Tracy/Logger/Logger.php b/src/Tracy/Logger/Logger.php index 43fd3d201..8b9b14a17 100644 --- a/src/Tracy/Logger/Logger.php +++ b/src/Tracy/Logger/Logger.php @@ -18,23 +18,22 @@ */ class Logger implements ILogger { - /** @var string|null name of the directory where errors should be logged */ - public $directory; + /** name of the directory where errors should be logged */ + public ?string $directory = null; - /** @var string|array|null email or emails to which send error notifications */ - public $email; + /** email or emails to which send error notifications */ + public string|array|null $email = null; - /** @var string|null sender of email notifications */ - public $fromEmail; + /** sender of email notifications */ + public ?string $fromEmail = null; - /** @var mixed interval for sending email is 2 days */ - public $emailSnooze = '2 days'; + /** interval for sending email is 2 days */ + public mixed $emailSnooze = '2 days'; /** @var callable handler for sending emails */ public $mailer; - /** @var BlueScreen|null */ - private $blueScreen; + private ?BlueScreen $blueScreen = null; public function __construct(?string $directory, string|array|null $email = null, ?BlueScreen $blueScreen = null) @@ -81,10 +80,7 @@ public function log(mixed $message, string $level = self::INFO) } - /** - * @param mixed $message - */ - public static function formatMessage($message): string + public static function formatMessage(mixed $message): string { if ($message instanceof \Throwable) { foreach (Helpers::getExceptionChain($message) as $exception) { @@ -104,10 +100,7 @@ public static function formatMessage($message): string } - /** - * @param mixed $message - */ - public static function formatLogLine($message, ?string $exceptionFile = null): string + public static function formatLogLine(mixed $message, ?string $exceptionFile = null): string { return implode(' ', [ date('[Y-m-d H-i-s]'), @@ -155,10 +148,7 @@ protected function logException(\Throwable $exception, ?string $file = null): st } - /** - * @param mixed $message - */ - protected function sendEmail($message): void + protected function sendEmail(mixed $message): void { $snooze = is_numeric($this->emailSnooze) ? $this->emailSnooze @@ -177,10 +167,9 @@ protected function sendEmail($message): void /** * Default mailer. - * @param mixed $message * @internal */ - public function defaultMailer($message, string $email): void + public function defaultMailer(mixed $message, string $email): void { $host = preg_replace('#[^\w.-]+#', '', $_SERVER['SERVER_NAME'] ?? php_uname('n')); mail( From b1554b976fc5b9c9dfc033ba956cc2806f7e70f2 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 3 Apr 2024 20:38:58 +0200 Subject: [PATCH 15/18] error.log changed to warning.log --- src/Tracy/Debugger/ProductionStrategy.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tracy/Debugger/ProductionStrategy.php b/src/Tracy/Debugger/ProductionStrategy.php index 64fbd02c3..a47db9ed7 100644 --- a/src/Tracy/Debugger/ProductionStrategy.php +++ b/src/Tracy/Debugger/ProductionStrategy.php @@ -65,7 +65,7 @@ public function handleError( $err = 'PHP ' . Helpers::errorTypeToString($severity) . ': ' . Helpers::improveError($message) . " in $file:$line"; } - Debugger::tryLog($err, Debugger::ERROR); + Debugger::tryLog($err, Debugger::WARNING); } From 16d978dd5052421ce24d41aed17eaccd9d51181d Mon Sep 17 00:00:00 2001 From: David Grudl Date: Mon, 29 Apr 2024 12:20:21 +0200 Subject: [PATCH 16/18] bar: errors panel => warnings --- .../Bar/panels/{errors.panel.phtml => warnings.panel.phtml} | 0 src/Tracy/Bar/panels/{errors.tab.phtml => warnings.tab.phtml} | 4 ++-- src/Tracy/Debugger/Debugger.php | 2 +- src/Tracy/Debugger/DevelopmentStrategy.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/Tracy/Bar/panels/{errors.panel.phtml => warnings.panel.phtml} (100%) rename src/Tracy/Bar/panels/{errors.tab.phtml => warnings.tab.phtml} (92%) diff --git a/src/Tracy/Bar/panels/errors.panel.phtml b/src/Tracy/Bar/panels/warnings.panel.phtml similarity index 100% rename from src/Tracy/Bar/panels/errors.panel.phtml rename to src/Tracy/Bar/panels/warnings.panel.phtml diff --git a/src/Tracy/Bar/panels/errors.tab.phtml b/src/Tracy/Bar/panels/warnings.tab.phtml similarity index 92% rename from src/Tracy/Bar/panels/errors.tab.phtml rename to src/Tracy/Bar/panels/warnings.tab.phtml index 70b0a53ed..baef3e1cf 100644 --- a/src/Tracy/Bar/panels/errors.tab.phtml +++ b/src/Tracy/Bar/panels/warnings.tab.phtml @@ -10,7 +10,7 @@ if (empty($data)) { } ?> - + 1 ? ' warnings' : ' warning' ?> diff --git a/src/Tracy/Debugger/Debugger.php b/src/Tracy/Debugger/Debugger.php index 73ff11e42..97ce50eee 100644 --- a/src/Tracy/Debugger/Debugger.php +++ b/src/Tracy/Debugger/Debugger.php @@ -410,7 +410,7 @@ public static function getBar(): Bar self::$bar = new Bar; self::$bar->addPanel($info = new DefaultBarPanel('info'), 'Tracy:info'); $info->cpuUsage = self::$cpuUsage; - self::$bar->addPanel(new DefaultBarPanel('errors'), 'Tracy:errors'); // filled by errorHandler() + self::$bar->addPanel(new DefaultBarPanel('warnings'), 'Tracy:warnings'); // filled by errorHandler() } return self::$bar; diff --git a/src/Tracy/Debugger/DevelopmentStrategy.php b/src/Tracy/Debugger/DevelopmentStrategy.php index dae2f60c2..e6bc46d38 100644 --- a/src/Tracy/Debugger/DevelopmentStrategy.php +++ b/src/Tracy/Debugger/DevelopmentStrategy.php @@ -91,7 +91,7 @@ public function handleError( } $message = Helpers::errorTypeToString($severity) . ': ' . Helpers::improveError($message); - $count = &$this->bar->getPanel('Tracy:errors')->data["$file|$line|$message"]; + $count = &$this->bar->getPanel('Tracy:warnings')->data["$file|$line|$message"]; if (!$count++ && !Helpers::isHtmlMode() && !Helpers::isAjax()) { echo "\n$message in $file on line $line\n"; From c976e41187cc0841b0b30e09c524457bb3b6f34a Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 23 Nov 2024 17:55:20 +0100 Subject: [PATCH 17/18] used attribute Deprecated --- src/Tracy/Debugger/Debugger.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Tracy/Debugger/Debugger.php b/src/Tracy/Debugger/Debugger.php index 97ce50eee..54f299692 100644 --- a/src/Tracy/Debugger/Debugger.php +++ b/src/Tracy/Debugger/Debugger.php @@ -29,19 +29,19 @@ class Debugger public const CookieSecret = 'tracy-debug'; - /** @deprecated use Debugger::Version */ + #[\Deprecated('use Debugger::Version')] public const VERSION = self::Version; - /** @deprecated use Debugger::Development */ + #[\Deprecated('use Debugger::Development')] public const DEVELOPMENT = self::Development; - /** @deprecated use Debugger::Production */ + #[\Deprecated('use Debugger::Production')] public const PRODUCTION = self::Production; - /** @deprecated use Debugger::Detect */ + #[\Deprecated('use Debugger::Detect')] public const DETECT = self::Detect; - /** @deprecated use Debugger::CookieSecret */ + #[\Deprecated('use Debugger::CookieSecret')] public const COOKIE_SECRET = self::CookieSecret; /** in production mode is suppressed any debugging output */ From 6aede04082068813905387c2e93f288bb048ac6f Mon Sep 17 00:00:00 2001 From: "milos.brecher" Date: Thu, 9 Oct 2025 22:04:13 +0200 Subject: [PATCH 18/18] Improve error 500 page layout for desktop and mobile --- src/Tracy/Debugger/assets/error.500.phtml | 29 ++++++++++++++++------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/Tracy/Debugger/assets/error.500.phtml b/src/Tracy/Debugger/assets/error.500.phtml index 7fe08f068..cd95bed40 100644 --- a/src/Tracy/Debugger/assets/error.500.phtml +++ b/src/Tracy/Debugger/assets/error.500.phtml @@ -19,24 +19,37 @@ namespace Tracy; Server Error
-
-

Server Error

+
+
+

Server Error

-

We're sorry! The server encountered an internal error and - was unable to complete your request. Please try again later.

+

We're sorry! The server encountered an internal error and + was unable to complete your request. Please try again later.

-

error 500 |
Tracy is unable to log error.

-
+

error 500 |
Tracy is unable to log error.

+
+
>