Failed Conditions
Pull Request — develop (#3581)
by Jonathan
12:44
created

Dumper::dump()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

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