30cb9fc0d6dffc32e76fd5a9ec2d145c348d3dce
[yaffs-website] / vendor / symfony / var-dumper / Caster / Caster.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\VarDumper\Caster;
13
14 use Symfony\Component\VarDumper\Cloner\Stub;
15
16 /**
17  * Helper for filtering out properties in casters.
18  *
19  * @author Nicolas Grekas <p@tchwork.com>
20  *
21  * @final
22  */
23 class Caster
24 {
25     const EXCLUDE_VERBOSE = 1;
26     const EXCLUDE_VIRTUAL = 2;
27     const EXCLUDE_DYNAMIC = 4;
28     const EXCLUDE_PUBLIC = 8;
29     const EXCLUDE_PROTECTED = 16;
30     const EXCLUDE_PRIVATE = 32;
31     const EXCLUDE_NULL = 64;
32     const EXCLUDE_EMPTY = 128;
33     const EXCLUDE_NOT_IMPORTANT = 256;
34     const EXCLUDE_STRICT = 512;
35
36     const PREFIX_VIRTUAL = "\0~\0";
37     const PREFIX_DYNAMIC = "\0+\0";
38     const PREFIX_PROTECTED = "\0*\0";
39
40     /**
41      * Casts objects to arrays and adds the dynamic property prefix.
42      *
43      * @param object $obj          The object to cast
44      * @param string $class        The class of the object
45      * @param bool   $hasDebugInfo Whether the __debugInfo method exists on $obj or not
46      *
47      * @return array The array-cast of the object, with prefixed dynamic properties
48      */
49     public static function castObject($obj, $class, $hasDebugInfo = false)
50     {
51         if ($class instanceof \ReflectionClass) {
52             @trigger_error(sprintf('Passing a ReflectionClass to "%s()" is deprecated since Symfony 3.3 and will be unsupported in 4.0. Pass the class name as string instead.', __METHOD__), E_USER_DEPRECATED);
53             $hasDebugInfo = $class->hasMethod('__debugInfo');
54             $class = $class->name;
55         }
56         if ($hasDebugInfo) {
57             $a = $obj->__debugInfo();
58         } elseif ($obj instanceof \Closure) {
59             $a = array();
60         } else {
61             $a = (array) $obj;
62         }
63         if ($obj instanceof \__PHP_Incomplete_Class) {
64             return $a;
65         }
66
67         if ($a) {
68             static $publicProperties = array();
69
70             $i = 0;
71             $prefixedKeys = array();
72             foreach ($a as $k => $v) {
73                 if (isset($k[0]) ? "\0" !== $k[0] : \PHP_VERSION_ID >= 70200) {
74                     if (!isset($publicProperties[$class])) {
75                         foreach (get_class_vars($class) as $prop => $v) {
76                             $publicProperties[$class][$prop] = true;
77                         }
78                     }
79                     if (!isset($publicProperties[$class][$k])) {
80                         $prefixedKeys[$i] = self::PREFIX_DYNAMIC.$k;
81                     }
82                 } elseif (isset($k[16]) && "\0" === $k[16] && 0 === strpos($k, "\0class@anonymous\0")) {
83                     $prefixedKeys[$i] = "\0".get_parent_class($class).'@anonymous'.strrchr($k, "\0");
84                 }
85                 ++$i;
86             }
87             if ($prefixedKeys) {
88                 $keys = array_keys($a);
89                 foreach ($prefixedKeys as $i => $k) {
90                     $keys[$i] = $k;
91                 }
92                 $a = array_combine($keys, $a);
93             }
94         }
95
96         return $a;
97     }
98
99     /**
100      * Filters out the specified properties.
101      *
102      * By default, a single match in the $filter bit field filters properties out, following an "or" logic.
103      * When EXCLUDE_STRICT is set, an "and" logic is applied: all bits must match for a property to be removed.
104      *
105      * @param array    $a                The array containing the properties to filter
106      * @param int      $filter           A bit field of Caster::EXCLUDE_* constants specifying which properties to filter out
107      * @param string[] $listedProperties List of properties to exclude when Caster::EXCLUDE_VERBOSE is set, and to preserve when Caster::EXCLUDE_NOT_IMPORTANT is set
108      * @param int      &$count           Set to the number of removed properties
109      *
110      * @return array The filtered array
111      */
112     public static function filter(array $a, $filter, array $listedProperties = array(), &$count = 0)
113     {
114         $count = 0;
115
116         foreach ($a as $k => $v) {
117             $type = self::EXCLUDE_STRICT & $filter;
118
119             if (null === $v) {
120                 $type |= self::EXCLUDE_NULL & $filter;
121                 $type |= self::EXCLUDE_EMPTY & $filter;
122             } elseif (false === $v || '' === $v || '0' === $v || 0 === $v || 0.0 === $v || array() === $v) {
123                 $type |= self::EXCLUDE_EMPTY & $filter;
124             }
125             if ((self::EXCLUDE_NOT_IMPORTANT & $filter) && !\in_array($k, $listedProperties, true)) {
126                 $type |= self::EXCLUDE_NOT_IMPORTANT;
127             }
128             if ((self::EXCLUDE_VERBOSE & $filter) && \in_array($k, $listedProperties, true)) {
129                 $type |= self::EXCLUDE_VERBOSE;
130             }
131
132             if (!isset($k[1]) || "\0" !== $k[0]) {
133                 $type |= self::EXCLUDE_PUBLIC & $filter;
134             } elseif ('~' === $k[1]) {
135                 $type |= self::EXCLUDE_VIRTUAL & $filter;
136             } elseif ('+' === $k[1]) {
137                 $type |= self::EXCLUDE_DYNAMIC & $filter;
138             } elseif ('*' === $k[1]) {
139                 $type |= self::EXCLUDE_PROTECTED & $filter;
140             } else {
141                 $type |= self::EXCLUDE_PRIVATE & $filter;
142             }
143
144             if ((self::EXCLUDE_STRICT & $filter) ? $type === $filter : $type) {
145                 unset($a[$k]);
146                 ++$count;
147             }
148         }
149
150         return $a;
151     }
152
153     public static function castPhpIncompleteClass(\__PHP_Incomplete_Class $c, array $a, Stub $stub, $isNested)
154     {
155         if (isset($a['__PHP_Incomplete_Class_Name'])) {
156             $stub->class .= '('.$a['__PHP_Incomplete_Class_Name'].')';
157             unset($a['__PHP_Incomplete_Class_Name']);
158         }
159
160         return $a;
161     }
162 }