From 6a12b99fb64a054164eeef697c1b6749fd8a35ad Mon Sep 17 00:00:00 2001 From: David Grudl Date: Mon, 9 Oct 2017 18:33:45 +0200 Subject: [PATCH 01/18] opened 2.7-dev --- composer.json | 2 +- readme.md | 1 + src/Tracy/Debugger/Debugger.php | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 8168015da..d06ea6f25 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } } } diff --git a/readme.md b/readme.md index 9b1869783..242a192dc 100644 --- a/readme.md +++ b/readme.md @@ -42,6 +42,7 @@ Alternatively, you can download the whole package or [tracy.phar](https://github | Tracy | PHP | compatible with browsers |-----------|---------------|---------- +| Tracy 2.7 | PHP 7.1 – 7.3 | Chrome 49+, Firefox 45+, MS Edge 14+, Safari 10+ and iOS Safari 10.2+ | Tracy 2.6 | PHP 7.1 – 7.3 | Chrome 49+, Firefox 45+, MS Edge 14+, Safari 10+ and iOS Safari 10.2+ | Tracy 2.5 | PHP 5.4.4 – 7.3 | Chrome 49+, Firefox 45+, MS Edge 12+, Safari 10+ and iOS Safari 10.2+ | Tracy 2.4 | PHP 5.4.4 – 7.2 | Chrome 29+, Firefox 28+, IE 11+ (except AJAX), MS Edge 12+, Safari 9+ and iOS Safari 9.2+ diff --git a/src/Tracy/Debugger/Debugger.php b/src/Tracy/Debugger/Debugger.php index 4cbc2828d..8e7b0ce6f 100644 --- a/src/Tracy/Debugger/Debugger.php +++ b/src/Tracy/Debugger/Debugger.php @@ -17,7 +17,7 @@ */ class Debugger { - public const VERSION = '2.6.4'; + public const VERSION = '2.7-dev'; /** server modes for Debugger::enable() */ public const From a2ceade8e91f70a2f020274c299a35f0561286cf Mon Sep 17 00:00:00 2001 From: David Grudl Date: Mon, 18 Feb 2019 16:07:58 +0100 Subject: [PATCH 02/18] bar: replaced attribute 'rel' with 'data-tracy-action' for closing & open-to-window links --- src/Tracy/Bar/assets/bar.js | 10 +++++----- src/Tracy/Bar/assets/bar.phtml | 2 +- src/Tracy/Bar/assets/panels.phtml | 4 ++-- tests/Tracy/expected/Debugger.barDump().expect | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Tracy/Bar/assets/bar.js b/src/Tracy/Bar/assets/bar.js index 1efffe2d0..3c25eb79a 100644 --- a/src/Tracy/Bar/assets/bar.js +++ b/src/Tracy/Bar/assets/bar.js @@ -62,9 +62,9 @@ elem.querySelectorAll('.tracy-icons a').forEach((link) => { link.addEventListener('click', (e) => { - if (link.rel === 'close') { + if (link.dataset.tracyAction === 'close') { this.toPeek(); - } else if (link.rel === 'window') { + } else if (link.dataset.tracyAction === 'window') { this.toWindow(); } e.preventDefault(); @@ -258,7 +258,7 @@ initTabs(elem) { elem.querySelectorAll('a').forEach((link) => { link.addEventListener('click', (e) => { - if (link.rel === 'close') { + if (link.dataset.tracyAction === 'close') { this.close(); } else if (link.rel) { @@ -284,7 +284,7 @@ }); link.addEventListener('mouseenter', (e) => { - if (e.buttons || !link.rel || link.rel === 'close' || elem.classList.contains('tracy-dragged')) { + if (e.buttons || !link.rel || elem.classList.contains('tracy-dragged')) { return; } @@ -311,7 +311,7 @@ link.addEventListener('mouseleave', () => { clearTimeout(this.displayTimeout); - if (link.rel && link.rel !== 'close' && !elem.classList.contains('tracy-dragged')) { + if (link.rel && !elem.classList.contains('tracy-dragged')) { Debug.panels[link.rel].blur(); } }); diff --git a/src/Tracy/Bar/assets/bar.phtml b/src/Tracy/Bar/assets/bar.phtml index baac001ba..8fa3a8641 100644 --- a/src/Tracy/Bar/assets/bar.phtml +++ b/src/Tracy/Bar/assets/bar.phtml @@ -32,6 +32,6 @@ namespace Tracy; -
  • ×
  • +
  • ×
  • diff --git a/src/Tracy/Bar/assets/panels.phtml b/src/Tracy/Bar/assets/panels.phtml index 77183bd75..b993aae80 100644 --- a/src/Tracy/Bar/assets/panels.phtml +++ b/src/Tracy/Bar/assets/panels.phtml @@ -18,8 +18,8 @@ use Tracy\Helpers; $icons = '
    - ¤ - × + ¤ + ×
    '; diff --git a/tests/Tracy/expected/Debugger.barDump().expect b/tests/Tracy/expected/Debugger.barDump().expect index 22bf7aff2..7a5a6a8bd 100644 --- a/tests/Tracy/expected/Debugger.barDump().expect +++ b/tests/Tracy/expected/Debugger.barDump().expect @@ -17,6 +17,6 @@ in file %a% on line %d%" data-tracy-href="editor:%a%"> - ¤ - × + ¤ + × From 66235f603c86f47ef08560e20313cf5dbcceff4d Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sun, 3 Mar 2019 19:35:51 +0100 Subject: [PATCH 03/18] Bluescreen: footer is always on bottom --- src/Tracy/BlueScreen/assets/bluescreen.css | 20 ++++++++++++++++--- src/Tracy/BlueScreen/assets/content.phtml | 20 +++++++++---------- .../expected/Debugger.E_ERROR.html.expect | 18 ++++++++--------- .../expected/Debugger.error-in-eval.expect | 18 ++++++++--------- .../expected/Debugger.exception.html.expect | 18 ++++++++--------- .../expected/Debugger.strict.html.expect | 18 ++++++++--------- 6 files changed, 63 insertions(+), 49 deletions(-) diff --git a/src/Tracy/BlueScreen/assets/bluescreen.css b/src/Tracy/BlueScreen/assets/bluescreen.css index 5befb8070..8afa1896d 100644 --- a/src/Tracy/BlueScreen/assets/bluescreen.css +++ b/src/Tracy/BlueScreen/assets/bluescreen.css @@ -36,6 +36,20 @@ padding: 3px; } +.tracy-bs-main { + display: flex; + flex-direction: column; + min-height: 100vh; +} + +.tracy-bs-main.tracy-collapsed { + display: none; +} + +#tracy-bs div.panel:last-of-type { + flex: 1; +} + #tracy-bs-error { background: #CD1818; color: white; @@ -153,7 +167,7 @@ list-style: none; } -#tracy-bs-logo a { +#tracy-bs .footer-logo a { position: absolute; bottom: 0; right: 0; @@ -165,8 +179,8 @@ margin: 0; } -#tracy-bs-logo a:hover, -#tracy-bs-logo a:focus { +#tracy-bs .footer-logo a:hover, +#tracy-bs .footer-logo a:focus { opacity: 1; transition: opacity 0.1s; } diff --git a/src/Tracy/BlueScreen/assets/content.phtml b/src/Tracy/BlueScreen/assets/content.phtml index 2a65aeab1..4879b6f29 100644 --- a/src/Tracy/BlueScreen/assets/content.phtml +++ b/src/Tracy/BlueScreen/assets/content.phtml @@ -28,7 +28,7 @@ $code = $exception->getCode() ? ' #' . $exception->getCode() : ''; ?>
    -
    +
    getMessage()): ?>

    @@ -357,15 +357,15 @@ $code = $exception->getCode() ? ' #' . $exception->getCode() : '';
    - - - - +
    >
    diff --git a/tests/Tracy/expected/Debugger.E_ERROR.html.expect b/tests/Tracy/expected/Debugger.E_ERROR.html.expect index d4e2aa276..40df02dc7 100644 --- a/tests/Tracy/expected/Debugger.E_ERROR.html.expect +++ b/tests/Tracy/expected/Debugger.E_ERROR.html.expect @@ -15,7 +15,7 @@
    -
    +

    Error

    @@ -211,14 +211,14 @@ - -
      -
    • %a%️
    • -
    • Report generated at %a%
    • -
    • CLI%a?%
    • -
    • PHP %a%
    - - +
    +
      +
    • %a%️
    • +
    • Report generated at %a%
    • +
    • CLI%a?%
    • +
    • PHP %a%
    + +
    diff --git a/tests/Tracy/expected/Debugger.error-in-eval.expect b/tests/Tracy/expected/Debugger.error-in-eval.expect index 2cefe40e8..522cc3b2f 100644 --- a/tests/Tracy/expected/Debugger.error-in-eval.expect +++ b/tests/Tracy/expected/Debugger.error-in-eval.expect @@ -15,7 +15,7 @@
    -
    +

    User Error

    @@ -182,14 +182,14 @@ - -
      -
    • %a%️
    • -
    • Report generated at %a%
    • -
    • CLI%a?%
    • -
    • PHP %a%
    - - +
    +
      +
    • %a%️
    • +
    • Report generated at %a%
    • +
    • CLI%a?%
    • +
    • PHP %a%
    + +
    diff --git a/tests/Tracy/expected/Debugger.exception.html.expect b/tests/Tracy/expected/Debugger.exception.html.expect index 8288a5848..48aac140b 100644 --- a/tests/Tracy/expected/Debugger.exception.html.expect +++ b/tests/Tracy/expected/Debugger.exception.html.expect @@ -15,7 +15,7 @@
    -
    +

    Exception #123

    @@ -178,14 +178,14 @@ - -
      -
    • %a%️
    • -
    • Report generated at %a%
    • -
    • CLI%a?%
    • -
    • PHP %a%
    - - +
    +
      +
    • %a%️
    • +
    • Report generated at %a%
    • +
    • CLI%a?%
    • +
    • PHP %a%
    + +
    diff --git a/tests/Tracy/expected/Debugger.strict.html.expect b/tests/Tracy/expected/Debugger.strict.html.expect index 7177e07e3..ca53c46e4 100644 --- a/tests/Tracy/expected/Debugger.strict.html.expect +++ b/tests/Tracy/expected/Debugger.strict.html.expect @@ -15,7 +15,7 @@
    -
    +

    Notice

    @@ -185,14 +185,14 @@ - -
      -
    • %a%️
    • -
    • Report generated at %a%
    • -
    • CLI%a?%
    • -
    • PHP %a%
    - - +
    +
      +
    • %a%️
    • +
    • Report generated at %a%
    • +
    • CLI%a?%
    • +
    • PHP %a%
    + +
    From 47fe5fed3b3f083a2e955a19897858623bc5fb7b Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 9 Mar 2019 01:25:47 +0100 Subject: [PATCH 04/18] BlueScreen: removed source from footer --- src/Tracy/BlueScreen/BlueScreen.php | 1 - src/Tracy/BlueScreen/assets/content.phtml | 2 -- tests/Tracy/expected/Debugger.E_ERROR.html.expect | 1 - tests/Tracy/expected/Debugger.error-in-eval.expect | 1 - tests/Tracy/expected/Debugger.exception.html.expect | 1 - tests/Tracy/expected/Debugger.strict.html.expect | 1 - 6 files changed, 7 deletions(-) diff --git a/src/Tracy/BlueScreen/BlueScreen.php b/src/Tracy/BlueScreen/BlueScreen.php index 429b6081a..671ae9147 100644 --- a/src/Tracy/BlueScreen/BlueScreen.php +++ b/src/Tracy/BlueScreen/BlueScreen.php @@ -116,7 +116,6 @@ private function renderTemplate(\Throwable $exception, string $template, $toScre ); $info = array_filter($this->info); $source = Helpers::getSource(); - $sourceIsUrl = preg_match('#^https?://#', $source); $title = $exception instanceof \ErrorException ? Helpers::errorTypeToString($exception->getSeverity()) : Helpers::getClass($exception); diff --git a/src/Tracy/BlueScreen/assets/content.phtml b/src/Tracy/BlueScreen/assets/content.phtml index 4879b6f29..80b6c79ec 100644 --- a/src/Tracy/BlueScreen/assets/content.phtml +++ b/src/Tracy/BlueScreen/assets/content.phtml @@ -12,7 +12,6 @@ * @param array $info * @param string $title * @param string $source - * @param bool $sourceIsUrl * @param array $lastError * @param array $httpHeaders * @param callable $dump @@ -361,7 +360,6 @@ $code = $exception->getCode() ? ' #' . $exception->getCode() : ''; diff --git a/tests/Tracy/expected/Debugger.E_ERROR.html.expect b/tests/Tracy/expected/Debugger.E_ERROR.html.expect index 40df02dc7..987e85150 100644 --- a/tests/Tracy/expected/Debugger.E_ERROR.html.expect +++ b/tests/Tracy/expected/Debugger.E_ERROR.html.expect @@ -215,7 +215,6 @@
    • %a%️
    • Report generated at %a%
    • -
    • CLI%a?%
    • PHP %a%
    diff --git a/tests/Tracy/expected/Debugger.error-in-eval.expect b/tests/Tracy/expected/Debugger.error-in-eval.expect index 522cc3b2f..ef8e08371 100644 --- a/tests/Tracy/expected/Debugger.error-in-eval.expect +++ b/tests/Tracy/expected/Debugger.error-in-eval.expect @@ -186,7 +186,6 @@
    • %a%️
    • Report generated at %a%
    • -
    • CLI%a?%
    • PHP %a%
    diff --git a/tests/Tracy/expected/Debugger.exception.html.expect b/tests/Tracy/expected/Debugger.exception.html.expect index 48aac140b..36283fdd4 100644 --- a/tests/Tracy/expected/Debugger.exception.html.expect +++ b/tests/Tracy/expected/Debugger.exception.html.expect @@ -182,7 +182,6 @@
    • %a%️
    • Report generated at %a%
    • -
    • CLI%a?%
    • PHP %a%
    diff --git a/tests/Tracy/expected/Debugger.strict.html.expect b/tests/Tracy/expected/Debugger.strict.html.expect index ca53c46e4..5314b7337 100644 --- a/tests/Tracy/expected/Debugger.strict.html.expect +++ b/tests/Tracy/expected/Debugger.strict.html.expect @@ -189,7 +189,6 @@
    • %a%️
    • Report generated at %a%
    • -
    • CLI%a?%
    • PHP %a%
    From 6ff7adcac3fca952eda4e7893bd60e3dd355c690 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Tue, 16 Jul 2019 00:44:35 +0200 Subject: [PATCH 05/18] Logger: added priority to exception file name --- src/Tracy/Logger/Logger.php | 6 +++--- tests/Tracy/Debugger.logSeverity.E_NOTICE.phpt | 2 +- tests/Tracy/Logger.log().phpt | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Tracy/Logger/Logger.php b/src/Tracy/Logger/Logger.php index 4dea99014..7d06d9d7f 100644 --- a/src/Tracy/Logger/Logger.php +++ b/src/Tracy/Logger/Logger.php @@ -61,7 +61,7 @@ public function log($message, $level = self::INFO) } $exceptionFile = $message instanceof \Throwable - ? $this->getExceptionFile($message) + ? $this->getExceptionFile($message, $level) : null; $line = static::formatLogLine($message, $exceptionFile); $file = $this->directory . '/' . strtolower($level ?: self::INFO) . '.log'; @@ -119,7 +119,7 @@ public static function formatLogLine($message, string $exceptionFile = null): st } - public function getExceptionFile(\Throwable $exception): string + public function getExceptionFile(\Throwable $exception, string $level = self::EXCEPTION): string { while ($exception) { $data[] = [ @@ -135,7 +135,7 @@ public function getExceptionFile(\Throwable $exception): string return $dir . $file; } } - return $dir . 'exception--' . @date('Y-m-d--H-i') . "--$hash.html"; // @ timezone may not be set + return $dir . $level . '--' . @date('Y-m-d--H-i') . "--$hash.html"; // @ timezone may not be set } diff --git a/tests/Tracy/Debugger.logSeverity.E_NOTICE.phpt b/tests/Tracy/Debugger.logSeverity.E_NOTICE.phpt index a505a6c72..560c4b968 100644 --- a/tests/Tracy/Debugger.logSeverity.E_NOTICE.phpt +++ b/tests/Tracy/Debugger.logSeverity.E_NOTICE.phpt @@ -19,5 +19,5 @@ Debugger::$logSeverity = E_NOTICE; $variable = $missingVariable; -Assert::count(1, glob(TEMP_DIR . '/exception*.html')); +Assert::count(1, glob(TEMP_DIR . '/error*.html')); Assert::count(1, glob(TEMP_DIR . '/error.log')); diff --git a/tests/Tracy/Logger.log().phpt b/tests/Tracy/Logger.log().phpt index c8eee25ec..7dfa867b1 100644 --- a/tests/Tracy/Logger.log().phpt +++ b/tests/Tracy/Logger.log().phpt @@ -32,23 +32,23 @@ test(function () { test(function () { $logger = new Logger(TEMP_DIR); $logger->log(new ErrorException('Msg', 0, E_ERROR, __FILE__, __LINE__), 'c'); - Assert::match('[%a%] Fatal Error: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ exception-%a%.html', file_get_contents($logger->directory . '/c.log')); + Assert::match('[%a%] Fatal Error: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ c-%a%.html', file_get_contents($logger->directory . '/c.log')); }); test(function () { $logger = new Logger(TEMP_DIR); $logger->log(new ErrorException('Msg', 0, E_WARNING, __FILE__, __LINE__), 'd'); - Assert::match('[%a%] Warning: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ exception-%a%.html', file_get_contents($logger->directory . '/d.log')); + Assert::match('[%a%] Warning: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ d-%a%.html', file_get_contents($logger->directory . '/d.log')); }); test(function () { $logger = new Logger(TEMP_DIR); $logger->log(new ErrorException('Msg', 0, E_COMPILE_ERROR, __FILE__, __LINE__), 'e'); - Assert::match('[%a%] Compile Error: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ exception-%a%.html', file_get_contents($logger->directory . '/e.log')); + Assert::match('[%a%] Compile Error: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ e-%a%.html', file_get_contents($logger->directory . '/e.log')); }); test(function () { $logger = new Logger(TEMP_DIR); $logger->log(new ErrorException('Msg', 0, E_NOTICE, __FILE__, __LINE__), 'f'); - Assert::match('[%a%] Notice: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ exception-%a%.html', file_get_contents($logger->directory . '/f.log')); + Assert::match('[%a%] Notice: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ f-%a%.html', file_get_contents($logger->directory . '/f.log')); }); From 2fb8ad8898df92cd40c0f1dcb3c1a04cd7b51dbb Mon Sep 17 00:00:00 2001 From: David Grudl Date: Mon, 11 Mar 2019 23:57:52 +0100 Subject: [PATCH 06/18] TracyExtension: added getConfigSchema() --- composer.json | 7 +++- src/Bridges/Nette/TracyExtension.php | 57 +++++++++++++++------------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/composer.json b/composer.json index d06ea6f25..eebbafc97 100644 --- a/composer.json +++ b/composer.json @@ -20,11 +20,14 @@ "ext-json": "*" }, "require-dev": { - "nette/utils": "^2.4 || ^3.0", - "nette/di": "^2.4 || ~3.0.0", + "nette/utils": "^3.0", + "nette/di": "^3.0", "nette/tester": "^2.2", "psr/log": "^1.0" }, + "conflict": { + "nette/di": "<3.0" + }, "suggest": { "https://nette.org/donate": "Please support Tracy via a donation" }, diff --git a/src/Bridges/Nette/TracyExtension.php b/src/Bridges/Nette/TracyExtension.php index 6b82df021..b2d9102fa 100644 --- a/src/Bridges/Nette/TracyExtension.php +++ b/src/Bridges/Nette/TracyExtension.php @@ -10,6 +10,7 @@ namespace Tracy\Bridges\Nette; use Nette; +use Nette\Schema\Expect; use Tracy; @@ -18,26 +19,6 @@ */ class TracyExtension extends Nette\DI\CompilerExtension { - public $defaults = [ - 'email' => null, - 'fromEmail' => null, - 'logSeverity' => null, - 'editor' => null, - 'browser' => null, - 'errorTemplate' => null, - 'strictMode' => null, - 'showBar' => null, - 'maxLen' => null, - 'maxLength' => null, - 'maxDepth' => null, - 'showLocation' => null, - 'scream' => null, - 'bar' => [], // of class name - 'blueScreen' => [], // of callback - 'editorMapping' => [], - 'netteMailer' => true, - ]; - /** @var bool */ private $debugMode; @@ -52,9 +33,31 @@ public function __construct(bool $debugMode = false, bool $cliMode = false) } + public function getConfigSchema(): Nette\Schema\Schema + { + return Expect::structure([ + 'email' => Expect::email()->dynamic(), + 'fromEmail' => Expect::email()->dynamic(), + 'logSeverity' => Expect::scalar(), + 'editor' => Expect::string()->dynamic(), + 'browser' => Expect::string()->dynamic(), + 'errorTemplate' => Expect::string()->dynamic(), + 'strictMode' => Expect::bool()->dynamic(), + 'showBar' => Expect::bool()->dynamic(), + 'maxLength' => Expect::int()->dynamic(), + 'maxDepth' => Expect::int()->dynamic(), + 'showLocation' => Expect::bool()->dynamic(), + 'scream' => Expect::bool()->dynamic(), + 'bar' => Expect::listOf('class|Nette\DI\Definitions\Statement'), + 'blueScreen' => Expect::listOf('callable'), + 'editorMapping' => Expect::arrayOf('string')->dynamic(), + 'netteMailer' => Expect::bool(true), + ]); + } + + public function loadConfiguration() { - $this->validateConfig($this->defaults); $builder = $this->getContainerBuilder(); $builder->addDefinition($this->prefix('logger')) @@ -74,7 +77,7 @@ public function afterCompile(Nette\PhpGenerator\ClassType $class) $initialize = $class->getMethod('initialize'); $builder = $this->getContainerBuilder(); - $options = $this->config; + $options = (array) $this->config; unset($options['bar'], $options['blueScreen'], $options['netteMailer']); if (isset($options['logSeverity'])) { $res = 0; @@ -94,17 +97,17 @@ public function afterCompile(Nette\PhpGenerator\ClassType $class) } $logger = $builder->getDefinition($this->prefix('logger')); - if ($logger->getFactory()->getEntity() !== [Tracy\Debugger::class, 'getLogger']) { + if (!$logger instanceof Nette\DI\ServiceDefinition || $logger->getFactory()->getEntity() !== [Tracy\Debugger::class, 'getLogger']) { $initialize->addBody($builder->formatPhp('Tracy\Debugger::setLogger(?);', [$logger])); } - if ($this->config['netteMailer'] && $builder->getByType(Nette\Mail\IMailer::class)) { + if ($this->config->netteMailer && $builder->getByType(Nette\Mail\IMailer::class)) { $initialize->addBody($builder->formatPhp('Tracy\Debugger::getLogger()->mailer = ?;', [ - [new Nette\DI\Statement(Tracy\Bridges\Nette\MailSender::class, ['fromEmail' => $this->config['fromEmail']]), 'send'], + [new Nette\DI\Statement(Tracy\Bridges\Nette\MailSender::class, ['fromEmail' => $this->config->fromEmail]), 'send'], ])); } if ($this->debugMode) { - foreach ((array) $this->config['bar'] as $item) { + foreach ($this->config->bar as $item) { if (is_string($item) && substr($item, 0, 1) === '@') { $item = new Nette\DI\Statement(['@' . $builder::THIS_CONTAINER, 'getService'], [substr($item, 1)]); } elseif (is_string($item)) { @@ -122,7 +125,7 @@ public function afterCompile(Nette\PhpGenerator\ClassType $class) } } - foreach ((array) $this->config['blueScreen'] as $item) { + foreach ($this->config->blueScreen as $item) { $initialize->addBody($builder->formatPhp( '$this->getService(?)->addPanel(?);', Nette\DI\Helpers::filterArguments([$this->prefix('blueScreen'), $item]) From b174cc816d78626620bb2d5b78db46b3fe405250 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Tue, 6 Aug 2019 02:21:48 +0200 Subject: [PATCH 07/18] tested against PHP 7.4 --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 22c4a68a1..e9af3075c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ php: - 7.1 - 7.2 - 7.3 + - 7.4snapshot env: - PHP_BIN=php @@ -69,6 +70,7 @@ jobs: allow_failures: - stage: Static Analysis (informative) - stage: Code Coverage + - php: 7.4snapshot sudo: false From 3b69b81f315eec70f4738ee9f15ec0f426d04fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bar=C3=A1=C5=A1ek?= Date: Sat, 10 Aug 2019 22:02:35 +0200 Subject: [PATCH 08/18] InfoPanel: Add information about localhost IP. --- src/Tracy/Bar/panels/info.panel.phtml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Tracy/Bar/panels/info.panel.phtml b/src/Tracy/Bar/panels/info.panel.phtml index 4eb57c86c..9719299a1 100644 --- a/src/Tracy/Bar/panels/info.panel.phtml +++ b/src/Tracy/Bar/panels/info.panel.phtml @@ -25,6 +25,13 @@ $countClasses = function (array $list): int { })); }; +$ipFormatter = static function (?string $ip): ?string { + if ($ip === '127.0.0.1' || $ip === '::1') { + $ip .= ' (localhost)'; + } + return $ip; +}; + $opcache = function_exists('opcache_get_status') ? @opcache_get_status() : null; // @ can be restricted $cachedFiles = isset($opcache['scripts']) ? array_intersect(array_keys($opcache['scripts']), get_included_files()) : []; @@ -36,8 +43,8 @@ $info = [ 'OPcache' => $opcache ? round(count($cachedFiles) * 100 / count(get_included_files())) . '% cached' : null, 'Classes + interfaces + traits' => $countClasses(get_declared_classes()) . ' + ' . $countClasses(get_declared_interfaces()) . ' + ' . $countClasses(get_declared_traits()), - 'Your IP' => $_SERVER['REMOTE_ADDR'] ?? null, - 'Server IP' => $_SERVER['SERVER_ADDR'] ?? null, + 'Your IP' => $ipFormatter($_SERVER['REMOTE_ADDR'] ?? null), + 'Server IP' => $ipFormatter($_SERVER['SERVER_ADDR'] ?? null), 'HTTP method / response code' => isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] . ' / ' . http_response_code() : null, 'PHP' => PHP_VERSION, 'Xdebug' => extension_loaded('xdebug') ? phpversion('xdebug') : null, From 9f3b88face8d6702f4074d66a937b416320aae87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bar=C3=A1=C5=A1ek?= Date: Thu, 29 Aug 2019 16:03:26 +0200 Subject: [PATCH 09/18] Bridge: Remove redundant
     and 
    . --- src/Bridges/Nette/Bridge.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bridges/Nette/Bridge.php b/src/Bridges/Nette/Bridge.php index 0221cbe7c..407662ab8 100644 --- a/src/Bridges/Nette/Bridge.php +++ b/src/Bridges/Nette/Bridge.php @@ -58,7 +58,7 @@ public static function renderLatteError(?\Throwable $e): ?array 'panel' => '

    File: ' . Helpers::editorLink($templateFile, $templateLine) . '

    ' . ($templateLine === null ? '' - : '
    ' . BlueScreen::highlightFile($templateFile, $templateLine) . '
    '), + : BlueScreen::highlightFile($templateFile, $templateLine)), ]; } } From be4f4ac9224a0270c46c999d27da6c6e7b0e8e97 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Fri, 30 Aug 2019 13:24:19 +0200 Subject: [PATCH 10/18] BlueScreen: keysToHide respected in title [Closes #381] --- src/Tracy/BlueScreen/BlueScreen.php | 21 ++++++++++++--------- src/Tracy/BlueScreen/assets/content.phtml | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Tracy/BlueScreen/BlueScreen.php b/src/Tracy/BlueScreen/BlueScreen.php index 671ae9147..6fad73da1 100644 --- a/src/Tracy/BlueScreen/BlueScreen.php +++ b/src/Tracy/BlueScreen/BlueScreen.php @@ -240,11 +240,11 @@ private function renderActions(\Throwable $ex): array /** * Returns syntax highlighted source code. */ - public static function highlightFile(string $file, int $line, int $lines = 15, array $vars = []): ?string + public static function highlightFile(string $file, int $line, int $lines = 15, array $vars = [], array $keysToHide = []): ?string { $source = @file_get_contents($file); // @ file may not exist if ($source) { - $source = static::highlightPhp($source, $line, $lines, $vars); + $source = static::highlightPhp($source, $line, $lines, $vars, $keysToHide); if ($editor = Helpers::editorUri($file, $line)) { $source = substr_replace($source, ' data-tracy-href="' . Helpers::escapeHtml($editor) . '"', 4, 0); } @@ -256,7 +256,7 @@ public static function highlightFile(string $file, int $line, int $lines = 15, a /** * Returns syntax highlighted source code. */ - public static function highlightPhp(string $source, int $line, int $lines = 15, array $vars = []): string + public static function highlightPhp(string $source, int $line, int $lines = 15, array $vars = [], array $keysToHide = []): string { if (function_exists('ini_set')) { ini_set('highlight.comment', '#998; font-style: italic'); @@ -273,12 +273,15 @@ public static function highlightPhp(string $source, int $line, int $lines = 15, $out .= static::highlightLine($source, $line, $lines); if ($vars) { - $out = preg_replace_callback('#">\$(\w+)( )?#', function (array $m) use ($vars): string { - return array_key_exists($m[1], $vars) - ? '" title="' - . str_replace('"', '"', trim(strip_tags(Dumper::toHtml($vars[$m[1]], [Dumper::DEPTH => 1])))) - . $m[0] - : $m[0]; + $out = preg_replace_callback('#">\$(\w+)( )?#', function (array $m) use ($vars, $keysToHide): string { + if (array_key_exists($m[1], $vars)) { + $dump = Dumper::toHtml($vars[$m[1]], [ + Dumper::DEPTH => 1, + Dumper::KEYS_TO_HIDE => $keysToHide, + ]); + return '" title="' . str_replace('"', '"', trim(strip_tags($dump))) . $m[0]; + } + return $m[0]; }, $out); } diff --git a/src/Tracy/BlueScreen/assets/content.phtml b/src/Tracy/BlueScreen/assets/content.phtml index 80b6c79ec..88a293b5c 100644 --- a/src/Tracy/BlueScreen/assets/content.phtml +++ b/src/Tracy/BlueScreen/assets/content.phtml @@ -83,7 +83,7 @@ $code = $exception->getCode() ? ' #' . $exception->getCode() : '';

    File: getFile(), $ex->getLine()) ?>

    - getFile())): ?>getFile(), $ex->getLine(), 15, $ex instanceof \ErrorException && isset($ex->context) ? $ex->context : []) ?> + getFile())): ?>getFile(), $ex->getLine(), 15, $ex instanceof \ErrorException && isset($ex->context) ? $ex->context : [], $this->keysToHide) ?>
    From dba50097581bf9fa97fc8012e8bcee349440da41 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Fri, 30 Aug 2019 13:46:44 +0200 Subject: [PATCH 11/18] Dumper: hidden values are rendered with variable's type [Closes #380] --- src/Tracy/Dumper/Dumper.php | 24 ++++++++++++++++++------ tests/Tracy/Dumper.keysToHide.phpt | 24 ++++++++++++------------ 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/Tracy/Dumper/Dumper.php b/src/Tracy/Dumper/Dumper.php index d08f913ca..54e8ec6e8 100644 --- a/src/Tracy/Dumper/Dumper.php +++ b/src/Tracy/Dumper/Dumper.php @@ -297,10 +297,13 @@ private function dumpArray(&$var, array $options, int $level): string $out = $span . '>' . $out . count($var) . ")\n" . ''; $options['parents'][] = $var; foreach ($var as $k => &$v) { - $hide = is_string($k) && isset($this->keysToHide[strtolower($k)]) ? self::HIDDEN_VALUE : null; + $hide = is_string($k) && isset($this->keysToHide[strtolower($k)]); $out .= ' ' . str_repeat('| ', $level) . '' . '' . Helpers::escapeHtml($this->encodeKey($k)) . ' => ' - . ($hide ? $this->dumpString($hide) : $this->dumpVar($v, $options, $level + 1)); + . ($hide + ? Helpers::escapeHtml(self::hideValue($v)) . "\n" + : $this->dumpVar($v, $options, $level + 1) + ); } array_pop($options['parents']); @@ -361,10 +364,13 @@ private function dumpObject(&$var, array $options, int $level): string $vis = ' ' . ($k[1] === '*' ? 'protected' : 'private') . ''; $k = substr($k, strrpos($k, "\x00") + 1); } - $hide = is_string($k) && isset($this->keysToHide[strtolower($k)]) ? self::HIDDEN_VALUE : null; + $hide = is_string($k) && isset($this->keysToHide[strtolower($k)]); $out .= ' ' . str_repeat('| ', $level) . '' . '' . Helpers::escapeHtml($this->encodeKey($k)) . "$vis => " - . ($hide ? $this->dumpString($hide) : $this->dumpVar($v, $options, $level + 1)); + . ($hide + ? Helpers::escapeHtml(self::hideValue($v)) . "\n" + : $this->dumpVar($v, $options, $level + 1) + ); } array_pop($options['parents']); @@ -419,7 +425,7 @@ private function toJson(&$var, array $options = [], int $level = 0) $options['parents'][] = $var; foreach ($var as $k => &$v) { $hide = is_string($k) && isset($this->keysToHide[strtolower($k)]); - $res[] = [$this->encodeKey($k), $hide ? self::HIDDEN_VALUE : $this->toJson($v, $options, $level + 1)]; + $res[] = [$this->encodeKey($k), $hide ? ['type' => self::hideValue($v)] : $this->toJson($v, $options, $level + 1)]; } array_pop($options['parents']); return $res; @@ -456,7 +462,7 @@ private function toJson(&$var, array $options = [], int $level = 0) $k = substr($k, strrpos($k, "\x00") + 1); } $hide = is_string($k) && isset($this->keysToHide[strtolower($k)]); - $obj['items'][] = [$this->encodeKey($k), $hide ? self::HIDDEN_VALUE : $this->toJson($v, $options, $level + 1), $vis]; + $obj['items'][] = [$this->encodeKey($k), $hide ? ['type' => self::hideValue($v)] : $this->toJson($v, $options, $level + 1), $vis]; } } return ['object' => $obj['id']]; @@ -619,6 +625,12 @@ private static function exportPhpIncompleteClass(\__PHP_Incomplete_Class $obj): } + private static function hideValue($var): string + { + return self::HIDDEN_VALUE . ' (' . (is_object($var) ? Helpers::getClass($var) : gettype($var)) . ')'; + } + + /** * Finds the location where dump was called. Returns [file, line, code] */ diff --git a/tests/Tracy/Dumper.keysToHide.phpt b/tests/Tracy/Dumper.keysToHide.phpt index 054ef6182..fb523bdd1 100644 --- a/tests/Tracy/Dumper.keysToHide.phpt +++ b/tests/Tracy/Dumper.keysToHide.phpt @@ -26,14 +26,14 @@ $obj = (object) [ Assert::match('stdClass #%a% a => 456 - password => "*****" (5) - PASSWORD => "*****" (5) - Pin => "*****" (5) + password => ***** (string) + PASSWORD => ***** (string) + Pin => ***** (string) inner => array (4) | a => 123 - | password => "*****" (5) - | PASSWORD => "*****" (5) - | Pin => "*****" (5) + | password => ***** (string) + | PASSWORD => ***** (string) + | Pin => ***** (string) ', Dumper::toText($obj, [Dumper::KEYS_TO_HIDE => ['password', 'PIN']])); @@ -49,16 +49,16 @@ Assert::equal([ 'hash' => Expect::match('%h%'), 'items' => [ ['a', 456, 0], - ['password', '*****', 0], - ['PASSWORD', '*****', 0], - ['Pin', '*****', 0], + ['password', ['type' => '***** (string)'], 0], + ['PASSWORD', ['type' => '***** (string)'], 0], + ['Pin', ['type' => '***** (string)'], 0], [ 'inner', [ ['a', 123], - ['password', '*****'], - ['PASSWORD', '*****'], - ['Pin', '*****'], + ['password', ['type' => '***** (string)']], + ['PASSWORD', ['type' => '***** (string)']], + ['Pin', ['type' => '***** (string)']], ], 0, ], From 9270a2c89488bec38ee4e359758d3aa7d0c9be8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bar=C3=A1=C5=A1ek?= Date: Fri, 13 Sep 2019 11:39:39 +0200 Subject: [PATCH 12/18] Bridge: Template line can be null. (#384) --- src/Bridges/Nette/Bridge.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bridges/Nette/Bridge.php b/src/Bridges/Nette/Bridge.php index 407662ab8..d57d197b6 100644 --- a/src/Bridges/Nette/Bridge.php +++ b/src/Bridges/Nette/Bridge.php @@ -52,7 +52,7 @@ public static function renderLatteError(?\Throwable $e): ?array $lines = file($file); if (preg_match('#// source: (\S+\.latte)#', $lines[1], $m) && @is_file($m[1])) { // @ - may trigger error $templateFile = $m[1]; - $templateLine = preg_match('#/\* line (\d+) \*/#', $lines[$e->getLine() - 1], $m) ? (int) $m[1] : null; + $templateLine = $e->getLine() && preg_match('#/\* line (\d+) \*/#', $lines[$e->getLine() - 1], $m) ? (int) $m[1] : null; return [ 'tab' => 'Template', 'panel' => '

    File: ' . Helpers::editorLink($templateFile, $templateLine) . '

    ' From aeca31238aa57708f271c1f815548f17ae437306 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Fri, 13 Sep 2019 11:14:49 +0200 Subject: [PATCH 13/18] Dumper: added truncateString() --- src/Tracy/Dumper/Dumper.php | 64 +++++++++++++---------- tests/Tracy/Dumper.truncateString(().phpt | 29 ++++++++++ 2 files changed, 64 insertions(+), 29 deletions(-) create mode 100644 tests/Tracy/Dumper.truncateString(().phpt diff --git a/src/Tracy/Dumper/Dumper.php b/src/Tracy/Dumper/Dumper.php index 54e8ec6e8..45dec5672 100644 --- a/src/Tracy/Dumper/Dumper.php +++ b/src/Tracy/Dumper/Dumper.php @@ -504,39 +504,23 @@ public static function formatSnapshotAttribute(array &$snapshot): string */ public static function encodeString(string $s, int $maxLength = null): string { - static $table; - if ($table === null) { - foreach (array_merge(range("\x00", "\x1F"), range("\x7F", "\xFF")) as $ch) { - $table[$ch] = '\x' . str_pad(dechex(ord($ch)), 2, '0', STR_PAD_LEFT); - } - $table['\\'] = '\\\\'; - $table["\r"] = '\r'; - $table["\n"] = '\n'; - $table["\t"] = '\t'; - } - - if ($maxLength && strlen($s) > $maxLength) { // shortens to $maxLength in UTF-8 or longer - if (function_exists('mb_substr')) { - $s = mb_substr($tmp = $s, 0, $maxLength, 'UTF-8'); - $shortened = $s !== $tmp; - } else { - $i = $len = 0; - $maxI = $maxLength * 4; // max UTF-8 length - do { - if (($s[$i] < "\x80" || $s[$i] >= "\xC0") && (++$len > $maxLength) || $i >= $maxI) { - $s = substr($s, 0, $i); - $shortened = true; - break; - } - } while (isset($s[++$i])); - } + if ($maxLength) { + $s = self::truncateString($tmp = $s, $maxLength); + $shortened = $s !== $tmp; } if (preg_match('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u', $s) || preg_last_error()) { // is binary? - if ($maxLength && strlen($s) > $maxLength) { - $s = substr($s, 0, $maxLength); - $shortened = true; + static $table; + if ($table === null) { + foreach (array_merge(range("\x00", "\x1F"), range("\x7F", "\xFF")) as $ch) { + $table[$ch] = '\x' . str_pad(dechex(ord($ch)), 2, '0', STR_PAD_LEFT); + } + $table['\\'] = '\\\\'; + $table["\r"] = '\r'; + $table["\n"] = '\n'; + $table["\t"] = '\t'; } + $s = strtr($s, $table); } @@ -544,6 +528,28 @@ public static function encodeString(string $s, int $maxLength = null): string } + /** + * @internal + */ + public static function truncateString(string $s, int $maxLength): string + { + if (!preg_match('##u', $s)) { + $s = substr($s, 0, $maxLength); // not UTF-8 + } elseif (function_exists('mb_substr')) { + $s = mb_substr($s, 0, $maxLength, 'UTF-8'); + } else { + $i = $len = 0; + do { + if (($s[$i] < "\x80" || $s[$i] >= "\xC0") && (++$len > $maxLength)) { + $s = substr($s, 0, $i); + break; + } + } while (isset($s[++$i])); + } + return $s; + } + + /** * @param int|string $k * @return int|string diff --git a/tests/Tracy/Dumper.truncateString(().phpt b/tests/Tracy/Dumper.truncateString(().phpt new file mode 100644 index 000000000..0ec85cbfe --- /dev/null +++ b/tests/Tracy/Dumper.truncateString(().phpt @@ -0,0 +1,29 @@ + Date: Fri, 13 Sep 2019 14:34:05 +0200 Subject: [PATCH 14/18] Debugger: workaround for PHP bug #77722 --- src/Tracy/Debugger/Debugger.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Tracy/Debugger/Debugger.php b/src/Tracy/Debugger/Debugger.php index 8e7b0ce6f..6790f09aa 100644 --- a/src/Tracy/Debugger/Debugger.php +++ b/src/Tracy/Debugger/Debugger.php @@ -602,6 +602,7 @@ public static function detectDebugMode($list = null): bool if (!isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !isset($_SERVER['HTTP_FORWARDED'])) { $list[] = '127.0.0.1'; $list[] = '::1'; + $list[] = '[::1]'; // workaround for PHP < 7.3.4 } return in_array($addr, $list, true) || in_array("$secret@$addr", $list, true); } From eb59baf337f61a6ead13127ee7e9b54c87ab550c Mon Sep 17 00:00:00 2001 From: David Grudl Date: Fri, 13 Sep 2019 14:42:57 +0200 Subject: [PATCH 15/18] fixes for PHP 7.4 --- src/Tracy/Debugger/Debugger.php | 2 +- tests/Tracy/Debugger.E_RECOVERABLE_ERROR.phpt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Tracy/Debugger/Debugger.php b/src/Tracy/Debugger/Debugger.php index 6790f09aa..e7b328943 100644 --- a/src/Tracy/Debugger/Debugger.php +++ b/src/Tracy/Debugger/Debugger.php @@ -262,7 +262,7 @@ public static function shutdownHandler(): void self::$reserved = null; $error = error_get_last(); - if (in_array($error['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE, E_RECOVERABLE_ERROR, E_USER_ERROR], true)) { + if (in_array($error['type'] ?? null, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE, E_RECOVERABLE_ERROR, E_USER_ERROR], true)) { self::exceptionHandler( Helpers::fixStack(new ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line'])), false diff --git a/tests/Tracy/Debugger.E_RECOVERABLE_ERROR.phpt b/tests/Tracy/Debugger.E_RECOVERABLE_ERROR.phpt index 90be618c1..6321dea7d 100644 --- a/tests/Tracy/Debugger.E_RECOVERABLE_ERROR.phpt +++ b/tests/Tracy/Debugger.E_RECOVERABLE_ERROR.phpt @@ -2,6 +2,7 @@ /** * Test: Tracy\Debugger E_RECOVERABLE_ERROR error. + * @phpversion < 7.4 */ declare(strict_types=1); From d97208b176e5ded25e4039155633e32e645f1b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bar=C3=A1=C5=A1ek?= Date: Fri, 13 Sep 2019 15:07:35 +0200 Subject: [PATCH 16/18] Bluescreen: added length limit for exception message (#383) --- src/Tracy/BlueScreen/BlueScreen.php | 4 +++- src/Tracy/BlueScreen/assets/content.phtml | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Tracy/BlueScreen/BlueScreen.php b/src/Tracy/BlueScreen/BlueScreen.php index 6fad73da1..7f1a4ae87 100644 --- a/src/Tracy/BlueScreen/BlueScreen.php +++ b/src/Tracy/BlueScreen/BlueScreen.php @@ -15,6 +15,8 @@ */ class BlueScreen { + private const MAX_MESSAGE_LENGTH = 2000; + /** @var string[] */ public $info = []; @@ -112,7 +114,7 @@ private function renderTemplate(\Throwable $exception, string $template, $toScre $messageHtml = preg_replace( '#\'\S(?:[^\']|\\\\\')*\S\'|"\S(?:[^"]|\\\\")*\S"#', '$0', - htmlspecialchars((string) $exception->getMessage(), ENT_SUBSTITUTE, 'UTF-8') + htmlspecialchars(Dumper::encodeString((string) $exception->getMessage(), self::MAX_MESSAGE_LENGTH), ENT_SUBSTITUTE, 'UTF-8') ); $info = array_filter($this->info); $source = Helpers::getSource(); diff --git a/src/Tracy/BlueScreen/assets/content.phtml b/src/Tracy/BlueScreen/assets/content.phtml index 88a293b5c..0a7404bbc 100644 --- a/src/Tracy/BlueScreen/assets/content.phtml +++ b/src/Tracy/BlueScreen/assets/content.phtml @@ -29,10 +29,10 @@ $code = $exception->getCode() ? ' #' . $exception->getCode() : '';
    - getMessage()): ?>

    + getMessage()): ?>

    -

    +

    >

    From dd17b8e5506dd79c77afce3f0743cf1b7d18db53 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 18 Sep 2019 20:23:35 +0200 Subject: [PATCH 17/18] tests: TEMP_DIR replaced with getTempDir() --- tests/Tracy/Debugger.log().error.phpt | 4 +-- tests/Tracy/Debugger.log().samefile.phpt | 6 ++-- ...gger.logSeverity.E_NOTICE.development.phpt | 6 ++-- .../Tracy/Debugger.logSeverity.E_NOTICE.phpt | 6 ++-- tests/Tracy/Debugger.logging.error.phpt | 2 +- tests/Tracy/Debugger.logging.warnings.phpt | 2 +- tests/Tracy/Logger.extensible.phpt | 4 +-- tests/Tracy/Logger.log().errors.phpt | 8 +++--- tests/Tracy/Logger.log().phpt | 12 ++++---- tests/bootstrap.php | 28 +++++++++++++++---- 10 files changed, 47 insertions(+), 31 deletions(-) diff --git a/tests/Tracy/Debugger.log().error.phpt b/tests/Tracy/Debugger.log().error.phpt index 8951e5670..c9f24601b 100644 --- a/tests/Tracy/Debugger.log().error.phpt +++ b/tests/Tracy/Debugger.log().error.phpt @@ -19,11 +19,11 @@ Assert::exception(function () { // no error -Debugger::$logDirectory = TEMP_DIR; +Debugger::$logDirectory = getTempDir(); Debugger::log('Hello'); -Debugger::$logDirectory = TEMP_DIR . '/unknown'; +Debugger::$logDirectory = getTempDir() . '/unknown'; Assert::exception(function () { Debugger::log('Hello'); }, 'RuntimeException', "Logging directory '%a%' is not found or is not directory."); diff --git a/tests/Tracy/Debugger.log().samefile.phpt b/tests/Tracy/Debugger.log().samefile.phpt index 70afe81a9..212825168 100644 --- a/tests/Tracy/Debugger.log().samefile.phpt +++ b/tests/Tracy/Debugger.log().samefile.phpt @@ -14,7 +14,7 @@ require __DIR__ . '/../bootstrap.php'; // Setup environment -Debugger::$logDirectory = TEMP_DIR; +Debugger::$logDirectory = getTempDir(); function foo($fp) @@ -24,9 +24,9 @@ function foo($fp) for ($i = 0; $i < 3; $i++) { - $path = TEMP_DIR . "/$i"; + $path = getTempDir() . "/$i"; try { - $files[] = $file = fopen(TEMP_DIR . "/$i", 'w'); + $files[] = $file = fopen(getTempDir() . "/$i", 'w'); foo($file); } catch (Exception $e) { $name[] = Debugger::log($e); diff --git a/tests/Tracy/Debugger.logSeverity.E_NOTICE.development.phpt b/tests/Tracy/Debugger.logSeverity.E_NOTICE.development.phpt index 0d641dfa2..0292154a7 100644 --- a/tests/Tracy/Debugger.logSeverity.E_NOTICE.development.phpt +++ b/tests/Tracy/Debugger.logSeverity.E_NOTICE.development.phpt @@ -14,10 +14,10 @@ require __DIR__ . '/../bootstrap.php'; // Setup environment -Debugger::enable(Debugger::DEVELOPMENT, TEMP_DIR); +Debugger::enable(Debugger::DEVELOPMENT, getTempDir()); Debugger::$logSeverity = E_NOTICE; $variable = $missingVariable; -Assert::count(0, glob(TEMP_DIR . '/exception*.html')); -Assert::count(0, glob(TEMP_DIR . '/error.log')); +Assert::count(0, glob(getTempDir() . '/exception*.html')); +Assert::count(0, glob(getTempDir() . '/error.log')); diff --git a/tests/Tracy/Debugger.logSeverity.E_NOTICE.phpt b/tests/Tracy/Debugger.logSeverity.E_NOTICE.phpt index 560c4b968..647857f35 100644 --- a/tests/Tracy/Debugger.logSeverity.E_NOTICE.phpt +++ b/tests/Tracy/Debugger.logSeverity.E_NOTICE.phpt @@ -14,10 +14,10 @@ require __DIR__ . '/../bootstrap.php'; // Setup environment -Debugger::enable(Debugger::PRODUCTION, TEMP_DIR); +Debugger::enable(Debugger::PRODUCTION, getTempDir()); Debugger::$logSeverity = E_NOTICE; $variable = $missingVariable; -Assert::count(1, glob(TEMP_DIR . '/error*.html')); -Assert::count(1, glob(TEMP_DIR . '/error.log')); +Assert::count(1, glob(getTempDir() . '/error*.html')); +Assert::count(1, glob(getTempDir() . '/error.log')); diff --git a/tests/Tracy/Debugger.logging.error.phpt b/tests/Tracy/Debugger.logging.error.phpt index bd6d6c329..d10d9bf2b 100644 --- a/tests/Tracy/Debugger.logging.error.phpt +++ b/tests/Tracy/Debugger.logging.error.phpt @@ -19,7 +19,7 @@ require __DIR__ . '/../bootstrap.php'; // Setup environment $_SERVER['HTTP_HOST'] = 'nette.org'; -Debugger::$logDirectory = TEMP_DIR; +Debugger::$logDirectory = getTempDir(); Debugger::getLogger()->mailer = function () {}; diff --git a/tests/Tracy/Debugger.logging.warnings.phpt b/tests/Tracy/Debugger.logging.warnings.phpt index 1b84f4abe..6e7f42283 100644 --- a/tests/Tracy/Debugger.logging.warnings.phpt +++ b/tests/Tracy/Debugger.logging.warnings.phpt @@ -16,7 +16,7 @@ require __DIR__ . '/../bootstrap.php'; // Setup environment $_SERVER['HTTP_HOST'] = 'nette.org'; -$logDirectory = TEMP_DIR; +$logDirectory = getTempDir(); Debugger::getLogger()->mailer = function () {}; diff --git a/tests/Tracy/Logger.extensible.phpt b/tests/Tracy/Logger.extensible.phpt index 6226fac3b..8143f12d3 100644 --- a/tests/Tracy/Logger.extensible.phpt +++ b/tests/Tracy/Logger.extensible.phpt @@ -37,7 +37,7 @@ class CustomLogger extends Logger test(function () { - $logger = new CustomLogger(TEMP_DIR); + $logger = new CustomLogger(getTempDir()); $logger->log(new Exception('First'), 'a'); Assert::match('a', $logger->collector[0][0]); @@ -47,7 +47,7 @@ test(function () { }); test(function () { - $logger = new CustomLogger(TEMP_DIR); + $logger = new CustomLogger(getTempDir()); $logger->log('message', 'b'); Assert::match('b', $logger->collector[0][0]); diff --git a/tests/Tracy/Logger.log().errors.phpt b/tests/Tracy/Logger.log().errors.phpt index 31bc82729..311391c81 100644 --- a/tests/Tracy/Logger.log().errors.phpt +++ b/tests/Tracy/Logger.log().errors.phpt @@ -13,18 +13,18 @@ use Tracy\Logger; require __DIR__ . '/../bootstrap.php'; -$logger = new Logger(TEMP_DIR); +$logger = new Logger(getTempDir()); $logger->log('Hello'); // no error Assert::exception(function () { - $logger = new Logger(TEMP_DIR . '/unknown'); + $logger = new Logger(getTempDir() . '/unknown'); $logger->log('Hello'); }, 'RuntimeException', "Logging directory '%a%' is not found or is not directory."); Assert::exception(function () { - $logger = new Logger(TEMP_DIR); - mkdir(TEMP_DIR . '/test.log'); + $logger = new Logger(getTempDir()); + mkdir(getTempDir() . '/test.log'); $logger->log('Hello', 'test'); }, 'RuntimeException', "Unable to write to log file '%a%'. Is directory writable?"); diff --git a/tests/Tracy/Logger.log().phpt b/tests/Tracy/Logger.log().phpt index 7dfa867b1..1c47d0ba5 100644 --- a/tests/Tracy/Logger.log().phpt +++ b/tests/Tracy/Logger.log().phpt @@ -15,7 +15,7 @@ require __DIR__ . '/../bootstrap.php'; test(function () { $e = new Exception('First'); - $logger = new Logger(TEMP_DIR); + $logger = new Logger(getTempDir()); $logger->log($e, 'a'); Assert::match('[%a%] Exception: First in %a%:%d% %A%', file_get_contents($logger->directory . '/a.log')); }); @@ -24,31 +24,31 @@ test(function () { $e = new Exception('First'); $e = new InvalidArgumentException('Second', 0, $e); $e = new RuntimeException('Third', 0, $e); - $logger = new Logger(TEMP_DIR); + $logger = new Logger(getTempDir()); $logger->log($e, 'b'); Assert::match('[%a%] RuntimeException: Third in %a%:%d% caused by InvalidArgumentException: Second in %a%:%d% caused by Exception: First in %a%:%d% %A%', file_get_contents($logger->directory . '/b.log')); }); test(function () { - $logger = new Logger(TEMP_DIR); + $logger = new Logger(getTempDir()); $logger->log(new ErrorException('Msg', 0, E_ERROR, __FILE__, __LINE__), 'c'); Assert::match('[%a%] Fatal Error: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ c-%a%.html', file_get_contents($logger->directory . '/c.log')); }); test(function () { - $logger = new Logger(TEMP_DIR); + $logger = new Logger(getTempDir()); $logger->log(new ErrorException('Msg', 0, E_WARNING, __FILE__, __LINE__), 'd'); Assert::match('[%a%] Warning: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ d-%a%.html', file_get_contents($logger->directory . '/d.log')); }); test(function () { - $logger = new Logger(TEMP_DIR); + $logger = new Logger(getTempDir()); $logger->log(new ErrorException('Msg', 0, E_COMPILE_ERROR, __FILE__, __LINE__), 'e'); Assert::match('[%a%] Compile Error: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ e-%a%.html', file_get_contents($logger->directory . '/e.log')); }); test(function () { - $logger = new Logger(TEMP_DIR); + $logger = new Logger(getTempDir()); $logger->log(new ErrorException('Msg', 0, E_NOTICE, __FILE__, __LINE__), 'f'); Assert::match('[%a%] Notice: Msg in %a%Logger.log().phpt:%d% @ CLI (PID: %d%): %a% @@ f-%a%.html', file_get_contents($logger->directory . '/f.log')); }); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index d443f15ca..8733d39bb 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -16,12 +16,7 @@ date_default_timezone_set('Europe/Prague'); ini_set('serialize_precision', '14'); $_GET = $_POST = $_COOKIE = []; - - -// create temporary directory -define('TEMP_DIR', __DIR__ . '/tmp/' . getmypid()); -@mkdir(dirname(TEMP_DIR)); // @ - directory may already exist -Tester\Helpers::purge(TEMP_DIR); +define('USER_CONST', 1); if (extension_loaded('xdebug')) { @@ -29,6 +24,27 @@ } +function getTempDir(): string +{ + $dir = __DIR__ . '/tmp/' . getmypid(); + + if (empty($GLOBALS['\\lock'])) { + // garbage collector + $GLOBALS['\\lock'] = $lock = fopen(__DIR__ . '/lock', 'w'); + if (rand(0, 100)) { + flock($lock, LOCK_SH); + @mkdir(dirname($dir)); + } elseif (flock($lock, LOCK_EX)) { + Tester\Helpers::purge(dirname($dir)); + } + + @mkdir($dir); + } + + return $dir; +} + + function test(\Closure $function): void { $function(); From 5c1a93cb763886482ddc80e139dd424c2a0180df Mon Sep 17 00:00:00 2001 From: Ondrej Date: Tue, 24 Sep 2019 10:23:08 +0200 Subject: [PATCH 18/18] Bar: ignore pannels --- src/Tracy/Bar/Bar.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Tracy/Bar/Bar.php b/src/Tracy/Bar/Bar.php index e105a505c..db4d4d6a1 100644 --- a/src/Tracy/Bar/Bar.php +++ b/src/Tracy/Bar/Bar.php @@ -24,6 +24,8 @@ class Bar /** @var string|NULL generated by renderLoader() */ private $contentId; + /** @var array|string[] */ + private $ignorePanels = []; /** * Add custom panel. @@ -52,6 +54,16 @@ public function getPanel(string $id): ?IBarPanel /** + * @param string $panelId + * @return static + */ + public function ignorePanel(string $panelId) { + $this->ignorePanels[] = $panelId; + return $this; + } + + + /** * Renders loading