Passed
Push — main ( 3c77fc...4b9cf0 )
by Sammy
02:22 queued 30s
created

Debugger::init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 2
rs 10
1
<?php
2
3
namespace HexMakina\Debugger
4
{
5
    class Debugger
6
    {
7
8
        public function __debugInfo(): array
9
        {
10
            return [json_encode(get_object_vars($this))];
11
        }
12
13
        public static function displayErrors($error_message = null)
14
        {
15
            $should_display = ini_get('display_errors') == '1';
16
17
            if ($should_display && !empty($error_message)) {
18
                echo self::toHTML($error_message);
19
            }
20
        }
21
22
      // -- visual dump (depends on env)
23
        public static function vd($var, $var_name = null, $full_backtrace = false)
24
        {
25
            self::displayErrors(self::dump($var, $var_name, $full_backtrace));
26
        }
27
28
      // -- visual dump and DIE
29
        public static function dd($var, $var_name = null, $full_backtrace = true)
30
        {
31
            self::vd($var, $var_name, $full_backtrace);
32
            die;
33
        }
34
35
      // -- dump on variable type (Throwables, array, anything else)
36
        public static function dump($var, $var_name = null, $full_backtrace = true)
37
        {
38
            if (is_object($var) && (is_subclass_of($var, 'Error') || is_subclass_of($var, 'Exception'))) {
39
                $backtrace = $var->getTrace();
40
                $full_backtrace = true;
41
                $var_dump  = self::formatThrowable($var);
42
            } else {
43
                $backtrace = debug_backtrace();
44
45
                ob_start();
46
                var_dump($var);
47
                $var_dump = ob_get_clean();
48
            }
49
50
            return PHP_EOL
51
            . "*******"
52
            . (empty($var_name) ? '' : " ($var_name) ")
53
            . "*******"
54
            . PHP_EOL
55
            . self::tracesToString($backtrace, $full_backtrace)
56
            . PHP_EOL
57
            . $var_dump;
58
        }
59
60
      // -- formatting
61
62
      // -- formatting : first line of \Throwable-based error
63
        public static function formatThrowable(\Throwable $err)
64
        {
65
            return PHP_EOL . sprintf(
66
                '%s (%d) in file %s:%d' . PHP_EOL . '%s',
67
                get_class($err),
68
                $err->getCode(),
69
                self::formatFilename($err->getFile()),
70
                $err->getLine(),
71
                $err->getMessage()
72
            );
73
        }
74
75
        public static function formatFilename($file, $reduce_file_depth_to = 5)
76
        {
77
            return implode('/', array_slice(explode('/', $file), -$reduce_file_depth_to, $reduce_file_depth_to));
78
        }
79
80
      // -- formatting : nice backtrace
81
        public static function tracesToString($traces, $full_backtrace)
82
        {
83
            $formated_traces = [];
84
85
            foreach ($traces as $depth => $trace) {
86
                $function_name = $trace['function'] ?? '?';
87
                $class_name = $trace['class'] ?? '?';
88
89
                if (self::isInternalFunctionCall($class_name, $function_name)) {
90
                    continue;
91
                }
92
93
                if (!self::isShortcutCall($function_name) && isset($trace['args'])) {
94
                    $args = self::traceArgsToString($trace['args']);
95
                } else {
96
                    $args = microtime(true);
97
                }
98
99
                $call_file = isset($trace['file']) ? basename($trace['file']) : '?';
100
                $call_line = $trace['line'] ?? '?';
101
102
                $formated_traces [] = sprintf(
103
                    '[%-23.23s %3s]  %s%s(%s)',
104
                    $call_file,
105
                    $call_line,
106
                    "$class_name::",
107
                    $function_name,
108
                    $args
109
                );
110
111
                if ($full_backtrace === false) {
112
                    break;
113
                }
114
            }
115
116
            return implode(PHP_EOL, array_reverse($formated_traces));
117
        }
118
119
        private static function traceArgsToString($trace_args)
120
        {
121
            $ret = [];
122
            foreach ($trace_args as $arg) {
123
                if (is_null($arg)) {
124
                    $ret[] = 'NULL';
125
                } elseif (is_bool($arg)) {
126
                    $ret[] = 'bool:' . ((int)$arg);
127
                } elseif (is_scalar($arg)) {
128
                    $ret[] = $arg;
129
                } elseif (is_object($arg)) {
130
                    $ret[] = get_class($arg);
131
                } elseif (is_array($arg)) {
132
                    $ret[] = 'Array #' . count($arg);
133
                } else {
134
                    $ret[] = 'unknown type';
135
                }
136
            }
137
            $ret = implode(', ', $ret);
138
            return $ret;
139
        }
140
141
        private static function isInternalFunctionCall($class_name, $function_name): bool
142
        {
143
            return $class_name === __CLASS__ && in_array($function_name, ['dump', 'vd', 'dd']);
144
        }
145
146
        private static function isShortcutCall($function_name): bool
147
        {
148
            return in_array($function_name, ['vd', 'dd','vdt', 'ddt']);
149
        }
150
151
        private static function toHTML($message)
152
        {
153
            $css = [
154
            'text-align:left',
155
            'z-index:9999',
156
            'background-color:#FFF',
157
            'color:#000',
158
            'padding:0.5em',
159
            'font-size:0.7em',
160
            'margin:0 0 1em 0',
161
            'font-family:courier'
162
            ];
163
164
            return sprintf('<pre style="%s">%s</pre>', implode(';', $css), $message);
165
        }
166
    }
167
}
168
namespace
169
{
170
    if (!function_exists('vd')) {
171
        function vd($var, $var_name = null)
172
        {
173
            \HexMakina\Debugger\Debugger::vd($var, $var_name, false);
174
        }
175
    }
176
    if (!function_exists('dd')) {
177
        function dd($var, $var_name = null)
178
        {
179
            \HexMakina\Debugger\Debugger::dd($var, $var_name, false);
180
        }
181
    }
182
    if (!function_exists('vdt')) {
183
        function vdt($var, $var_name = null)
184
        {
185
            \HexMakina\Debugger\Debugger::vd($var, $var_name, true);
186
        }
187
    }
188
    if (!function_exists('ddt')) {
189
        function ddt($var, $var_name = null)
190
        {
191
            \HexMakina\Debugger\Debugger::dd($var, $var_name, true);
192
        }
193
    }
194
}
195