Completed
Pull Request — master (#546)
by Richard
09:47
created

Kint_Renderer_Text   B

Complexity

Total Complexity 54

Size/Duplication

Total Lines 298
Duplicated Lines 10.4 %

Coupling/Cohesion

Components 2
Dependencies 5

Importance

Changes 0
Metric Value
dl 31
loc 298
rs 7.0642
c 0
b 0
f 0
wmc 54
lcom 2
cbo 5

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
A render() 5 19 4
A boxText() 0 14 2
A renderTitle() 0 14 4
D renderHeader() 9 39 11
D renderChildren() 0 31 9
A colorValue() 0 4 1
A colorType() 0 4 1
A colorTitle() 0 4 1
A postRender() 0 18 4
A parserPlugins() 0 15 4
C calledFrom() 5 28 7
A ideLink() 0 4 1
A getPlugin() 12 12 3
A escape() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Kint_Renderer_Text often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Kint_Renderer_Text, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
class Kint_Renderer_Text extends Kint_Renderer
4
{
5
    public static $object_renderers = array(
6
        'blacklist' => 'Kint_Renderer_Text_Blacklist',
7
        'depth_limit' => 'Kint_Renderer_Text_DepthLimit',
8
        'nothing' => 'Kint_Renderer_Text_Nothing',
9
        'recursion' => 'Kint_Renderer_Text_Recursion',
10
        'trace' => 'Kint_Renderer_Text_Trace',
11
    );
12
13
    /**
14
     * Parser plugins must be instanceof one of these or
15
     * it will be removed for performance reasons.
16
     */
17
    public static $parser_plugin_whitelist = array(
18
        'Kint_Parser_Blacklist',
19
        'Kint_Parser_Stream',
20
        'Kint_Parser_Trace',
21
    );
22
23
    /**
24
     * The maximum length of a string before it is truncated.
25
     *
26
     * Falsey to disable
27
     *
28
     * @var int
29
     */
30
    public static $strlen_max = 0;
31
32
    /**
33
     * The default width of the terminal for headers.
34
     *
35
     * @var int
36
     */
37
    public static $default_width = 80;
38
39
    /**
40
     * Indentation width.
41
     *
42
     * @var int
43
     */
44
    public static $default_indent = 4;
45
46
    /**
47
     * Decorate the header and footer.
48
     *
49
     * @var bool
50
     */
51
    public static $decorations = true;
52
53
    public $header_width = 80;
54
    public $indent_width = 4;
55
56
    protected $plugin_objs = array();
57
    protected $previous_caller;
58
    protected $callee;
59
    protected $show_minitrace = true;
60
61
    public function __construct(array $params = array())
62
    {
63
        parent::__construct($params);
64
65
        $params += array(
66
            'callee' => null,
67
            'caller' => null,
68
        );
69
70
        $this->callee = $params['callee'];
71
        $this->previous_caller = $params['caller'];
72
        $this->show_minitrace = !empty($params['settings']['display_called_from']);
73
        $this->header_width = self::$default_width;
74
        $this->indent_width = self::$default_indent;
75
    }
76
77
    public function render(Kint_Object $o)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
78
    {
79 View Code Duplication
        if ($plugin = $this->getPlugin(self::$object_renderers, $o->hints)) {
80
            if (strlen($output = $plugin->render($o))) {
81
                return $output;
82
            }
83
        }
84
85
        $out = '';
86
87
        if ($o->depth == 0) {
88
            $out .= $this->colorTitle($this->renderTitle($o)).PHP_EOL;
89
        }
90
91
        $out .= $this->renderHeader($o);
92
        $out .= $this->renderChildren($o).PHP_EOL;
93
94
        return $out;
95
    }
96
97
    public function boxText($text, $width)
98
    {
99
        if (Kint_Object_Blob::strlen($text) > $width - 4) {
100
            $text = Kint_Object_Blob::substr($text, 0, $width - 7).'...';
101
        }
102
103
        $text .= str_repeat(' ', $width - 4 - Kint_Object_Blob::strlen($text));
104
105
        $out = '┌'.str_repeat('─', $width - 2).'┐'.PHP_EOL;
106
        $out .= '│ '.$this->escape($text).' │'.PHP_EOL;
107
        $out .= '└'.str_repeat('─', $width - 2).'┘';
108
109
        return $out;
110
    }
111
112
    public function renderTitle(Kint_Object $o)
113
    {
114
        if (($name = $o->getName()) === null) {
115
            $name = 'literal';
116
        }
117
118
        if (self::$decorations) {
119
            return $this->boxText($name, $this->header_width);
120
        } elseif (Kint_Object_Blob::strlen($name) > $this->header_width) {
121
            return Kint_Object_Blob::substr($name, 0, $this->header_width - 3).'...';
122
        } else {
123
            return $name;
124
        }
125
    }
126
127
    public function renderHeader(Kint_Object $o)
128
    {
129
        $output = array();
130
131
        if ($o->depth) {
132
            if (($s = $o->getModifiers()) !== null) {
133
                $output[] = $s;
134
            }
135
136
            if ($o->name !== null) {
137
                $output[] = $this->escape(var_export($o->name, true));
138
139
                if (($s = $o->getOperator()) !== null) {
140
                    $output[] = $this->escape($s);
141
                }
142
            }
143
        }
144
145
        if (($s = $o->getType()) !== null) {
146
            if ($o->reference) {
147
                $s = '&'.$s;
148
            }
149
150
            $output[] = $this->colorType($this->escape($s));
151
        }
152
153 View Code Duplication
        if (($s = $o->getSize()) !== null) {
154
            $output[] = '('.$this->escape($s).')';
155
        }
156
157 View Code Duplication
        if (($s = $o->getValueShort()) !== null) {
158
            if (self::$strlen_max && Kint_Object_Blob::strlen($s) > self::$strlen_max) {
159
                $s = substr($s, 0, self::$strlen_max).'...';
160
            }
161
            $output[] = $this->colorValue($this->escape($s));
162
        }
163
164
        return str_repeat(' ', $o->depth * $this->indent_width).implode(' ', $output);
165
    }
166
167
    public function renderChildren(Kint_Object $o)
168
    {
169
        if ($o->type === 'array') {
170
            $output = ' [';
171
        } elseif ($o->type === 'object') {
172
            $output = ' (';
173
        } else {
174
            return '';
175
        }
176
177
        $children = '';
178
179
        if ($o->value && is_array($o->value->contents)) {
180
            foreach ($o->value->contents as $child) {
181
                $children .= $this->render($child);
182
            }
183
        }
184
185
        if ($children) {
186
            $output .= PHP_EOL.$children;
187
            $output .= str_repeat(' ', $o->depth * $this->indent_width);
188
        }
189
190
        if ($o->type === 'array') {
191
            $output .= ']';
192
        } elseif ($o->type === 'object') {
193
            $output .= ')';
194
        }
195
196
        return $output;
197
    }
198
199
    public function colorValue($string)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
200
    {
201
        return $string;
202
    }
203
204
    public function colorType($string)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
205
    {
206
        return $string;
207
    }
208
209
    public function colorTitle($string)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
210
    {
211
        return $string;
212
    }
213
214
    public function postRender()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
215
    {
216
        if (self::$decorations) {
217
            $output = str_repeat('═', $this->header_width);
218
        } else {
219
            $output = '';
220
        }
221
222
        if (!$this->show_minitrace) {
223
            return $this->colorTitle($output);
224
        } else {
225
            if ($output) {
226
                $output .= PHP_EOL;
227
            }
228
229
            return $this->colorTitle($output.$this->calledFrom().PHP_EOL);
230
        }
231
    }
232
233
    public function parserPlugins(array $plugins)
234
    {
235
        $return = array();
236
237
        foreach ($plugins as $index => $plugin) {
238
            foreach (self::$parser_plugin_whitelist as $whitelist) {
239
                if ($plugin instanceof $whitelist) {
240
                    $return[] = $plugin;
241
                    continue 2;
242
                }
243
            }
244
        }
245
246
        return $return;
247
    }
248
249
    protected function calledFrom()
250
    {
251
        $output = '';
252
253
        if (isset($this->callee['file'])) {
254
            $output .= 'Called from '.$this->ideLink($this->callee['file'], $this->callee['line']);
255
        }
256
257
        $caller = '';
258
259
        if (isset($this->previous_caller['class'])) {
260
            $caller .= $this->previous_caller['class'];
261
        }
262
        if (isset($this->previous_caller['type'])) {
263
            $caller .= $this->previous_caller['type'];
264
        }
265 View Code Duplication
        if (isset($this->previous_caller['function'])
266
            && !in_array($this->previous_caller['function'], array('include', 'include_once', 'require', 'require_once'))
267
        ) {
268
            $caller .= $this->previous_caller['function'].'()';
269
        }
270
271
        if ($caller) {
272
            $output .= ' ['.$caller.']';
273
        }
274
275
        return $output;
276
    }
277
278
    public function ideLink($file, $line)
279
    {
280
        return $this->escape(Kint::shortenPath($file)).':'.$line;
281
    }
282
283 View Code Duplication
    protected function getPlugin(array $plugins, array $hints)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
284
    {
285
        if ($plugins = $this->matchPlugins($plugins, $hints)) {
286
            $plugin = end($plugins);
287
288
            if (!isset($this->plugin_objs[$plugin])) {
289
                $this->plugin_objs[$plugin] = new $plugin($this);
290
            }
291
292
            return $this->plugin_objs[$plugin];
293
        }
294
    }
295
296
    public function escape($string, $encoding = false)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
297
    {
298
        return $string;
299
    }
300
}
301