Passed
Push — main ( 4b9cf0...c9dd63 )
by Sammy
02:15
created

Debugger::__debugInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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