mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-19 23:32:17 +02:00
N°6934 - Symfony 6.4 - upgrade Symfony bundles to 6.4 (#580)
* Update Symfony lib to version ~6.4.0 * Update code missing return type * Add an iTop general configuration entry to store application secret (Symfony mandatory parameter) * Use dependency injection in ExceptionListener & UserProvider classes
This commit is contained in:
@@ -28,6 +28,7 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
'Symfony\Component\VarDumper\Caster\CutArrayStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castCutArray'],
|
||||
'Symfony\Component\VarDumper\Caster\ConstStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'],
|
||||
'Symfony\Component\VarDumper\Caster\EnumStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castEnum'],
|
||||
'Symfony\Component\VarDumper\Caster\ScalarStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castScalar'],
|
||||
|
||||
'Fiber' => ['Symfony\Component\VarDumper\Caster\FiberCaster', 'castFiber'],
|
||||
|
||||
@@ -66,9 +67,6 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
'DOMAttr' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castAttr'],
|
||||
'DOMElement' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castElement'],
|
||||
'DOMText' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castText'],
|
||||
'DOMTypeinfo' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castTypeinfo'],
|
||||
'DOMDomError' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDomError'],
|
||||
'DOMLocator' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLocator'],
|
||||
'DOMDocumentType' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDocumentType'],
|
||||
'DOMNotation' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNotation'],
|
||||
'DOMEntity' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castEntity'],
|
||||
@@ -92,10 +90,12 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
'Symfony\Component\HttpFoundation\Request' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castRequest'],
|
||||
'Symfony\Component\Uid\Ulid' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castUlid'],
|
||||
'Symfony\Component\Uid\Uuid' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castUuid'],
|
||||
'Symfony\Component\VarExporter\Internal\LazyObjectState' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castLazyObjectState'],
|
||||
'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castThrowingCasterException'],
|
||||
'Symfony\Component\VarDumper\Caster\TraceStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castTraceStub'],
|
||||
'Symfony\Component\VarDumper\Caster\FrameStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castFrameStub'],
|
||||
'Symfony\Component\VarDumper\Cloner\AbstractCloner' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
|
||||
'Symfony\Component\ErrorHandler\Exception\FlattenException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castFlattenException'],
|
||||
'Symfony\Component\ErrorHandler\Exception\SilencedErrorContext' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castSilencedErrorContext'],
|
||||
|
||||
'Imagine\Image\ImageInterface' => ['Symfony\Component\VarDumper\Caster\ImagineCaster', 'castImage'],
|
||||
@@ -127,9 +127,11 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
'SplObjectStorage' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castObjectStorage'],
|
||||
'SplPriorityQueue' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castHeap'],
|
||||
'OuterIterator' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castOuterIterator'],
|
||||
'WeakMap' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castWeakMap'],
|
||||
'WeakReference' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castWeakReference'],
|
||||
|
||||
'Redis' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedis'],
|
||||
'Relay\Relay' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedis'],
|
||||
'RedisArray' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedisArray'],
|
||||
'RedisCluster' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedisCluster'],
|
||||
|
||||
@@ -156,7 +158,6 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
'mysqli_driver' => ['Symfony\Component\VarDumper\Caster\MysqliCaster', 'castMysqliDriver'],
|
||||
|
||||
'CurlHandle' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castCurl'],
|
||||
':curl' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castCurl'],
|
||||
|
||||
':dba' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'],
|
||||
':dba persistent' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'],
|
||||
@@ -164,7 +165,6 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
'GdImage' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castGd'],
|
||||
':gd' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castGd'],
|
||||
|
||||
':mysql link' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castMysqlLink'],
|
||||
':pgsql large object' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLargeObject'],
|
||||
':pgsql link' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLink'],
|
||||
':pgsql link persistent' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLink'],
|
||||
@@ -192,6 +192,9 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
'RdKafka\Topic' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopic'],
|
||||
'RdKafka\TopicPartition' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopicPartition'],
|
||||
'RdKafka\TopicConf' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopicConf'],
|
||||
|
||||
'FFI\CData' => ['Symfony\Component\VarDumper\Caster\FFICaster', 'castCTypeOrCData'],
|
||||
'FFI\CType' => ['Symfony\Component\VarDumper\Caster\FFICaster', 'castCTypeOrCData'],
|
||||
];
|
||||
|
||||
protected $maxItems = 2500;
|
||||
@@ -201,15 +204,15 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
/**
|
||||
* @var array<string, list<callable>>
|
||||
*/
|
||||
private $casters = [];
|
||||
private array $casters = [];
|
||||
|
||||
/**
|
||||
* @var callable|null
|
||||
*/
|
||||
private $prevErrorHandler;
|
||||
|
||||
private $classInfo = [];
|
||||
private $filter = 0;
|
||||
private array $classInfo = [];
|
||||
private int $filter = 0;
|
||||
|
||||
/**
|
||||
* @param callable[]|null $casters A map of casters
|
||||
@@ -218,10 +221,7 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
*/
|
||||
public function __construct(array $casters = null)
|
||||
{
|
||||
if (null === $casters) {
|
||||
$casters = static::$defaultCasters;
|
||||
}
|
||||
$this->addCasters($casters);
|
||||
$this->addCasters($casters ?? static::$defaultCasters);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,6 +233,8 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
* see e.g. static::$defaultCasters.
|
||||
*
|
||||
* @param callable[] $casters A map of casters
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addCasters(array $casters)
|
||||
{
|
||||
@@ -243,6 +245,8 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
|
||||
/**
|
||||
* Sets the maximum number of items to clone past the minimum depth in nested structures.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMaxItems(int $maxItems)
|
||||
{
|
||||
@@ -251,6 +255,8 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
|
||||
/**
|
||||
* Sets the maximum cloned length for strings.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMaxString(int $maxString)
|
||||
{
|
||||
@@ -260,6 +266,8 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
/**
|
||||
* Sets the minimum tree depth where we are guaranteed to clone all the items. After this
|
||||
* depth is reached, only setMaxItems items will be cloned.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMinDepth(int $minDepth)
|
||||
{
|
||||
@@ -269,12 +277,9 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
/**
|
||||
* Clones a PHP variable.
|
||||
*
|
||||
* @param mixed $var Any PHP variable
|
||||
* @param int $filter A bit field of Caster::EXCLUDE_* constants
|
||||
*
|
||||
* @return Data
|
||||
* @param int $filter A bit field of Caster::EXCLUDE_* constants
|
||||
*/
|
||||
public function cloneVar($var, int $filter = 0)
|
||||
public function cloneVar(mixed $var, int $filter = 0): Data
|
||||
{
|
||||
$this->prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) {
|
||||
if (\E_RECOVERABLE_ERROR === $type || \E_USER_ERROR === $type) {
|
||||
@@ -306,26 +311,20 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
|
||||
/**
|
||||
* Effectively clones the PHP variable.
|
||||
*
|
||||
* @param mixed $var Any PHP variable
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function doClone($var);
|
||||
abstract protected function doClone(mixed $var): array;
|
||||
|
||||
/**
|
||||
* Casts an object to an array representation.
|
||||
*
|
||||
* @param bool $isNested True if the object is nested in the dumped structure
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function castObject(Stub $stub, bool $isNested)
|
||||
protected function castObject(Stub $stub, bool $isNested): array
|
||||
{
|
||||
$obj = $stub->value;
|
||||
$class = $stub->class;
|
||||
|
||||
if (\PHP_VERSION_ID < 80000 ? "\0" === ($class[15] ?? null) : str_contains($class, "@anonymous\0")) {
|
||||
if (str_contains($class, "@anonymous\0")) {
|
||||
$stub->class = get_debug_type($obj);
|
||||
}
|
||||
if (isset($this->classInfo[$class])) {
|
||||
@@ -376,10 +375,8 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
* Casts a resource to an array representation.
|
||||
*
|
||||
* @param bool $isNested True if the object is nested in the dumped structure
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function castResource(Stub $stub, bool $isNested)
|
||||
protected function castResource(Stub $stub, bool $isNested): array
|
||||
{
|
||||
$a = [];
|
||||
$res = $stub->value;
|
||||
|
||||
@@ -18,10 +18,6 @@ interface ClonerInterface
|
||||
{
|
||||
/**
|
||||
* Clones a PHP variable.
|
||||
*
|
||||
* @param mixed $var Any PHP variable
|
||||
*
|
||||
* @return Data
|
||||
*/
|
||||
public function cloneVar($var);
|
||||
public function cloneVar(mixed $var): Data;
|
||||
}
|
||||
|
||||
@@ -17,15 +17,15 @@ use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
class Data implements \ArrayAccess, \Countable, \IteratorAggregate, \Stringable
|
||||
{
|
||||
private $data;
|
||||
private $position = 0;
|
||||
private $key = 0;
|
||||
private $maxDepth = 20;
|
||||
private $maxItemsPerDepth = -1;
|
||||
private $useRefHandles = -1;
|
||||
private $context = [];
|
||||
private array $data;
|
||||
private int $position = 0;
|
||||
private int|string $key = 0;
|
||||
private int $maxDepth = 20;
|
||||
private int $maxItemsPerDepth = -1;
|
||||
private int $useRefHandles = -1;
|
||||
private array $context = [];
|
||||
|
||||
/**
|
||||
* @param array $data An array as returned by ClonerInterface::cloneVar()
|
||||
@@ -35,10 +35,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getType()
|
||||
public function getType(): ?string
|
||||
{
|
||||
$item = $this->data[$this->position][$this->key];
|
||||
|
||||
@@ -71,7 +68,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
*
|
||||
* @return string|int|float|bool|array|Data[]|null
|
||||
*/
|
||||
public function getValue($recursive = false)
|
||||
public function getValue(array|bool $recursive = false): string|int|float|bool|array|null
|
||||
{
|
||||
$item = $this->data[$this->position][$this->key];
|
||||
|
||||
@@ -110,20 +107,12 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
return $children;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
return \count($this->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Traversable
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
public function getIterator(): \Traversable
|
||||
{
|
||||
if (!\is_array($value = $this->getValue())) {
|
||||
throw new \LogicException(sprintf('"%s" object holds non-iterable type "%s".', self::class, get_debug_type($value)));
|
||||
@@ -132,6 +121,9 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
yield from $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get(string $key)
|
||||
{
|
||||
if (null !== $data = $this->seek($key)) {
|
||||
@@ -143,54 +135,32 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset(string $key)
|
||||
public function __isset(string $key): bool
|
||||
{
|
||||
return null !== $this->seek($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($key)
|
||||
public function offsetExists(mixed $key): bool
|
||||
{
|
||||
return $this->__isset($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($key)
|
||||
public function offsetGet(mixed $key): mixed
|
||||
{
|
||||
return $this->__get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($key, $value)
|
||||
public function offsetSet(mixed $key, mixed $value): void
|
||||
{
|
||||
throw new \BadMethodCallException(self::class.' objects are immutable.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($key)
|
||||
public function offsetUnset(mixed $key): void
|
||||
{
|
||||
throw new \BadMethodCallException(self::class.' objects are immutable.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
$value = $this->getValue();
|
||||
|
||||
@@ -203,10 +173,8 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns a depth limited clone of $this.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function withMaxDepth(int $maxDepth)
|
||||
public function withMaxDepth(int $maxDepth): static
|
||||
{
|
||||
$data = clone $this;
|
||||
$data->maxDepth = $maxDepth;
|
||||
@@ -216,10 +184,8 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Limits the number of elements per depth level.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function withMaxItemsPerDepth(int $maxItemsPerDepth)
|
||||
public function withMaxItemsPerDepth(int $maxItemsPerDepth): static
|
||||
{
|
||||
$data = clone $this;
|
||||
$data->maxItemsPerDepth = $maxItemsPerDepth;
|
||||
@@ -231,10 +197,8 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
* Enables/disables objects' identifiers tracking.
|
||||
*
|
||||
* @param bool $useRefHandles False to hide global ref. handles
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function withRefHandles(bool $useRefHandles)
|
||||
public function withRefHandles(bool $useRefHandles): static
|
||||
{
|
||||
$data = clone $this;
|
||||
$data->useRefHandles = $useRefHandles ? -1 : 0;
|
||||
@@ -242,10 +206,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function withContext(array $context)
|
||||
public function withContext(array $context): static
|
||||
{
|
||||
$data = clone $this;
|
||||
$data->context = $context;
|
||||
@@ -253,14 +214,15 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getContext(): array
|
||||
{
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seeks to a specific key in nested data structures.
|
||||
*
|
||||
* @param string|int $key The key to seek to
|
||||
*
|
||||
* @return static|null
|
||||
*/
|
||||
public function seek($key)
|
||||
public function seek(string|int $key): ?static
|
||||
{
|
||||
$item = $this->data[$this->position][$this->key];
|
||||
|
||||
@@ -303,21 +265,21 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Dumps data with a DumperInterface dumper.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dump(DumperInterface $dumper)
|
||||
{
|
||||
$refs = [0];
|
||||
$cursor = new Cursor();
|
||||
$cursor->hashType = -1;
|
||||
$cursor->attr = $this->context[SourceContextProvider::class] ?? [];
|
||||
$label = $this->context['label'] ?? '';
|
||||
|
||||
if ($cursor->attr = $this->context[SourceContextProvider::class] ?? []) {
|
||||
$cursor->attr['if_links'] = true;
|
||||
$cursor->hashType = -1;
|
||||
$dumper->dumpScalar($cursor, 'default', '^');
|
||||
$cursor->attr = ['if_links' => true];
|
||||
$dumper->dumpScalar($cursor, 'default', ' ');
|
||||
$cursor->hashType = 0;
|
||||
if ($cursor->attr || '' !== $label) {
|
||||
$dumper->dumpScalar($cursor, 'label', $label);
|
||||
}
|
||||
|
||||
$cursor->hashType = 0;
|
||||
$this->dumpItem($dumper, $cursor, $refs, $this->data[$this->position][$this->key]);
|
||||
}
|
||||
|
||||
@@ -326,7 +288,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
*
|
||||
* @param mixed $item A Stub object or the original value being dumped
|
||||
*/
|
||||
private function dumpItem(DumperInterface $dumper, Cursor $cursor, array &$refs, $item)
|
||||
private function dumpItem(DumperInterface $dumper, Cursor $cursor, array &$refs, mixed $item): void
|
||||
{
|
||||
$cursor->refIndex = 0;
|
||||
$cursor->softRefTo = $cursor->softRefHandle = $cursor->softRefCount = 0;
|
||||
@@ -408,6 +370,10 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
$dumper->leaveHash($cursor, $item->type, $item->class, $withChildren, $cut);
|
||||
break;
|
||||
|
||||
case Stub::TYPE_SCALAR:
|
||||
$dumper->dumpScalar($cursor, 'default', $item->attr['value']);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \RuntimeException(sprintf('Unexpected Stub type: "%s".', $item->type));
|
||||
}
|
||||
@@ -448,7 +414,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
return $hashCut;
|
||||
}
|
||||
|
||||
private function getStub($item)
|
||||
private function getStub(mixed $item): mixed
|
||||
{
|
||||
if (!$item || !\is_array($item)) {
|
||||
return $item;
|
||||
|
||||
@@ -21,10 +21,9 @@ interface DumperInterface
|
||||
/**
|
||||
* Dumps a scalar value.
|
||||
*
|
||||
* @param string $type The PHP type of the value being dumped
|
||||
* @param string|int|float|bool $value The scalar value being dumped
|
||||
* @return void
|
||||
*/
|
||||
public function dumpScalar(Cursor $cursor, string $type, $value);
|
||||
public function dumpScalar(Cursor $cursor, string $type, string|int|float|bool|null $value);
|
||||
|
||||
/**
|
||||
* Dumps a string.
|
||||
@@ -32,25 +31,31 @@ interface DumperInterface
|
||||
* @param string $str The string being dumped
|
||||
* @param bool $bin Whether $str is UTF-8 or binary encoded
|
||||
* @param int $cut The number of characters $str has been cut by
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut);
|
||||
|
||||
/**
|
||||
* Dumps while entering an hash.
|
||||
*
|
||||
* @param int $type A Cursor::HASH_* const for the type of hash
|
||||
* @param string|int $class The object class, resource type or array count
|
||||
* @param bool $hasChild When the dump of the hash has child item
|
||||
* @param int $type A Cursor::HASH_* const for the type of hash
|
||||
* @param string|int|null $class The object class, resource type or array count
|
||||
* @param bool $hasChild When the dump of the hash has child item
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enterHash(Cursor $cursor, int $type, $class, bool $hasChild);
|
||||
public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild);
|
||||
|
||||
/**
|
||||
* Dumps while leaving an hash.
|
||||
*
|
||||
* @param int $type A Cursor::HASH_* const for the type of hash
|
||||
* @param string|int $class The object class, resource type or array count
|
||||
* @param bool $hasChild When the dump of the hash has child item
|
||||
* @param int $cut The number of items the hash has been cut by
|
||||
* @param int $type A Cursor::HASH_* const for the type of hash
|
||||
* @param string|int|null $class The object class, resource type or array count
|
||||
* @param bool $hasChild When the dump of the hash has child item
|
||||
* @param int $cut The number of items the hash has been cut by
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function leaveHash(Cursor $cursor, int $type, $class, bool $hasChild, int $cut);
|
||||
public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ class Stub
|
||||
public const TYPE_ARRAY = 3;
|
||||
public const TYPE_OBJECT = 4;
|
||||
public const TYPE_RESOURCE = 5;
|
||||
public const TYPE_SCALAR = 6;
|
||||
|
||||
public const STRING_BINARY = 1;
|
||||
public const STRING_UTF8 = 2;
|
||||
@@ -39,7 +40,7 @@ class Stub
|
||||
public $position = 0;
|
||||
public $attr = [];
|
||||
|
||||
private static $defaultProperties = [];
|
||||
private static array $defaultProperties = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
||||
@@ -16,13 +16,9 @@ namespace Symfony\Component\VarDumper\Cloner;
|
||||
*/
|
||||
class VarCloner extends AbstractCloner
|
||||
{
|
||||
private static $gid;
|
||||
private static $arrayCache = [];
|
||||
private static array $arrayCache = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doClone($var)
|
||||
protected function doClone(mixed $var): array
|
||||
{
|
||||
$len = 1; // Length of $queue
|
||||
$pos = 0; // Number of cloned items past the minimum depth
|
||||
@@ -44,9 +40,6 @@ class VarCloner extends AbstractCloner
|
||||
$stub = null; // Stub capturing the main properties of an original item value
|
||||
// or null if the original value is used directly
|
||||
|
||||
if (!$gid = self::$gid) {
|
||||
$gid = self::$gid = md5(random_bytes(6)); // Unique string used to detect the special $GLOBALS variable
|
||||
}
|
||||
$arrayStub = new Stub();
|
||||
$arrayStub->type = Stub::TYPE_ARRAY;
|
||||
$fromObjCast = false;
|
||||
@@ -65,22 +58,13 @@ class VarCloner extends AbstractCloner
|
||||
foreach ($vals as $k => $v) {
|
||||
// $v is the original value or a stub object in case of hard references
|
||||
|
||||
if (\PHP_VERSION_ID >= 70400) {
|
||||
$zvalRef = ($r = \ReflectionReference::fromArrayElement($vals, $k)) ? $r->getId() : null;
|
||||
} else {
|
||||
$refs[$k] = $cookie;
|
||||
$zvalRef = $vals[$k] === $cookie;
|
||||
}
|
||||
$zvalRef = ($r = \ReflectionReference::fromArrayElement($vals, $k)) ? $r->getId() : null;
|
||||
|
||||
if ($zvalRef) {
|
||||
$vals[$k] = &$stub; // Break hard references to make $queue completely
|
||||
unset($stub); // independent from the original structure
|
||||
if (\PHP_VERSION_ID >= 70400 ? null !== $vals[$k] = $hardRefs[$zvalRef] ?? null : $v instanceof Stub && isset($hardRefs[spl_object_id($v)])) {
|
||||
if (\PHP_VERSION_ID >= 70400) {
|
||||
$v = $vals[$k];
|
||||
} else {
|
||||
$refs[$k] = $vals[$k] = $v;
|
||||
}
|
||||
if (null !== $vals[$k] = $hardRefs[$zvalRef] ?? null) {
|
||||
$v = $vals[$k];
|
||||
if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) {
|
||||
++$v->value->refCount;
|
||||
}
|
||||
@@ -90,15 +74,7 @@ class VarCloner extends AbstractCloner
|
||||
$vals[$k] = new Stub();
|
||||
$vals[$k]->value = $v;
|
||||
$vals[$k]->handle = ++$refsCounter;
|
||||
|
||||
if (\PHP_VERSION_ID >= 70400) {
|
||||
$hardRefs[$zvalRef] = $vals[$k];
|
||||
} else {
|
||||
$refs[$k] = $vals[$k];
|
||||
$h = spl_object_id($refs[$k]);
|
||||
$hardRefs[$h] = &$refs[$k];
|
||||
$values[$h] = $v;
|
||||
}
|
||||
$hardRefs[$zvalRef] = $vals[$k];
|
||||
}
|
||||
// Create $stub when the original value $v cannot be used directly
|
||||
// If $v is a nested structure, put that structure in array $a
|
||||
@@ -140,57 +116,15 @@ class VarCloner extends AbstractCloner
|
||||
}
|
||||
$stub = $arrayStub;
|
||||
|
||||
if (\PHP_VERSION_ID >= 80100) {
|
||||
$stub->class = array_is_list($v) ? Stub::ARRAY_INDEXED : Stub::ARRAY_ASSOC;
|
||||
$a = $v;
|
||||
break;
|
||||
}
|
||||
|
||||
$stub->class = Stub::ARRAY_INDEXED;
|
||||
|
||||
$j = -1;
|
||||
foreach ($v as $gk => $gv) {
|
||||
if ($gk !== ++$j) {
|
||||
$stub->class = Stub::ARRAY_ASSOC;
|
||||
$a = $v;
|
||||
$a[$gid] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Copies of $GLOBALS have very strange behavior,
|
||||
// let's detect them with some black magic
|
||||
if (isset($v[$gid])) {
|
||||
unset($v[$gid]);
|
||||
$a = [];
|
||||
foreach ($v as $gk => &$gv) {
|
||||
if ($v === $gv && (\PHP_VERSION_ID < 70400 || !isset($hardRefs[\ReflectionReference::fromArrayElement($v, $gk)->getId()]))) {
|
||||
unset($v);
|
||||
$v = new Stub();
|
||||
$v->value = [$v->cut = \count($gv), Stub::TYPE_ARRAY => 0];
|
||||
$v->handle = -1;
|
||||
if (\PHP_VERSION_ID >= 70400) {
|
||||
$gv = &$a[$gk];
|
||||
$hardRefs[\ReflectionReference::fromArrayElement($a, $gk)->getId()] = &$gv;
|
||||
} else {
|
||||
$gv = &$hardRefs[spl_object_id($v)];
|
||||
}
|
||||
$gv = $v;
|
||||
}
|
||||
|
||||
$a[$gk] = &$gv;
|
||||
}
|
||||
unset($gv);
|
||||
} else {
|
||||
$a = $v;
|
||||
}
|
||||
$stub->class = array_is_list($v) ? Stub::ARRAY_INDEXED : Stub::ARRAY_ASSOC;
|
||||
$a = $v;
|
||||
break;
|
||||
|
||||
case \is_object($v):
|
||||
if (empty($objRefs[$h = spl_object_id($v)])) {
|
||||
$stub = new Stub();
|
||||
$stub->type = Stub::TYPE_OBJECT;
|
||||
$stub->class = \get_class($v);
|
||||
$stub->class = $v::class;
|
||||
$stub->value = $v;
|
||||
$stub->handle = $h;
|
||||
$a = $this->castObject($stub, 0 < $i);
|
||||
@@ -274,10 +208,8 @@ class VarCloner extends AbstractCloner
|
||||
|
||||
if (!$zvalRef) {
|
||||
$vals[$k] = $stub;
|
||||
} elseif (\PHP_VERSION_ID >= 70400) {
|
||||
$hardRefs[$zvalRef]->value = $stub;
|
||||
} else {
|
||||
$refs[$k]->value = $stub;
|
||||
$hardRefs[$zvalRef]->value = $stub;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user