Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.11-dev"
"dev-master": "3.0-dev"
}
}
}
13 changes: 12 additions & 1 deletion examples/dump.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,23 @@
echo "<h2>Objects</h2>\n";
echo "<p>Hover over the name <code>\$baz</code> to see property declaring class and over the hash <code>#5</code> to see same objects.</p>\n";

enum Suit
{
case Clubs;
case Diamonds;
case Hearts;
case Spades;
}

class ParentClass
{
public $foo = [10, 20];

protected $bar = 30;

private $baz = 'parent';

public Suit $enum = Suit::Clubs;
}

#[\AllowDynamicProperties]
Expand Down Expand Up @@ -87,7 +97,8 @@ class ChildClass extends ParentClass

$arr = [
fopen(__FILE__, 'r'),
new class {},
new class {
},
function ($x, $y) use (&$arr, $obj) {},
];

Expand Down
15 changes: 10 additions & 5 deletions src/Bridges/Nette/TracyExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,25 @@
foreach ($options as $key => $value) {
if ($value !== null) {
$tbl = [
'keysToHide' => 'array_push(Tracy\Debugger::getBlueScreen()->keysToHide, ... ?)',
'fromEmail' => 'if ($logger instanceof Tracy\Logger) $logger->fromEmail = ?',
'emailSnooze' => 'if ($logger instanceof Tracy\Logger) $logger->emailSnooze = ?',
'keysToHide' => [
'$keysToHide = ?',
'array_push(Tracy\Debugger::$keysToHide, ...$keysToHide)',
'array_push(Tracy\Debugger::getBlueScreen()->keysToHide, ...$keysToHide)',
'array_push(Nette\Bridges\DITracy\ContainerPanel::$keysToHide, ...$keysToHide)',
],
'fromEmail' => ['if ($logger instanceof Tracy\Logger) $logger->fromEmail = ?'],
'emailSnooze' => ['if ($logger instanceof Tracy\Logger) $logger->emailSnooze = ?'],
];
$initialize->addBody($builder->formatPhp(
($tbl[$key] ?? 'Tracy\Debugger::$' . $key . ' = ?') . ';',
(isset($tbl[$key]) ? implode(";\n", $tbl[$key]) : ('Tracy\Debugger::$' . $key . ' = ?')) . ';',
Nette\DI\Helpers::filterArguments([$value]),
));
}
}

if ($this->config->netteMailer && $builder->getByType(Nette\Mail\IMailer::class)) {

Check failure on line 124 in src/Bridges/Nette/TracyExtension.php

View workflow job for this annotation

GitHub Actions / PHPStan

Cannot access property $netteMailer on array|object.
$params = [];
$params['fromEmail'] = $this->config->fromEmail;

Check failure on line 126 in src/Bridges/Nette/TracyExtension.php

View workflow job for this annotation

GitHub Actions / PHPStan

Cannot access property $fromEmail on array|object.
if (class_exists(Nette\Http\Request::class)) {
$params['host'] = new Statement('$this->getByType(?, false)\?->getUrl()->getHost()', [Nette\Http\Request::class]);
}
Expand All @@ -129,9 +134,9 @@
}

if ($this->debugMode) {
foreach ($this->config->bar as $item) {

Check failure on line 137 in src/Bridges/Nette/TracyExtension.php

View workflow job for this annotation

GitHub Actions / PHPStan

Cannot access property $bar on array|object.
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);
}
Expand All @@ -152,7 +157,7 @@
}
}

foreach ($this->config->blueScreen as $item) {

Check failure on line 160 in src/Bridges/Nette/TracyExtension.php

View workflow job for this annotation

GitHub Actions / PHPStan

Cannot access property $blueScreen on array|object.
$initialize->addBody($builder->formatPhp(
'$this->getService(?)->addPanel(?);',
Nette\DI\Helpers::filterArguments([$this->prefix('blueScreen'), $item]),
Expand Down
2 changes: 1 addition & 1 deletion src/Tracy/BlueScreen/BlueScreen.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
/** @var callable[] functions that returns action for exceptions */
private array $actions = [];
private array $fileGenerators = [];
private ?array $snapshot = null;

Check failure on line 50 in src/Tracy/BlueScreen/BlueScreen.php

View workflow job for this annotation

GitHub Actions / PHPStan

Property Tracy\BlueScreen::$snapshot (array|null) is never assigned array so it can be removed from the property type.

/** @var \WeakMap<\Fiber|\Generator> */
private \WeakMap $fibers;
Expand Down Expand Up @@ -321,7 +321,7 @@
? CodeHighlighter::highlightPhp($source, $line, $column)
: '<pre class=tracy-code><div>' . CodeHighlighter::highlightLine(htmlspecialchars($source, ENT_IGNORE, 'UTF-8'), $line, $column) . '</div></pre>';

if ($editor = Helpers::editorUri($file, $line)) {
if ($editor = Helpers::editorUri($file, line: $line, column: $column)) {
$source = substr_replace($source, ' title="Ctrl-Click to open in editor" data-tracy-href="' . Helpers::escapeHtml($editor) . '"', 4, 0);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Tracy/BlueScreen/assets/section-stack-callStack.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ if (!$stack) {
</div>

<div class="tracy-tab-panel<?= $sourceMapped['active'] ? ' tracy-active' : '' ?>">
<?= BlueScreen::highlightFile($sourceMapped['file'], $sourceMapped['line'], php: false) ?>
<?= BlueScreen::highlightFile($sourceMapped['file'], line: $sourceMapped['line'] ?? 0, column: $sourceMapped['column'] ?? 0, php: false) ?>
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/Tracy/BlueScreen/assets/section-stack-sourceFile.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ $sourceMapped = $sourceOriginal ? Debugger::mapSource($file, $line) : null;

<div class="tracy-tab-panel<?= $sourceMapped['active'] ? ' tracy-active' : '' ?>">
<p><b>File:</b> <?= Helpers::editorLink($sourceMapped['file'], $sourceMapped['line']) ?></p>
<?= BlueScreen::highlightFile($sourceMapped['file'], $sourceMapped['line'], php: false) ?>
<?= BlueScreen::highlightFile($sourceMapped['file'], line: $sourceMapped['line'] ?? 0, column: $sourceMapped['column'] ?? 0, php: false) ?>
</div>
</div>
</div>
Expand Down
15 changes: 8 additions & 7 deletions src/Tracy/Debugger/Debugger.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 */
Expand Down Expand Up @@ -552,6 +552,7 @@ public static function barDump(mixed $var, ?string $title = null, array $options
Dumper::TRUNCATE => self::$maxLength,
Dumper::LOCATION => self::$showLocation ?: Dumper::LOCATION_CLASS | Dumper::LOCATION_SOURCE,
Dumper::LAZY => true,
Dumper::KEYS_TO_HIDE => self::$keysToHide,
])];
}

Expand Down Expand Up @@ -586,7 +587,7 @@ public static function addSourceMapper(callable $mapper): void
}


/** @return array{file: string, line: int, label: string, active: bool} */
/** @return array{file: string, line: int, column: int, label: string, active: bool} */
public static function mapSource(string $file, int $line): ?array
{
foreach (self::$sourceMappers as $mapper) {
Expand Down
2 changes: 1 addition & 1 deletion src/Tracy/Debugger/ProductionStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}


Expand Down
24 changes: 24 additions & 0 deletions src/Tracy/Dumper/Exposer.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ final class Exposer
{
public static function exposeObject(object $obj, Value $value, Describer $describer): void
{
if (PHP_VERSION_ID >= 80400 && (new \ReflectionClass($obj))->isUninitializedLazyObject($obj)) {
self::exposeLazyObject($obj, $describer, $value);
return;
}

$values = get_mangled_object_vars($obj);
$props = self::getProperties($obj::class);

Expand Down Expand Up @@ -276,4 +281,23 @@ public static function exposeDsMap(
$describer->addPropertyTo($value, (string) $i++, new Ds\Pair($k, $v));
}
}


private static function exposeLazyObject(object $obj, Describer $describer, Value $value): void
{
$rc = new \ReflectionClass($obj);
foreach ($rc->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) {
if (!$prop->isLazy($obj)) {
$describer->addPropertyTo(
$value,
$prop->getName(),
$prop->getValue($obj),
Value::PropertyPublic,
described: $describer->describeEnumProperty($obj::class, $prop->getName(), $prop->getValue($obj)),
);
}
}

$value->value .= ' (lazy)';
}
}
3 changes: 2 additions & 1 deletion src/Tracy/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static function editorUri(
string $action = 'open',
string $search = '',
string $replace = '',
?int $column = null,
): ?string
{
if (Debugger::$editor && $file && ($action === 'create' || @is_file($file))) { // @ - may trigger error
Expand All @@ -67,7 +68,7 @@ public static function editorUri(
return strtr(Debugger::$editor, [
'%action' => $action,
'%file' => rawurlencode($file),
'%line' => $line ?: 1,
'%line' => ($line ?: 1) . ($column ? ':' . $column : ''),
'%search' => rawurlencode($search),
'%replace' => rawurlencode($replace),
]);
Expand Down
37 changes: 13 additions & 24 deletions src/Tracy/Logger/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand All @@ -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]'),
Expand Down Expand Up @@ -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
Expand All @@ -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(
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
56 changes: 56 additions & 0 deletions tests/Dumper/Dumper.toHtml().specials.lazyObject.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

/**
* Test: Tracy\Dumper::toHtml() & lazy object
* @phpversion 8.4
*/

declare(strict_types=1);

use Tester\Assert;
use Tracy\Dumper;

require __DIR__ . '/../bootstrap.php';


class LazyClass
{
public function __construct(
public int $id,
public string $title,
) {
}
}

$rc = new ReflectionClass(LazyClass::class);
$ghost = $rc->newLazyGhost(function () {});

// new ghost
Assert::match(
<<<'XX'
<pre class="tracy-dump tracy-light"><span class="tracy-dump-object">LazyClass (lazy)</span> <span class="tracy-dump-hash">#%d%</span></pre>
XX,
Dumper::toHtml($ghost, [Dumper::DEPTH => 3]),
);

// preinitialized property
$rc->getProperty('id')->setRawValueWithoutLazyInitialization($ghost, 123);

Assert::match(
<<<'XX'
<pre class="tracy-dump tracy-light"
><span class="tracy-toggle"><span class="tracy-dump-object">LazyClass (lazy)</span> <span class="tracy-dump-hash">#%d%</span></span>
<div><span class="tracy-dump-indent"> </span><span class="tracy-dump-public">id</span>: <span class="tracy-dump-number">123</span>
</div></pre>
XX,
Dumper::toHtml($ghost, [Dumper::DEPTH => 3]),
);

// proxy
$proxy = $rc->newLazyProxy(function () { return new LazyClass; });
Assert::match(
<<<'XX'
<pre class="tracy-dump tracy-light"><span class="tracy-dump-object">LazyClass (lazy)</span> <span class="tracy-dump-hash">#%d%</span></pre>
XX,
Dumper::toHtml($proxy, [Dumper::DEPTH => 3]),
);
File renamed without changes.
Loading
Loading