Import latest app updates from streamline

An updated set of source files and initialization was provided by streamline to
address issues observed during initial testing. These files have been updated in
order to generate a new set of app images.
This commit is contained in:
2024-04-11 11:16:51 -07:00
parent cb4c6b4c1a
commit 4a89356390
10435 changed files with 107737 additions and 1220538 deletions
@@ -1,227 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts Amqp related classes to array representation.
*
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*
* @final
*/
class AmqpCaster
{
private const FLAGS = [
\AMQP_DURABLE => 'AMQP_DURABLE',
\AMQP_PASSIVE => 'AMQP_PASSIVE',
\AMQP_EXCLUSIVE => 'AMQP_EXCLUSIVE',
\AMQP_AUTODELETE => 'AMQP_AUTODELETE',
\AMQP_INTERNAL => 'AMQP_INTERNAL',
\AMQP_NOLOCAL => 'AMQP_NOLOCAL',
\AMQP_AUTOACK => 'AMQP_AUTOACK',
\AMQP_IFEMPTY => 'AMQP_IFEMPTY',
\AMQP_IFUNUSED => 'AMQP_IFUNUSED',
\AMQP_MANDATORY => 'AMQP_MANDATORY',
\AMQP_IMMEDIATE => 'AMQP_IMMEDIATE',
\AMQP_MULTIPLE => 'AMQP_MULTIPLE',
\AMQP_NOWAIT => 'AMQP_NOWAIT',
\AMQP_REQUEUE => 'AMQP_REQUEUE',
];
private const EXCHANGE_TYPES = [
\AMQP_EX_TYPE_DIRECT => 'AMQP_EX_TYPE_DIRECT',
\AMQP_EX_TYPE_FANOUT => 'AMQP_EX_TYPE_FANOUT',
\AMQP_EX_TYPE_TOPIC => 'AMQP_EX_TYPE_TOPIC',
\AMQP_EX_TYPE_HEADERS => 'AMQP_EX_TYPE_HEADERS',
];
/**
* @return array
*/
public static function castConnection(\AMQPConnection $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'is_connected' => $c->isConnected(),
];
// Recent version of the extension already expose private properties
if (isset($a["\x00AMQPConnection\x00login"])) {
return $a;
}
// BC layer in the amqp lib
if (method_exists($c, 'getReadTimeout')) {
$timeout = $c->getReadTimeout();
} else {
$timeout = $c->getTimeout();
}
$a += [
$prefix.'is_connected' => $c->isConnected(),
$prefix.'login' => $c->getLogin(),
$prefix.'password' => $c->getPassword(),
$prefix.'host' => $c->getHost(),
$prefix.'vhost' => $c->getVhost(),
$prefix.'port' => $c->getPort(),
$prefix.'read_timeout' => $timeout,
];
return $a;
}
/**
* @return array
*/
public static function castChannel(\AMQPChannel $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'is_connected' => $c->isConnected(),
$prefix.'channel_id' => $c->getChannelId(),
];
// Recent version of the extension already expose private properties
if (isset($a["\x00AMQPChannel\x00connection"])) {
return $a;
}
$a += [
$prefix.'connection' => $c->getConnection(),
$prefix.'prefetch_size' => $c->getPrefetchSize(),
$prefix.'prefetch_count' => $c->getPrefetchCount(),
];
return $a;
}
/**
* @return array
*/
public static function castQueue(\AMQPQueue $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'flags' => self::extractFlags($c->getFlags()),
];
// Recent version of the extension already expose private properties
if (isset($a["\x00AMQPQueue\x00name"])) {
return $a;
}
$a += [
$prefix.'connection' => $c->getConnection(),
$prefix.'channel' => $c->getChannel(),
$prefix.'name' => $c->getName(),
$prefix.'arguments' => $c->getArguments(),
];
return $a;
}
/**
* @return array
*/
public static function castExchange(\AMQPExchange $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'flags' => self::extractFlags($c->getFlags()),
];
$type = isset(self::EXCHANGE_TYPES[$c->getType()]) ? new ConstStub(self::EXCHANGE_TYPES[$c->getType()], $c->getType()) : $c->getType();
// Recent version of the extension already expose private properties
if (isset($a["\x00AMQPExchange\x00name"])) {
$a["\x00AMQPExchange\x00type"] = $type;
return $a;
}
$a += [
$prefix.'connection' => $c->getConnection(),
$prefix.'channel' => $c->getChannel(),
$prefix.'name' => $c->getName(),
$prefix.'type' => $type,
$prefix.'arguments' => $c->getArguments(),
];
return $a;
}
/**
* @return array
*/
public static function castEnvelope(\AMQPEnvelope $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
$prefix = Caster::PREFIX_VIRTUAL;
$deliveryMode = new ConstStub($c->getDeliveryMode().(2 === $c->getDeliveryMode() ? ' (persistent)' : ' (non-persistent)'), $c->getDeliveryMode());
// Recent version of the extension already expose private properties
if (isset($a["\x00AMQPEnvelope\x00body"])) {
$a["\0AMQPEnvelope\0delivery_mode"] = $deliveryMode;
return $a;
}
if (!($filter & Caster::EXCLUDE_VERBOSE)) {
$a += [$prefix.'body' => $c->getBody()];
}
$a += [
$prefix.'delivery_tag' => $c->getDeliveryTag(),
$prefix.'is_redelivery' => $c->isRedelivery(),
$prefix.'exchange_name' => $c->getExchangeName(),
$prefix.'routing_key' => $c->getRoutingKey(),
$prefix.'content_type' => $c->getContentType(),
$prefix.'content_encoding' => $c->getContentEncoding(),
$prefix.'headers' => $c->getHeaders(),
$prefix.'delivery_mode' => $deliveryMode,
$prefix.'priority' => $c->getPriority(),
$prefix.'correlation_id' => $c->getCorrelationId(),
$prefix.'reply_to' => $c->getReplyTo(),
$prefix.'expiration' => $c->getExpiration(),
$prefix.'message_id' => $c->getMessageId(),
$prefix.'timestamp' => $c->getTimeStamp(),
$prefix.'type' => $c->getType(),
$prefix.'user_id' => $c->getUserId(),
$prefix.'app_id' => $c->getAppId(),
];
return $a;
}
private static function extractFlags(int $flags): ConstStub
{
$flagsArray = [];
foreach (self::FLAGS as $value => $name) {
if ($flags & $value) {
$flagsArray[] = $name;
}
}
if (!$flagsArray) {
$flagsArray = ['AMQP_NOPARAM'];
}
return new ConstStub(implode('|', $flagsArray), $flags);
}
}
@@ -1,80 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Represents a list of function arguments.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class ArgsStub extends EnumStub
{
private static array $parameters = [];
public function __construct(array $args, string $function, ?string $class)
{
[$variadic, $params] = self::getParameters($function, $class);
$values = [];
foreach ($args as $k => $v) {
$values[$k] = !\is_scalar($v) && !$v instanceof Stub ? new CutStub($v) : $v;
}
if (null === $params) {
parent::__construct($values, false);
return;
}
if (\count($values) < \count($params)) {
$params = \array_slice($params, 0, \count($values));
} elseif (\count($values) > \count($params)) {
$values[] = new EnumStub(array_splice($values, \count($params)), false);
$params[] = $variadic;
}
if (['...'] === $params) {
$this->dumpKeys = false;
$this->value = $values[0]->value;
} else {
$this->value = array_combine($params, $values);
}
}
private static function getParameters(string $function, ?string $class): array
{
if (isset(self::$parameters[$k = $class.'::'.$function])) {
return self::$parameters[$k];
}
try {
$r = null !== $class ? new \ReflectionMethod($class, $function) : new \ReflectionFunction($function);
} catch (\ReflectionException) {
return [null, null];
}
$variadic = '...';
$params = [];
foreach ($r->getParameters() as $v) {
$k = '$'.$v->name;
if ($v->isPassedByReference()) {
$k = '&'.$k;
}
if ($v->isVariadic()) {
$variadic .= $k;
} else {
$params[] = $k;
}
}
return self::$parameters[$k] = [$variadic, $params];
}
}
@@ -1,198 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Helper for filtering out properties in casters.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class Caster
{
public const EXCLUDE_VERBOSE = 1;
public const EXCLUDE_VIRTUAL = 2;
public const EXCLUDE_DYNAMIC = 4;
public const EXCLUDE_PUBLIC = 8;
public const EXCLUDE_PROTECTED = 16;
public const EXCLUDE_PRIVATE = 32;
public const EXCLUDE_NULL = 64;
public const EXCLUDE_EMPTY = 128;
public const EXCLUDE_NOT_IMPORTANT = 256;
public const EXCLUDE_STRICT = 512;
public const EXCLUDE_UNINITIALIZED = 1024;
public const PREFIX_VIRTUAL = "\0~\0";
public const PREFIX_DYNAMIC = "\0+\0";
public const PREFIX_PROTECTED = "\0*\0";
// usage: sprintf(Caster::PATTERN_PRIVATE, $class, $property)
public const PATTERN_PRIVATE = "\0%s\0%s";
private static array $classProperties = [];
/**
* Casts objects to arrays and adds the dynamic property prefix.
*
* @param bool $hasDebugInfo Whether the __debugInfo method exists on $obj or not
*/
public static function castObject(object $obj, string $class, bool $hasDebugInfo = false, ?string $debugClass = null): array
{
if ($hasDebugInfo) {
try {
$debugInfo = $obj->__debugInfo();
} catch (\Throwable) {
// ignore failing __debugInfo()
$hasDebugInfo = false;
}
}
$a = $obj instanceof \Closure ? [] : (array) $obj;
if ($obj instanceof \__PHP_Incomplete_Class) {
return $a;
}
$classProperties = self::$classProperties[$class] ??= self::getClassProperties(new \ReflectionClass($class));
$a = array_replace($classProperties, $a);
if ($a) {
$debugClass ??= get_debug_type($obj);
$i = 0;
$prefixedKeys = [];
foreach ($a as $k => $v) {
if ("\0" !== ($k[0] ?? '')) {
if (!isset($classProperties[$k])) {
$prefixedKeys[$i] = self::PREFIX_DYNAMIC.$k;
}
} elseif ($debugClass !== $class && 1 === strpos($k, $class)) {
$prefixedKeys[$i] = "\0".$debugClass.strrchr($k, "\0");
}
++$i;
}
if ($prefixedKeys) {
$keys = array_keys($a);
foreach ($prefixedKeys as $i => $k) {
$keys[$i] = $k;
}
$a = array_combine($keys, $a);
}
}
if ($hasDebugInfo && \is_array($debugInfo)) {
foreach ($debugInfo as $k => $v) {
if (!isset($k[0]) || "\0" !== $k[0]) {
if (\array_key_exists(self::PREFIX_DYNAMIC.$k, $a)) {
continue;
}
$k = self::PREFIX_VIRTUAL.$k;
}
unset($a[$k]);
$a[$k] = $v;
}
}
return $a;
}
/**
* Filters out the specified properties.
*
* By default, a single match in the $filter bit field filters properties out, following an "or" logic.
* When EXCLUDE_STRICT is set, an "and" logic is applied: all bits must match for a property to be removed.
*
* @param array $a The array containing the properties to filter
* @param int $filter A bit field of Caster::EXCLUDE_* constants specifying which properties to filter out
* @param string[] $listedProperties List of properties to exclude when Caster::EXCLUDE_VERBOSE is set, and to preserve when Caster::EXCLUDE_NOT_IMPORTANT is set
* @param int|null &$count Set to the number of removed properties
*/
public static function filter(array $a, int $filter, array $listedProperties = [], ?int &$count = 0): array
{
$count = 0;
foreach ($a as $k => $v) {
$type = self::EXCLUDE_STRICT & $filter;
if (null === $v) {
$type |= self::EXCLUDE_NULL & $filter;
$type |= self::EXCLUDE_EMPTY & $filter;
} elseif (false === $v || '' === $v || '0' === $v || 0 === $v || 0.0 === $v || [] === $v) {
$type |= self::EXCLUDE_EMPTY & $filter;
} elseif ($v instanceof UninitializedStub) {
$type |= self::EXCLUDE_UNINITIALIZED & $filter;
}
if ((self::EXCLUDE_NOT_IMPORTANT & $filter) && !\in_array($k, $listedProperties, true)) {
$type |= self::EXCLUDE_NOT_IMPORTANT;
}
if ((self::EXCLUDE_VERBOSE & $filter) && \in_array($k, $listedProperties, true)) {
$type |= self::EXCLUDE_VERBOSE;
}
if (!isset($k[1]) || "\0" !== $k[0]) {
$type |= self::EXCLUDE_PUBLIC & $filter;
} elseif ('~' === $k[1]) {
$type |= self::EXCLUDE_VIRTUAL & $filter;
} elseif ('+' === $k[1]) {
$type |= self::EXCLUDE_DYNAMIC & $filter;
} elseif ('*' === $k[1]) {
$type |= self::EXCLUDE_PROTECTED & $filter;
} else {
$type |= self::EXCLUDE_PRIVATE & $filter;
}
if ((self::EXCLUDE_STRICT & $filter) ? $type === $filter : $type) {
unset($a[$k]);
++$count;
}
}
return $a;
}
public static function castPhpIncompleteClass(\__PHP_Incomplete_Class $c, array $a, Stub $stub, bool $isNested): array
{
if (isset($a['__PHP_Incomplete_Class_Name'])) {
$stub->class .= '('.$a['__PHP_Incomplete_Class_Name'].')';
unset($a['__PHP_Incomplete_Class_Name']);
}
return $a;
}
private static function getClassProperties(\ReflectionClass $class): array
{
$classProperties = [];
$className = $class->name;
if ($parent = $class->getParentClass()) {
$classProperties += self::$classProperties[$parent->name] ??= self::getClassProperties($parent);
}
foreach ($class->getProperties() as $p) {
if ($p->isStatic()) {
continue;
}
$classProperties[match (true) {
$p->isPublic() => $p->name,
$p->isProtected() => self::PREFIX_PROTECTED.$p->name,
default => "\0".$className."\0".$p->name,
}] = new UninitializedStub($p);
}
return $classProperties;
}
}
@@ -1,107 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Represents a PHP class identifier.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class ClassStub extends ConstStub
{
/**
* @param string $identifier A PHP identifier, e.g. a class, method, interface, etc. name
* @param callable $callable The callable targeted by the identifier when it is ambiguous or not a real PHP identifier
*/
public function __construct(string $identifier, callable|array|string|null $callable = null)
{
$this->value = $identifier;
try {
if (null !== $callable) {
if ($callable instanceof \Closure) {
$r = new \ReflectionFunction($callable);
} elseif (\is_object($callable)) {
$r = [$callable, '__invoke'];
} elseif (\is_array($callable)) {
$r = $callable;
} elseif (false !== $i = strpos($callable, '::')) {
$r = [substr($callable, 0, $i), substr($callable, 2 + $i)];
} else {
$r = new \ReflectionFunction($callable);
}
} elseif (0 < $i = strpos($identifier, '::') ?: strpos($identifier, '->')) {
$r = [substr($identifier, 0, $i), substr($identifier, 2 + $i)];
} else {
$r = new \ReflectionClass($identifier);
}
if (\is_array($r)) {
try {
$r = new \ReflectionMethod($r[0], $r[1]);
} catch (\ReflectionException) {
$r = new \ReflectionClass($r[0]);
}
}
if (str_contains($identifier, "@anonymous\0")) {
$this->value = $identifier = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', fn ($m) => class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0], $identifier);
}
if (null !== $callable && $r instanceof \ReflectionFunctionAbstract) {
$s = ReflectionCaster::castFunctionAbstract($r, [], new Stub(), true, Caster::EXCLUDE_VERBOSE);
$s = ReflectionCaster::getSignature($s);
if (str_ends_with($identifier, '()')) {
$this->value = substr_replace($identifier, $s, -2);
} else {
$this->value .= $s;
}
}
} catch (\ReflectionException) {
return;
} finally {
if (0 < $i = strrpos($this->value, '\\')) {
$this->attr['ellipsis'] = \strlen($this->value) - $i;
$this->attr['ellipsis-type'] = 'class';
$this->attr['ellipsis-tail'] = 1;
}
}
if ($f = $r->getFileName()) {
$this->attr['file'] = $f;
$this->attr['line'] = $r->getStartLine();
}
}
/**
* @return mixed
*/
public static function wrapCallable(mixed $callable)
{
if (\is_object($callable) || !\is_callable($callable)) {
return $callable;
}
if (!\is_array($callable)) {
$callable = new static($callable, $callable);
} elseif (\is_string($callable[0])) {
$callable[0] = new static($callable[0], $callable);
} else {
$callable[1] = new static($callable[1], $callable);
}
return $callable;
}
}
@@ -1,33 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Represents a PHP constant and its value.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class ConstStub extends Stub
{
public function __construct(string $name, string|int|float|null $value = null)
{
$this->class = $name;
$this->value = 1 < \func_num_args() ? $value : $name;
}
public function __toString(): string
{
return (string) $this->value;
}
}
@@ -1,30 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
/**
* Represents a cut array.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class CutArrayStub extends CutStub
{
public $preservedSubset;
public function __construct(array $value, array $preservedKeys)
{
parent::__construct($value);
$this->preservedSubset = array_intersect_key($value, array_flip($preservedKeys));
$this->cut -= \count($this->preservedSubset);
}
}
@@ -1,64 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Represents the main properties of a PHP variable, pre-casted by a caster.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class CutStub extends Stub
{
public function __construct(mixed $value)
{
$this->value = $value;
switch (\gettype($value)) {
case 'object':
$this->type = self::TYPE_OBJECT;
$this->class = $value::class;
if ($value instanceof \Closure) {
ReflectionCaster::castClosure($value, [], $this, true, Caster::EXCLUDE_VERBOSE);
}
$this->cut = -1;
break;
case 'array':
$this->type = self::TYPE_ARRAY;
$this->class = self::ARRAY_ASSOC;
$this->cut = $this->value = \count($value);
break;
case 'resource':
case 'unknown type':
case 'resource (closed)':
$this->type = self::TYPE_RESOURCE;
$this->handle = (int) $value;
if ('Unknown' === $this->class = @get_resource_type($value)) {
$this->class = 'Closed';
}
$this->cut = -1;
break;
case 'string':
$this->type = self::TYPE_STRING;
$this->class = preg_match('//u', $value) ? self::STRING_UTF8 : self::STRING_BINARY;
$this->cut = self::STRING_BINARY === $this->class ? \strlen($value) : mb_strlen($value, 'UTF-8');
$this->value = '';
break;
}
}
}
@@ -1,312 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts DOM related classes to array representation.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class DOMCaster
{
private const ERROR_CODES = [
\DOM_PHP_ERR => 'DOM_PHP_ERR',
\DOM_INDEX_SIZE_ERR => 'DOM_INDEX_SIZE_ERR',
\DOMSTRING_SIZE_ERR => 'DOMSTRING_SIZE_ERR',
\DOM_HIERARCHY_REQUEST_ERR => 'DOM_HIERARCHY_REQUEST_ERR',
\DOM_WRONG_DOCUMENT_ERR => 'DOM_WRONG_DOCUMENT_ERR',
\DOM_INVALID_CHARACTER_ERR => 'DOM_INVALID_CHARACTER_ERR',
\DOM_NO_DATA_ALLOWED_ERR => 'DOM_NO_DATA_ALLOWED_ERR',
\DOM_NO_MODIFICATION_ALLOWED_ERR => 'DOM_NO_MODIFICATION_ALLOWED_ERR',
\DOM_NOT_FOUND_ERR => 'DOM_NOT_FOUND_ERR',
\DOM_NOT_SUPPORTED_ERR => 'DOM_NOT_SUPPORTED_ERR',
\DOM_INUSE_ATTRIBUTE_ERR => 'DOM_INUSE_ATTRIBUTE_ERR',
\DOM_INVALID_STATE_ERR => 'DOM_INVALID_STATE_ERR',
\DOM_SYNTAX_ERR => 'DOM_SYNTAX_ERR',
\DOM_INVALID_MODIFICATION_ERR => 'DOM_INVALID_MODIFICATION_ERR',
\DOM_NAMESPACE_ERR => 'DOM_NAMESPACE_ERR',
\DOM_INVALID_ACCESS_ERR => 'DOM_INVALID_ACCESS_ERR',
\DOM_VALIDATION_ERR => 'DOM_VALIDATION_ERR',
];
private const NODE_TYPES = [
\XML_ELEMENT_NODE => 'XML_ELEMENT_NODE',
\XML_ATTRIBUTE_NODE => 'XML_ATTRIBUTE_NODE',
\XML_TEXT_NODE => 'XML_TEXT_NODE',
\XML_CDATA_SECTION_NODE => 'XML_CDATA_SECTION_NODE',
\XML_ENTITY_REF_NODE => 'XML_ENTITY_REF_NODE',
\XML_ENTITY_NODE => 'XML_ENTITY_NODE',
\XML_PI_NODE => 'XML_PI_NODE',
\XML_COMMENT_NODE => 'XML_COMMENT_NODE',
\XML_DOCUMENT_NODE => 'XML_DOCUMENT_NODE',
\XML_DOCUMENT_TYPE_NODE => 'XML_DOCUMENT_TYPE_NODE',
\XML_DOCUMENT_FRAG_NODE => 'XML_DOCUMENT_FRAG_NODE',
\XML_NOTATION_NODE => 'XML_NOTATION_NODE',
\XML_HTML_DOCUMENT_NODE => 'XML_HTML_DOCUMENT_NODE',
\XML_DTD_NODE => 'XML_DTD_NODE',
\XML_ELEMENT_DECL_NODE => 'XML_ELEMENT_DECL_NODE',
\XML_ATTRIBUTE_DECL_NODE => 'XML_ATTRIBUTE_DECL_NODE',
\XML_ENTITY_DECL_NODE => 'XML_ENTITY_DECL_NODE',
\XML_NAMESPACE_DECL_NODE => 'XML_NAMESPACE_DECL_NODE',
];
/**
* @return array
*/
public static function castException(\DOMException $e, array $a, Stub $stub, bool $isNested)
{
$k = Caster::PREFIX_PROTECTED.'code';
if (isset($a[$k], self::ERROR_CODES[$a[$k]])) {
$a[$k] = new ConstStub(self::ERROR_CODES[$a[$k]], $a[$k]);
}
return $a;
}
/**
* @return array
*/
public static function castLength($dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'length' => $dom->length,
];
return $a;
}
/**
* @return array
*/
public static function castImplementation(\DOMImplementation $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
Caster::PREFIX_VIRTUAL.'Core' => '1.0',
Caster::PREFIX_VIRTUAL.'XML' => '2.0',
];
return $a;
}
/**
* @return array
*/
public static function castNode(\DOMNode $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'nodeName' => $dom->nodeName,
'nodeValue' => new CutStub($dom->nodeValue),
'nodeType' => new ConstStub(self::NODE_TYPES[$dom->nodeType], $dom->nodeType),
'parentNode' => new CutStub($dom->parentNode),
'childNodes' => $dom->childNodes,
'firstChild' => new CutStub($dom->firstChild),
'lastChild' => new CutStub($dom->lastChild),
'previousSibling' => new CutStub($dom->previousSibling),
'nextSibling' => new CutStub($dom->nextSibling),
'attributes' => $dom->attributes,
'ownerDocument' => new CutStub($dom->ownerDocument),
'namespaceURI' => $dom->namespaceURI,
'prefix' => $dom->prefix,
'localName' => $dom->localName,
'baseURI' => $dom->baseURI ? new LinkStub($dom->baseURI) : $dom->baseURI,
'textContent' => new CutStub($dom->textContent),
];
return $a;
}
/**
* @return array
*/
public static function castNameSpaceNode(\DOMNameSpaceNode $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'nodeName' => $dom->nodeName,
'nodeValue' => new CutStub($dom->nodeValue),
'nodeType' => new ConstStub(self::NODE_TYPES[$dom->nodeType], $dom->nodeType),
'prefix' => $dom->prefix,
'localName' => $dom->localName,
'namespaceURI' => $dom->namespaceURI,
'ownerDocument' => new CutStub($dom->ownerDocument),
'parentNode' => new CutStub($dom->parentNode),
];
return $a;
}
/**
* @return array
*/
public static function castDocument(\DOMDocument $dom, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
$a += [
'doctype' => $dom->doctype,
'implementation' => $dom->implementation,
'documentElement' => new CutStub($dom->documentElement),
'actualEncoding' => $dom->actualEncoding,
'encoding' => $dom->encoding,
'xmlEncoding' => $dom->xmlEncoding,
'standalone' => $dom->standalone,
'xmlStandalone' => $dom->xmlStandalone,
'version' => $dom->version,
'xmlVersion' => $dom->xmlVersion,
'strictErrorChecking' => $dom->strictErrorChecking,
'documentURI' => $dom->documentURI ? new LinkStub($dom->documentURI) : $dom->documentURI,
'config' => $dom->config,
'formatOutput' => $dom->formatOutput,
'validateOnParse' => $dom->validateOnParse,
'resolveExternals' => $dom->resolveExternals,
'preserveWhiteSpace' => $dom->preserveWhiteSpace,
'recover' => $dom->recover,
'substituteEntities' => $dom->substituteEntities,
];
if (!($filter & Caster::EXCLUDE_VERBOSE)) {
$formatOutput = $dom->formatOutput;
$dom->formatOutput = true;
$a += [Caster::PREFIX_VIRTUAL.'xml' => $dom->saveXML()];
$dom->formatOutput = $formatOutput;
}
return $a;
}
/**
* @return array
*/
public static function castCharacterData(\DOMCharacterData $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'data' => $dom->data,
'length' => $dom->length,
];
return $a;
}
/**
* @return array
*/
public static function castAttr(\DOMAttr $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'name' => $dom->name,
'specified' => $dom->specified,
'value' => $dom->value,
'ownerElement' => $dom->ownerElement,
'schemaTypeInfo' => $dom->schemaTypeInfo,
];
return $a;
}
/**
* @return array
*/
public static function castElement(\DOMElement $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'tagName' => $dom->tagName,
'schemaTypeInfo' => $dom->schemaTypeInfo,
];
return $a;
}
/**
* @return array
*/
public static function castText(\DOMText $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'wholeText' => $dom->wholeText,
];
return $a;
}
/**
* @return array
*/
public static function castDocumentType(\DOMDocumentType $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'name' => $dom->name,
'entities' => $dom->entities,
'notations' => $dom->notations,
'publicId' => $dom->publicId,
'systemId' => $dom->systemId,
'internalSubset' => $dom->internalSubset,
];
return $a;
}
/**
* @return array
*/
public static function castNotation(\DOMNotation $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'publicId' => $dom->publicId,
'systemId' => $dom->systemId,
];
return $a;
}
/**
* @return array
*/
public static function castEntity(\DOMEntity $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'publicId' => $dom->publicId,
'systemId' => $dom->systemId,
'notationName' => $dom->notationName,
'actualEncoding' => $dom->actualEncoding,
'encoding' => $dom->encoding,
'version' => $dom->version,
];
return $a;
}
/**
* @return array
*/
public static function castProcessingInstruction(\DOMProcessingInstruction $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'target' => $dom->target,
'data' => $dom->data,
];
return $a;
}
/**
* @return array
*/
public static function castXPath(\DOMXPath $dom, array $a, Stub $stub, bool $isNested)
{
$a += [
'document' => $dom->document,
];
return $a;
}
}
@@ -1,139 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts DateTimeInterface related classes to array representation.
*
* @author Dany Maillard <danymaillard93b@gmail.com>
*
* @final
*/
class DateCaster
{
private const PERIOD_LIMIT = 3;
/**
* @return array
*/
public static function castDateTime(\DateTimeInterface $d, array $a, Stub $stub, bool $isNested, int $filter)
{
$prefix = Caster::PREFIX_VIRTUAL;
$location = $d->getTimezone() ? $d->getTimezone()->getLocation() : null;
$fromNow = (new \DateTimeImmutable())->diff($d);
$title = $d->format('l, F j, Y')
."\n".self::formatInterval($fromNow).' from now'
.($location ? ($d->format('I') ? "\nDST On" : "\nDST Off") : '')
;
unset(
$a[Caster::PREFIX_DYNAMIC.'date'],
$a[Caster::PREFIX_DYNAMIC.'timezone'],
$a[Caster::PREFIX_DYNAMIC.'timezone_type']
);
$a[$prefix.'date'] = new ConstStub(self::formatDateTime($d, $location ? ' e (P)' : ' P'), $title);
$stub->class .= $d->format(' @U');
return $a;
}
/**
* @return array
*/
public static function castInterval(\DateInterval $interval, array $a, Stub $stub, bool $isNested, int $filter)
{
$now = new \DateTimeImmutable('@0', new \DateTimeZone('UTC'));
$numberOfSeconds = $now->add($interval)->getTimestamp() - $now->getTimestamp();
$title = number_format($numberOfSeconds, 0, '.', ' ').'s';
$i = [Caster::PREFIX_VIRTUAL.'interval' => new ConstStub(self::formatInterval($interval), $title)];
return $filter & Caster::EXCLUDE_VERBOSE ? $i : $i + $a;
}
private static function formatInterval(\DateInterval $i): string
{
$format = '%R ';
if (0 === $i->y && 0 === $i->m && ($i->h >= 24 || $i->i >= 60 || $i->s >= 60)) {
$d = new \DateTimeImmutable('@0', new \DateTimeZone('UTC'));
$i = $d->diff($d->add($i)); // recalculate carry over points
$format .= 0 < $i->days ? '%ad ' : '';
} else {
$format .= ($i->y ? '%yy ' : '').($i->m ? '%mm ' : '').($i->d ? '%dd ' : '');
}
$format .= $i->h || $i->i || $i->s || $i->f ? '%H:%I:'.self::formatSeconds($i->s, substr($i->f, 2)) : '';
$format = '%R ' === $format ? '0s' : $format;
return $i->format(rtrim($format));
}
/**
* @return array
*/
public static function castTimeZone(\DateTimeZone $timeZone, array $a, Stub $stub, bool $isNested, int $filter)
{
$location = $timeZone->getLocation();
$formatted = (new \DateTimeImmutable('now', $timeZone))->format($location ? 'e (P)' : 'P');
$title = $location && \extension_loaded('intl') ? \Locale::getDisplayRegion('-'.$location['country_code']) : '';
$z = [Caster::PREFIX_VIRTUAL.'timezone' => new ConstStub($formatted, $title)];
return $filter & Caster::EXCLUDE_VERBOSE ? $z : $z + $a;
}
/**
* @return array
*/
public static function castPeriod(\DatePeriod $p, array $a, Stub $stub, bool $isNested, int $filter)
{
$dates = [];
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())
? 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));
}
$period = sprintf(
'every %s, from %s%s %s',
self::formatInterval($p->getDateInterval()),
$p->include_start_date ? '[' : ']',
self::formatDateTime($p->getStartDate()),
($end = $p->getEndDate()) ? 'to '.self::formatDateTime($end).(\PHP_VERSION_ID >= 80200 && $p->include_end_date ? ']' : '[') : 'recurring '.$p->recurrences.' time/s'
);
$p = [Caster::PREFIX_VIRTUAL.'period' => new ConstStub($period, implode("\n", $dates))];
return $filter & Caster::EXCLUDE_VERBOSE ? $p : $p + $a;
}
private static function formatDateTime(\DateTimeInterface $d, string $extra = ''): string
{
return $d->format('Y-m-d H:i:'.self::formatSeconds($d->format('s'), $d->format('u')).$extra);
}
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));
}
}
@@ -1,71 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Doctrine\Common\Proxy\Proxy as CommonProxy;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Proxy\Proxy as OrmProxy;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts Doctrine related classes to array representation.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class DoctrineCaster
{
/**
* @return array
*/
public static function castCommonProxy(CommonProxy $proxy, array $a, Stub $stub, bool $isNested)
{
foreach (['__cloner__', '__initializer__'] as $k) {
if (\array_key_exists($k, $a)) {
unset($a[$k]);
++$stub->cut;
}
}
return $a;
}
/**
* @return array
*/
public static function castOrmProxy(OrmProxy $proxy, array $a, Stub $stub, bool $isNested)
{
foreach (['_entityPersister', '_identifier'] as $k) {
if (\array_key_exists($k = "\0Doctrine\\ORM\\Proxy\\Proxy\0".$k, $a)) {
unset($a[$k]);
++$stub->cut;
}
}
return $a;
}
/**
* @return array
*/
public static function castPersistentCollection(PersistentCollection $coll, array $a, Stub $stub, bool $isNested)
{
foreach (['snapshot', 'association', 'typeClass'] as $k) {
if (\array_key_exists($k = "\0Doctrine\\ORM\\PersistentCollection\0".$k, $a)) {
$a[$k] = new CutStub($a[$k]);
}
}
return $a;
}
}
@@ -1,70 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Ds\Collection;
use Ds\Map;
use Ds\Pair;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts Ds extension classes to array representation.
*
* @author Jáchym Toušek <enumag@gmail.com>
*
* @final
*/
class DsCaster
{
public static function castCollection(Collection $c, array $a, Stub $stub, bool $isNested): array
{
$a[Caster::PREFIX_VIRTUAL.'count'] = $c->count();
$a[Caster::PREFIX_VIRTUAL.'capacity'] = $c->capacity();
if (!$c instanceof Map) {
$a += $c->toArray();
}
return $a;
}
public static function castMap(Map $c, array $a, Stub $stub, bool $isNested): array
{
foreach ($c as $k => $v) {
$a[] = new DsPairStub($k, $v);
}
return $a;
}
public static function castPair(Pair $c, array $a, Stub $stub, bool $isNested): array
{
foreach ($c->toArray() as $k => $v) {
$a[Caster::PREFIX_VIRTUAL.$k] = $v;
}
return $a;
}
public static function castPairStub(DsPairStub $c, array $a, Stub $stub, bool $isNested): array
{
if ($isNested) {
$stub->class = Pair::class;
$stub->value = null;
$stub->handle = 0;
$a = $c->value;
}
return $a;
}
}
@@ -1,28 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class DsPairStub extends Stub
{
public function __construct(mixed $key, mixed $value)
{
$this->value = [
Caster::PREFIX_VIRTUAL.'key' => $key,
Caster::PREFIX_VIRTUAL.'value' => $value,
];
}
}
@@ -1,30 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Represents an enumeration of values.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class EnumStub extends Stub
{
public $dumpKeys = true;
public function __construct(array $values, bool $dumpKeys = true)
{
$this->value = $values;
$this->dumpKeys = $dumpKeys;
}
}
@@ -1,419 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\ErrorHandler\Exception\FlattenException;
use Symfony\Component\ErrorHandler\Exception\SilencedErrorContext;
use Symfony\Component\VarDumper\Cloner\Stub;
use Symfony\Component\VarDumper\Exception\ThrowingCasterException;
/**
* Casts common Exception classes to array representation.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class ExceptionCaster
{
public static int $srcContext = 1;
public static bool $traceArgs = true;
public static array $errorTypes = [
\E_DEPRECATED => 'E_DEPRECATED',
\E_USER_DEPRECATED => 'E_USER_DEPRECATED',
\E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
\E_ERROR => 'E_ERROR',
\E_WARNING => 'E_WARNING',
\E_PARSE => 'E_PARSE',
\E_NOTICE => 'E_NOTICE',
\E_CORE_ERROR => 'E_CORE_ERROR',
\E_CORE_WARNING => 'E_CORE_WARNING',
\E_COMPILE_ERROR => 'E_COMPILE_ERROR',
\E_COMPILE_WARNING => 'E_COMPILE_WARNING',
\E_USER_ERROR => 'E_USER_ERROR',
\E_USER_WARNING => 'E_USER_WARNING',
\E_USER_NOTICE => 'E_USER_NOTICE',
\E_STRICT => 'E_STRICT',
];
private static array $framesCache = [];
/**
* @return array
*/
public static function castError(\Error $e, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
return self::filterExceptionArray($stub->class, $a, "\0Error\0", $filter);
}
/**
* @return array
*/
public static function castException(\Exception $e, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
return self::filterExceptionArray($stub->class, $a, "\0Exception\0", $filter);
}
/**
* @return array
*/
public static function castErrorException(\ErrorException $e, array $a, Stub $stub, bool $isNested)
{
if (isset($a[$s = Caster::PREFIX_PROTECTED.'severity'], self::$errorTypes[$a[$s]])) {
$a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]);
}
return $a;
}
/**
* @return array
*/
public static function castThrowingCasterException(ThrowingCasterException $e, array $a, Stub $stub, bool $isNested)
{
$trace = Caster::PREFIX_VIRTUAL.'trace';
$prefix = Caster::PREFIX_PROTECTED;
$xPrefix = "\0Exception\0";
if (isset($a[$xPrefix.'previous'], $a[$trace]) && $a[$xPrefix.'previous'] instanceof \Exception) {
$b = (array) $a[$xPrefix.'previous'];
$class = get_debug_type($a[$xPrefix.'previous']);
self::traceUnshift($b[$xPrefix.'trace'], $class, $b[$prefix.'file'], $b[$prefix.'line']);
$a[$trace] = new TraceStub($b[$xPrefix.'trace'], false, 0, -\count($a[$trace]->value));
}
unset($a[$xPrefix.'previous'], $a[$prefix.'code'], $a[$prefix.'file'], $a[$prefix.'line']);
return $a;
}
/**
* @return array
*/
public static function castSilencedErrorContext(SilencedErrorContext $e, array $a, Stub $stub, bool $isNested)
{
$sPrefix = "\0".SilencedErrorContext::class."\0";
if (!isset($a[$s = $sPrefix.'severity'])) {
return $a;
}
if (isset(self::$errorTypes[$a[$s]])) {
$a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]);
}
$trace = [[
'file' => $a[$sPrefix.'file'],
'line' => $a[$sPrefix.'line'],
]];
if (isset($a[$sPrefix.'trace'])) {
$trace = array_merge($trace, $a[$sPrefix.'trace']);
}
unset($a[$sPrefix.'file'], $a[$sPrefix.'line'], $a[$sPrefix.'trace']);
$a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace, self::$traceArgs);
return $a;
}
/**
* @return array
*/
public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, bool $isNested)
{
if (!$isNested) {
return $a;
}
$stub->class = '';
$stub->handle = 0;
$frames = $trace->value;
$prefix = Caster::PREFIX_VIRTUAL;
$a = [];
$j = \count($frames);
if (0 > $i = $trace->sliceOffset) {
$i = max(0, $j + $i);
}
if (!isset($trace->value[$i])) {
return [];
}
$lastCall = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '';
$frames[] = ['function' => ''];
$collapse = false;
for ($j += $trace->numberingOffset - $i++; isset($frames[$i]); ++$i, --$j) {
$f = $frames[$i];
$call = isset($f['function']) ? (isset($f['class']) ? $f['class'].$f['type'] : '').$f['function'] : '???';
$frame = new FrameStub(
[
'object' => $f['object'] ?? null,
'class' => $f['class'] ?? null,
'type' => $f['type'] ?? null,
'function' => $f['function'] ?? null,
] + $frames[$i - 1],
false,
true
);
$f = self::castFrameStub($frame, [], $frame, true);
if (isset($f[$prefix.'src'])) {
foreach ($f[$prefix.'src']->value as $label => $frame) {
if (str_starts_with($label, "\0~collapse=0")) {
if ($collapse) {
$label = substr_replace($label, '1', 11, 1);
} else {
$collapse = true;
}
}
$label = substr_replace($label, "title=Stack level $j.&", 2, 0);
}
$f = $frames[$i - 1];
if ($trace->keepArgs && !empty($f['args']) && $frame instanceof EnumStub) {
$frame->value['arguments'] = new ArgsStub($f['args'], $f['function'] ?? null, $f['class'] ?? null);
}
} elseif ('???' !== $lastCall) {
$label = new ClassStub($lastCall);
if (isset($label->attr['ellipsis'])) {
$label->attr['ellipsis'] += 2;
$label = substr_replace($prefix, "ellipsis-type=class&ellipsis={$label->attr['ellipsis']}&ellipsis-tail=1&title=Stack level $j.", 2, 0).$label->value.'()';
} else {
$label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$label->value.'()';
}
} 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;
$lastCall = $call;
}
if (null !== $trace->sliceLength) {
$a = \array_slice($a, 0, $trace->sliceLength, true);
}
return $a;
}
/**
* @return array
*/
public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, bool $isNested)
{
if (!$isNested) {
return $a;
}
$f = $frame->value;
$prefix = Caster::PREFIX_VIRTUAL;
if (isset($f['file'], $f['line'])) {
$cacheKey = $f;
unset($cacheKey['object'], $cacheKey['args']);
$cacheKey[] = self::$srcContext;
$cacheKey = implode('-', $cacheKey);
if (isset(self::$framesCache[$cacheKey])) {
$a[$prefix.'src'] = self::$framesCache[$cacheKey];
} else {
if (preg_match('/\((\d+)\)(?:\([\da-f]{32}\))? : (?:eval\(\)\'d code|runtime-created function)$/', $f['file'], $match)) {
$f['file'] = substr($f['file'], 0, -\strlen($match[0]));
$f['line'] = (int) $match[1];
}
$src = $f['line'];
$srcKey = $f['file'];
$ellipsis = new LinkStub($srcKey, 0);
$srcAttr = 'collapse='.(int) $ellipsis->inVendor;
$ellipsisTail = $ellipsis->attr['ellipsis-tail'] ?? 0;
$ellipsis = $ellipsis->attr['ellipsis'] ?? 0;
if (is_file($f['file']) && 0 <= self::$srcContext) {
if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) {
$template = null;
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']));
}
if (null !== $template) {
$ellipsis = 0;
$templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : '');
$templateInfo = $template->getDebugInfo();
if (isset($templateInfo[$f['line']])) {
if (!method_exists($template, 'getSourceContext') || !is_file($templatePath = $template->getSourceContext()->getPath())) {
$templatePath = null;
}
if ($templateSrc) {
$src = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext, 'twig', $templatePath, $f);
$srcKey = ($templatePath ?: $template->getTemplateName()).':'.$templateInfo[$f['line']];
}
}
}
}
if ($srcKey == $f['file']) {
$src = self::extractSource(file_get_contents($f['file']), $f['line'], self::$srcContext, 'php', $f['file'], $f);
$srcKey .= ':'.$f['line'];
if ($ellipsis) {
$ellipsis += 1 + \strlen($f['line']);
}
}
$srcAttr .= sprintf('&separator= &file=%s&line=%d', rawurlencode($f['file']), $f['line']);
} else {
$srcAttr .= '&separator=:';
}
$srcAttr .= $ellipsis ? '&ellipsis-type=path&ellipsis='.$ellipsis.'&ellipsis-tail='.$ellipsisTail : '';
self::$framesCache[$cacheKey] = $a[$prefix.'src'] = new EnumStub(["\0~$srcAttr\0$srcKey" => $src]);
}
}
unset($a[$prefix.'args'], $a[$prefix.'line'], $a[$prefix.'file']);
if ($frame->inTraceStub) {
unset($a[$prefix.'class'], $a[$prefix.'type'], $a[$prefix.'function']);
}
foreach ($a as $k => $v) {
if (!$v) {
unset($a[$k]);
}
}
if ($frame->keepArgs && !empty($f['args'])) {
$a[$prefix.'arguments'] = new ArgsStub($f['args'], $f['function'], $f['class']);
}
return $a;
}
/**
* @return array
*/
public static function castFlattenException(FlattenException $e, array $a, Stub $stub, bool $isNested)
{
if ($isNested) {
$k = sprintf(Caster::PATTERN_PRIVATE, FlattenException::class, 'traceAsString');
$a[$k] = new CutStub($a[$k]);
}
return $a;
}
private static function filterExceptionArray(string $xClass, array $a, string $xPrefix, int $filter): array
{
if (isset($a[$xPrefix.'trace'])) {
$trace = $a[$xPrefix.'trace'];
unset($a[$xPrefix.'trace']); // Ensures the trace is always last
} else {
$trace = [];
}
if (!($filter & Caster::EXCLUDE_VERBOSE) && $trace) {
if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) {
self::traceUnshift($trace, $xClass, $a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']);
}
$a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace, self::$traceArgs);
}
if (empty($a[$xPrefix.'previous'])) {
unset($a[$xPrefix.'previous']);
}
unset($a[$xPrefix.'string'], $a[Caster::PREFIX_DYNAMIC.'xdebug_message']);
if (isset($a[Caster::PREFIX_PROTECTED.'message']) && str_contains($a[Caster::PREFIX_PROTECTED.'message'], "@anonymous\0")) {
$a[Caster::PREFIX_PROTECTED.'message'] = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', fn ($m) => class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0], $a[Caster::PREFIX_PROTECTED.'message']);
}
if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) {
$a[Caster::PREFIX_PROTECTED.'file'] = new LinkStub($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']);
}
return $a;
}
private static function traceUnshift(array &$trace, ?string $class, string $file, int $line): void
{
if (isset($trace[0]['file'], $trace[0]['line']) && $trace[0]['file'] === $file && $trace[0]['line'] === $line) {
return;
}
array_unshift($trace, [
'function' => $class ? 'new '.$class : null,
'file' => $file,
'line' => $line,
]);
}
private static function extractSource(string $srcLines, int $line, int $srcContext, string $lang, ?string $file, array $frame): EnumStub
{
$srcLines = explode("\n", $srcLines);
$src = [];
for ($i = $line - 1 - $srcContext; $i <= $line - 1 + $srcContext; ++$i) {
$src[] = ($srcLines[$i] ?? '')."\n";
}
if ($frame['function'] ?? false) {
$stub = new CutStub(new \stdClass());
$stub->class = (isset($frame['class']) ? $frame['class'].$frame['type'] : '').$frame['function'];
$stub->type = Stub::TYPE_OBJECT;
$stub->attr['cut_hash'] = true;
$stub->attr['file'] = $frame['file'];
$stub->attr['line'] = $frame['line'];
try {
$caller = isset($frame['class']) ? new \ReflectionMethod($frame['class'], $frame['function']) : new \ReflectionFunction($frame['function']);
$stub->class .= ReflectionCaster::getSignature(ReflectionCaster::castFunctionAbstract($caller, [], $stub, true, Caster::EXCLUDE_VERBOSE));
if ($f = $caller->getFileName()) {
$stub->attr['file'] = $f;
$stub->attr['line'] = $caller->getStartLine();
}
} catch (\ReflectionException) {
// ignore fake class/function
}
$srcLines = ["\0~separator=\0" => $stub];
} else {
$stub = null;
$srcLines = [];
}
$ltrim = 0;
do {
$pad = null;
for ($i = $srcContext << 1; $i >= 0; --$i) {
if (isset($src[$i][$ltrim]) && "\r" !== ($c = $src[$i][$ltrim]) && "\n" !== $c) {
$pad ??= $c;
if ((' ' !== $c && "\t" !== $c) || $pad !== $c) {
break;
}
}
}
++$ltrim;
} while (0 > $i && null !== $pad);
--$ltrim;
foreach ($src as $i => $c) {
if ($ltrim) {
$c = isset($c[$ltrim]) && "\r" !== $c[$ltrim] ? substr($c, $ltrim) : ltrim($c, " \t");
}
$c = substr($c, 0, -1);
if ($i !== $srcContext) {
$c = new ConstStub('default', $c);
} else {
$c = new ConstStub($c, $stub ? 'in '.$stub->class : '');
if (null !== $file) {
$c->attr['file'] = $file;
$c->attr['line'] = $line;
}
}
$c->attr['lang'] = $lang;
$srcLines[sprintf("\0~separator= &%d\0", $i + $line - $srcContext)] = $c;
}
return new EnumStub($srcLines);
}
}
@@ -1,161 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use FFI\CData;
use FFI\CType;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts FFI extension classes to array representation.
*
* @author Nesmeyanov Kirill <nesk@xakep.ru>
*/
final class FFICaster
{
/**
* In case of "char*" contains a string, the length of which depends on
* some other parameter, then during the generation of the string it is
* possible to go beyond the allowable memory area.
*
* This restriction serves to ensure that processing does not take
* up the entire allowable PHP memory limit.
*/
private const MAX_STRING_LENGTH = 255;
public static function castCTypeOrCData(CData|CType $data, array $args, Stub $stub): array
{
if ($data instanceof CType) {
$type = $data;
$data = null;
} else {
$type = \FFI::typeof($data);
}
$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,
CType::TYPE_DOUBLE,
\defined('\FFI\CType::TYPE_LONGDOUBLE') ? CType::TYPE_LONGDOUBLE : -1,
CType::TYPE_UINT8,
CType::TYPE_SINT8,
CType::TYPE_UINT16,
CType::TYPE_SINT16,
CType::TYPE_UINT32,
CType::TYPE_SINT32,
CType::TYPE_UINT64,
CType::TYPE_SINT64,
CType::TYPE_BOOL,
CType::TYPE_CHAR,
CType::TYPE_ENUM => null !== $data ? [Caster::PREFIX_VIRTUAL.'cdata' => $data->cdata] : [],
CType::TYPE_POINTER => self::castFFIPointer($stub, $type, $data),
CType::TYPE_STRUCT => self::castFFIStructLike($type, $data),
CType::TYPE_FUNC => self::castFFIFunction($stub, $type),
default => $args,
};
}
private static function castFFIFunction(Stub $stub, CType $type): array
{
$arguments = [];
for ($i = 0, $count = $type->getFuncParameterCount(); $i < $count; ++$i) {
$param = $type->getFuncParameterType($i);
$arguments[] = $param->getName();
}
$abi = match ($type->getFuncABI()) {
CType::ABI_DEFAULT,
CType::ABI_CDECL => '[cdecl]',
CType::ABI_FASTCALL => '[fastcall]',
CType::ABI_THISCALL => '[thiscall]',
CType::ABI_STDCALL => '[stdcall]',
CType::ABI_PASCAL => '[pascal]',
CType::ABI_REGISTER => '[register]',
CType::ABI_MS => '[ms]',
CType::ABI_SYSV => '[sysv]',
CType::ABI_VECTORCALL => '[vectorcall]',
default => '[unknown abi]'
};
$returnType = $type->getFuncReturnType();
$stub->class = $abi.' callable('.implode(', ', $arguments).'): '
.$returnType->getName();
return [Caster::PREFIX_VIRTUAL.'returnType' => $returnType];
}
private static function castFFIPointer(Stub $stub, CType $type, ?CData $data = null): array
{
$ptr = $type->getPointerType();
if (null === $data) {
return [Caster::PREFIX_VIRTUAL.'0' => $ptr];
}
return match ($ptr->getKind()) {
CType::TYPE_CHAR => [Caster::PREFIX_VIRTUAL.'cdata' => self::castFFIStringValue($data)],
CType::TYPE_FUNC => self::castFFIFunction($stub, $ptr),
default => [Caster::PREFIX_VIRTUAL.'cdata' => $data[0]],
};
}
private static function castFFIStringValue(CData $data): string|CutStub
{
$result = [];
for ($i = 0; $i < self::MAX_STRING_LENGTH; ++$i) {
$result[$i] = $data[$i];
if ("\0" === $result[$i]) {
return implode('', $result);
}
}
$string = implode('', $result);
$stub = new CutStub($string);
$stub->cut = -1;
$stub->value = $string;
return $stub;
}
private static function castFFIStructLike(CType $type, ?CData $data = null): array
{
$isUnion = ($type->getAttributes() & CType::ATTR_UNION) === CType::ATTR_UNION;
$result = [];
foreach ($type->getStructFieldNames() as $name) {
$field = $type->getStructFieldType($name);
// Retrieving the value of a field from a union containing
// a pointer is not a safe operation, because may contain
// incorrect data.
$isUnsafe = $isUnion && CType::TYPE_POINTER === $field->getKind();
if ($isUnsafe) {
$result[Caster::PREFIX_VIRTUAL.$name.'?'] = $field;
} elseif (null === $data) {
$result[Caster::PREFIX_VIRTUAL.$name] = $field;
} else {
$fieldName = $data->{$name} instanceof CData ? '' : $field->getName().' ';
$result[Caster::PREFIX_VIRTUAL.$fieldName.$name] = $data->{$name};
}
}
return $result;
}
}
@@ -1,46 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts Fiber related classes to array representation.
*
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
final class FiberCaster
{
/**
* @return array
*/
public static function castFiber(\Fiber $fiber, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
$prefix = Caster::PREFIX_VIRTUAL;
if ($fiber->isTerminated()) {
$status = 'terminated';
} elseif ($fiber->isRunning()) {
$status = 'running';
} elseif ($fiber->isSuspended()) {
$status = 'suspended';
} elseif ($fiber->isStarted()) {
$status = 'started';
} else {
$status = 'not started';
}
$a[$prefix.'status'] = $status;
return $a;
}
}
@@ -1,30 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
/**
* Represents a single backtrace frame as returned by debug_backtrace() or Exception->getTrace().
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class FrameStub extends EnumStub
{
public $keepArgs;
public $inTraceStub;
public function __construct(array $frame, bool $keepArgs = true, bool $inTraceStub = false)
{
$this->value = $frame;
$this->keepArgs = $keepArgs;
$this->inTraceStub = $inTraceStub;
}
}
@@ -1,32 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts GMP objects to array representation.
*
* @author Hamza Amrouche <hamza.simperfit@gmail.com>
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class GmpCaster
{
public static function castGmp(\GMP $gmp, array $a, Stub $stub, bool $isNested, int $filter): array
{
$a[Caster::PREFIX_VIRTUAL.'value'] = new ConstStub(gmp_strval($gmp), gmp_strval($gmp));
return $a;
}
}
@@ -1,37 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Imagine\Image\ImageInterface;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
final class ImagineCaster
{
public static function castImage(ImageInterface $c, array $a, Stub $stub, bool $isNested): array
{
$imgData = $c->get('png');
if (\strlen($imgData) > 1 * 1000 * 1000) {
$a += [
Caster::PREFIX_VIRTUAL.'image' => new ConstStub($c->getSize()),
];
} else {
$a += [
Caster::PREFIX_VIRTUAL.'image' => new ImgStub($imgData, 'image/png', $c->getSize()),
];
}
return $a;
}
}
@@ -1,26 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
class ImgStub extends ConstStub
{
public function __construct(string $data, string $contentType, string $size = '')
{
$this->value = '';
$this->attr['img-data'] = $data;
$this->attr['img-size'] = $size;
$this->attr['content-type'] = $contentType;
}
}
@@ -1,187 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* @author Nicolas Grekas <p@tchwork.com>
* @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
*
* @final
*/
class IntlCaster
{
/**
* @return array
*/
public static function castMessageFormatter(\MessageFormatter $c, array $a, Stub $stub, bool $isNested)
{
$a += [
Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(),
Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(),
];
return self::castError($c, $a);
}
/**
* @return array
*/
public static function castNumberFormatter(\NumberFormatter $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
$a += [
Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(),
Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(),
];
if ($filter & Caster::EXCLUDE_VERBOSE) {
$stub->cut += 3;
return self::castError($c, $a);
}
$a += [
Caster::PREFIX_VIRTUAL.'attributes' => new EnumStub(
[
'PARSE_INT_ONLY' => $c->getAttribute(\NumberFormatter::PARSE_INT_ONLY),
'GROUPING_USED' => $c->getAttribute(\NumberFormatter::GROUPING_USED),
'DECIMAL_ALWAYS_SHOWN' => $c->getAttribute(\NumberFormatter::DECIMAL_ALWAYS_SHOWN),
'MAX_INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_INTEGER_DIGITS),
'MIN_INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_INTEGER_DIGITS),
'INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::INTEGER_DIGITS),
'MAX_FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_FRACTION_DIGITS),
'MIN_FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_FRACTION_DIGITS),
'FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::FRACTION_DIGITS),
'MULTIPLIER' => $c->getAttribute(\NumberFormatter::MULTIPLIER),
'GROUPING_SIZE' => $c->getAttribute(\NumberFormatter::GROUPING_SIZE),
'ROUNDING_MODE' => $c->getAttribute(\NumberFormatter::ROUNDING_MODE),
'ROUNDING_INCREMENT' => $c->getAttribute(\NumberFormatter::ROUNDING_INCREMENT),
'FORMAT_WIDTH' => $c->getAttribute(\NumberFormatter::FORMAT_WIDTH),
'PADDING_POSITION' => $c->getAttribute(\NumberFormatter::PADDING_POSITION),
'SECONDARY_GROUPING_SIZE' => $c->getAttribute(\NumberFormatter::SECONDARY_GROUPING_SIZE),
'SIGNIFICANT_DIGITS_USED' => $c->getAttribute(\NumberFormatter::SIGNIFICANT_DIGITS_USED),
'MIN_SIGNIFICANT_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_SIGNIFICANT_DIGITS),
'MAX_SIGNIFICANT_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_SIGNIFICANT_DIGITS),
'LENIENT_PARSE' => $c->getAttribute(\NumberFormatter::LENIENT_PARSE),
]
),
Caster::PREFIX_VIRTUAL.'text_attributes' => new EnumStub(
[
'POSITIVE_PREFIX' => $c->getTextAttribute(\NumberFormatter::POSITIVE_PREFIX),
'POSITIVE_SUFFIX' => $c->getTextAttribute(\NumberFormatter::POSITIVE_SUFFIX),
'NEGATIVE_PREFIX' => $c->getTextAttribute(\NumberFormatter::NEGATIVE_PREFIX),
'NEGATIVE_SUFFIX' => $c->getTextAttribute(\NumberFormatter::NEGATIVE_SUFFIX),
'PADDING_CHARACTER' => $c->getTextAttribute(\NumberFormatter::PADDING_CHARACTER),
'CURRENCY_CODE' => $c->getTextAttribute(\NumberFormatter::CURRENCY_CODE),
'DEFAULT_RULESET' => $c->getTextAttribute(\NumberFormatter::DEFAULT_RULESET),
'PUBLIC_RULESETS' => $c->getTextAttribute(\NumberFormatter::PUBLIC_RULESETS),
]
),
Caster::PREFIX_VIRTUAL.'symbols' => new EnumStub(
[
'DECIMAL_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL),
'GROUPING_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL),
'PATTERN_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::PATTERN_SEPARATOR_SYMBOL),
'PERCENT_SYMBOL' => $c->getSymbol(\NumberFormatter::PERCENT_SYMBOL),
'ZERO_DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::ZERO_DIGIT_SYMBOL),
'DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::DIGIT_SYMBOL),
'MINUS_SIGN_SYMBOL' => $c->getSymbol(\NumberFormatter::MINUS_SIGN_SYMBOL),
'PLUS_SIGN_SYMBOL' => $c->getSymbol(\NumberFormatter::PLUS_SIGN_SYMBOL),
'CURRENCY_SYMBOL' => $c->getSymbol(\NumberFormatter::CURRENCY_SYMBOL),
'INTL_CURRENCY_SYMBOL' => $c->getSymbol(\NumberFormatter::INTL_CURRENCY_SYMBOL),
'MONETARY_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::MONETARY_SEPARATOR_SYMBOL),
'EXPONENTIAL_SYMBOL' => $c->getSymbol(\NumberFormatter::EXPONENTIAL_SYMBOL),
'PERMILL_SYMBOL' => $c->getSymbol(\NumberFormatter::PERMILL_SYMBOL),
'PAD_ESCAPE_SYMBOL' => $c->getSymbol(\NumberFormatter::PAD_ESCAPE_SYMBOL),
'INFINITY_SYMBOL' => $c->getSymbol(\NumberFormatter::INFINITY_SYMBOL),
'NAN_SYMBOL' => $c->getSymbol(\NumberFormatter::NAN_SYMBOL),
'SIGNIFICANT_DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::SIGNIFICANT_DIGIT_SYMBOL),
'MONETARY_GROUPING_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL),
]
),
];
return self::castError($c, $a);
}
/**
* @return array
*/
public static function castIntlTimeZone(\IntlTimeZone $c, array $a, Stub $stub, bool $isNested)
{
$a += [
Caster::PREFIX_VIRTUAL.'display_name' => $c->getDisplayName(),
Caster::PREFIX_VIRTUAL.'id' => $c->getID(),
Caster::PREFIX_VIRTUAL.'raw_offset' => $c->getRawOffset(),
];
if ($c->useDaylightTime()) {
$a += [
Caster::PREFIX_VIRTUAL.'dst_savings' => $c->getDSTSavings(),
];
}
return self::castError($c, $a);
}
/**
* @return array
*/
public static function castIntlCalendar(\IntlCalendar $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
$a += [
Caster::PREFIX_VIRTUAL.'type' => $c->getType(),
Caster::PREFIX_VIRTUAL.'first_day_of_week' => $c->getFirstDayOfWeek(),
Caster::PREFIX_VIRTUAL.'minimal_days_in_first_week' => $c->getMinimalDaysInFirstWeek(),
Caster::PREFIX_VIRTUAL.'repeated_wall_time_option' => $c->getRepeatedWallTimeOption(),
Caster::PREFIX_VIRTUAL.'skipped_wall_time_option' => $c->getSkippedWallTimeOption(),
Caster::PREFIX_VIRTUAL.'time' => $c->getTime(),
Caster::PREFIX_VIRTUAL.'in_daylight_time' => $c->inDaylightTime(),
Caster::PREFIX_VIRTUAL.'is_lenient' => $c->isLenient(),
Caster::PREFIX_VIRTUAL.'time_zone' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getTimeZone()) : $c->getTimeZone(),
];
return self::castError($c, $a);
}
/**
* @return array
*/
public static function castIntlDateFormatter(\IntlDateFormatter $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
$a += [
Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(),
Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(),
Caster::PREFIX_VIRTUAL.'calendar' => $c->getCalendar(),
Caster::PREFIX_VIRTUAL.'time_zone_id' => $c->getTimeZoneId(),
Caster::PREFIX_VIRTUAL.'time_type' => $c->getTimeType(),
Caster::PREFIX_VIRTUAL.'date_type' => $c->getDateType(),
Caster::PREFIX_VIRTUAL.'calendar_object' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getCalendarObject()) : $c->getCalendarObject(),
Caster::PREFIX_VIRTUAL.'time_zone' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getTimeZone()) : $c->getTimeZone(),
];
return self::castError($c, $a);
}
private static function castError(object $c, array $a): array
{
if ($errorCode = $c->getErrorCode()) {
$a += [
Caster::PREFIX_VIRTUAL.'error_code' => $errorCode,
Caster::PREFIX_VIRTUAL.'error_message' => $c->getErrorMessage(),
];
}
return $a;
}
}
@@ -1,105 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
/**
* Represents a file or a URL.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class LinkStub extends ConstStub
{
public $inVendor = false;
private static array $vendorRoots;
private static array $composerRoots = [];
public function __construct(string $label, int $line = 0, ?string $href = null)
{
$this->value = $label;
if (!\is_string($href ??= $label)) {
return;
}
if (str_starts_with($href, 'file://')) {
if ($href === $label) {
$label = substr($label, 7);
}
$href = substr($href, 7);
} elseif (str_contains($href, '://')) {
$this->attr['href'] = $href;
return;
}
if (!is_file($href)) {
return;
}
if ($line) {
$this->attr['line'] = $line;
}
if ($label !== $this->attr['file'] = realpath($href) ?: $href) {
return;
}
if ($composerRoot = $this->getComposerRoot($href, $this->inVendor)) {
$this->attr['ellipsis'] = \strlen($href) - \strlen($composerRoot) + 1;
$this->attr['ellipsis-type'] = 'path';
$this->attr['ellipsis-tail'] = 1 + ($this->inVendor ? 2 + \strlen(implode('', \array_slice(explode(\DIRECTORY_SEPARATOR, substr($href, 1 - $this->attr['ellipsis'])), 0, 2))) : 0);
} elseif (3 < \count($ellipsis = explode(\DIRECTORY_SEPARATOR, $href))) {
$this->attr['ellipsis'] = 2 + \strlen(implode('', \array_slice($ellipsis, -2)));
$this->attr['ellipsis-type'] = 'path';
$this->attr['ellipsis-tail'] = 1;
}
}
private function getComposerRoot(string $file, bool &$inVendor): string|false
{
if (!isset(self::$vendorRoots)) {
self::$vendorRoots = [];
foreach (get_declared_classes() as $class) {
if ('C' === $class[0] && str_starts_with($class, 'ComposerAutoloaderInit')) {
$r = new \ReflectionClass($class);
$v = \dirname($r->getFileName(), 2);
if (is_file($v.'/composer/installed.json')) {
self::$vendorRoots[] = $v.\DIRECTORY_SEPARATOR;
}
}
}
}
$inVendor = false;
if (isset(self::$composerRoots[$dir = \dirname($file)])) {
return self::$composerRoots[$dir];
}
foreach (self::$vendorRoots as $root) {
if ($inVendor = str_starts_with($file, $root)) {
return $root;
}
}
$parent = $dir;
while (!@is_file($parent.'/composer.json')) {
if (!@file_exists($parent)) {
// open_basedir restriction in effect
break;
}
if ($parent === \dirname($parent)) {
return self::$composerRoots[$dir] = false;
}
$parent = \dirname($parent);
}
return self::$composerRoots[$dir] = $parent.\DIRECTORY_SEPARATOR;
}
}
@@ -1,84 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
*
* @final
*/
class MemcachedCaster
{
private static array $optionConstants;
private static array $defaultOptions;
/**
* @return array
*/
public static function castMemcached(\Memcached $c, array $a, Stub $stub, bool $isNested)
{
$a += [
Caster::PREFIX_VIRTUAL.'servers' => $c->getServerList(),
Caster::PREFIX_VIRTUAL.'options' => new EnumStub(
self::getNonDefaultOptions($c)
),
];
return $a;
}
private static function getNonDefaultOptions(\Memcached $c): array
{
self::$defaultOptions ??= self::discoverDefaultOptions();
self::$optionConstants ??= self::getOptionConstants();
$nonDefaultOptions = [];
foreach (self::$optionConstants as $constantKey => $value) {
if (self::$defaultOptions[$constantKey] !== $option = $c->getOption($value)) {
$nonDefaultOptions[$constantKey] = $option;
}
}
return $nonDefaultOptions;
}
private static function discoverDefaultOptions(): array
{
$defaultMemcached = new \Memcached();
$defaultMemcached->addServer('127.0.0.1', 11211);
$defaultOptions = [];
self::$optionConstants ??= self::getOptionConstants();
foreach (self::$optionConstants as $constantKey => $value) {
$defaultOptions[$constantKey] = $defaultMemcached->getOption($value);
}
return $defaultOptions;
}
private static function getOptionConstants(): array
{
$reflectedMemcached = new \ReflectionClass(\Memcached::class);
$optionConstants = [];
foreach ($reflectedMemcached->getConstants() as $constantKey => $value) {
if (str_starts_with($constantKey, 'OPT_')) {
$optionConstants[$constantKey] = $value;
}
}
return $optionConstants;
}
}
@@ -1,33 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
final class MysqliCaster
{
public static function castMysqliDriver(\mysqli_driver $c, array $a, Stub $stub, bool $isNested): array
{
foreach ($a as $k => $v) {
if (isset($c->$k)) {
$a[$k] = $c->$k;
}
}
return $a;
}
}
@@ -1,128 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts PDO related classes to array representation.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class PdoCaster
{
private const PDO_ATTRIBUTES = [
'CASE' => [
\PDO::CASE_LOWER => 'LOWER',
\PDO::CASE_NATURAL => 'NATURAL',
\PDO::CASE_UPPER => 'UPPER',
],
'ERRMODE' => [
\PDO::ERRMODE_SILENT => 'SILENT',
\PDO::ERRMODE_WARNING => 'WARNING',
\PDO::ERRMODE_EXCEPTION => 'EXCEPTION',
],
'TIMEOUT',
'PREFETCH',
'AUTOCOMMIT',
'PERSISTENT',
'DRIVER_NAME',
'SERVER_INFO',
'ORACLE_NULLS' => [
\PDO::NULL_NATURAL => 'NATURAL',
\PDO::NULL_EMPTY_STRING => 'EMPTY_STRING',
\PDO::NULL_TO_STRING => 'TO_STRING',
],
'CLIENT_VERSION',
'SERVER_VERSION',
'STATEMENT_CLASS',
'EMULATE_PREPARES',
'CONNECTION_STATUS',
'STRINGIFY_FETCHES',
'DEFAULT_FETCH_MODE' => [
\PDO::FETCH_ASSOC => 'ASSOC',
\PDO::FETCH_BOTH => 'BOTH',
\PDO::FETCH_LAZY => 'LAZY',
\PDO::FETCH_NUM => 'NUM',
\PDO::FETCH_OBJ => 'OBJ',
],
];
/**
* @return array
*/
public static function castPdo(\PDO $c, array $a, Stub $stub, bool $isNested)
{
$attr = [];
$errmode = $c->getAttribute(\PDO::ATTR_ERRMODE);
$c->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
foreach (self::PDO_ATTRIBUTES as $k => $v) {
if (!isset($k[0])) {
$k = $v;
$v = [];
}
try {
$attr[$k] = 'ERRMODE' === $k ? $errmode : $c->getAttribute(\constant('PDO::ATTR_'.$k));
if ($v && isset($v[$attr[$k]])) {
$attr[$k] = new ConstStub($v[$attr[$k]], $attr[$k]);
}
} catch (\Exception) {
}
}
if (isset($attr[$k = 'STATEMENT_CLASS'][1])) {
if ($attr[$k][1]) {
$attr[$k][1] = new ArgsStub($attr[$k][1], '__construct', $attr[$k][0]);
}
$attr[$k][0] = new ClassStub($attr[$k][0]);
}
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'inTransaction' => method_exists($c, 'inTransaction'),
$prefix.'errorInfo' => $c->errorInfo(),
$prefix.'attributes' => new EnumStub($attr),
];
if ($a[$prefix.'inTransaction']) {
$a[$prefix.'inTransaction'] = $c->inTransaction();
} else {
unset($a[$prefix.'inTransaction']);
}
if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) {
unset($a[$prefix.'errorInfo']);
}
$c->setAttribute(\PDO::ATTR_ERRMODE, $errmode);
return $a;
}
/**
* @return array
*/
public static function castPdoStatement(\PDOStatement $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a[$prefix.'errorInfo'] = $c->errorInfo();
if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) {
unset($a[$prefix.'errorInfo']);
}
return $a;
}
}
@@ -1,165 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts pqsql resources to array representation.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class PgSqlCaster
{
private const PARAM_CODES = [
'server_encoding',
'client_encoding',
'is_superuser',
'session_authorization',
'DateStyle',
'TimeZone',
'IntervalStyle',
'integer_datetimes',
'application_name',
'standard_conforming_strings',
];
private const TRANSACTION_STATUS = [
\PGSQL_TRANSACTION_IDLE => 'PGSQL_TRANSACTION_IDLE',
\PGSQL_TRANSACTION_ACTIVE => 'PGSQL_TRANSACTION_ACTIVE',
\PGSQL_TRANSACTION_INTRANS => 'PGSQL_TRANSACTION_INTRANS',
\PGSQL_TRANSACTION_INERROR => 'PGSQL_TRANSACTION_INERROR',
\PGSQL_TRANSACTION_UNKNOWN => 'PGSQL_TRANSACTION_UNKNOWN',
];
private const RESULT_STATUS = [
\PGSQL_EMPTY_QUERY => 'PGSQL_EMPTY_QUERY',
\PGSQL_COMMAND_OK => 'PGSQL_COMMAND_OK',
\PGSQL_TUPLES_OK => 'PGSQL_TUPLES_OK',
\PGSQL_COPY_OUT => 'PGSQL_COPY_OUT',
\PGSQL_COPY_IN => 'PGSQL_COPY_IN',
\PGSQL_BAD_RESPONSE => 'PGSQL_BAD_RESPONSE',
\PGSQL_NONFATAL_ERROR => 'PGSQL_NONFATAL_ERROR',
\PGSQL_FATAL_ERROR => 'PGSQL_FATAL_ERROR',
];
private const DIAG_CODES = [
'severity' => \PGSQL_DIAG_SEVERITY,
'sqlstate' => \PGSQL_DIAG_SQLSTATE,
'message' => \PGSQL_DIAG_MESSAGE_PRIMARY,
'detail' => \PGSQL_DIAG_MESSAGE_DETAIL,
'hint' => \PGSQL_DIAG_MESSAGE_HINT,
'statement position' => \PGSQL_DIAG_STATEMENT_POSITION,
'internal position' => \PGSQL_DIAG_INTERNAL_POSITION,
'internal query' => \PGSQL_DIAG_INTERNAL_QUERY,
'context' => \PGSQL_DIAG_CONTEXT,
'file' => \PGSQL_DIAG_SOURCE_FILE,
'line' => \PGSQL_DIAG_SOURCE_LINE,
'function' => \PGSQL_DIAG_SOURCE_FUNCTION,
];
/**
* @return array
*/
public static function castLargeObject($lo, array $a, Stub $stub, bool $isNested)
{
$a['seek position'] = pg_lo_tell($lo);
return $a;
}
/**
* @return array
*/
public static function castLink($link, array $a, Stub $stub, bool $isNested)
{
$a['status'] = pg_connection_status($link);
$a['status'] = new ConstStub(\PGSQL_CONNECTION_OK === $a['status'] ? 'PGSQL_CONNECTION_OK' : 'PGSQL_CONNECTION_BAD', $a['status']);
$a['busy'] = pg_connection_busy($link);
$a['transaction'] = pg_transaction_status($link);
if (isset(self::TRANSACTION_STATUS[$a['transaction']])) {
$a['transaction'] = new ConstStub(self::TRANSACTION_STATUS[$a['transaction']], $a['transaction']);
}
$a['pid'] = pg_get_pid($link);
$a['last error'] = pg_last_error($link);
$a['last notice'] = pg_last_notice($link);
$a['host'] = pg_host($link);
$a['port'] = pg_port($link);
$a['dbname'] = pg_dbname($link);
$a['options'] = pg_options($link);
$a['version'] = pg_version($link);
foreach (self::PARAM_CODES as $v) {
if (false !== $s = pg_parameter_status($link, $v)) {
$a['param'][$v] = $s;
}
}
$a['param']['client_encoding'] = pg_client_encoding($link);
$a['param'] = new EnumStub($a['param']);
return $a;
}
/**
* @return array
*/
public static function castResult($result, array $a, Stub $stub, bool $isNested)
{
$a['num rows'] = pg_num_rows($result);
$a['status'] = pg_result_status($result);
if (isset(self::RESULT_STATUS[$a['status']])) {
$a['status'] = new ConstStub(self::RESULT_STATUS[$a['status']], $a['status']);
}
$a['command-completion tag'] = pg_result_status($result, \PGSQL_STATUS_STRING);
if (-1 === $a['num rows']) {
foreach (self::DIAG_CODES as $k => $v) {
$a['error'][$k] = pg_result_error_field($result, $v);
}
}
$a['affected rows'] = pg_affected_rows($result);
$a['last OID'] = pg_last_oid($result);
$fields = pg_num_fields($result);
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)),
'nullable' => (bool) pg_field_is_null($result, $i),
'storage' => pg_field_size($result, $i).' bytes',
'display' => pg_field_prtlen($result, $i).' chars',
];
if (' (OID: )' === $field['table']) {
$field['table'] = null;
}
if ('-1 bytes' === $field['storage']) {
$field['storage'] = 'variable size';
} elseif ('1 bytes' === $field['storage']) {
$field['storage'] = '1 byte';
}
if ('1 chars' === $field['display']) {
$field['display'] = '1 char';
}
$a['fields'][] = new EnumStub($field);
}
return $a;
}
}
@@ -1,36 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use ProxyManager\Proxy\ProxyInterface;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class ProxyManagerCaster
{
/**
* @return array
*/
public static function castProxy(ProxyInterface $c, array $a, Stub $stub, bool $isNested)
{
if ($parent = get_parent_class($c)) {
$stub->class .= ' - '.$parent;
}
$stub->class .= '@proxy';
return $a;
}
}
@@ -1,222 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use RdKafka\Conf;
use RdKafka\Exception as RdKafkaException;
use RdKafka\KafkaConsumer;
use RdKafka\Message;
use RdKafka\Metadata\Broker as BrokerMetadata;
use RdKafka\Metadata\Collection as CollectionMetadata;
use RdKafka\Metadata\Partition as PartitionMetadata;
use RdKafka\Metadata\Topic as TopicMetadata;
use RdKafka\Topic;
use RdKafka\TopicConf;
use RdKafka\TopicPartition;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts RdKafka related classes to array representation.
*
* @author Romain Neutron <imprec@gmail.com>
*/
class RdKafkaCaster
{
/**
* @return array
*/
public static function castKafkaConsumer(KafkaConsumer $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
try {
$assignment = $c->getAssignment();
} catch (RdKafkaException) {
$assignment = [];
}
$a += [
$prefix.'subscription' => $c->getSubscription(),
$prefix.'assignment' => $assignment,
];
$a += self::extractMetadata($c);
return $a;
}
/**
* @return array
*/
public static function castTopic(Topic $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'name' => $c->getName(),
];
return $a;
}
/**
* @return array
*/
public static function castTopicPartition(TopicPartition $c, array $a)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'offset' => $c->getOffset(),
$prefix.'partition' => $c->getPartition(),
$prefix.'topic' => $c->getTopic(),
];
return $a;
}
/**
* @return array
*/
public static function castMessage(Message $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'errstr' => $c->errstr(),
];
return $a;
}
/**
* @return array
*/
public static function castConf(Conf $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
foreach ($c->dump() as $key => $value) {
$a[$prefix.$key] = $value;
}
return $a;
}
/**
* @return array
*/
public static function castTopicConf(TopicConf $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
foreach ($c->dump() as $key => $value) {
$a[$prefix.$key] = $value;
}
return $a;
}
/**
* @return array
*/
public static function castRdKafka(\RdKafka $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'out_q_len' => $c->getOutQLen(),
];
$a += self::extractMetadata($c);
return $a;
}
/**
* @return array
*/
public static function castCollectionMetadata(CollectionMetadata $c, array $a, Stub $stub, bool $isNested)
{
$a += iterator_to_array($c);
return $a;
}
/**
* @return array
*/
public static function castTopicMetadata(TopicMetadata $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'name' => $c->getTopic(),
$prefix.'partitions' => $c->getPartitions(),
];
return $a;
}
/**
* @return array
*/
public static function castPartitionMetadata(PartitionMetadata $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'id' => $c->getId(),
$prefix.'err' => $c->getErr(),
$prefix.'leader' => $c->getLeader(),
];
return $a;
}
/**
* @return array
*/
public static function castBrokerMetadata(BrokerMetadata $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$a += [
$prefix.'id' => $c->getId(),
$prefix.'host' => $c->getHost(),
$prefix.'port' => $c->getPort(),
];
return $a;
}
/**
* @return array
*/
private static function extractMetadata(KafkaConsumer|\RdKafka $c)
{
$prefix = Caster::PREFIX_VIRTUAL;
try {
$m = $c->getMetadata(true, null, 500);
} catch (RdKafkaException) {
return [];
}
return [
$prefix.'orig_broker_id' => $m->getOrigBrokerId(),
$prefix.'orig_broker_name' => $m->getOrigBrokerName(),
$prefix.'brokers' => $m->getBrokers(),
$prefix.'topics' => $m->getTopics(),
];
}
}
@@ -1,159 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Relay\Relay;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts Redis class from ext-redis to array representation.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class RedisCaster
{
private const SERIALIZERS = [
0 => 'NONE', // Redis::SERIALIZER_NONE
1 => 'PHP', // Redis::SERIALIZER_PHP
2 => 'IGBINARY', // Optional Redis::SERIALIZER_IGBINARY
];
private const MODES = [
0 => 'ATOMIC', // Redis::ATOMIC
1 => 'MULTI', // Redis::MULTI
2 => 'PIPELINE', // Redis::PIPELINE
];
private const COMPRESSION_MODES = [
0 => 'NONE', // Redis::COMPRESSION_NONE
1 => 'LZF', // Redis::COMPRESSION_LZF
];
private const FAILOVER_OPTIONS = [
\RedisCluster::FAILOVER_NONE => 'NONE',
\RedisCluster::FAILOVER_ERROR => 'ERROR',
\RedisCluster::FAILOVER_DISTRIBUTE => 'DISTRIBUTE',
\RedisCluster::FAILOVER_DISTRIBUTE_SLAVES => 'DISTRIBUTE_SLAVES',
];
/**
* @return array
*/
public static function castRedis(\Redis|Relay $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
if (!$connected = $c->isConnected()) {
return $a + [
$prefix.'isConnected' => $connected,
];
}
$mode = $c->getMode();
return $a + [
$prefix.'isConnected' => $connected,
$prefix.'host' => $c->getHost(),
$prefix.'port' => $c->getPort(),
$prefix.'auth' => $c->getAuth(),
$prefix.'mode' => isset(self::MODES[$mode]) ? new ConstStub(self::MODES[$mode], $mode) : $mode,
$prefix.'dbNum' => $c->getDbNum(),
$prefix.'timeout' => $c->getTimeout(),
$prefix.'lastError' => $c->getLastError(),
$prefix.'persistentId' => $c->getPersistentID(),
$prefix.'options' => self::getRedisOptions($c),
];
}
/**
* @return array
*/
public static function castRedisArray(\RedisArray $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
return $a + [
$prefix.'hosts' => $c->_hosts(),
$prefix.'function' => ClassStub::wrapCallable($c->_function()),
$prefix.'lastError' => $c->getLastError(),
$prefix.'options' => self::getRedisOptions($c),
];
}
/**
* @return array
*/
public static function castRedisCluster(\RedisCluster $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$failover = $c->getOption(\RedisCluster::OPT_SLAVE_FAILOVER);
$a += [
$prefix.'_masters' => $c->_masters(),
$prefix.'_redir' => $c->_redir(),
$prefix.'mode' => new ConstStub($c->getMode() ? 'MULTI' : 'ATOMIC', $c->getMode()),
$prefix.'lastError' => $c->getLastError(),
$prefix.'options' => self::getRedisOptions($c, [
'SLAVE_FAILOVER' => isset(self::FAILOVER_OPTIONS[$failover]) ? new ConstStub(self::FAILOVER_OPTIONS[$failover], $failover) : $failover,
]),
];
return $a;
}
private static function getRedisOptions(\Redis|Relay|\RedisArray|\RedisCluster $redis, array $options = []): EnumStub
{
$serializer = $redis->getOption(\defined('Redis::OPT_SERIALIZER') ? \Redis::OPT_SERIALIZER : 1);
if (\is_array($serializer)) {
foreach ($serializer as &$v) {
if (isset(self::SERIALIZERS[$v])) {
$v = new ConstStub(self::SERIALIZERS[$v], $v);
}
}
} elseif (isset(self::SERIALIZERS[$serializer])) {
$serializer = new ConstStub(self::SERIALIZERS[$serializer], $serializer);
}
$compression = \defined('Redis::OPT_COMPRESSION') ? $redis->getOption(\Redis::OPT_COMPRESSION) : 0;
if (\is_array($compression)) {
foreach ($compression as &$v) {
if (isset(self::COMPRESSION_MODES[$v])) {
$v = new ConstStub(self::COMPRESSION_MODES[$v], $v);
}
}
} elseif (isset(self::COMPRESSION_MODES[$compression])) {
$compression = new ConstStub(self::COMPRESSION_MODES[$compression], $compression);
}
$retry = \defined('Redis::OPT_SCAN') ? $redis->getOption(\Redis::OPT_SCAN) : 0;
if (\is_array($retry)) {
foreach ($retry as &$v) {
$v = new ConstStub($v ? 'RETRY' : 'NORETRY', $v);
}
} else {
$retry = new ConstStub($retry ? 'RETRY' : 'NORETRY', $retry);
}
$options += [
'TCP_KEEPALIVE' => \defined('Redis::OPT_TCP_KEEPALIVE') ? $redis->getOption(\Redis::OPT_TCP_KEEPALIVE) : Relay::OPT_TCP_KEEPALIVE,
'READ_TIMEOUT' => $redis->getOption(\defined('Redis::OPT_READ_TIMEOUT') ? \Redis::OPT_READ_TIMEOUT : Relay::OPT_READ_TIMEOUT),
'COMPRESSION' => $compression,
'SERIALIZER' => $serializer,
'PREFIX' => $redis->getOption(\defined('Redis::OPT_PREFIX') ? \Redis::OPT_PREFIX : Relay::OPT_PREFIX),
'SCAN' => $retry,
];
return new EnumStub($options);
}
}
@@ -1,485 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts Reflector related classes to array representation.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class ReflectionCaster
{
public const UNSET_CLOSURE_FILE_INFO = ['Closure' => __CLASS__.'::unsetClosureFileInfo'];
private const EXTRA_MAP = [
'docComment' => 'getDocComment',
'extension' => 'getExtensionName',
'isDisabled' => 'isDisabled',
'isDeprecated' => 'isDeprecated',
'isInternal' => 'isInternal',
'isUserDefined' => 'isUserDefined',
'isGenerator' => 'isGenerator',
'isVariadic' => 'isVariadic',
];
/**
* @return array
*/
public static function castClosure(\Closure $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
$prefix = Caster::PREFIX_VIRTUAL;
$c = new \ReflectionFunction($c);
$a = static::castFunctionAbstract($c, $a, $stub, $isNested, $filter);
if (!str_contains($c->name, '{closure}')) {
$stub->class = isset($a[$prefix.'class']) ? $a[$prefix.'class']->value.'::'.$c->name : $c->name;
unset($a[$prefix.'class']);
}
unset($a[$prefix.'extra']);
$stub->class .= self::getSignature($a);
if ($f = $c->getFileName()) {
$stub->attr['file'] = $f;
$stub->attr['line'] = $c->getStartLine();
}
unset($a[$prefix.'parameters']);
if ($filter & Caster::EXCLUDE_VERBOSE) {
$stub->cut += ($c->getFileName() ? 2 : 0) + \count($a);
return [];
}
if ($f) {
$a[$prefix.'file'] = new LinkStub($f, $c->getStartLine());
$a[$prefix.'line'] = $c->getStartLine().' to '.$c->getEndLine();
}
return $a;
}
/**
* @return array
*/
public static function unsetClosureFileInfo(\Closure $c, array $a)
{
unset($a[Caster::PREFIX_VIRTUAL.'file'], $a[Caster::PREFIX_VIRTUAL.'line']);
return $a;
}
public static function castGenerator(\Generator $c, array $a, Stub $stub, bool $isNested): array
{
// Cannot create ReflectionGenerator based on a terminated Generator
try {
$reflectionGenerator = new \ReflectionGenerator($c);
} catch (\Exception) {
$a[Caster::PREFIX_VIRTUAL.'closed'] = true;
return $a;
}
return self::castReflectionGenerator($reflectionGenerator, $a, $stub, $isNested);
}
/**
* @return array
*/
public static function castType(\ReflectionType $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
if ($c instanceof \ReflectionNamedType) {
$a += [
$prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : (string) $c,
$prefix.'allowsNull' => $c->allowsNull(),
$prefix.'isBuiltin' => $c->isBuiltin(),
];
} elseif ($c instanceof \ReflectionUnionType || $c instanceof \ReflectionIntersectionType) {
$a[$prefix.'allowsNull'] = $c->allowsNull();
self::addMap($a, $c, [
'types' => 'getTypes',
]);
} else {
$a[$prefix.'allowsNull'] = $c->allowsNull();
}
return $a;
}
/**
* @return array
*/
public static function castAttribute(\ReflectionAttribute $c, array $a, Stub $stub, bool $isNested)
{
self::addMap($a, $c, [
'name' => 'getName',
'arguments' => 'getArguments',
]);
return $a;
}
/**
* @return array
*/
public static function castReflectionGenerator(\ReflectionGenerator $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
if ($c->getThis()) {
$a[$prefix.'this'] = new CutStub($c->getThis());
}
$function = $c->getFunction();
$frame = [
'class' => $function->class ?? null,
'type' => isset($function->class) ? ($function->isStatic() ? '::' : '->') : null,
'function' => $function->name,
'file' => $c->getExecutingFile(),
'line' => $c->getExecutingLine(),
];
if ($trace = $c->getTrace(\DEBUG_BACKTRACE_IGNORE_ARGS)) {
$function = new \ReflectionGenerator($c->getExecutingGenerator());
array_unshift($trace, [
'function' => 'yield',
'file' => $function->getExecutingFile(),
'line' => $function->getExecutingLine(),
]);
$trace[] = $frame;
$a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1);
} else {
$function = new FrameStub($frame, false, true);
$function = ExceptionCaster::castFrameStub($function, [], $function, true);
$a[$prefix.'executing'] = $function[$prefix.'src'];
}
$a[Caster::PREFIX_VIRTUAL.'closed'] = false;
return $a;
}
/**
* @return array
*/
public static function castClass(\ReflectionClass $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
$prefix = Caster::PREFIX_VIRTUAL;
if ($n = \Reflection::getModifierNames($c->getModifiers())) {
$a[$prefix.'modifiers'] = implode(' ', $n);
}
self::addMap($a, $c, [
'extends' => 'getParentClass',
'implements' => 'getInterfaceNames',
'constants' => 'getReflectionConstants',
]);
foreach ($c->getProperties() as $n) {
$a[$prefix.'properties'][$n->name] = $n;
}
foreach ($c->getMethods() as $n) {
$a[$prefix.'methods'][$n->name] = $n;
}
self::addAttributes($a, $c, $prefix);
if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
self::addExtra($a, $c);
}
return $a;
}
/**
* @return array
*/
public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
$prefix = Caster::PREFIX_VIRTUAL;
self::addMap($a, $c, [
'returnsReference' => 'returnsReference',
'returnType' => 'getReturnType',
'class' => \PHP_VERSION_ID >= 80111 ? 'getClosureCalledClass' : 'getClosureScopeClass',
'this' => 'getClosureThis',
]);
if (isset($a[$prefix.'returnType'])) {
$v = $a[$prefix.'returnType'];
$v = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
$a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType'] instanceof \ReflectionNamedType && $a[$prefix.'returnType']->allowsNull() && 'mixed' !== $v ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
}
if (isset($a[$prefix.'class'])) {
$a[$prefix.'class'] = new ClassStub($a[$prefix.'class']);
}
if (isset($a[$prefix.'this'])) {
$a[$prefix.'this'] = new CutStub($a[$prefix.'this']);
}
foreach ($c->getParameters() as $v) {
$k = '$'.$v->name;
if ($v->isVariadic()) {
$k = '...'.$k;
}
if ($v->isPassedByReference()) {
$k = '&'.$k;
}
$a[$prefix.'parameters'][$k] = $v;
}
if (isset($a[$prefix.'parameters'])) {
$a[$prefix.'parameters'] = new EnumStub($a[$prefix.'parameters']);
}
self::addAttributes($a, $c, $prefix);
if (!($filter & Caster::EXCLUDE_VERBOSE) && $v = $c->getStaticVariables()) {
foreach ($v as $k => &$v) {
if (\is_object($v)) {
$a[$prefix.'use']['$'.$k] = new CutStub($v);
} else {
$a[$prefix.'use']['$'.$k] = &$v;
}
}
unset($v);
$a[$prefix.'use'] = new EnumStub($a[$prefix.'use']);
}
if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
self::addExtra($a, $c);
}
return $a;
}
/**
* @return array
*/
public static function castClassConstant(\ReflectionClassConstant $c, array $a, Stub $stub, bool $isNested)
{
$a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
$a[Caster::PREFIX_VIRTUAL.'value'] = $c->getValue();
self::addAttributes($a, $c);
return $a;
}
/**
* @return array
*/
public static function castMethod(\ReflectionMethod $c, array $a, Stub $stub, bool $isNested)
{
$a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
return $a;
}
/**
* @return array
*/
public static function castParameter(\ReflectionParameter $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
self::addMap($a, $c, [
'position' => 'getPosition',
'isVariadic' => 'isVariadic',
'byReference' => 'isPassedByReference',
'allowsNull' => 'allowsNull',
]);
self::addAttributes($a, $c, $prefix);
if ($v = $c->getType()) {
$a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
}
if (isset($a[$prefix.'typeHint'])) {
$v = $a[$prefix.'typeHint'];
$a[$prefix.'typeHint'] = new ClassStub($v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
} else {
unset($a[$prefix.'allowsNull']);
}
if ($c->isOptional()) {
try {
$a[$prefix.'default'] = $v = $c->getDefaultValue();
if ($c->isDefaultValueConstant() && !\is_object($v)) {
$a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v);
}
if (null === $v) {
unset($a[$prefix.'allowsNull']);
}
} catch (\ReflectionException) {
}
}
return $a;
}
/**
* @return array
*/
public static function castProperty(\ReflectionProperty $c, array $a, Stub $stub, bool $isNested)
{
$a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
self::addAttributes($a, $c);
self::addExtra($a, $c);
return $a;
}
/**
* @return array
*/
public static function castReference(\ReflectionReference $c, array $a, Stub $stub, bool $isNested)
{
$a[Caster::PREFIX_VIRTUAL.'id'] = $c->getId();
return $a;
}
/**
* @return array
*/
public static function castExtension(\ReflectionExtension $c, array $a, Stub $stub, bool $isNested)
{
self::addMap($a, $c, [
'version' => 'getVersion',
'dependencies' => 'getDependencies',
'iniEntries' => 'getIniEntries',
'isPersistent' => 'isPersistent',
'isTemporary' => 'isTemporary',
'constants' => 'getConstants',
'functions' => 'getFunctions',
'classes' => 'getClasses',
]);
return $a;
}
/**
* @return array
*/
public static function castZendExtension(\ReflectionZendExtension $c, array $a, Stub $stub, bool $isNested)
{
self::addMap($a, $c, [
'version' => 'getVersion',
'author' => 'getAuthor',
'copyright' => 'getCopyright',
'url' => 'getURL',
]);
return $a;
}
/**
* @return string
*/
public static function getSignature(array $a)
{
$prefix = Caster::PREFIX_VIRTUAL;
$signature = '';
if (isset($a[$prefix.'parameters'])) {
foreach ($a[$prefix.'parameters']->value as $k => $param) {
$signature .= ', ';
if ($type = $param->getType()) {
if (!$type instanceof \ReflectionNamedType) {
$signature .= $type.' ';
} else {
if (!$param->isOptional() && $param->allowsNull() && 'mixed' !== $type->getName()) {
$signature .= '?';
}
$signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' ';
}
}
$signature .= $k;
if (!$param->isDefaultValueAvailable()) {
continue;
}
$v = $param->getDefaultValue();
$signature .= ' = ';
if ($param->isDefaultValueConstant()) {
$signature .= substr(strrchr('\\'.$param->getDefaultValueConstantName(), '\\'), 1);
} elseif (null === $v) {
$signature .= 'null';
} elseif (\is_array($v)) {
$signature .= $v ? '[…'.\count($v).']' : '[]';
} elseif (\is_string($v)) {
$signature .= 10 > \strlen($v) && !str_contains($v, '\\') ? "'{$v}'" : "'…".\strlen($v)."'";
} elseif (\is_bool($v)) {
$signature .= $v ? 'true' : 'false';
} elseif (\is_object($v)) {
$signature .= 'new '.substr(strrchr('\\'.get_debug_type($v), '\\'), 1);
} else {
$signature .= $v;
}
}
}
$signature = (empty($a[$prefix.'returnsReference']) ? '' : '&').'('.substr($signature, 2).')';
if (isset($a[$prefix.'returnType'])) {
$signature .= ': '.substr(strrchr('\\'.$a[$prefix.'returnType'], '\\'), 1);
}
return $signature;
}
private static function addExtra(array &$a, \Reflector $c): void
{
$x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : [];
if (method_exists($c, 'getFileName') && $m = $c->getFileName()) {
$x['file'] = new LinkStub($m, $c->getStartLine());
$x['line'] = $c->getStartLine().' to '.$c->getEndLine();
}
self::addMap($x, $c, self::EXTRA_MAP, '');
if ($x) {
$a[Caster::PREFIX_VIRTUAL.'extra'] = new EnumStub($x);
}
}
private static function addMap(array &$a, object $c, array $map, string $prefix = Caster::PREFIX_VIRTUAL): void
{
foreach ($map as $k => $m) {
if ('isDisabled' === $k) {
continue;
}
if (method_exists($c, $m) && false !== ($m = $c->$m()) && null !== $m) {
$a[$prefix.$k] = $m instanceof \Reflector ? $m->name : $m;
}
}
}
private static function addAttributes(array &$a, \Reflector $c, string $prefix = Caster::PREFIX_VIRTUAL): void
{
foreach ($c->getAttributes() as $n) {
$a[$prefix.'attributes'][] = $n;
}
}
}
@@ -1,106 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts common resource types to array representation.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class ResourceCaster
{
public static function castCurl(\CurlHandle $h, array $a, Stub $stub, bool $isNested): array
{
return curl_getinfo($h);
}
/**
* @return array
*/
public static function castDba($dba, array $a, Stub $stub, bool $isNested)
{
$list = dba_list();
$a['file'] = $list[(int) $dba];
return $a;
}
/**
* @return array
*/
public static function castProcess($process, array $a, Stub $stub, bool $isNested)
{
return proc_get_status($process);
}
public static function castStream($stream, array $a, Stub $stub, bool $isNested): array
{
$a = stream_get_meta_data($stream) + static::castStreamContext($stream, $a, $stub, $isNested);
if ($a['uri'] ?? false) {
$a['uri'] = new LinkStub($a['uri']);
}
return $a;
}
/**
* @return array
*/
public static function castStreamContext($stream, array $a, Stub $stub, bool $isNested)
{
return @stream_context_get_params($stream) ?: $a;
}
/**
* @return array
*/
public static function castGd($gd, array $a, Stub $stub, bool $isNested)
{
$a['size'] = imagesx($gd).'x'.imagesy($gd);
$a['trueColor'] = imageistruecolor($gd);
return $a;
}
/**
* @return array
*/
public static function castOpensslX509($h, array $a, Stub $stub, bool $isNested)
{
$stub->cut = -1;
$info = openssl_x509_parse($h, false);
$pin = openssl_pkey_get_public($h);
$pin = openssl_pkey_get_details($pin)['key'];
$pin = \array_slice(explode("\n", $pin), 1, -2);
$pin = base64_decode(implode('', $pin));
$pin = base64_encode(hash('sha256', $pin, true));
$a += [
'subject' => new EnumStub(array_intersect_key($info['subject'], ['organizationName' => true, 'commonName' => true])),
'issuer' => new EnumStub(array_intersect_key($info['issuer'], ['organizationName' => true, 'commonName' => true])),
'expiry' => new ConstStub(date(\DateTimeInterface::ISO8601, $info['validTo_time_t']), $info['validTo_time_t']),
'fingerprint' => new EnumStub([
'md5' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'md5')), 2, ':', true)),
'sha1' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'sha1')), 2, ':', true)),
'sha256' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'sha256')), 2, ':', true)),
'pin-sha256' => new ConstStub($pin),
]),
];
return $a;
}
}
@@ -1,27 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Represents any arbitrary value.
*
* @author Alexandre Daubois <alex.daubois@gmail.com>
*/
class ScalarStub extends Stub
{
public function __construct(mixed $value)
{
$this->value = $value;
}
}
@@ -1,286 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts SPL related classes to array representation.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class SplCaster
{
private const SPL_FILE_OBJECT_FLAGS = [
\SplFileObject::DROP_NEW_LINE => 'DROP_NEW_LINE',
\SplFileObject::READ_AHEAD => 'READ_AHEAD',
\SplFileObject::SKIP_EMPTY => 'SKIP_EMPTY',
\SplFileObject::READ_CSV => 'READ_CSV',
];
/**
* @return array
*/
public static function castArrayObject(\ArrayObject $c, array $a, Stub $stub, bool $isNested)
{
return self::castSplArray($c, $a, $stub, $isNested);
}
/**
* @return array
*/
public static function castArrayIterator(\ArrayIterator $c, array $a, Stub $stub, bool $isNested)
{
return self::castSplArray($c, $a, $stub, $isNested);
}
/**
* @return array
*/
public static function castHeap(\Iterator $c, array $a, Stub $stub, bool $isNested)
{
$a += [
Caster::PREFIX_VIRTUAL.'heap' => iterator_to_array(clone $c),
];
return $a;
}
/**
* @return array
*/
public static function castDoublyLinkedList(\SplDoublyLinkedList $c, array $a, Stub $stub, bool $isNested)
{
$prefix = Caster::PREFIX_VIRTUAL;
$mode = $c->getIteratorMode();
$c->setIteratorMode(\SplDoublyLinkedList::IT_MODE_KEEP | $mode & ~\SplDoublyLinkedList::IT_MODE_DELETE);
$a += [
$prefix.'mode' => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_DELETE) ? 'IT_MODE_DELETE' : 'IT_MODE_KEEP'), $mode),
$prefix.'dllist' => iterator_to_array($c),
];
$c->setIteratorMode($mode);
return $a;
}
/**
* @return array
*/
public static function castFileInfo(\SplFileInfo $c, array $a, Stub $stub, bool $isNested)
{
static $map = [
'path' => 'getPath',
'filename' => 'getFilename',
'basename' => 'getBasename',
'pathname' => 'getPathname',
'extension' => 'getExtension',
'realPath' => 'getRealPath',
'aTime' => 'getATime',
'mTime' => 'getMTime',
'cTime' => 'getCTime',
'inode' => 'getInode',
'size' => 'getSize',
'perms' => 'getPerms',
'owner' => 'getOwner',
'group' => 'getGroup',
'type' => 'getType',
'writable' => 'isWritable',
'readable' => 'isReadable',
'executable' => 'isExecutable',
'file' => 'isFile',
'dir' => 'isDir',
'link' => 'isLink',
'linkTarget' => 'getLinkTarget',
];
$prefix = Caster::PREFIX_VIRTUAL;
unset($a["\0SplFileInfo\0fileName"]);
unset($a["\0SplFileInfo\0pathName"]);
try {
$c->isReadable();
} catch (\RuntimeException $e) {
if ('Object not initialized' !== $e->getMessage()) {
throw $e;
}
$a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
return $a;
} catch (\Error $e) {
if ('Object not initialized' !== $e->getMessage()) {
throw $e;
}
$a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
return $a;
}
foreach ($map as $key => $accessor) {
try {
$a[$prefix.$key] = $c->$accessor();
} catch (\Exception) {
}
}
if ($a[$prefix.'realPath'] ?? false) {
$a[$prefix.'realPath'] = new LinkStub($a[$prefix.'realPath']);
}
if (isset($a[$prefix.'perms'])) {
$a[$prefix.'perms'] = new ConstStub(sprintf('0%o', $a[$prefix.'perms']), $a[$prefix.'perms']);
}
static $mapDate = ['aTime', 'mTime', 'cTime'];
foreach ($mapDate as $key) {
if (isset($a[$prefix.$key])) {
$a[$prefix.$key] = new ConstStub(date('Y-m-d H:i:s', $a[$prefix.$key]), $a[$prefix.$key]);
}
}
return $a;
}
/**
* @return array
*/
public static function castFileObject(\SplFileObject $c, array $a, Stub $stub, bool $isNested)
{
static $map = [
'csvControl' => 'getCsvControl',
'flags' => 'getFlags',
'maxLineLen' => 'getMaxLineLen',
'fstat' => 'fstat',
'eof' => 'eof',
'key' => 'key',
];
$prefix = Caster::PREFIX_VIRTUAL;
foreach ($map as $key => $accessor) {
try {
$a[$prefix.$key] = $c->$accessor();
} catch (\Exception) {
}
}
if (isset($a[$prefix.'flags'])) {
$flagsArray = [];
foreach (self::SPL_FILE_OBJECT_FLAGS as $value => $name) {
if ($a[$prefix.'flags'] & $value) {
$flagsArray[] = $name;
}
}
$a[$prefix.'flags'] = new ConstStub(implode('|', $flagsArray), $a[$prefix.'flags']);
}
if (isset($a[$prefix.'fstat'])) {
$a[$prefix.'fstat'] = new CutArrayStub($a[$prefix.'fstat'], ['dev', 'ino', 'nlink', 'rdev', 'blksize', 'blocks']);
}
return $a;
}
/**
* @return array
*/
public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $stub, bool $isNested)
{
$storage = [];
unset($a[Caster::PREFIX_DYNAMIC."\0gcdata"]); // Don't hit https://bugs.php.net/65967
unset($a["\0SplObjectStorage\0storage"]);
$clone = clone $c;
foreach ($clone as $obj) {
$storage[] = new EnumStub([
'object' => $obj,
'info' => $clone->getInfo(),
]);
}
$a += [
Caster::PREFIX_VIRTUAL.'storage' => $storage,
];
return $a;
}
/**
* @return array
*/
public static function castOuterIterator(\OuterIterator $c, array $a, Stub $stub, bool $isNested)
{
$a[Caster::PREFIX_VIRTUAL.'innerIterator'] = $c->getInnerIterator();
return $a;
}
/**
* @return array
*/
public static function castWeakReference(\WeakReference $c, array $a, Stub $stub, bool $isNested)
{
$a[Caster::PREFIX_VIRTUAL.'object'] = $c->get();
return $a;
}
/**
* @return array
*/
public static function castWeakMap(\WeakMap $c, array $a, Stub $stub, bool $isNested)
{
$map = [];
foreach (clone $c as $obj => $data) {
$map[] = new EnumStub([
'object' => $obj,
'data' => $data,
]);
}
$a += [
Caster::PREFIX_VIRTUAL.'map' => $map,
];
return $a;
}
private static function castSplArray(\ArrayObject|\ArrayIterator $c, array $a, Stub $stub, bool $isNested): array
{
$prefix = Caster::PREFIX_VIRTUAL;
$flags = $c->getFlags();
if (!($flags & \ArrayObject::STD_PROP_LIST)) {
$c->setFlags(\ArrayObject::STD_PROP_LIST);
$a = Caster::castObject($c, $c::class, method_exists($c, '__debugInfo'), $stub->class);
$c->setFlags($flags);
}
unset($a["\0ArrayObject\0storage"], $a["\0ArrayIterator\0storage"]);
$a += [
$prefix.'storage' => $c->getArrayCopy(),
$prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST),
$prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS),
];
if ($c instanceof \ArrayObject) {
$a[$prefix.'iteratorClass'] = new ClassStub($c->getIteratorClass());
}
return $a;
}
}
@@ -1,107 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts a caster's Stub.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class StubCaster
{
/**
* @return array
*/
public static function castStub(Stub $c, array $a, Stub $stub, bool $isNested)
{
if ($isNested) {
$stub->type = $c->type;
$stub->class = $c->class;
$stub->value = $c->value;
$stub->handle = $c->handle;
$stub->cut = $c->cut;
$stub->attr = $c->attr;
if (Stub::TYPE_REF === $c->type && !$c->class && \is_string($c->value) && !preg_match('//u', $c->value)) {
$stub->type = Stub::TYPE_STRING;
$stub->class = Stub::STRING_BINARY;
}
$a = [];
}
return $a;
}
/**
* @return array
*/
public static function castCutArray(CutArrayStub $c, array $a, Stub $stub, bool $isNested)
{
return $isNested ? $c->preservedSubset : $a;
}
/**
* @return array
*/
public static function cutInternals($obj, array $a, Stub $stub, bool $isNested)
{
if ($isNested) {
$stub->cut += \count($a);
return [];
}
return $a;
}
/**
* @return array
*/
public static function castEnum(EnumStub $c, array $a, Stub $stub, bool $isNested)
{
if ($isNested) {
$stub->class = $c->dumpKeys ? '' : null;
$stub->handle = 0;
$stub->value = null;
$stub->cut = $c->cut;
$stub->attr = $c->attr;
$a = [];
if ($c->value) {
foreach (array_keys($c->value) as $k) {
$keys[] = !isset($k[0]) || "\0" !== $k[0] ? Caster::PREFIX_VIRTUAL.$k : $k;
}
// Preserve references with array_combine()
$a = array_combine($keys, $c->value);
}
}
return $a;
}
/**
* @return array
*/
public static function castScalar(ScalarStub $scalarStub, array $a, Stub $stub)
{
$stub->type = Stub::TYPE_SCALAR;
$stub->attr['value'] = $scalarStub->value;
return $a;
}
}
@@ -1,139 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Uid\Ulid;
use Symfony\Component\Uid\Uuid;
use Symfony\Component\VarDumper\Cloner\Stub;
use Symfony\Component\VarExporter\Internal\LazyObjectState;
/**
* @final
*/
class SymfonyCaster
{
private const REQUEST_GETTERS = [
'pathInfo' => 'getPathInfo',
'requestUri' => 'getRequestUri',
'baseUrl' => 'getBaseUrl',
'basePath' => 'getBasePath',
'method' => 'getMethod',
'format' => 'getRequestFormat',
];
/**
* @return array
*/
public static function castRequest(Request $request, array $a, Stub $stub, bool $isNested)
{
$clone = null;
foreach (self::REQUEST_GETTERS as $prop => $getter) {
$key = Caster::PREFIX_PROTECTED.$prop;
if (\array_key_exists($key, $a) && null === $a[$key]) {
$clone ??= clone $request;
$a[Caster::PREFIX_VIRTUAL.$prop] = $clone->{$getter}();
}
}
return $a;
}
/**
* @return array
*/
public static function castHttpClient($client, array $a, Stub $stub, bool $isNested)
{
$multiKey = sprintf("\0%s\0multi", $client::class);
if (isset($a[$multiKey])) {
$a[$multiKey] = new CutStub($a[$multiKey]);
}
return $a;
}
/**
* @return array
*/
public static function castHttpClientResponse($response, array $a, Stub $stub, bool $isNested)
{
$stub->cut += \count($a);
$a = [];
foreach ($response->getInfo() as $k => $v) {
$a[Caster::PREFIX_VIRTUAL.$k] = $v;
}
return $a;
}
/**
* @return array
*/
public static function castLazyObjectState($state, array $a, Stub $stub, bool $isNested)
{
if (!$isNested) {
return $a;
}
$stub->cut += \count($a) - 1;
$instance = $a['realInstance'] ?? null;
$a = ['status' => new ConstStub(match ($a['status']) {
LazyObjectState::STATUS_INITIALIZED_FULL => 'INITIALIZED_FULL',
LazyObjectState::STATUS_INITIALIZED_PARTIAL => 'INITIALIZED_PARTIAL',
LazyObjectState::STATUS_UNINITIALIZED_FULL => 'UNINITIALIZED_FULL',
LazyObjectState::STATUS_UNINITIALIZED_PARTIAL => 'UNINITIALIZED_PARTIAL',
}, $a['status'])];
if ($instance) {
$a['realInstance'] = $instance;
--$stub->cut;
}
return $a;
}
/**
* @return array
*/
public static function castUuid(Uuid $uuid, array $a, Stub $stub, bool $isNested)
{
$a[Caster::PREFIX_VIRTUAL.'toBase58'] = $uuid->toBase58();
$a[Caster::PREFIX_VIRTUAL.'toBase32'] = $uuid->toBase32();
// symfony/uid >= 5.3
if (method_exists($uuid, 'getDateTime')) {
$a[Caster::PREFIX_VIRTUAL.'time'] = $uuid->getDateTime()->format('Y-m-d H:i:s.u \U\T\C');
}
return $a;
}
/**
* @return array
*/
public static function castUlid(Ulid $ulid, array $a, Stub $stub, bool $isNested)
{
$a[Caster::PREFIX_VIRTUAL.'toBase58'] = $ulid->toBase58();
$a[Caster::PREFIX_VIRTUAL.'toRfc4122'] = $ulid->toRfc4122();
// symfony/uid >= 5.3
if (method_exists($ulid, 'getDateTime')) {
$a[Caster::PREFIX_VIRTUAL.'time'] = $ulid->getDateTime()->format('Y-m-d H:i:s.v \U\T\C');
}
return $a;
}
}
@@ -1,36 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Represents a backtrace as returned by debug_backtrace() or Exception->getTrace().
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class TraceStub extends Stub
{
public $keepArgs;
public $sliceOffset;
public $sliceLength;
public $numberingOffset;
public function __construct(array $trace, bool $keepArgs = true, int $sliceOffset = 0, ?int $sliceLength = null, int $numberingOffset = 0)
{
$this->value = $trace;
$this->keepArgs = $keepArgs;
$this->sliceOffset = $sliceOffset;
$this->sliceLength = $sliceLength;
$this->numberingOffset = $numberingOffset;
}
}
@@ -1,25 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
/**
* Represents an uninitialized property.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class UninitializedStub extends ConstStub
{
public function __construct(\ReflectionProperty $property)
{
parent::__construct('?'.($property->hasType() ? ' '.$property->getType() : ''), 'Uninitialized property');
}
}
@@ -1,30 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Ramsey\Uuid\UuidInterface;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
final class UuidCaster
{
public static function castRamseyUuid(UuidInterface $c, array $a, Stub $stub, bool $isNested): array
{
$a += [
Caster::PREFIX_VIRTUAL.'uuid' => (string) $c,
];
return $a;
}
}
@@ -1,95 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts XmlReader class to array representation.
*
* @author Baptiste Clavié <clavie.b@gmail.com>
*
* @final
*/
class XmlReaderCaster
{
private const NODE_TYPES = [
\XMLReader::NONE => 'NONE',
\XMLReader::ELEMENT => 'ELEMENT',
\XMLReader::ATTRIBUTE => 'ATTRIBUTE',
\XMLReader::TEXT => 'TEXT',
\XMLReader::CDATA => 'CDATA',
\XMLReader::ENTITY_REF => 'ENTITY_REF',
\XMLReader::ENTITY => 'ENTITY',
\XMLReader::PI => 'PI (Processing Instruction)',
\XMLReader::COMMENT => 'COMMENT',
\XMLReader::DOC => 'DOC',
\XMLReader::DOC_TYPE => 'DOC_TYPE',
\XMLReader::DOC_FRAGMENT => 'DOC_FRAGMENT',
\XMLReader::NOTATION => 'NOTATION',
\XMLReader::WHITESPACE => 'WHITESPACE',
\XMLReader::SIGNIFICANT_WHITESPACE => 'SIGNIFICANT_WHITESPACE',
\XMLReader::END_ELEMENT => 'END_ELEMENT',
\XMLReader::END_ENTITY => 'END_ENTITY',
\XMLReader::XML_DECLARATION => 'XML_DECLARATION',
];
/**
* @return array
*/
public static function castXmlReader(\XMLReader $reader, array $a, Stub $stub, bool $isNested)
{
try {
$properties = [
'LOADDTD' => @$reader->getParserProperty(\XMLReader::LOADDTD),
'DEFAULTATTRS' => @$reader->getParserProperty(\XMLReader::DEFAULTATTRS),
'VALIDATE' => @$reader->getParserProperty(\XMLReader::VALIDATE),
'SUBST_ENTITIES' => @$reader->getParserProperty(\XMLReader::SUBST_ENTITIES),
];
} catch (\Error) {
$properties = [
'LOADDTD' => false,
'DEFAULTATTRS' => false,
'VALIDATE' => false,
'SUBST_ENTITIES' => false,
];
}
$props = Caster::PREFIX_VIRTUAL.'parserProperties';
$info = [
'localName' => $reader->localName,
'prefix' => $reader->prefix,
'nodeType' => new ConstStub(self::NODE_TYPES[$reader->nodeType], $reader->nodeType),
'depth' => $reader->depth,
'isDefault' => $reader->isDefault,
'isEmptyElement' => \XMLReader::NONE === $reader->nodeType ? null : $reader->isEmptyElement,
'xmlLang' => $reader->xmlLang,
'attributeCount' => $reader->attributeCount,
'value' => $reader->value,
'namespaceURI' => $reader->namespaceURI,
'baseURI' => $reader->baseURI ? new LinkStub($reader->baseURI) : $reader->baseURI,
$props => $properties,
];
if ($info[$props] = Caster::filter($info[$props], Caster::EXCLUDE_EMPTY, [], $count)) {
$info[$props] = new EnumStub($info[$props]);
$info[$props]->cut = $count;
}
$a = Caster::filter($a, Caster::EXCLUDE_UNINITIALIZED, [], $count);
$info = Caster::filter($info, Caster::EXCLUDE_EMPTY, [], $count);
// +2 because hasValue and hasAttributes are always filtered
$stub->cut += $count + 2;
return $a + $info;
}
}
@@ -1,66 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts XML resources to array representation.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final
*/
class XmlResourceCaster
{
private const XML_ERRORS = [
\XML_ERROR_NONE => 'XML_ERROR_NONE',
\XML_ERROR_NO_MEMORY => 'XML_ERROR_NO_MEMORY',
\XML_ERROR_SYNTAX => 'XML_ERROR_SYNTAX',
\XML_ERROR_NO_ELEMENTS => 'XML_ERROR_NO_ELEMENTS',
\XML_ERROR_INVALID_TOKEN => 'XML_ERROR_INVALID_TOKEN',
\XML_ERROR_UNCLOSED_TOKEN => 'XML_ERROR_UNCLOSED_TOKEN',
\XML_ERROR_PARTIAL_CHAR => 'XML_ERROR_PARTIAL_CHAR',
\XML_ERROR_TAG_MISMATCH => 'XML_ERROR_TAG_MISMATCH',
\XML_ERROR_DUPLICATE_ATTRIBUTE => 'XML_ERROR_DUPLICATE_ATTRIBUTE',
\XML_ERROR_JUNK_AFTER_DOC_ELEMENT => 'XML_ERROR_JUNK_AFTER_DOC_ELEMENT',
\XML_ERROR_PARAM_ENTITY_REF => 'XML_ERROR_PARAM_ENTITY_REF',
\XML_ERROR_UNDEFINED_ENTITY => 'XML_ERROR_UNDEFINED_ENTITY',
\XML_ERROR_RECURSIVE_ENTITY_REF => 'XML_ERROR_RECURSIVE_ENTITY_REF',
\XML_ERROR_ASYNC_ENTITY => 'XML_ERROR_ASYNC_ENTITY',
\XML_ERROR_BAD_CHAR_REF => 'XML_ERROR_BAD_CHAR_REF',
\XML_ERROR_BINARY_ENTITY_REF => 'XML_ERROR_BINARY_ENTITY_REF',
\XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF => 'XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF',
\XML_ERROR_MISPLACED_XML_PI => 'XML_ERROR_MISPLACED_XML_PI',
\XML_ERROR_UNKNOWN_ENCODING => 'XML_ERROR_UNKNOWN_ENCODING',
\XML_ERROR_INCORRECT_ENCODING => 'XML_ERROR_INCORRECT_ENCODING',
\XML_ERROR_UNCLOSED_CDATA_SECTION => 'XML_ERROR_UNCLOSED_CDATA_SECTION',
\XML_ERROR_EXTERNAL_ENTITY_HANDLING => 'XML_ERROR_EXTERNAL_ENTITY_HANDLING',
];
/**
* @return array
*/
public static function castXml($h, array $a, Stub $stub, bool $isNested)
{
$a['current_byte_index'] = xml_get_current_byte_index($h);
$a['current_column_number'] = xml_get_current_column_number($h);
$a['current_line_number'] = xml_get_current_line_number($h);
$a['error_code'] = xml_get_error_code($h);
if (isset(self::XML_ERRORS[$a['error_code']])) {
$a['error_code'] = new ConstStub(self::XML_ERRORS[$a['error_code']], $a['error_code']);
}
return $a;
}
}