Completed
Pull Request — 2.11.x (#3956)
by David
14:33
created

Dumper   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Test Coverage

Coverage 84.75%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 22
eloc 55
c 3
b 0
f 0
dl 0
loc 139
ccs 50
cts 59
cp 0.8475
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
C export() 0 49 12
A getClass() 0 15 3
A fillReturnWithClassAttributes() 0 14 4
A dump() 0 21 2
1
<?php
2
3
namespace Doctrine\DBAL\Tools;
4
5
use ArrayIterator;
6
use ArrayObject;
7
use DateTimeInterface;
8
use Doctrine\Common\Collections\Collection;
0 ignored issues
show
Bug introduced by
The type Doctrine\Common\Collections\Collection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Doctrine\Common\Persistence\Proxy;
0 ignored issues
show
Bug introduced by
The type Doctrine\Common\Persistence\Proxy was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use stdClass;
11
use function array_keys;
12
use function assert;
13
use function class_exists;
14
use function count;
15
use function end;
16
use function explode;
17
use function extension_loaded;
18
use function get_class;
19
use function html_entity_decode;
20
use function ini_set;
21
use function is_array;
22
use function is_object;
23
use function is_string;
24
use function ob_get_clean;
25
use function ob_start;
26
use function strip_tags;
27
use function strlen;
28
use function strrpos;
29
use function substr;
30
use function var_dump;
31
32
/**
33
 * Static class used to dump the variable to be used on output.
34
 * Simplified port of Util\Debug from doctrine/common.
35
 *
36
 * @internal
37
 */
38
final class Dumper
39
{
40
    /**
41
     * Private constructor (prevents instantiation).
42
     */
43
    private function __construct()
44
    {
45
    }
46
47
    /**
48
     * Returns a dump of the public, protected and private properties of $var.
49
     *
50
     * @link https://xdebug.org/
51
     *
52
     * @param mixed $var      The variable to dump.
53
     * @param int   $maxDepth The maximum nesting level for object properties.
54
     */
55 253
    public static function dump($var, int $maxDepth = 2) : string
56
    {
57 253
        $html = ini_set('html_errors', '1');
58 253
        assert(is_string($html));
59
60 253
        if (extension_loaded('xdebug')) {
61 3
            ini_set('xdebug.var_display_max_depth', (string) $maxDepth);
62
        }
63
64 253
        $var = self::export($var, $maxDepth);
65
66 253
        ob_start();
67 253
        var_dump($var);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($var) looks like debug code. Are you sure you do not want to remove it?
Loading history...
68
69
        try {
70 253
            $output = ob_get_clean();
71 253
            assert(is_string($output));
72
73 253
            return strip_tags(html_entity_decode($output));
74
        } finally {
75 253
            ini_set('html_errors', $html);
76
        }
77
    }
78
79
    /**
80
     * @param mixed $var
81
     *
82
     * @return mixed
83
     */
84 262
    public static function export($var, int $maxDepth)
85
    {
86 262
        $return = null;
87 262
        $isObj  = is_object($var);
88
89 262
        if ($var instanceof Collection) {
90
            $var = $var->toArray();
91
        }
92
93 262
        if ($maxDepth === 0) {
94 127
            return is_object($var) ? get_class($var)
95 127
                : (is_array($var) ? 'Array(' . count($var) . ')' : $var);
96
        }
97
98 262
        if (is_array($var)) {
99 254
            $return = [];
100
101 254
            foreach ($var as $k => $v) {
102 254
                $return[$k] = self::export($v, $maxDepth - 1);
103
            }
104
105 254
            return $return;
106
        }
107
108 262
        if (! $isObj) {
109 259
            return $var;
110
        }
111
112 183
        $return = new stdClass();
113 183
        if ($var instanceof DateTimeInterface) {
114 103
            $return->__CLASS__ = get_class($var);
115 103
            $return->date      = $var->format('c');
116 103
            $return->timezone  = $var->getTimezone()->getName();
117
118 103
            return $return;
119
        }
120
121 180
        $return->__CLASS__ = self::getClass($var);
122
123 180
        if ($var instanceof Proxy) {
124
            $return->__IS_PROXY__          = true;
125
            $return->__PROXY_INITIALIZED__ = $var->__isInitialized();
126
        }
127
128 180
        if ($var instanceof ArrayObject || $var instanceof ArrayIterator) {
129 76
            $return->__STORAGE__ = self::export($var->getArrayCopy(), $maxDepth - 1);
130
        }
131
132 180
        return self::fillReturnWithClassAttributes($var, $return, $maxDepth);
133
    }
134
135
    /**
136
     * Fill the $return variable with class attributes
137
     * Based on obj2array function from {@see https://secure.php.net/manual/en/function.get-object-vars.php#47075}
138
     *
139
     * @param object $var
140
     *
141
     * @return mixed
142
     */
143 180
    private static function fillReturnWithClassAttributes($var, stdClass $return, int $maxDepth)
144
    {
145 180
        $clone = (array) $var;
146
147 180
        foreach (array_keys($clone) as $key) {
148 180
            $aux  = explode("\0", $key);
149 180
            $name = end($aux);
150 180
            if ($aux[0] === '') {
151 52
                $name .= ':' . ($aux[1] === '*' ? 'protected' : $aux[1] . ':private');
152
            }
153 180
            $return->$name = self::export($clone[$key], $maxDepth - 1);
154
        }
155
156 180
        return $return;
157
    }
158
159
    /**
160
     * @param object $object
161
     */
162 180
    private static function getClass($object) : string
163
    {
164 180
        $class = get_class($object);
165
166 180
        if (! class_exists(Proxy::class)) {
167 180
            return $class;
168
        }
169
170
        $pos = strrpos($class, '\\' . Proxy::MARKER . '\\');
171
172
        if ($pos === false) {
173
            return $class;
174
        }
175
176
        return substr($class, $pos + strlen(Proxy::MARKER) + 2);
177
    }
178
}
179