Chris@13
|
1 <?php
|
Chris@13
|
2
|
Chris@13
|
3 /*
|
Chris@13
|
4 * This file is part of Psy Shell.
|
Chris@13
|
5 *
|
Chris@13
|
6 * (c) 2012-2018 Justin Hileman
|
Chris@13
|
7 *
|
Chris@13
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@13
|
9 * file that was distributed with this source code.
|
Chris@13
|
10 */
|
Chris@13
|
11
|
Chris@13
|
12 namespace Psy\VarDumper;
|
Chris@13
|
13
|
Chris@13
|
14 use Symfony\Component\Console\Formatter\OutputFormatter;
|
Chris@13
|
15 use Symfony\Component\VarDumper\Caster\Caster;
|
Chris@13
|
16 use Symfony\Component\VarDumper\Cloner\Stub;
|
Chris@13
|
17
|
Chris@13
|
18 /**
|
Chris@13
|
19 * A Presenter service.
|
Chris@13
|
20 */
|
Chris@13
|
21 class Presenter
|
Chris@13
|
22 {
|
Chris@13
|
23 const VERBOSE = 1;
|
Chris@13
|
24
|
Chris@13
|
25 private $cloner;
|
Chris@13
|
26 private $dumper;
|
Chris@13
|
27 private $exceptionsImportants = [
|
Chris@13
|
28 "\0*\0message",
|
Chris@13
|
29 "\0*\0code",
|
Chris@13
|
30 "\0*\0file",
|
Chris@13
|
31 "\0*\0line",
|
Chris@13
|
32 "\0Exception\0previous",
|
Chris@13
|
33 ];
|
Chris@13
|
34 private $styles = [
|
Chris@13
|
35 'num' => 'number',
|
Chris@13
|
36 'const' => 'const',
|
Chris@13
|
37 'str' => 'string',
|
Chris@13
|
38 'cchr' => 'default',
|
Chris@13
|
39 'note' => 'class',
|
Chris@13
|
40 'ref' => 'default',
|
Chris@13
|
41 'public' => 'public',
|
Chris@13
|
42 'protected' => 'protected',
|
Chris@13
|
43 'private' => 'private',
|
Chris@13
|
44 'meta' => 'comment',
|
Chris@13
|
45 'key' => 'comment',
|
Chris@13
|
46 'index' => 'number',
|
Chris@13
|
47 ];
|
Chris@13
|
48
|
Chris@13
|
49 public function __construct(OutputFormatter $formatter, $forceArrayIndexes = false)
|
Chris@13
|
50 {
|
Chris@13
|
51 // Work around https://github.com/symfony/symfony/issues/23572
|
Chris@17
|
52 $oldLocale = \setlocale(LC_NUMERIC, 0);
|
Chris@17
|
53 \setlocale(LC_NUMERIC, 'C');
|
Chris@13
|
54
|
Chris@13
|
55 $this->dumper = new Dumper($formatter, $forceArrayIndexes);
|
Chris@13
|
56 $this->dumper->setStyles($this->styles);
|
Chris@13
|
57
|
Chris@13
|
58 // Now put the locale back
|
Chris@17
|
59 \setlocale(LC_NUMERIC, $oldLocale);
|
Chris@13
|
60
|
Chris@13
|
61 $this->cloner = new Cloner();
|
Chris@13
|
62 $this->cloner->addCasters(['*' => function ($obj, array $a, Stub $stub, $isNested, $filter = 0) {
|
Chris@13
|
63 if ($filter || $isNested) {
|
Chris@13
|
64 if ($obj instanceof \Exception) {
|
Chris@13
|
65 $a = Caster::filter($a, Caster::EXCLUDE_NOT_IMPORTANT | Caster::EXCLUDE_EMPTY, $this->exceptionsImportants);
|
Chris@13
|
66 } else {
|
Chris@13
|
67 $a = Caster::filter($a, Caster::EXCLUDE_PROTECTED | Caster::EXCLUDE_PRIVATE);
|
Chris@13
|
68 }
|
Chris@13
|
69 }
|
Chris@13
|
70
|
Chris@13
|
71 return $a;
|
Chris@13
|
72 }]);
|
Chris@13
|
73 }
|
Chris@13
|
74
|
Chris@13
|
75 /**
|
Chris@13
|
76 * Register casters.
|
Chris@13
|
77 *
|
Chris@13
|
78 * @see http://symfony.com/doc/current/components/var_dumper/advanced.html#casters
|
Chris@13
|
79 *
|
Chris@13
|
80 * @param callable[] $casters A map of casters
|
Chris@13
|
81 */
|
Chris@13
|
82 public function addCasters(array $casters)
|
Chris@13
|
83 {
|
Chris@13
|
84 $this->cloner->addCasters($casters);
|
Chris@13
|
85 }
|
Chris@13
|
86
|
Chris@13
|
87 /**
|
Chris@13
|
88 * Present a reference to the value.
|
Chris@13
|
89 *
|
Chris@13
|
90 * @param mixed $value
|
Chris@13
|
91 *
|
Chris@13
|
92 * @return string
|
Chris@13
|
93 */
|
Chris@13
|
94 public function presentRef($value)
|
Chris@13
|
95 {
|
Chris@13
|
96 return $this->present($value, 0);
|
Chris@13
|
97 }
|
Chris@13
|
98
|
Chris@13
|
99 /**
|
Chris@13
|
100 * Present a full representation of the value.
|
Chris@13
|
101 *
|
Chris@13
|
102 * If $depth is 0, the value will be presented as a ref instead.
|
Chris@13
|
103 *
|
Chris@13
|
104 * @param mixed $value
|
Chris@13
|
105 * @param int $depth (default: null)
|
Chris@13
|
106 * @param int $options One of Presenter constants
|
Chris@13
|
107 *
|
Chris@13
|
108 * @return string
|
Chris@13
|
109 */
|
Chris@13
|
110 public function present($value, $depth = null, $options = 0)
|
Chris@13
|
111 {
|
Chris@13
|
112 $data = $this->cloner->cloneVar($value, !($options & self::VERBOSE) ? Caster::EXCLUDE_VERBOSE : 0);
|
Chris@13
|
113
|
Chris@13
|
114 if (null !== $depth) {
|
Chris@13
|
115 $data = $data->withMaxDepth($depth);
|
Chris@13
|
116 }
|
Chris@13
|
117
|
Chris@13
|
118 // Work around https://github.com/symfony/symfony/issues/23572
|
Chris@17
|
119 $oldLocale = \setlocale(LC_NUMERIC, 0);
|
Chris@17
|
120 \setlocale(LC_NUMERIC, 'C');
|
Chris@13
|
121
|
Chris@13
|
122 $output = '';
|
Chris@13
|
123 $this->dumper->dump($data, function ($line, $depth) use (&$output) {
|
Chris@13
|
124 if ($depth >= 0) {
|
Chris@13
|
125 if ('' !== $output) {
|
Chris@13
|
126 $output .= PHP_EOL;
|
Chris@13
|
127 }
|
Chris@17
|
128 $output .= \str_repeat(' ', $depth) . $line;
|
Chris@13
|
129 }
|
Chris@13
|
130 });
|
Chris@13
|
131
|
Chris@13
|
132 // Now put the locale back
|
Chris@17
|
133 \setlocale(LC_NUMERIC, $oldLocale);
|
Chris@13
|
134
|
Chris@13
|
135 return OutputFormatter::escape($output);
|
Chris@13
|
136 }
|
Chris@13
|
137 }
|