Passed
Push — main ( 05d87f...31758c )
by Sammy
01:44
created

Debugger::trace_args_to_string()   C

Complexity

Conditions 13
Paths 13

Size

Total Lines 47
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
eloc 26
c 1
b 0
f 0
nc 13
nop 1
dl 0
loc 47
rs 6.6166

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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