Failed Conditions
Pull Request — develop (#3518)
by Michael
29:00 queued 25:29
created

Dumper::dump()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3.004

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 24
ccs 12
cts 13
cp 0.9231
rs 9.7998
c 0
b 0
f 0
cc 3
nc 4
nop 2
crap 3.004
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 286
    public static function dump($var, int $maxDepth = 2) : string
59
    {
60 286
        $html = ini_get('html_errors');
61
62 286
        if ($html !== true) {
63 286
            ini_set('html_errors', '1');
64
        }
65
66 286
        if (extension_loaded('xdebug')) {
67
            ini_set('xdebug.var_display_max_depth', (string) $maxDepth);
68
        }
69
70 286
        $var = self::export($var, $maxDepth);
71
72 286
        ob_start();
73 286
        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 286
            $output = ob_get_clean();
77 286
            assert(is_string($output));
78
79 286
            return strip_tags(html_entity_decode($output));
80
        } finally {
81 286
            ini_set('html_errors', $html);
82
        }
83
    }
84
85
    /**
86
     * @param mixed $var
87
     *
88
     * @return mixed
89
     */
90 286
    public static function export($var, int $maxDepth)
91
    {
92 286
        $return = null;
93 286
        $isObj  = is_object($var);
94
95 286
        if ($var instanceof Collection) {
96
            $var = $var->toArray();
97
        }
98
99 286
        if ($maxDepth === 0) {
100 156
            return is_object($var) ? get_class($var)
101 156
                : (is_array($var) ? 'Array(' . count($var) . ')' : $var);
102
        }
103
104 286
        if (is_array($var)) {
105 286
            $return = [];
106
107 286
            foreach ($var as $k => $v) {
108 286
                $return[$k] = self::export($v, $maxDepth - 1);
109
            }
110
111 286
            return $return;
112
        }
113
114 286
        if (! $isObj) {
115 286
            return $var;
116
        }
117
118 208
        $return = new stdClass();
119 208
        if ($var instanceof DateTimeInterface) {
120 130
            $return->__CLASS__ = get_class($var);
121 130
            $return->date      = $var->format('c');
122 130
            $return->timezone  = $var->getTimezone()->getName();
123
124 130
            return $return;
125
        }
126
127 208
        $return->__CLASS__ = self::getClass($var);
128
129 208
        if ($var instanceof Proxy) {
130
            $return->__IS_PROXY__          = true;
131
            $return->__PROXY_INITIALIZED__ = $var->__isInitialized();
132
        }
133
134 208
        if ($var instanceof ArrayObject || $var instanceof ArrayIterator) {
135 78
            $return->__STORAGE__ = self::export($var->getArrayCopy(), $maxDepth - 1);
136
        }
137
138 208
        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
     * @param object $var
146
     *
147
     * @return mixed
148
     */
149 208
    private static function fillReturnWithClassAttributes($var, stdClass $return, int $maxDepth)
150
    {
151 208
        $clone = (array) $var;
152
153 208
        foreach (array_keys($clone) as $key) {
154 208
            $aux  = explode("\0", (string) $key);
155 208
            $name = end($aux);
156 208
            if ($aux[0] === '') {
157 52
                $name .= ':' . ($aux[1] === '*' ? 'protected' : $aux[1] . ':private');
158
            }
159 208
            $return->$name = self::export($clone[$key], $maxDepth - 1);
160
        }
161
162 208
        return $return;
163
    }
164
165
    /**
166
     * @param object $object
167
     */
168 208
    private static function getClass($object) : string
169
    {
170 208
        $class = get_class($object);
171
172 208
        if (! class_exists(Proxy::class)) {
173 208
            return $class;
174
        }
175
176
        $pos = strrpos($class, '\\' . Proxy::MARKER . '\\');
177
178
        if ($pos === false) {
179
            return $class;
180
        }
181
182
        return substr($class, $pos + strlen(Proxy::MARKER) + 2);
183
    }
184
}
185