Completed
Pull Request — develop (#3570)
by Jonathan
155:39 queued 152:58
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 230
    public static function dump($var, int $maxDepth = 2) : string
59
    {
60 230
        $html = ini_get('html_errors');
61
62 230
        if ($html !== '1') {
63 230
            ini_set('html_errors', '1');
64
        }
65
66 230
        if (extension_loaded('xdebug')) {
67
            ini_set('xdebug.var_display_max_depth', (string) $maxDepth);
68
        }
69
70 230
        $var = self::export($var, $maxDepth);
71
72 230
        ob_start();
73 230
        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 230
            $output = ob_get_clean();
77 230
            assert(is_string($output));
78
79 230
            return strip_tags(html_entity_decode($output));
80
        } finally {
81 230
            ini_set('html_errors', $html);
82
        }
83
    }
84
85
    /**
86
     * @param mixed $var
87
     *
88
     * @return mixed
89
     */
90 230
    public static function export($var, int $maxDepth)
91
    {
92 230
        $return = null;
93 230
        $isObj  = is_object($var);
94
95 230
        if ($var instanceof Collection) {
96
            $var = $var->toArray();
97
        }
98
99 230
        if ($maxDepth === 0) {
100 115
            return is_object($var) ? get_class($var)
101 115
                : (is_array($var) ? 'Array(' . count($var) . ')' : $var);
102
        }
103
104 230
        if (is_array($var)) {
105 230
            $return = [];
106
107 230
            foreach ($var as $k => $v) {
108 230
                $return[$k] = self::export($v, $maxDepth - 1);
109
            }
110
111 230
            return $return;
112
        }
113
114 230
        if (! $isObj) {
115 230
            return $var;
116
        }
117
118 161
        $return = new stdClass();
119 161
        if ($var instanceof DateTimeInterface) {
120 92
            $return->__CLASS__ = get_class($var);
121 92
            $return->date      = $var->format('c');
122 92
            $return->timezone  = $var->getTimezone()->getName();
123
124 92
            return $return;
125
        }
126
127 161
        $return->__CLASS__ = self::getClass($var);
128
129 161
        if ($var instanceof Proxy) {
130
            $return->__IS_PROXY__          = true;
131
            $return->__PROXY_INITIALIZED__ = $var->__isInitialized();
132
        }
133
134 161
        if ($var instanceof ArrayObject || $var instanceof ArrayIterator) {
135 69
            $return->__STORAGE__ = self::export($var->getArrayCopy(), $maxDepth - 1);
136
        }
137
138 161
        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 161
    private static function fillReturnWithClassAttributes(object $var, stdClass $return, int $maxDepth)
148
    {
149 161
        $clone = (array) $var;
150
151 161
        foreach (array_keys($clone) as $key) {
152 161
            $aux  = explode("\0", (string) $key);
153 161
            $name = end($aux);
154 161
            if ($aux[0] === '') {
155 46
                $name .= ':' . ($aux[1] === '*' ? 'protected' : $aux[1] . ':private');
156
            }
157 161
            $return->$name = self::export($clone[$key], $maxDepth - 1);
158
        }
159
160 161
        return $return;
161
    }
162
163 161
    private static function getClass(object $object) : string
164
    {
165 161
        $class = get_class($object);
166
167 161
        if (! class_exists(Proxy::class)) {
168 161
            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