update patch 1
This commit is contained in:
+6
@@ -1,6 +1,12 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
7.2
|
||||
---
|
||||
|
||||
* Add support for `FORCE_COLOR` environment variable
|
||||
* Add support for virtual properties
|
||||
|
||||
7.1
|
||||
---
|
||||
|
||||
|
||||
+2
-3
@@ -42,10 +42,9 @@ class ArgsStub extends EnumStub
|
||||
$params[] = $variadic;
|
||||
}
|
||||
if (['...'] === $params) {
|
||||
$this->dumpKeys = false;
|
||||
$this->value = $values[0]->value;
|
||||
parent::__construct($values[0]->value, false);
|
||||
} else {
|
||||
$this->value = array_combine($params, $values);
|
||||
parent::__construct(array_combine($params, $values));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -190,7 +190,7 @@ class Caster
|
||||
$p->isPublic() => $p->name,
|
||||
$p->isProtected() => self::PREFIX_PROTECTED.$p->name,
|
||||
default => "\0".$className."\0".$p->name,
|
||||
}] = new UninitializedStub($p);
|
||||
}] = \PHP_VERSION_ID >= 80400 && $p->isVirtual() ? new VirtualStub($p) : new UninitializedStub($p);
|
||||
}
|
||||
|
||||
return $classProperties;
|
||||
|
||||
+4
-4
@@ -93,16 +93,16 @@ class DateCaster
|
||||
foreach (clone $p as $i => $d) {
|
||||
if (self::PERIOD_LIMIT === $i) {
|
||||
$now = new \DateTimeImmutable('now', new \DateTimeZone('UTC'));
|
||||
$dates[] = sprintf('%s more', ($end = $p->getEndDate())
|
||||
$dates[] = \sprintf('%s more', ($end = $p->getEndDate())
|
||||
? ceil(($end->format('U.u') - $d->format('U.u')) / ((int) $now->add($p->getDateInterval())->format('U.u') - (int) $now->format('U.u')))
|
||||
: $p->recurrences - $i
|
||||
);
|
||||
break;
|
||||
}
|
||||
$dates[] = sprintf('%s) %s', $i + 1, self::formatDateTime($d));
|
||||
$dates[] = \sprintf('%s) %s', $i + 1, self::formatDateTime($d));
|
||||
}
|
||||
|
||||
$period = sprintf(
|
||||
$period = \sprintf(
|
||||
'every %s, from %s%s %s',
|
||||
self::formatInterval($p->getDateInterval()),
|
||||
$p->include_start_date ? '[' : ']',
|
||||
@@ -122,6 +122,6 @@ class DateCaster
|
||||
|
||||
private static function formatSeconds(string $s, string $us): string
|
||||
{
|
||||
return sprintf('%02d.%s', $s, 0 === ($len = \strlen($t = rtrim($us, '0'))) ? '0' : ($len <= 3 ? str_pad($t, 3, '0') : $us));
|
||||
return \sprintf('%02d.%s', $s, 0 === ($len = \strlen($t = rtrim($us, '0'))) ? '0' : ($len <= 3 ? str_pad($t, 3, '0') : $us));
|
||||
}
|
||||
}
|
||||
|
||||
+4
-5
@@ -20,11 +20,10 @@ use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
*/
|
||||
class EnumStub extends Stub
|
||||
{
|
||||
public bool $dumpKeys = true;
|
||||
|
||||
public function __construct(array $values, bool $dumpKeys = true)
|
||||
{
|
||||
public function __construct(
|
||||
array $values,
|
||||
public bool $dumpKeys = true,
|
||||
) {
|
||||
$this->value = $values;
|
||||
$this->dumpKeys = $dumpKeys;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -174,7 +174,7 @@ class ExceptionCaster
|
||||
} else {
|
||||
$label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$lastCall;
|
||||
}
|
||||
$a[substr_replace($label, sprintf('separator=%s&', $frame instanceof EnumStub ? ' ' : ':'), 2, 0)] = $frame;
|
||||
$a[substr_replace($label, \sprintf('separator=%s&', $frame instanceof EnumStub ? ' ' : ':'), 2, 0)] = $frame;
|
||||
|
||||
$lastCall = $call;
|
||||
}
|
||||
@@ -219,7 +219,7 @@ class ExceptionCaster
|
||||
if (isset($f['object'])) {
|
||||
$template = $f['object'];
|
||||
} elseif ((new \ReflectionClass($f['class']))->isInstantiable()) {
|
||||
$template = unserialize(sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class']));
|
||||
$template = unserialize(\sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class']));
|
||||
}
|
||||
if (null !== $template) {
|
||||
$ellipsis = 0;
|
||||
@@ -243,7 +243,7 @@ class ExceptionCaster
|
||||
$ellipsis += 1 + \strlen($f['line']);
|
||||
}
|
||||
}
|
||||
$srcAttr .= sprintf('&separator= &file=%s&line=%d', rawurlencode($f['file']), $f['line']);
|
||||
$srcAttr .= \sprintf('&separator= &file=%s&line=%d', rawurlencode($f['file']), $f['line']);
|
||||
} else {
|
||||
$srcAttr .= '&separator=:';
|
||||
}
|
||||
@@ -271,7 +271,7 @@ class ExceptionCaster
|
||||
public static function castFlattenException(FlattenException $e, array $a, Stub $stub, bool $isNested): array
|
||||
{
|
||||
if ($isNested) {
|
||||
$k = sprintf(Caster::PATTERN_PRIVATE, FlattenException::class, 'traceAsString');
|
||||
$k = \sprintf(Caster::PATTERN_PRIVATE, FlattenException::class, 'traceAsString');
|
||||
$a[$k] = new CutStub($a[$k]);
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ class ExceptionCaster
|
||||
}
|
||||
}
|
||||
$c->attr['lang'] = $lang;
|
||||
$srcLines[sprintf("\0~separator=› &%d\0", $i + $line - $srcContext)] = $c;
|
||||
$srcLines[\sprintf("\0~separator=› &%d\0", $i + $line - $srcContext)] = $c;
|
||||
}
|
||||
|
||||
return new EnumStub($srcLines);
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ final class FFICaster
|
||||
$type = \FFI::typeof($data);
|
||||
}
|
||||
|
||||
$stub->class = sprintf('%s<%s> size %d align %d', ($data ?? $type)::class, $type->getName(), $type->getSize(), $type->getAlignment());
|
||||
$stub->class = \sprintf('%s<%s> size %d align %d', ($data ?? $type)::class, $type->getName(), $type->getSize(), $type->getAlignment());
|
||||
|
||||
return match ($type->getKind()) {
|
||||
CType::TYPE_FLOAT,
|
||||
|
||||
+6
-8
@@ -18,13 +18,11 @@ namespace Symfony\Component\VarDumper\Caster;
|
||||
*/
|
||||
class FrameStub extends EnumStub
|
||||
{
|
||||
public bool $keepArgs;
|
||||
public bool $inTraceStub;
|
||||
|
||||
public function __construct(array $frame, bool $keepArgs = true, bool $inTraceStub = false)
|
||||
{
|
||||
$this->value = $frame;
|
||||
$this->keepArgs = $keepArgs;
|
||||
$this->inTraceStub = $inTraceStub;
|
||||
public function __construct(
|
||||
array $frame,
|
||||
public bool $keepArgs = true,
|
||||
public bool $inTraceStub = false,
|
||||
) {
|
||||
parent::__construct($frame);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -131,8 +131,8 @@ class PgSqlCaster
|
||||
for ($i = 0; $i < $fields; ++$i) {
|
||||
$field = [
|
||||
'name' => pg_field_name($result, $i),
|
||||
'table' => sprintf('%s (OID: %s)', pg_field_table($result, $i), pg_field_table($result, $i, true)),
|
||||
'type' => sprintf('%s (OID: %s)', pg_field_type($result, $i), pg_field_type_oid($result, $i)),
|
||||
'table' => \sprintf('%s (OID: %s)', pg_field_table($result, $i), pg_field_table($result, $i, true)),
|
||||
'type' => \sprintf('%s (OID: %s)', pg_field_type($result, $i), pg_field_type_oid($result, $i)),
|
||||
'nullable' => (bool) pg_field_is_null($result, $i),
|
||||
'storage' => pg_field_size($result, $i).' bytes',
|
||||
'display' => pg_field_prtlen($result, $i).' chars',
|
||||
|
||||
+3
-3
@@ -126,7 +126,7 @@ class SplCaster
|
||||
}
|
||||
|
||||
if (isset($a[$prefix.'perms'])) {
|
||||
$a[$prefix.'perms'] = new ConstStub(sprintf('0%o', $a[$prefix.'perms']), $a[$prefix.'perms']);
|
||||
$a[$prefix.'perms'] = new ConstStub(\sprintf('0%o', $a[$prefix.'perms']), $a[$prefix.'perms']);
|
||||
}
|
||||
|
||||
static $mapDate = ['aTime', 'mTime', 'cTime'];
|
||||
@@ -187,7 +187,7 @@ class SplCaster
|
||||
$storage[] = new EnumStub([
|
||||
'object' => $obj,
|
||||
'info' => $clone->getInfo(),
|
||||
]);
|
||||
]);
|
||||
}
|
||||
|
||||
$a += [
|
||||
@@ -219,7 +219,7 @@ class SplCaster
|
||||
$map[] = new EnumStub([
|
||||
'object' => $obj,
|
||||
'data' => $data,
|
||||
]);
|
||||
]);
|
||||
}
|
||||
|
||||
$a += [
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ class SymfonyCaster
|
||||
|
||||
public static function castHttpClient($client, array $a, Stub $stub, bool $isNested): array
|
||||
{
|
||||
$multiKey = sprintf("\0%s\0multi", $client::class);
|
||||
$multiKey = \sprintf("\0%s\0multi", $client::class);
|
||||
if (isset($a[$multiKey])) {
|
||||
$a[$multiKey] = new CutStub($a[$multiKey]);
|
||||
}
|
||||
|
||||
+7
-11
@@ -20,17 +20,13 @@ use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
*/
|
||||
class TraceStub extends Stub
|
||||
{
|
||||
public bool $keepArgs;
|
||||
public int $sliceOffset;
|
||||
public ?int $sliceLength;
|
||||
public int $numberingOffset;
|
||||
|
||||
public function __construct(array $trace, bool $keepArgs = true, int $sliceOffset = 0, ?int $sliceLength = null, int $numberingOffset = 0)
|
||||
{
|
||||
public function __construct(
|
||||
array $trace,
|
||||
public bool $keepArgs = true,
|
||||
public int $sliceOffset = 0,
|
||||
public ?int $sliceLength = null,
|
||||
public int $numberingOffset = 0,
|
||||
) {
|
||||
$this->value = $trace;
|
||||
$this->keepArgs = $keepArgs;
|
||||
$this->sliceOffset = $sliceOffset;
|
||||
$this->sliceLength = $sliceLength;
|
||||
$this->numberingOffset = $numberingOffset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +100,8 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
'Symfony\Component\HttpClient\CurlHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'],
|
||||
'Symfony\Component\HttpClient\NativeHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'],
|
||||
'Symfony\Component\HttpClient\Response\AmpResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
|
||||
'Symfony\Component\HttpClient\Response\AmpResponseV4' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
|
||||
'Symfony\Component\HttpClient\Response\AmpResponseV5' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
|
||||
'Symfony\Component\HttpClient\Response\CurlResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
|
||||
'Symfony\Component\HttpClient\Response\NativeResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
|
||||
'Symfony\Component\HttpFoundation\Request' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castRequest'],
|
||||
|
||||
+3
-3
@@ -115,7 +115,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate, \Stringable
|
||||
public function getIterator(): \Traversable
|
||||
{
|
||||
if (!\is_array($value = $this->getValue())) {
|
||||
throw new \LogicException(sprintf('"%s" object holds non-iterable type "%s".', self::class, get_debug_type($value)));
|
||||
throw new \LogicException(\sprintf('"%s" object holds non-iterable type "%s".', self::class, get_debug_type($value)));
|
||||
}
|
||||
|
||||
yield from $value;
|
||||
@@ -165,7 +165,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate, \Stringable
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
return sprintf('%s (count=%d)', $this->getType(), \count($value));
|
||||
return \sprintf('%s (count=%d)', $this->getType(), \count($value));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -370,7 +370,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate, \Stringable
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \RuntimeException(sprintf('Unexpected Stub type: "%s".', $item->type));
|
||||
throw new \RuntimeException(\sprintf('Unexpected Stub type: "%s".', $item->type));
|
||||
}
|
||||
} elseif ('array' === $type) {
|
||||
$dumper->enterHash($cursor, Cursor::HASH_INDEXED, 0, false);
|
||||
|
||||
@@ -26,12 +26,11 @@ use Symfony\Component\VarDumper\Dumper\CliDumper;
|
||||
*/
|
||||
class CliDescriptor implements DumpDescriptorInterface
|
||||
{
|
||||
private CliDumper $dumper;
|
||||
private mixed $lastIdentifier = null;
|
||||
|
||||
public function __construct(CliDumper $dumper)
|
||||
{
|
||||
$this->dumper = $dumper;
|
||||
public function __construct(
|
||||
private CliDumper $dumper,
|
||||
) {
|
||||
}
|
||||
|
||||
public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void
|
||||
@@ -47,7 +46,7 @@ class CliDescriptor implements DumpDescriptorInterface
|
||||
if (isset($context['request'])) {
|
||||
$request = $context['request'];
|
||||
$this->lastIdentifier = $request['identifier'];
|
||||
$section = sprintf('%s %s', $request['method'], $request['uri']);
|
||||
$section = \sprintf('%s %s', $request['method'], $request['uri']);
|
||||
if ($controller = $request['controller']) {
|
||||
$rows[] = ['controller', rtrim($this->dumper->dump($controller, true), "\n")];
|
||||
}
|
||||
@@ -62,9 +61,9 @@ class CliDescriptor implements DumpDescriptorInterface
|
||||
|
||||
if (isset($context['source'])) {
|
||||
$source = $context['source'];
|
||||
$sourceInfo = sprintf('%s on line %d', $source['name'], $source['line']);
|
||||
$sourceInfo = \sprintf('%s on line %d', $source['name'], $source['line']);
|
||||
if ($fileLink = $source['file_link'] ?? null) {
|
||||
$sourceInfo = sprintf('<href=%s>%s</>', $fileLink, $sourceInfo);
|
||||
$sourceInfo = \sprintf('<href=%s>%s</>', $fileLink, $sourceInfo);
|
||||
}
|
||||
$rows[] = ['source', $sourceInfo];
|
||||
$file = $source['file_relative'] ?? $source['file'];
|
||||
|
||||
@@ -24,12 +24,11 @@ use Symfony\Component\VarDumper\Dumper\HtmlDumper;
|
||||
*/
|
||||
class HtmlDescriptor implements DumpDescriptorInterface
|
||||
{
|
||||
private HtmlDumper $dumper;
|
||||
private bool $initialized = false;
|
||||
|
||||
public function __construct(HtmlDumper $dumper)
|
||||
{
|
||||
$this->dumper = $dumper;
|
||||
public function __construct(
|
||||
private HtmlDumper $dumper,
|
||||
) {
|
||||
}
|
||||
|
||||
public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void
|
||||
@@ -45,22 +44,22 @@ class HtmlDescriptor implements DumpDescriptorInterface
|
||||
if (isset($context['request'])) {
|
||||
$request = $context['request'];
|
||||
$controller = "<span class='dumped-tag'>{$this->dumper->dump($request['controller'], true, ['maxDepth' => 0])}</span>";
|
||||
$title = sprintf('<code>%s</code> <a href="%s">%s</a>', $request['method'], $uri = $request['uri'], $uri);
|
||||
$title = \sprintf('<code>%s</code> <a href="%s">%s</a>', $request['method'], $uri = $request['uri'], $uri);
|
||||
$dedupIdentifier = $request['identifier'];
|
||||
} elseif (isset($context['cli'])) {
|
||||
$title = '<code>$ </code>'.$context['cli']['command_line'];
|
||||
$dedupIdentifier = $context['cli']['identifier'];
|
||||
} else {
|
||||
$dedupIdentifier = uniqid('', true);
|
||||
$dedupIdentifier = bin2hex(random_bytes(4));
|
||||
}
|
||||
|
||||
$sourceDescription = '';
|
||||
if (isset($context['source'])) {
|
||||
$source = $context['source'];
|
||||
$projectDir = $source['project_dir'] ?? null;
|
||||
$sourceDescription = sprintf('%s on line %d', $source['name'], $source['line']);
|
||||
$sourceDescription = \sprintf('%s on line %d', $source['name'], $source['line']);
|
||||
if (isset($source['file_link'])) {
|
||||
$sourceDescription = sprintf('<a href="%s">%s</a>', $source['file_link'], $sourceDescription);
|
||||
$sourceDescription = \sprintf('<a href="%s">%s</a>', $source['file_link'], $sourceDescription);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +104,7 @@ HTML
|
||||
|
||||
$renderedTags = '';
|
||||
foreach ($tags as $key => $value) {
|
||||
$renderedTags .= sprintf('<li><span class="badge">%s</span>%s</li>', $key, $value);
|
||||
$renderedTags .= \sprintf('<li><span class="badge">%s</span>%s</li>', $key, $value);
|
||||
}
|
||||
|
||||
return <<<HTML
|
||||
|
||||
+7
-8
@@ -38,14 +38,13 @@ use Symfony\Component\VarDumper\Server\DumpServer;
|
||||
#[AsCommand(name: 'server:dump', description: 'Start a dump server that collects and displays dumps in a single place')]
|
||||
class ServerDumpCommand extends Command
|
||||
{
|
||||
private DumpServer $server;
|
||||
|
||||
/** @var DumpDescriptorInterface[] */
|
||||
private array $descriptors;
|
||||
|
||||
public function __construct(DumpServer $server, array $descriptors = [])
|
||||
{
|
||||
$this->server = $server;
|
||||
public function __construct(
|
||||
private DumpServer $server,
|
||||
array $descriptors = [],
|
||||
) {
|
||||
$this->descriptors = $descriptors + [
|
||||
'cli' => new CliDescriptor(new CliDumper()),
|
||||
'html' => new HtmlDescriptor(new HtmlDumper()),
|
||||
@@ -57,7 +56,7 @@ class ServerDumpCommand extends Command
|
||||
protected function configure(): void
|
||||
{
|
||||
$this
|
||||
->addOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format (%s)', implode(', ', $this->getAvailableFormats())), 'cli')
|
||||
->addOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format (%s)', implode(', ', $this->getAvailableFormats())), 'cli')
|
||||
->setHelp(<<<'EOF'
|
||||
<info>%command.name%</info> starts a dump server that collects and displays
|
||||
dumps in a single place for debugging you application:
|
||||
@@ -80,7 +79,7 @@ EOF
|
||||
$format = $input->getOption('format');
|
||||
|
||||
if (!$descriptor = $this->descriptors[$format] ?? null) {
|
||||
throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $format));
|
||||
throw new InvalidArgumentException(\sprintf('Unsupported format "%s".', $format));
|
||||
}
|
||||
|
||||
$errorIo = $io->getErrorStyle();
|
||||
@@ -88,7 +87,7 @@ EOF
|
||||
|
||||
$this->server->start();
|
||||
|
||||
$errorIo->success(sprintf('Server listening on %s', $this->server->getHost()));
|
||||
$errorIo->success(\sprintf('Server listening on %s', $this->server->getHost()));
|
||||
$errorIo->comment('Quit the server with CONTROL-C.');
|
||||
|
||||
$this->server->listen(function (Data $data, array $context, int $clientId) use ($descriptor, $io) {
|
||||
|
||||
+5
-4
@@ -36,7 +36,6 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
|
||||
protected $outputStream;
|
||||
protected string $decimalPoint = '.';
|
||||
protected string $indentPad = ' ';
|
||||
protected int $flags;
|
||||
|
||||
private string $charset = '';
|
||||
|
||||
@@ -45,9 +44,11 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
|
||||
* @param string|null $charset The default character encoding to use for non-UTF8 strings
|
||||
* @param int $flags A bit field of static::DUMP_* constants to fine tune dumps representation
|
||||
*/
|
||||
public function __construct($output = null, ?string $charset = null, int $flags = 0)
|
||||
{
|
||||
$this->flags = $flags;
|
||||
public function __construct(
|
||||
$output = null,
|
||||
?string $charset = null,
|
||||
protected int $flags = 0,
|
||||
) {
|
||||
$this->setCharset($charset ?: \ini_get('php.output_encoding') ?: \ini_get('default_charset') ?: 'UTF-8');
|
||||
$this->setOutput($output ?: static::$defaultOutput);
|
||||
if (!$output && \is_string(static::$defaultOutput)) {
|
||||
|
||||
+20
-8
@@ -33,12 +33,13 @@ class CliDumper extends AbstractDumper
|
||||
'default' => '0;38;5;208',
|
||||
'num' => '1;38;5;38',
|
||||
'const' => '1;38;5;208',
|
||||
'virtual' => '3',
|
||||
'str' => '1;38;5;113',
|
||||
'note' => '38;5;38',
|
||||
'ref' => '38;5;247',
|
||||
'public' => '',
|
||||
'protected' => '',
|
||||
'private' => '',
|
||||
'public' => '39',
|
||||
'protected' => '39',
|
||||
'private' => '39',
|
||||
'meta' => '38;5;170',
|
||||
'key' => '38;5;113',
|
||||
'index' => '38;5;38',
|
||||
@@ -347,7 +348,10 @@ class CliDumper extends AbstractDumper
|
||||
if ($cursor->hashKeyIsBinary) {
|
||||
$key = $this->utf8Encode($key);
|
||||
}
|
||||
$attr = ['binary' => $cursor->hashKeyIsBinary];
|
||||
$attr = [
|
||||
'binary' => $cursor->hashKeyIsBinary,
|
||||
'virtual' => $cursor->attr['virtual'] ?? false,
|
||||
];
|
||||
$bin = $cursor->hashKeyIsBinary ? 'b' : '';
|
||||
$style = 'key';
|
||||
switch ($cursor->hashType) {
|
||||
@@ -371,7 +375,7 @@ class CliDumper extends AbstractDumper
|
||||
// no break
|
||||
case Cursor::HASH_OBJECT:
|
||||
if (!isset($key[0]) || "\0" !== $key[0]) {
|
||||
$this->line .= '+'.$bin.$this->style('public', $key).': ';
|
||||
$this->line .= '+'.$bin.$this->style('public', $key, $attr).': ';
|
||||
} elseif (0 < strpos($key, "\0", 1)) {
|
||||
$key = explode("\0", substr($key, 1), 2);
|
||||
|
||||
@@ -459,7 +463,7 @@ class CliDumper extends AbstractDumper
|
||||
$s = $startCchr;
|
||||
$c = $c[$i = 0];
|
||||
do {
|
||||
$s .= $map[$c[$i]] ?? sprintf('\x%02X', \ord($c[$i]));
|
||||
$s .= $map[$c[$i]] ?? \sprintf('\x%02X', \ord($c[$i]));
|
||||
} while (isset($c[++$i]));
|
||||
|
||||
return $s.$endCchr;
|
||||
@@ -506,6 +510,9 @@ class CliDumper extends AbstractDumper
|
||||
if ('label' === $style && '' !== $value) {
|
||||
$value .= ' ';
|
||||
}
|
||||
if ($this->colors && ($attr['virtual'] ?? false)) {
|
||||
$value = "\033[{$this->styles['virtual']}m".$value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
@@ -552,7 +559,7 @@ class CliDumper extends AbstractDumper
|
||||
protected function dumpLine(int $depth, bool $endOfValue = false): void
|
||||
{
|
||||
if ($this->colors ??= $this->supportsColors()) {
|
||||
$this->line = sprintf("\033[%sm%s\033[m", $this->styles['default'], $this->line);
|
||||
$this->line = \sprintf("\033[%sm%s\033[m", $this->styles['default'], $this->line);
|
||||
}
|
||||
parent::dumpLine($depth);
|
||||
}
|
||||
@@ -591,6 +598,11 @@ class CliDumper extends AbstractDumper
|
||||
return false;
|
||||
}
|
||||
|
||||
// Follow https://force-color.org/
|
||||
if ('' !== (($_SERVER['FORCE_COLOR'] ?? getenv('FORCE_COLOR'))[0] ?? '')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Detect msysgit/mingw and assume this is a tty because detection
|
||||
// does not work correctly, see https://github.com/composer/composer/issues/9690
|
||||
if (!@stream_isatty($stream) && !\in_array(strtoupper((string) getenv('MSYSTEM')), ['MINGW32', 'MINGW64'], true)) {
|
||||
@@ -632,7 +644,7 @@ class CliDumper extends AbstractDumper
|
||||
|| 'Hyper' === getenv('TERM_PROGRAM');
|
||||
|
||||
if (!$result) {
|
||||
$version = sprintf(
|
||||
$version = \sprintf(
|
||||
'%s.%s.%s',
|
||||
PHP_WINDOWS_VERSION_MAJOR,
|
||||
PHP_WINDOWS_VERSION_MINOR,
|
||||
|
||||
+3
-4
@@ -22,12 +22,11 @@ use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
*/
|
||||
final class RequestContextProvider implements ContextProviderInterface
|
||||
{
|
||||
private RequestStack $requestStack;
|
||||
private VarCloner $cloner;
|
||||
|
||||
public function __construct(RequestStack $requestStack)
|
||||
{
|
||||
$this->requestStack = $requestStack;
|
||||
public function __construct(
|
||||
private RequestStack $requestStack,
|
||||
) {
|
||||
$this->cloner = new VarCloner();
|
||||
$this->cloner->setMaxItems(0);
|
||||
$this->cloner->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO);
|
||||
|
||||
+6
-11
@@ -25,17 +25,12 @@ use Twig\Template;
|
||||
*/
|
||||
final class SourceContextProvider implements ContextProviderInterface
|
||||
{
|
||||
private int $limit;
|
||||
private ?string $charset;
|
||||
private ?string $projectDir;
|
||||
private ?FileLinkFormatter $fileLinkFormatter;
|
||||
|
||||
public function __construct(?string $charset = null, ?string $projectDir = null, ?FileLinkFormatter $fileLinkFormatter = null, int $limit = 9)
|
||||
{
|
||||
$this->charset = $charset;
|
||||
$this->projectDir = $projectDir;
|
||||
$this->fileLinkFormatter = $fileLinkFormatter;
|
||||
$this->limit = $limit;
|
||||
public function __construct(
|
||||
private ?string $charset = null,
|
||||
private ?string $projectDir = null,
|
||||
private ?FileLinkFormatter $fileLinkFormatter = null,
|
||||
private int $limit = 9,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getContext(): ?array
|
||||
|
||||
@@ -19,16 +19,13 @@ use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface;
|
||||
*/
|
||||
class ContextualizedDumper implements DataDumperInterface
|
||||
{
|
||||
private DataDumperInterface $wrappedDumper;
|
||||
private array $contextProviders;
|
||||
|
||||
/**
|
||||
* @param ContextProviderInterface[] $contextProviders
|
||||
*/
|
||||
public function __construct(DataDumperInterface $wrappedDumper, array $contextProviders)
|
||||
{
|
||||
$this->wrappedDumper = $wrappedDumper;
|
||||
$this->contextProviders = $contextProviders;
|
||||
public function __construct(
|
||||
private DataDumperInterface $wrappedDumper,
|
||||
private array $contextProviders,
|
||||
) {
|
||||
}
|
||||
|
||||
public function dump(Data $data): ?string
|
||||
|
||||
+23
-18
@@ -29,6 +29,7 @@ class HtmlDumper extends CliDumper
|
||||
'default' => 'background-color:#18171B; color:#FF8400; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all',
|
||||
'num' => 'font-weight:bold; color:#1299DA',
|
||||
'const' => 'font-weight:bold',
|
||||
'virtual' => 'font-style:italic',
|
||||
'str' => 'font-weight:bold; color:#56DB3A',
|
||||
'note' => 'color:#1299DA',
|
||||
'ref' => 'color:#A0A0A0',
|
||||
@@ -45,6 +46,7 @@ class HtmlDumper extends CliDumper
|
||||
'default' => 'background:none; color:#CC7832; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all',
|
||||
'num' => 'font-weight:bold; color:#1299DA',
|
||||
'const' => 'font-weight:bold',
|
||||
'virtual' => 'font-style:italic',
|
||||
'str' => 'font-weight:bold; color:#629755;',
|
||||
'note' => 'color:#6897BB',
|
||||
'ref' => 'color:#6E6E6E',
|
||||
@@ -91,7 +93,7 @@ class HtmlDumper extends CliDumper
|
||||
public function setTheme(string $themeName): void
|
||||
{
|
||||
if (!isset(static::$themes[$themeName])) {
|
||||
throw new \InvalidArgumentException(sprintf('Theme "%s" does not exist in class "%s".', $themeName, static::class));
|
||||
throw new \InvalidArgumentException(\sprintf('Theme "%s" does not exist in class "%s".', $themeName, static::class));
|
||||
}
|
||||
|
||||
$this->setStyles(static::$themes[$themeName]);
|
||||
@@ -777,7 +779,7 @@ EOHTML
|
||||
$this->line .= $cursor->depth >= $this->displayOptions['maxDepth'] ? ' <samp class=sf-dump-compact>' : ' <samp class=sf-dump-expanded>';
|
||||
$this->endValue($cursor);
|
||||
$this->line .= $this->indentPad;
|
||||
$this->line .= sprintf('<img src="data:%s;base64,%s" /></samp>', $cursor->attr['content-type'], base64_encode($cursor->attr['img-data']));
|
||||
$this->line .= \sprintf('<img src="data:%s;base64,%s" /></samp>', $cursor->attr['content-type'], base64_encode($cursor->attr['img-data']));
|
||||
$this->endValue($cursor);
|
||||
} else {
|
||||
parent::dumpString($cursor, $str, $bin, $cut);
|
||||
@@ -805,7 +807,7 @@ EOHTML
|
||||
$r = Cursor::HASH_OBJECT !== $type ? 1 - (Cursor::HASH_RESOURCE !== $type) : 2;
|
||||
$r .= $r && 0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->refIndex;
|
||||
|
||||
$this->line .= sprintf(' id=%s-ref%s', $this->dumpId, $r);
|
||||
$this->line .= \sprintf(' id=%s-ref%s', $this->dumpId, $r);
|
||||
}
|
||||
$this->line .= $eol;
|
||||
$this->dumpLine($cursor->depth);
|
||||
@@ -831,19 +833,19 @@ EOHTML
|
||||
|
||||
if ('ref' === $style) {
|
||||
if (empty($attr['count'])) {
|
||||
return sprintf('<a class=sf-dump-ref>%s</a>', $v);
|
||||
return \sprintf('<a class=sf-dump-ref>%s</a>', $v);
|
||||
}
|
||||
$r = ('#' !== $v[0] ? 1 - ('@' !== $v[0]) : 2).substr($value, 1);
|
||||
|
||||
return sprintf('<a class=sf-dump-ref href=#%s-ref%s title="%d occurrences">%s</a>', $this->dumpId, $r, 1 + $attr['count'], $v);
|
||||
return \sprintf('<a class=sf-dump-ref href=#%s-ref%s title="%d occurrences">%s</a>', $this->dumpId, $r, 1 + $attr['count'], $v);
|
||||
}
|
||||
|
||||
if ('const' === $style && isset($attr['value'])) {
|
||||
$style .= sprintf(' title="%s"', esc(\is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value'])));
|
||||
$style .= \sprintf(' title="%s"', esc(\is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value'])));
|
||||
} elseif ('public' === $style) {
|
||||
$style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property');
|
||||
$style .= \sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property');
|
||||
} elseif ('str' === $style && 1 < $attr['length']) {
|
||||
$style .= sprintf(' title="%d%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : '');
|
||||
$style .= \sprintf(' title="%d%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : '');
|
||||
} elseif ('note' === $style && 0 < ($attr['depth'] ?? 0) && false !== $c = strrpos($value, '\\')) {
|
||||
$style .= ' title=""';
|
||||
$attr += [
|
||||
@@ -854,23 +856,23 @@ EOHTML
|
||||
} elseif ('protected' === $style) {
|
||||
$style .= ' title="Protected property"';
|
||||
} elseif ('meta' === $style && isset($attr['title'])) {
|
||||
$style .= sprintf(' title="%s"', esc($this->utf8Encode($attr['title'])));
|
||||
$style .= \sprintf(' title="%s"', esc($this->utf8Encode($attr['title'])));
|
||||
} elseif ('private' === $style) {
|
||||
$style .= sprintf(' title="Private property defined in class: `%s`"', esc($this->utf8Encode($attr['class'])));
|
||||
$style .= \sprintf(' title="Private property defined in class: `%s`"', esc($this->utf8Encode($attr['class'])));
|
||||
}
|
||||
|
||||
if (isset($attr['ellipsis'])) {
|
||||
$class = 'sf-dump-ellipsis';
|
||||
if (isset($attr['ellipsis-type'])) {
|
||||
$class = sprintf('"%s sf-dump-ellipsis-%s"', $class, $attr['ellipsis-type']);
|
||||
$class = \sprintf('"%s sf-dump-ellipsis-%s"', $class, $attr['ellipsis-type']);
|
||||
}
|
||||
$label = esc(substr($value, -$attr['ellipsis']));
|
||||
$style = str_replace(' title="', " title=\"$v\n", $style);
|
||||
$v = sprintf('<span class=%s>%s</span>', $class, substr($v, 0, -\strlen($label)));
|
||||
$v = \sprintf('<span class=%s>%s</span>', $class, substr($v, 0, -\strlen($label)));
|
||||
|
||||
if (!empty($attr['ellipsis-tail'])) {
|
||||
$tail = \strlen(esc(substr($value, -$attr['ellipsis'], $attr['ellipsis-tail'])));
|
||||
$v .= sprintf('<span class=%s>%s</span>%s', $class, substr($label, 0, $tail), substr($label, $tail));
|
||||
$v .= \sprintf('<span class=%s>%s</span>%s', $class, substr($label, 0, $tail), substr($label, $tail));
|
||||
} else {
|
||||
$v .= $label;
|
||||
}
|
||||
@@ -893,7 +895,7 @@ EOHTML
|
||||
$s .= '">';
|
||||
}
|
||||
|
||||
$s .= $map[$c[$i]] ?? sprintf('\x%02X', \ord($c[$i]));
|
||||
$s .= $map[$c[$i]] ?? \sprintf('\x%02X', \ord($c[$i]));
|
||||
} while (isset($c[++$i]));
|
||||
|
||||
return $s.'</span>';
|
||||
@@ -913,14 +915,17 @@ EOHTML
|
||||
$v .= '^';
|
||||
}
|
||||
$target = isset($attr['file']) ? '' : ' target="_blank"';
|
||||
$v = sprintf('<a href="%s"%s rel="noopener noreferrer">%s</a>', esc($this->utf8Encode($attr['href'])), $target, $v);
|
||||
$v = \sprintf('<a href="%s"%s rel="noopener noreferrer">%s</a>', esc($this->utf8Encode($attr['href'])), $target, $v);
|
||||
}
|
||||
if (isset($attr['lang'])) {
|
||||
$v = sprintf('<code class="%s">%s</code>', esc($attr['lang']), $v);
|
||||
$v = \sprintf('<code class="%s">%s</code>', esc($attr['lang']), $v);
|
||||
}
|
||||
if ('label' === $style) {
|
||||
$v .= ' ';
|
||||
}
|
||||
if ($attr['virtual'] ?? false) {
|
||||
$v = '<span class=sf-dump-virtual>'.$v.'</span>';
|
||||
}
|
||||
|
||||
return $v;
|
||||
}
|
||||
@@ -928,7 +933,7 @@ EOHTML
|
||||
protected function dumpLine(int $depth, bool $endOfValue = false): void
|
||||
{
|
||||
if (-1 === $this->lastDepth) {
|
||||
$this->line = sprintf($this->dumpPrefix, $this->dumpId, $this->indentPad).$this->line;
|
||||
$this->line = \sprintf($this->dumpPrefix, $this->dumpId, $this->indentPad).$this->line;
|
||||
}
|
||||
if ($this->headerIsDumped !== ($this->outputStream ?? $this->lineDumper)) {
|
||||
$this->line = $this->getDumpHeader().$this->line;
|
||||
@@ -940,7 +945,7 @@ EOHTML
|
||||
$args[] = json_encode($this->extraDisplayOptions, \JSON_FORCE_OBJECT);
|
||||
}
|
||||
// Replace is for BC
|
||||
$this->line .= sprintf(str_replace('"%s"', '%s', $this->dumpSuffix), implode(', ', $args));
|
||||
$this->line .= \sprintf(str_replace('"%s"', '%s', $this->dumpSuffix), implode(', ', $args));
|
||||
}
|
||||
$this->lastDepth = $depth;
|
||||
|
||||
|
||||
+5
-4
@@ -23,17 +23,18 @@ use Symfony\Component\VarDumper\Server\Connection;
|
||||
class ServerDumper implements DataDumperInterface
|
||||
{
|
||||
private Connection $connection;
|
||||
private ?DataDumperInterface $wrappedDumper;
|
||||
|
||||
/**
|
||||
* @param string $host The server host
|
||||
* @param DataDumperInterface|null $wrappedDumper A wrapped instance used whenever we failed contacting the server
|
||||
* @param ContextProviderInterface[] $contextProviders Context providers indexed by context name
|
||||
*/
|
||||
public function __construct(string $host, ?DataDumperInterface $wrappedDumper = null, array $contextProviders = [])
|
||||
{
|
||||
public function __construct(
|
||||
string $host,
|
||||
private ?DataDumperInterface $wrappedDumper = null,
|
||||
array $contextProviders = [],
|
||||
) {
|
||||
$this->connection = new Connection($host, $contextProviders);
|
||||
$this->wrappedDumper = $wrappedDumper;
|
||||
}
|
||||
|
||||
public function getContextProviders(): array
|
||||
|
||||
+4
-4
@@ -22,7 +22,6 @@ use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface;
|
||||
class Connection
|
||||
{
|
||||
private string $host;
|
||||
private array $contextProviders;
|
||||
|
||||
/**
|
||||
* @var resource|null
|
||||
@@ -33,14 +32,15 @@ class Connection
|
||||
* @param string $host The server host
|
||||
* @param ContextProviderInterface[] $contextProviders Context providers indexed by context name
|
||||
*/
|
||||
public function __construct(string $host, array $contextProviders = [])
|
||||
{
|
||||
public function __construct(
|
||||
string $host,
|
||||
private array $contextProviders = [],
|
||||
) {
|
||||
if (!str_contains($host, '://')) {
|
||||
$host = 'tcp://'.$host;
|
||||
}
|
||||
|
||||
$this->host = $host;
|
||||
$this->contextProviders = $contextProviders;
|
||||
}
|
||||
|
||||
public function getContextProviders(): array
|
||||
|
||||
+5
-5
@@ -25,27 +25,27 @@ use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
class DumpServer
|
||||
{
|
||||
private string $host;
|
||||
private ?LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* @var resource|null
|
||||
*/
|
||||
private $socket;
|
||||
|
||||
public function __construct(string $host, ?LoggerInterface $logger = null)
|
||||
{
|
||||
public function __construct(
|
||||
string $host,
|
||||
private ?LoggerInterface $logger = null,
|
||||
) {
|
||||
if (!str_contains($host, '://')) {
|
||||
$host = 'tcp://'.$host;
|
||||
}
|
||||
|
||||
$this->host = $host;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function start(): void
|
||||
{
|
||||
if (!$this->socket = stream_socket_server($this->host, $errno, $errstr)) {
|
||||
throw new \RuntimeException(sprintf('Server start failed on "%s": ', $this->host).$errstr.' '.$errno);
|
||||
throw new \RuntimeException(\sprintf('Server start failed on "%s": ', $this->host).$errstr.' '.$errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ trait VarDumperTestTrait
|
||||
'flags' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array<string, callable> $casters
|
||||
*/
|
||||
protected function setUpVarDumper(array $casters, ?int $flags = null): void
|
||||
{
|
||||
$this->varDumperConfig['casters'] = $casters;
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
"symfony/http-kernel": "^6.4|^7.0",
|
||||
"symfony/process": "^6.4|^7.0",
|
||||
"symfony/uid": "^6.4|^7.0",
|
||||
"twig/twig": "^3.0.4"
|
||||
"twig/twig": "^3.12"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/console": "<6.4"
|
||||
|
||||
Reference in New Issue
Block a user