Passed
Push — master ( ba645d...9eba8c )
by Michael
07:09 queued 43s
created

TextRenderer::escape()   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 2
dl 0
loc 3
rs 10
1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2013 Jonathan Vollebregt ([email protected]), Rokas Šleinius ([email protected])
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
9
 * this software and associated documentation files (the "Software"), to deal in
10
 * the Software without restriction, including without limitation the rights to
11
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12
 * the Software, and to permit persons to whom the Software is furnished to do so,
13
 * subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in all
16
 * copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
 */
25
26
namespace Kint\Renderer;
27
28
use Kint\Kint;
29
use Kint\Object\BasicObject;
30
use Kint\Object\InstanceObject;
31
use Kint\Utils;
32
33
class TextRenderer extends Renderer
34
{
35
    /**
36
     * TextRenderer plugins should be instances of Kint\Renderer\Text\Plugin.
37
     */
38
    public static $plugins = array(
39
        'blacklist' => 'Kint\\Renderer\\Text\\BlacklistPlugin',
40
        'depth_limit' => 'Kint\\Renderer\\Text\\DepthLimitPlugin',
41
        'microtime' => 'Kint\\Renderer\\Text\\MicrotimePlugin',
42
        'recursion' => 'Kint\\Renderer\\Text\\RecursionPlugin',
43
        'trace' => 'Kint\\Renderer\\Text\\TracePlugin',
44
    );
45
46
    /**
47
     * Parser plugins must be instanceof one of these or
48
     * it will be removed for performance reasons.
49
     */
50
    public static $parser_plugin_whitelist = array(
51
        'Kint\\Parser\\BlacklistPlugin',
52
        'Kint\\Parser\\MicrotimePlugin',
53
        'Kint\\Parser\\StreamPlugin',
54
        'Kint\\Parser\\TracePlugin',
55
    );
56
57
    /**
58
     * The maximum length of a string before it is truncated.
59
     *
60
     * Falsey to disable
61
     *
62
     * @var int
63
     */
64
    public static $strlen_max = 0;
65
66
    /**
67
     * The default width of the terminal for headers.
68
     *
69
     * @var int
70
     */
71
    public static $default_width = 80;
72
73
    /**
74
     * Indentation width.
75
     *
76
     * @var int
77
     */
78
    public static $default_indent = 4;
79
80
    /**
81
     * Decorate the header and footer.
82
     *
83
     * @var bool
84
     */
85
    public static $decorations = true;
86
87
    /**
88
     * Sort mode for object properties.
89
     *
90
     * @var int
91
     */
92
    public static $sort = self::SORT_NONE;
93
94
    public $header_width = 80;
95
    public $indent_width = 4;
96
97
    protected $plugin_objs = array();
98
99
    public function __construct()
100
    {
101
        $this->header_width = self::$default_width;
102
        $this->indent_width = self::$default_indent;
103
    }
104
105
    public function render(BasicObject $o)
106
    {
107
        if ($plugin = $this->getPlugin(self::$plugins, $o->hints)) {
108
            if (\strlen($output = $plugin->render($o))) {
109
                return $output;
110
            }
111
        }
112
113
        $out = '';
114
115
        if (0 == $o->depth) {
116
            $out .= $this->colorTitle($this->renderTitle($o)).PHP_EOL;
117
        }
118
119
        $out .= $this->renderHeader($o);
120
        $out .= $this->renderChildren($o).PHP_EOL;
121
122
        return $out;
123
    }
124
125
    public function renderNothing()
126
    {
127
        if (self::$decorations) {
128
            return $this->colorTitle(
129
                $this->boxText('No argument', $this->header_width)
130
            ).PHP_EOL;
131
        }
132
133
        return $this->colorTitle('No argument').PHP_EOL;
134
    }
135
136
    public function boxText($text, $width)
137
    {
138
        $out = '┌'.\str_repeat('─', $width - 2).'┐'.PHP_EOL;
139
140
        if (\strlen($text)) {
141
            $text = Utils::truncateString($text, $width - 4);
142
            $text = \str_pad($text, $width - 4);
143
144
            $out .= '│ '.$this->escape($text).' │'.PHP_EOL;
145
        }
146
147
        $out .= '└'.\str_repeat('─', $width - 2).'┘';
148
149
        return $out;
150
    }
151
152
    public function renderTitle(BasicObject $o)
153
    {
154
        $name = (string) $o->getName();
155
156
        if (self::$decorations) {
157
            return $this->boxText($name, $this->header_width);
158
        }
159
160
        return Utils::truncateString($name, $this->header_width);
161
    }
162
163
    public function renderHeader(BasicObject $o)
164
    {
165
        $output = array();
166
167
        if ($o->depth) {
168
            if (null !== ($s = $o->getModifiers())) {
169
                $output[] = $s;
170
            }
171
172
            if (null !== $o->name) {
173
                $output[] = $this->escape(\var_export($o->name, true));
174
175
                if (null !== ($s = $o->getOperator())) {
176
                    $output[] = $this->escape($s);
177
                }
178
            }
179
        }
180
181
        if (null !== ($s = $o->getType())) {
182
            if ($o->reference) {
183
                $s = '&'.$s;
184
            }
185
186
            $output[] = $this->colorType($this->escape($s));
187
        }
188
189
        if (null !== ($s = $o->getSize())) {
190
            $output[] = '('.$this->escape($s).')';
191
        }
192
193
        if (null !== ($s = $o->getValueShort())) {
194
            if (self::$strlen_max) {
195
                $s = Utils::truncateString($s, self::$strlen_max);
196
            }
197
            $output[] = $this->colorValue($this->escape($s));
198
        }
199
200
        return \str_repeat(' ', $o->depth * $this->indent_width).\implode(' ', $output);
201
    }
202
203
    public function renderChildren(BasicObject $o)
204
    {
205
        if ('array' === $o->type) {
206
            $output = ' [';
207
        } elseif ('object' === $o->type) {
208
            $output = ' (';
209
        } else {
210
            return '';
211
        }
212
213
        $children = '';
214
215
        if ($o->value && \is_array($o->value->contents)) {
216
            if ($o instanceof InstanceObject && 'properties' === $o->value->getName()) {
217
                foreach (self::sortProperties($o->value->contents, self::$sort) as $obj) {
218
                    $children .= $this->render($obj);
219
                }
220
            } else {
221
                foreach ($o->value->contents as $child) {
222
                    $children .= $this->render($child);
223
                }
224
            }
225
        }
226
227
        if ($children) {
228
            $output .= PHP_EOL.$children;
229
            $output .= \str_repeat(' ', $o->depth * $this->indent_width);
230
        }
231
232
        if ('array' === $o->type) {
233
            $output .= ']';
234
        } else {
235
            $output .= ')';
236
        }
237
238
        return $output;
239
    }
240
241
    public function colorValue($string)
242
    {
243
        return $string;
244
    }
245
246
    public function colorType($string)
247
    {
248
        return $string;
249
    }
250
251
    public function colorTitle($string)
252
    {
253
        return $string;
254
    }
255
256
    public function postRender()
257
    {
258
        if (self::$decorations) {
259
            $output = \str_repeat('═', $this->header_width);
260
        } else {
261
            $output = '';
262
        }
263
264
        if (!$this->show_trace) {
265
            return $this->colorTitle($output);
266
        }
267
268
        if ($output) {
269
            $output .= PHP_EOL;
270
        }
271
272
        return $this->colorTitle($output.$this->calledFrom().PHP_EOL);
273
    }
274
275
    public function filterParserPlugins(array $plugins)
276
    {
277
        $return = array();
278
279
        foreach ($plugins as $index => $plugin) {
280
            foreach (self::$parser_plugin_whitelist as $whitelist) {
281
                if ($plugin instanceof $whitelist) {
282
                    $return[] = $plugin;
283
                    continue 2;
284
                }
285
            }
286
        }
287
288
        return $return;
289
    }
290
291
    public function ideLink($file, $line)
292
    {
293
        return $this->escape(Kint::shortenPath($file)).':'.$line;
294
    }
295
296
    public function escape($string, $encoding = false)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

296
    public function escape($string, /** @scrutinizer ignore-unused */ $encoding = false)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
297
    {
298
        return $string;
299
    }
300
301
    protected function calledFrom()
302
    {
303
        $output = '';
304
305
        if (isset($this->call_info['callee']['file'])) {
306
            $output .= 'Called from '.$this->ideLink(
307
                $this->call_info['callee']['file'],
308
                $this->call_info['callee']['line']
309
            );
310
        }
311
312
        if (isset($this->call_info['callee']['function']) && (
313
                !empty($this->call_info['callee']['class']) ||
314
                !\in_array(
315
                    $this->call_info['callee']['function'],
316
                    array('include', 'include_once', 'require', 'require_once'),
317
                    true
318
                )
319
            )
320
        ) {
321
            $output .= ' [';
322
            if (isset($this->call_info['callee']['class'])) {
323
                $output .= $this->call_info['callee']['class'];
324
            }
325
            if (isset($this->call_info['callee']['type'])) {
326
                $output .= $this->call_info['callee']['type'];
327
            }
328
            $output .= $this->call_info['callee']['function'].'()]';
329
        }
330
331
        return $output;
332
    }
333
334
    protected function getPlugin(array $plugins, array $hints)
335
    {
336
        if ($plugins = $this->matchPlugins($plugins, $hints)) {
337
            $plugin = \end($plugins);
338
339
            if (!isset($this->plugin_objs[$plugin])) {
340
                $this->plugin_objs[$plugin] = new $plugin($this);
341
            }
342
343
            return $this->plugin_objs[$plugin];
344
        }
345
    }
346
}
347