Kint_Parsers_ClassMethods   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 18.82%

Importance

Changes 0
Metric Value
dl 0
loc 165
ccs 16
cts 85
cp 0.1882
rs 9.6
c 0
b 0
f 0
wmc 32
lcom 1
cbo 3

1 Method

Rating   Name   Duplication   Size   Complexity  
D _parse() 0 152 32
1
<?php
2
3
namespace kint\parsers\custom;
4
5
use kint\inc\KintParser;
6
use kint\inc\KintVariableData;
7
use kint\Kint;
8
9
/**
10
 * Class Kint_Parsers_ClassMethods
11
 */
12
class Kint_Parsers_ClassMethods extends KintParser
13
{
14
  /**
15
   * @var array
16
   */
17
  private static $cache = array();
18
19
  /**
20
   * @param mixed $variable
21
   *
22
   * @return bool
23
   */
24 1
  protected function _parse(&$variable)
25
  {
26 1
    if (!is_object($variable)) {
27 1
      return false;
28
    }
29
30 1
    $className = get_class($variable);
31
32
    # assuming class definition will not change inside one request
33 1
    if (!isset(self::$cache[$className])) {
34 1
      $reflection = new \ReflectionClass($variable);
35
36 1
      $public = $private = $protected = array();
37
38
      // Class methods
39 1
      foreach ($reflection->getMethods() as $method) {
40
        $params = array();
41
42
        // Access type
43
        $access = implode(' ', \Reflection::getModifierNames($method->getModifiers()));
44
45
        // Method parameters
46
        foreach ($method->getParameters() as $param) {
47
          $paramString = '';
48
49
          if ($param->isArray()) {
50
            $paramString .= 'array ';
51
          } else {
52
            try {
53
              $paramClassName = $param->getClass();
54
              if ($paramClassName) {
55
                $paramString .= $paramClassName->name . ' ';
56
              }
57
            } catch (\ReflectionException $e) {
58
              preg_match('/\[\s\<\w+?>\s([\w]+)/', (string)$param, $matches);
59
              $paramClassName = isset($matches[1]) ? $matches[1] : '';
60
61
              $paramString .= ' UNDEFINED CLASS (' . $paramClassName . ') ';
62
            }
63
          }
64
65
          $paramString .= ($param->isPassedByReference() ? '&' : '') . '$' . $param->getName();
66
67
          if ($param->isDefaultValueAvailable()) {
68
            if (is_array($param->getDefaultValue())) {
69
              $arrayValues = array();
70
              foreach ($param->getDefaultValue() as $key => $value) {
71
                $arrayValues[] = $key . ' => ' . $value;
72
              }
73
74
              $defaultValue = 'array(' . implode(', ', $arrayValues) . ')';
75
            } elseif ($param->getDefaultValue() === null) {
76
              $defaultValue = 'NULL';
77
            } elseif ($param->getDefaultValue() === false) {
78
              $defaultValue = 'false';
79
            } elseif ($param->getDefaultValue() === true) {
80
              $defaultValue = 'true';
81
            } elseif ($param->getDefaultValue() === '') {
82
              $defaultValue = '""';
83
            } else {
84
              $defaultValue = $param->getDefaultValue();
85
            }
86
87
            $paramString .= ' = ' . $defaultValue;
88
          }
89
90
          $params[] = $paramString;
91
        }
92
93
        $output = new KintVariableData;
94
95
        // Simple DocBlock parser, look for @return
96
        $docBlock = $method->getDocComment();
97
        if ($docBlock) {
98
          $matches = array();
99
          if (preg_match_all('/@(\w+)\s+(.*)\r?\n/m', $docBlock, $matches)) {
100
            $lines = array_combine($matches[1], $matches[2]);
101
            if (isset($lines['return'])) {
102
              $output->operator = '->';
103
              # since we're outputting code, assumption that the string is utf8 is most likely correct
104
              # and saves resources
105
              $output->type = self::escape($lines['return'], 'UTF-8');
106
            }
107
          }
108
        }
109
110
        $output->name = ($method->returnsReference() ? '&' : '') . $method->getName() . '('
111
                        . implode(', ', $params) . ')';
112
        $output->access = $access;
113
114
        if (is_string($docBlock)) {
115
          $lines = array();
116
          foreach (explode("\n", $docBlock) as $line) {
117
            $line = trim($line);
118
119
            if (in_array($line, array('/**', '/*', '*/'), true)) {
120
              continue;
121
            } elseif (strpos($line, '*') === 0) {
122
              $line = trim(substr($line, 1));
123
            }
124
125
            $lines[] = self::escape($line, 'UTF-8');
126
          }
127
128
          $output->extendedValue = implode("\n", $lines) . "\n\n";
0 ignored issues
show
Documentation Bug introduced by
It seems like implode(' ', $lines) . ' ' of type string is incompatible with the declared type array<integer,object<kint\inc\KintVariableData>> of property $extendedValue.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
129
        }
130
131
        $declaringClass = $method->getDeclaringClass();
132
        $declaringClassName = $declaringClass->getName();
133
134
        if ($declaringClassName !== $className) {
135
          /** @noinspection PhpToStringImplementationInspection */
136
          $output->extendedValue .= "<small>Inherited from <i>{$declaringClassName}</i></small>\n";
137
        }
138
139
        $fileName = Kint::shortenPath($method->getFileName()) . ':' . $method->getStartLine();
140
        /** @noinspection PhpToStringImplementationInspection */
141
        $output->extendedValue .= "<small>Defined in {$fileName}</small>";
142
143
        $sortName = $access . $method->getName();
144
145
        if ($method->isPrivate()) {
146
          $private[$sortName] = $output;
147
        } elseif ($method->isProtected()) {
148
          $protected[$sortName] = $output;
149
        } else {
150
          $public[$sortName] = $output;
151
        }
152
      }
153
154 1
      if (!$private && !$protected && !$public) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $private of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
Bug Best Practice introduced by
The expression $protected of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
Bug Best Practice introduced by
The expression $public of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
155 1
        self::$cache[$className] = false;
156
      }
157
158 1
      ksort($public);
159 1
      ksort($protected);
160 1
      ksort($private);
161
162
      /** @noinspection AdditionOperationOnArraysInspection */
163 1
      self::$cache[$className] = $public + $protected + $private;
164
    }
165
166 1
    if (count(self::$cache[$className]) === 0) {
167 1
      return false;
168
    }
169
170
    $this->value = self::$cache[$className];
171
    $this->type = 'Available methods';
172
    $this->size = count(self::$cache[$className]);
173
174
    return true;
175
  }
176
}
177