Failed Conditions
Pull Request — master (#3546)
by Sergei
14:16
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
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_get;
21
use function ini_set;
22
use function is_array;
23
use function is_object;
24
use function is_string;
25
use function ob_get_clean;
26
use function ob_start;
27
use function strip_tags;
28
use function strlen;
29
use function strrpos;
30
use function substr;
31
use function var_dump;
32
33
/**
34
 * Static class used to dump the variable to be used on output.
35
 * Simplified port of Util\Debug from doctrine/common.
36
 *
37
 * @internal
38
 */
39
final class Dumper
40
{
41
    /**
42
     * Private constructor (prevents instantiation).
43
     */
44
    private function __construct()
45
    {
46
    }
47
48
    /**
49
     * Returns a dump of the public, protected and private properties of $var.
50
     *
51
     * @link https://xdebug.org/
52
     *
53
     * @param mixed $var      The variable to dump.
54
     * @param int   $maxDepth The maximum nesting level for object properties.
55
     */
56 281
    public static function dump($var, int $maxDepth = 2) : string
57
    {
58 281
        $html = ini_get('html_errors');
59
60 281
        if ($html !== true) {
61 281
            ini_set('html_errors', true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $newvalue of ini_set(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
            ini_set('html_errors', /** @scrutinizer ignore-type */ true);
Loading history...
62
        }
63
64 281
        if (extension_loaded('xdebug')) {
65 6
            ini_set('xdebug.var_display_max_depth', $maxDepth);
66
        }
67
68 281
        $var = self::export($var, $maxDepth);
69
70 281
        ob_start();
71 281
        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...
72
73
        try {
74 281
            $output = ob_get_clean();
75 281
            assert(is_string($output));
76
77 281
            return strip_tags(html_entity_decode($output));
78
        } finally {
79 281
            ini_set('html_errors', $html);
80
        }
81
    }
82
83
    /**
84
     * @param mixed $var
85
     *
86
     * @return mixed
87
     */
88 299
    public static function export($var, int $maxDepth)
89
    {
90 299
        $return = null;
91 299
        $isObj  = is_object($var);
92
93 299
        if ($var instanceof Collection) {
94
            $var = $var->toArray();
95
        }
96
97 299
        if ($maxDepth === 0) {
98 154
            return is_object($var) ? get_class($var)
99 154
                : (is_array($var) ? 'Array(' . count($var) . ')' : $var);
100
        }
101
102 299
        if (is_array($var)) {
103 283
            $return = [];
104
105 283
            foreach ($var as $k => $v) {
106 283
                $return[$k] = self::export($v, $maxDepth - 1);
107
            }
108
109 283
            return $return;
110
        }
111
112 299
        if (! $isObj) {
113 293
            return $var;
114
        }
115
116 216
        $return = new stdClass();
117 216
        if ($var instanceof DateTimeInterface) {
118 131
            $return->__CLASS__ = get_class($var);
119 131
            $return->date      = $var->format('c');
120 131
            $return->timezone  = $var->getTimezone()->getName();
121
122 131
            return $return;
123
        }
124
125 210
        $return->__CLASS__ = self::getClass($var);
126
127 210
        if ($var instanceof Proxy) {
128
            $return->__IS_PROXY__          = true;
129
            $return->__PROXY_INITIALIZED__ = $var->__isInitialized();
130
        }
131
132 210
        if ($var instanceof ArrayObject || $var instanceof ArrayIterator) {
133 77
            $return->__STORAGE__ = self::export($var->getArrayCopy(), $maxDepth - 1);
134
        }
135
136 210
        return self::fillReturnWithClassAttributes($var, $return, $maxDepth);
137
    }
138
139
    /**
140
     * Fill the $return variable with class attributes
141
     * Based on obj2array function from {@see https://secure.php.net/manual/en/function.get-object-vars.php#47075}
142
     *
143
     * @param object $var
144
     *
145
     * @return mixed
146
     */
147 210
    private static function fillReturnWithClassAttributes($var, stdClass $return, int $maxDepth)
148
    {
149 210
        $clone = (array) $var;
150
151 210
        foreach (array_keys($clone) as $key) {
152 210
            $aux  = explode("\0", $key);
153 210
            $name = end($aux);
154 210
            if ($aux[0] === '') {
155 54
                $name .= ':' . ($aux[1] === '*' ? 'protected' : $aux[1] . ':private');
156
            }
157 210
            $return->$name = self::export($clone[$key], $maxDepth - 1);
158
        }
159
160 210
        return $return;
161
    }
162
163
    /**
164
     * @param object $object
165
     */
166 210
    private static function getClass($object) : string
167
    {
168 210
        $class = get_class($object);
169
170 210
        if (! class_exists(Proxy::class)) {
171 210
            return $class;
172
        }
173
174
        $pos = strrpos($class, '\\' . Proxy::MARKER . '\\');
175
176
        if ($pos === false) {
177
            return $class;
178
        }
179
180
        return substr($class, $pos + strlen(Proxy::MARKER) + 2);
181
    }
182
}
183