diff --git a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml index 75819a017bf33..9cb70d08cc4bc 100644 --- a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml @@ -40,6 +40,19 @@ 0 + + + + + + %kernel.charset% + %kernel.project_dir% + + + + + + null %kernel.charset% diff --git a/src/Symfony/Component/VarDumper/Cloner/Data.php b/src/Symfony/Component/VarDumper/Cloner/Data.php index c4dd5eeb4b6d7..7e148bf49eab3 100644 --- a/src/Symfony/Component/VarDumper/Cloner/Data.php +++ b/src/Symfony/Component/VarDumper/Cloner/Data.php @@ -12,6 +12,7 @@ namespace Symfony\Component\VarDumper\Cloner; use Symfony\Component\VarDumper\Caster\Caster; +use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider; /** * @author Nicolas Grekas @@ -24,6 +25,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate private $maxDepth = 20; private $maxItemsPerDepth = -1; private $useRefHandles = -1; + private $context = []; /** * @param array $data An array as returned by ClonerInterface::cloneVar() @@ -227,6 +229,17 @@ public function withRefHandles($useRefHandles) return $data; } + /** + * @return static + */ + public function withContext(array $context) + { + $data = clone $this; + $data->context = $context; + + return $data; + } + /** * Seeks to a specific key in nested data structures. * @@ -281,7 +294,18 @@ public function seek($key) public function dump(DumperInterface $dumper) { $refs = [0]; - $this->dumpItem($dumper, new Cursor(), $refs, $this->data[$this->position][$this->key]); + $cursor = new Cursor(); + + 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; + } + + $this->dumpItem($dumper, $cursor, $refs, $this->data[$this->position][$this->key]); } /** diff --git a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php index f390cd7832567..2cef630cf0173 100644 --- a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php @@ -83,7 +83,7 @@ public function __construct($output = null, string $charset = null, int $flags = ]); } - $this->displayOptions['fileLinkFormat'] = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f'; + $this->displayOptions['fileLinkFormat'] = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f#L%l'; } /** @@ -490,6 +490,8 @@ protected function style($style, $value, $attr = []) if (isset($attr['href'])) { $value = "\033]8;;{$attr['href']}\033\\{$value}\033]8;;\033\\"; } + } elseif ($attr['if_links'] ?? false) { + return ''; } return $value; @@ -548,6 +550,10 @@ protected function dumpLine($depth, $endOfValue = false) protected function endValue(Cursor $cursor) { + if (-1 === $cursor->hashType) { + return; + } + if (Stub::ARRAY_INDEXED === $cursor->hashType || Stub::ARRAY_ASSOC === $cursor->hashType) { if (self::DUMP_TRAILING_COMMA & $this->flags && 0 < $cursor->depth) { $this->line .= ','; @@ -628,7 +634,7 @@ private function isWindowsTrueColor(): bool private function getSourceLink(string $file, int $line) { if ($fmt = $this->displayOptions['fileLinkFormat']) { - return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : ($fmt->format($file, $line) ?: 'file://'.$file); + return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : ($fmt->format($file, $line) ?: 'file://'.$file.'#L'.$line); } return false; diff --git a/src/Symfony/Component/VarDumper/Dumper/ContextualizedDumper.php b/src/Symfony/Component/VarDumper/Dumper/ContextualizedDumper.php new file mode 100644 index 0000000000000..76384176ef026 --- /dev/null +++ b/src/Symfony/Component/VarDumper/Dumper/ContextualizedDumper.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Dumper; + +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface; + +/** + * @author Kévin Thérage + */ +class ContextualizedDumper implements DataDumperInterface +{ + private $wrappedDumper; + private $contextProviders; + + /** + * @param ContextProviderInterface[] $contextProviders + */ + public function __construct(DataDumperInterface $wrappedDumper, array $contextProviders) + { + $this->wrappedDumper = $wrappedDumper; + $this->contextProviders = $contextProviders; + } + + public function dump(Data $data) + { + $context = []; + foreach ($this->contextProviders as $contextProvider) { + $context[\get_class($contextProvider)] = $contextProvider->getContext(); + } + + $this->wrappedDumper->dump($data->withContext($context)); + } +} diff --git a/src/Symfony/Component/VarDumper/Tests/Cloner/VarClonerTest.php b/src/Symfony/Component/VarDumper/Tests/Cloner/VarClonerTest.php index 334d5879d4997..2ffd65cfbc45d 100644 --- a/src/Symfony/Component/VarDumper/Tests/Cloner/VarClonerTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Cloner/VarClonerTest.php @@ -53,6 +53,10 @@ public function testMaxIntBoundary() [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 + [context:Symfony\Component\VarDumper\Cloner\Data:private] => Array + ( + ) + ) EOTXT; @@ -141,6 +145,10 @@ public function testClone() [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 + [context:Symfony\Component\VarDumper\Cloner\Data:private] => Array + ( + ) + ) EOTXT; @@ -309,6 +317,10 @@ public function testLimits() [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 + [context:Symfony\Component\VarDumper\Cloner\Data:private] => Array + ( + ) + ) EOTXT; @@ -327,7 +339,7 @@ public function testJsonCast() $clone = $cloner->cloneVar($data); $expected = <<<'EOTXT' -object(Symfony\Component\VarDumper\Cloner\Data)#%i (6) { +object(Symfony\Component\VarDumper\Cloner\Data)#%d (7) { ["data":"Symfony\Component\VarDumper\Cloner\Data":private]=> array(2) { [0]=> @@ -372,6 +384,9 @@ public function testJsonCast() int(-1) ["useRefHandles":"Symfony\Component\VarDumper\Cloner\Data":private]=> int(-1) + ["context":"Symfony\Component\VarDumper\Cloner\Data":private]=> + array(0) { + } } EOTXT; @@ -432,6 +447,10 @@ public function testCaster() [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 + [context:Symfony\Component\VarDumper\Cloner\Data:private] => Array + ( + ) + ) EOTXT; @@ -501,6 +520,10 @@ public function testPhp74() [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 + [context:Symfony\Component\VarDumper\Cloner\Data:private] => Array + ( + ) + ) EOTXT; diff --git a/src/Symfony/Component/VarDumper/Tests/Dumper/ContextualizedDumperTest.php b/src/Symfony/Component/VarDumper/Tests/Dumper/ContextualizedDumperTest.php new file mode 100644 index 0000000000000..ba717940bc7d2 --- /dev/null +++ b/src/Symfony/Component/VarDumper/Tests/Dumper/ContextualizedDumperTest.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\CliDumper; +use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider; +use Symfony\Component\VarDumper\Dumper\ContextualizedDumper; + +/** + * @author Kévin Thérage + */ +class ContextualizedDumperTest extends TestCase +{ + public function testContextualizedCliDumper() + { + $wrappedDumper = new CliDumper('php://output'); + $wrappedDumper->setColors(true); + + $var = 'example'; + $href = sprintf('file://%s#L%s', __FILE__, 37); + $dumper = new ContextualizedDumper($wrappedDumper, [new SourceContextProvider()]); + $cloner = new VarCloner(); + $data = $cloner->cloneVar($var); + + ob_start(); + $dumper->dump($data); + $out = ob_get_clean(); + + $this->assertStringContainsString("\e]8;;{$href}\e\\\e[", $out); + $this->assertStringContainsString("m{$var}\e[", $out); + } +} diff --git a/src/Symfony/Component/VarDumper/VarDumper.php b/src/Symfony/Component/VarDumper/VarDumper.php index 009f662f3bf27..d336d5d52bc98 100644 --- a/src/Symfony/Component/VarDumper/VarDumper.php +++ b/src/Symfony/Component/VarDumper/VarDumper.php @@ -14,6 +14,8 @@ use Symfony\Component\VarDumper\Caster\ReflectionCaster; use Symfony\Component\VarDumper\Cloner\VarCloner; use Symfony\Component\VarDumper\Dumper\CliDumper; +use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider; +use Symfony\Component\VarDumper\Dumper\ContextualizedDumper; use Symfony\Component\VarDumper\Dumper\HtmlDumper; // Load the global dump() function @@ -38,6 +40,8 @@ public static function dump($var) $dumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg']) ? new CliDumper() : new HtmlDumper(); } + $dumper = new ContextualizedDumper($dumper, [new SourceContextProvider()]); + self::$handler = function ($var) use ($cloner, $dumper) { $dumper->dump($cloner->cloneVar($var)); }; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy