Test Setup Failed
Push — test ( dd7d7c...b3915a )
by Jonathan
03:06
created

Kint   D

Complexity

Total Complexity 102

Size/Duplication

Total Lines 713
Duplicated Lines 1.96 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 14
loc 713
rs 4.4444
c 0
b 0
f 0
wmc 102
lcom 1
cbo 6

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A setParser() 0 4 1
A getParser() 0 4 1
A setRenderer() 0 4 1
A getRenderer() 0 4 1
D setStatesFromStatics() 0 33 9
B setStatesFromCallInfo() 0 20 7
B dumpAll() 0 23 5
A dumpVar() 0 6 1
A getStatics() 0 18 1
D createFromStatics() 0 31 9
C getBasesFromParamInfo() 0 51 8
F getCallInfo() 0 119 21
C trace() 7 56 10
C dump() 7 68 15
D shortenPath() 0 37 10
A getIdeLink() 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 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, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Kint;
4
5
use InvalidArgumentException;
6
use Kint\Object\BasicObject;
7
use Kint\Parser\Parser;
8
use Kint\Parser\Plugin;
9
use Kint\Renderer\Renderer;
10
use Kint\Renderer\TextRenderer;
11
12
class Kint
0 ignored issues
show
Coding Style introduced by
The property $enabled_mode is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $mode_default is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $mode_default_cli is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $file_link_format is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $display_called_from is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $app_root_dirs is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $max_depth is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $cli_detection is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $plugin_pool is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
13
{
14
    /**
15
     * @var mixed Kint mode
16
     *
17
     * false: Disabled
18
     * true: Enabled, default mode selection
19
     * other: Manual mode selection
20
     */
21
    public static $enabled_mode = true;
0 ignored issues
show
Coding Style introduced by
$enabled_mode does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
22
23
    /**
24
     * Default mode.
25
     *
26
     * @var string
27
     */
28
    public static $mode_default = self::MODE_RICH;
0 ignored issues
show
Coding Style introduced by
$mode_default does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
29
30
    /**
31
     * Default mode in CLI with cli_detection on.
32
     *
33
     * @var string
34
     */
35
    public static $mode_default_cli = self::MODE_CLI;
0 ignored issues
show
Coding Style introduced by
$mode_default_cli does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
36
37
    /**
38
     * @var bool Return output instead of echoing
39
     */
40
    public static $return;
41
42
    /**
43
     * @var string format of the link to the source file in trace entries.
44
     *
45
     * Use %f for file path, %l for line number.
46
     *
47
     * [!] EXAMPLE (works with for phpStorm and RemoteCall Plugin):
48
     *
49
     * Kint::$file_link_format = 'http://localhost:8091/?message=%f:%l';
50
     */
51
    public static $file_link_format = '';
0 ignored issues
show
Coding Style introduced by
$file_link_format does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
52
53
    /**
54
     * @var bool whether to display where kint was called from
55
     */
56
    public static $display_called_from = true;
0 ignored issues
show
Coding Style introduced by
$display_called_from does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
57
58
    /**
59
     * @var array base directories of your application that will be displayed instead of the full path.
60
     *
61
     * Keys are paths, values are replacement strings
62
     *
63
     * [!] EXAMPLE (for Laravel 5):
64
     *
65
     * Kint::$app_root_dirs = [
66
     *     base_path() => '<BASE>',
67
     *     app_path() => '<APP>',
68
     *     config_path() => '<CONFIG>',
69
     *     database_path() => '<DATABASE>',
70
     *     public_path() => '<PUBLIC>',
71
     *     resource_path() => '<RESOURCE>',
72
     *     storage_path() => '<STORAGE>',
73
     * ];
74
     *
75
     * Defaults to [$_SERVER['DOCUMENT_ROOT'] => '<ROOT>']
76
     */
77
    public static $app_root_dirs = array();
0 ignored issues
show
Coding Style introduced by
$app_root_dirs does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
78
79
    /**
80
     * @var int max array/object levels to go deep, if zero no limits are applied
81
     */
82
    public static $max_depth = 6;
0 ignored issues
show
Coding Style introduced by
$max_depth does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
83
84
    /**
85
     * @var bool expand all trees by default for rich view
86
     */
87
    public static $expanded = false;
88
89
    /**
90
     * @var bool enable detection when Kint is command line.
91
     *
92
     * Formats output with whitespace only; does not HTML-escape it
93
     */
94
    public static $cli_detection = true;
0 ignored issues
show
Coding Style introduced by
$cli_detection does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
95
96
    /**
97
     * @var array Kint aliases. Add debug functions in Kint wrappers here to fix modifiers and backtraces
98
     */
99
    public static $aliases = array(
100
        array('Kint\\Kint', 'dump'),
101
        array('Kint\\Kint', 'trace'),
102
        array('Kint\\Kint', 'dumpArray'),
103
    );
104
105
    /**
106
     * @var array Kint\Renderer\Renderer descendants. Add to array to extend.
107
     */
108
    public static $renderers = array(
109
        self::MODE_RICH => 'Kint\\Renderer\\RichRenderer',
110
        self::MODE_PLAIN => 'Kint\\Renderer\\PlainRenderer',
111
        self::MODE_TEXT => 'Kint\\Renderer\\TextRenderer',
112
        self::MODE_CLI => 'Kint\\Renderer\\CliRenderer',
113
    );
114
115
    const MODE_RICH = 'r';
116
    const MODE_TEXT = 't';
117
    const MODE_CLI = 'c';
118
    const MODE_PLAIN = 'p';
119
120
    public static $plugins = array(
121
        'Kint\\Parser\\ArrayObjectPlugin',
122
        'Kint\\Parser\\Base64Plugin',
123
        'Kint\\Parser\\BlacklistPlugin',
124
        'Kint\\Parser\\ClassMethodsPlugin',
125
        'Kint\\Parser\\ClassStaticsPlugin',
126
        'Kint\\Parser\\ClosurePlugin',
127
        'Kint\\Parser\\ColorPlugin',
128
        'Kint\\Parser\\DateTimePlugin',
129
        'Kint\\Parser\\FsPathPlugin',
130
        'Kint\\Parser\\IteratorPlugin',
131
        'Kint\\Parser\\JsonPlugin',
132
        'Kint\\Parser\\MicrotimePlugin',
133
        'Kint\\Parser\\SimpleXMLElementPlugin',
134
        'Kint\\Parser\\SplFileInfoPlugin',
135
        'Kint\\Parser\\SplObjectStoragePlugin',
136
        'Kint\\Parser\\StreamPlugin',
137
        'Kint\\Parser\\TablePlugin',
138
        'Kint\\Parser\\ThrowablePlugin',
139
        'Kint\\Parser\\TimestampPlugin',
140
        'Kint\\Parser\\ToStringPlugin',
141
        'Kint\\Parser\\TracePlugin',
142
        'Kint\\Parser\\XmlPlugin',
143
    );
144
145
    protected static $plugin_pool = array();
0 ignored issues
show
Coding Style introduced by
$plugin_pool does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
146
147
    protected $parser;
148
    protected $renderer;
149
150
    public function __construct(Parser $p, Renderer $r)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $p. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
151
    {
152
        $this->parser = $p;
153
        $this->renderer = $r;
154
    }
155
156
    public function setParser(Parser $p)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $p. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
157
    {
158
        $this->parser = $p;
159
    }
160
161
    public function getParser()
162
    {
163
        return $this->parser;
164
    }
165
166
    public function setRenderer(Renderer $r)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
167
    {
168
        $this->renderer = $r;
169
    }
170
171
    public function getRenderer()
172
    {
173
        return $this->renderer;
174
    }
175
176
    public function setStatesFromStatics(array $statics)
177
    {
178
        $this->renderer->setExpand(!empty($statics['expanded']));
179
        $this->renderer->setReturnMode(!empty($statics['return']));
180
        $this->renderer->setShowTrace(!empty($statics['display_called_from']));
181
182
        $this->parser->setDepthLimit(isset($statics['max_depth']) ? $statics['max_depth'] : false);
183
        $this->parser->clearPlugins();
184
185
        if (!isset($statics['plugins'])) {
186
            return;
187
        }
188
189
        $plugins = array();
190
191
        foreach ($statics['plugins'] as $plugin) {
192
            if ($plugin instanceof Plugin) {
193
                $plugins[] = $plugin;
194
            } elseif (is_string($plugin) && is_subclass_of($plugin, 'Kint\\Parser\\Plugin')) {
195
                if (!isset(self::$plugin_pool[$plugin])) {
196
                    $p = new $plugin();
197
                    self::$plugin_pool[$plugin] = $p;
198
                }
199
                $plugins[] = self::$plugin_pool[$plugin];
200
            }
201
        }
202
203
        $plugins = $this->renderer->filterParserPlugins($plugins);
204
205
        foreach ($plugins as $plugin) {
206
            $this->parser->addPlugin($plugin);
207
        }
208
    }
209
210
    public function setStatesFromCallInfo(array $info)
211
    {
212
        $this->renderer->setCallInfo($info);
213
214
        if (isset($info['modifiers']) && is_array($info['modifiers'])) {
215
            if (in_array('!', $info['modifiers'])) {
216
                $this->renderer->setExpand(true);
217
            }
218
219
            if (in_array('@', $info['modifiers'])) {
220
                $this->renderer->setReturnMode(true);
221
            }
222
223
            if (in_array('+', $info['modifiers'])) {
224
                $this->parser->setDepthLimit(false);
225
            }
226
        }
227
228
        $this->parser->setCallerClass(isset($info['caller']['class']) ? $info['caller']['class'] : null);
229
    }
230
231
    /**
232
     * Renders a list of vars including the pre and post renders.
233
     *
234
     * @param array         $vars Data to dump
235
     * @param BasicObject[] $base Base objects
236
     *
237
     * @return string
238
     */
239
    public function dumpAll(array $vars, array $base)
240
    {
241
        if (array_keys($vars) !== array_keys($base)) {
242
            throw new InvalidArgumentException('Kint::dumpAll requires arrays of identical size and keys as arguments');
243
        }
244
245
        $output = $this->renderer->preRender();
246
247
        if ($vars === array()) {
248
            $output .= $this->renderer->renderNothing();
249
        }
250
251
        foreach ($vars as $key => $arg) {
252
            if (!$base[$key] instanceof BasicObject) {
253
                throw new InvalidArgumentException('Kint::dumpAll requires all elements of the second argument to be BasicObject instances');
254
            }
255
            $output .= $this->dumpVar($arg, $base[$key]);
256
        }
257
258
        $output .= $this->renderer->postRender();
259
260
        return $output;
261
    }
262
263
    /**
264
     * Dumps and renders a var.
265
     *
266
     * @param mixed       $var  Data to dump
267
     * @param BasicObject $base Base object
268
     *
269
     * @return string
270
     */
271
    public function dumpVar(&$var, BasicObject $base)
272
    {
273
        return $this->renderer->render(
274
            $this->parser->parse($var, $base)
275
        );
276
    }
277
278
    /**
279
     * Gets all static settings at once.
280
     *
281
     * @return array Current static settings
282
     */
283
    public static function getStatics()
284
    {
285
        return array(
286
            'aliases' => self::$aliases,
287
            'app_root_dirs' => self::$app_root_dirs,
288
            'cli_detection' => self::$cli_detection,
289
            'display_called_from' => self::$display_called_from,
290
            'enabled_mode' => self::$enabled_mode,
291
            'expanded' => self::$expanded,
292
            'file_link_format' => self::$file_link_format,
293
            'max_depth' => self::$max_depth,
294
            'mode_default' => self::$mode_default,
295
            'mode_default_cli' => self::$mode_default_cli,
296
            'plugins' => self::$plugins,
297
            'renderers' => self::$renderers,
298
            'return' => self::$return,
299
        );
300
    }
301
302
    /**
303
     * Creates a Kint instances based on static settings.
304
     *
305
     * Also calls setStatesFromStatics for you
306
     *
307
     * @param array $statics array of statics as returned by getStatics
308
     *
309
     * @return Kint|null
310
     */
311
    public static function createFromStatics(array $statics)
312
    {
313
        $mode = false;
314
315
        if (isset($statics['enabled_mode'])) {
316
            $mode = $statics['enabled_mode'];
317
318
            if ($statics['enabled_mode'] === true && isset($statics['mode_default'])) {
319
                $mode = $statics['mode_default'];
320
321
                if (PHP_SAPI === 'cli' && !empty($statics['cli_detection']) && isset($statics['mode_default_cli'])) {
322
                    $mode = $statics['mode_default_cli'];
323
                }
324
            }
325
        }
326
327
        if (!$mode) {
328
            return null;
329
        }
330
331
        if (!isset($statics['renderers'][$mode])) {
332
            $renderer = new TextRenderer();
333
        } else {
334
            $renderer = new $statics['renderers'][$mode]();
335
        }
336
337
        $kintstance = new self(new Parser(), $renderer);
338
        $kintstance->setStatesFromStatics($statics);
339
340
        return $kintstance;
341
    }
342
343
    /**
344
     * Creates base objects given parameter info.
345
     *
346
     * @param array $params Parameters as returned from getCallInfo
347
     * @param int   $argc   Number of arguments the helper was called with
348
     *
349
     * @return BasicObject[] Base objects for the arguments
350
     */
351
    public static function getBasesFromParamInfo(array $params, $argc)
352
    {
353
        static $blacklist = array(
354
            'null',
355
            'true',
356
            'false',
357
            'array(...)',
358
            'array()',
359
            '[...]',
360
            '[]',
361
            '(...)',
362
            '()',
363
            '"..."',
364
            'b"..."',
365
            "'...'",
366
            "b'...'",
367
        );
368
369
        $params = array_values($params);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $params. This often makes code more readable.
Loading history...
370
        $bases = array();
371
372
        for ($i = 0; $i < $argc; ++$i) {
373
            if (isset($params[$i])) {
374
                $param = $params[$i];
375
            } else {
376
                $param = null;
377
            }
378
379
            if (!isset($param['name']) || is_numeric($param['name'])) {
380
                $name = null;
381
            } elseif (in_array(strtolower($param['name']), $blacklist, true)) {
382
                $name = null;
383
            } else {
384
                $name = $param['name'];
385
            }
386
387
            if (isset($param['path'])) {
388
                $access_path = $param['path'];
0 ignored issues
show
Coding Style introduced by
$access_path does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
389
390
                if (!empty($param['expression'])) {
391
                    $access_path = '('.$access_path.')';
0 ignored issues
show
Coding Style introduced by
$access_path does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
392
                }
393
            } else {
394
                $access_path = '$'.$i;
0 ignored issues
show
Coding Style introduced by
$access_path does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
395
            }
396
397
            $bases[] = BasicObject::blank($name, $access_path);
0 ignored issues
show
Coding Style introduced by
$access_path does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
398
        }
399
400
        return $bases;
401
    }
402
403
    /**
404
     * Gets call info from the backtrace, alias, and argument count.
405
     *
406
     * Aliases must be normalized beforehand (Utils::normalizeAliases)
407
     *
408
     * @param array $aliases Call aliases as found in Kint::$aliases
409
     * @param array $trace   Backtrace
410
     * @param int   $argc    Number of arguments
411
     *
412
     * @return array[5] Call info
0 ignored issues
show
Documentation introduced by
The doc-type array[5] could not be parsed: Expected "]" at position 2, but found "5". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
413
     */
414
    public static function getCallInfo(array $aliases, array $trace, $argc)
415
    {
416
        $found = false;
417
        $callee = null;
418
        $caller = null;
419
        $miniTrace = array();
420
421
        foreach ($trace as $index => $frame) {
422
            if (Utils::traceFrameIsListed($frame, $aliases)) {
423
                $found = true;
424
                $miniTrace = array();
425
            }
426
427
            if (!Utils::traceFrameIsListed($frame, array('spl_autoload_call'))) {
428
                $miniTrace[] = $frame;
429
            }
430
        }
431
432
        if ($found) {
433
            $callee = reset($miniTrace) ?: null;
434
            $caller = next($miniTrace) ?: null;
435
        }
436
437
        foreach ($miniTrace as $index => $frame) {
438
            if (!isset($frame['file'], $frame['line'])) {
439
                unset($miniTrace[$index]);
440
            } else {
441
                unset($frame['object'], $frame['args']);
442
                $miniTrace[$index] = $frame;
443
            }
444
        }
445
446
        $miniTrace = array_values($miniTrace);
447
448
        if (!isset($callee['file'], $callee['line']) || !is_readable($callee['file'])) {
449
            return array(
450
                'params' => null,
451
                'modifiers' => array(),
452
                'callee' => $callee,
453
                'caller' => $caller,
454
                'trace' => $miniTrace,
455
            );
456
        }
457
458
        // open the file and read it up to the position where the function call expression ended
459
        if (empty($callee['class'])) {
460
            $callfunc = $callee['function'];
461
        } else {
462
            $callfunc = array($callee['class'], $callee['function']);
463
        }
464
465
        $calls = CallFinder::getFunctionCalls(
466
            file_get_contents($callee['file']),
467
            $callee['line'],
468
            $callfunc
469
        );
470
471
        $return = array(
472
            'params' => null,
473
            'modifiers' => array(),
474
            'callee' => $callee,
475
            'caller' => $caller,
476
            'trace' => $miniTrace,
477
        );
478
479
        foreach ($calls as $call) {
480
            $is_unpack = false;
0 ignored issues
show
Coding Style introduced by
$is_unpack does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
481
482
            // Handle argument unpacking as a last resort
483
            if (KINT_PHP56) {
484
                foreach ($call['parameters'] as $i => &$param) {
485
                    if (strpos($param['name'], '...') === 0) {
486
                        if ($i === count($call['parameters']) - 1) {
487
                            for ($j = 1; $j + $i < $argc; ++$j) {
488
                                $call['parameters'][] = array(
489
                                    'name' => 'array_values('.substr($param['name'], 3).')['.$j.']',
490
                                    'path' => 'array_values('.substr($param['path'], 3).')['.$j.']',
491
                                    'expression' => false,
492
                                );
493
                            }
494
495
                            $param['name'] = 'reset('.substr($param['name'], 3).')';
496
                            $param['path'] = 'reset('.substr($param['path'], 3).')';
497
                            $param['expression'] = false;
498
                        } else {
499
                            $call['parameters'] = array_slice($call['parameters'], 0, $i);
500
                        }
501
502
                        $is_unpack = true;
0 ignored issues
show
Coding Style introduced by
$is_unpack does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
503
                        break;
504
                    }
505
                }
506
            }
507
508
            if ($is_unpack || count($call['parameters']) === $argc) {
0 ignored issues
show
Coding Style introduced by
$is_unpack does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
509
                if ($return['params'] === null) {
510
                    $return = array(
511
                        'params' => $call['parameters'],
512
                        'modifiers' => $call['modifiers'],
513
                        'callee' => $callee,
514
                        'caller' => $caller,
515
                        'trace' => $miniTrace,
516
                    );
517
                } else {
518
                    // If we have multiple calls on the same line with the same amount of arguments,
519
                    // we can't be sure which it is so just return null and let them figure it out
520
                    return array(
521
                        'params' => null,
522
                        'modifiers' => array(),
523
                        'callee' => $callee,
524
                        'caller' => $caller,
525
                        'trace' => $miniTrace,
526
                    );
527
                }
528
            }
529
        }
530
531
        return $return;
532
    }
533
534
    /**
535
     * Dumps a backtrace.
536
     *
537
     * Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true))
538
     *
539
     * @return string|int
540
     */
541
    public static function trace()
542
    {
543
        if (!self::$enabled_mode) {
544
            return 0;
545
        }
546
547
        Utils::normalizeAliases(self::$aliases);
548
549
        $args = func_get_args();
550
551
        $call_info = self::getCallInfo(self::$aliases, debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), count($args));
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
552
553
        $statics = self::getStatics();
554
555
        if (in_array('~', $call_info['modifiers'])) {
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
556
            $statics['enabled_mode'] = self::MODE_TEXT;
557
        }
558
559
        $kintstance = self::createFromStatics($statics);
560
561
        if (!$kintstance) {
562
            return 0;
563
        }
564
565
        if (in_array('-', $call_info['modifiers'])) {
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
566
            while (ob_get_level()) {
567
                ob_end_clean();
568
            }
569
        }
570
571
        $kintstance->setStatesFromCallInfo($call_info);
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
572
573
        $trimmed_trace = array();
0 ignored issues
show
Coding Style introduced by
$trimmed_trace does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
574
        $trace = debug_backtrace(true);
575
576
        foreach ($trace as $frame) {
577
            if (Utils::traceFrameIsListed($frame, self::$aliases)) {
578
                $trimmed_trace = array();
0 ignored issues
show
Coding Style introduced by
$trimmed_trace does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
579
            }
580
581
            $trimmed_trace[] = $frame;
0 ignored issues
show
Coding Style introduced by
$trimmed_trace does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
582
        }
583
584
        $output = $kintstance->dumpAll(
585
            array($trimmed_trace),
0 ignored issues
show
Coding Style introduced by
$trimmed_trace does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
586
            array(BasicObject::blank('Kint\\Kint::trace()', 'debug_backtrace(true)'))
587
        );
588
589 View Code Duplication
        if (self::$return || in_array('@', $call_info['modifiers'])) {
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
590
            return $output;
591
        } else {
592
            echo $output;
593
594
            return 0;
595
        }
596
    }
597
598
    /**
599
     * Dumps some data.
600
     *
601
     * Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true))
602
     *
603
     * @return string|int
604
     */
605
    public static function dump()
606
    {
607
        if (!self::$enabled_mode) {
608
            return 0;
609
        }
610
611
        Utils::normalizeAliases(self::$aliases);
612
613
        $args = func_get_args();
614
615
        $call_info = self::getCallInfo(self::$aliases, debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), count($args));
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
616
617
        $statics = self::getStatics();
618
619
        if (in_array('~', $call_info['modifiers'])) {
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
620
            $statics['enabled_mode'] = self::MODE_TEXT;
621
        }
622
623
        $kintstance = self::createFromStatics($statics);
624
625
        if (!$kintstance) {
626
            return 0;
627
        }
628
629
        if (in_array('-', $call_info['modifiers'])) {
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
630
            while (ob_get_level()) {
631
                ob_end_clean();
632
            }
633
        }
634
635
        $kintstance->setStatesFromCallInfo($call_info);
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
636
637
        // If the call is Kint::dump(1) then dump a backtrace instead
638
        if ($args === array(1) && (!isset($call_info['params'][0]['name']) || $call_info['params'][0]['name'] === '1')) {
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
639
            $args = debug_backtrace(true);
640
            $trace = array();
641
642
            foreach ($args as $index => $frame) {
643
                if (Utils::traceFrameIsListed($frame, self::$aliases)) {
644
                    $trace = array();
645
                }
646
647
                $trace[] = $frame;
648
            }
649
650
            $tracename = $call_info['callee']['function'].'(1)';
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
651
            if (isset($call_info['callee']['class'], $call_info['callee']['type'])) {
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
652
                $tracename = $call_info['callee']['class'].$call_info['callee']['type'].$tracename;
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
653
            }
654
            $tracebase = BasicObject::blank($tracename, 'debug_backtrace(true)');
655
656
            $output = $kintstance->dumpAll(array($trace), array($tracebase));
657
        } else {
658
            $bases = self::getBasesFromParamInfo(
659
                isset($call_info['params']) ? $call_info['params'] : array(),
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
660
                count($args)
661
            );
662
            $output = $kintstance->dumpAll($args, $bases);
663
        }
664
665 View Code Duplication
        if (self::$return || in_array('@', $call_info['modifiers'])) {
0 ignored issues
show
Coding Style introduced by
$call_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
666
            return $output;
667
        } else {
668
            echo $output;
669
670
            return 0;
671
        }
672
    }
673
674
    /**
675
     * generic path display callback, can be configured in app_root_dirs; purpose is
676
     * to show relevant path info and hide as much of the path as possible.
677
     *
678
     * @param string $file
679
     *
680
     * @return string
681
     */
682
    public static function shortenPath($file)
683
    {
684
        $file = array_values(array_filter(explode('/', str_replace('\\', '/', $file)), 'strlen'));
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $file. This often makes code more readable.
Loading history...
685
686
        $longest_match = 0;
0 ignored issues
show
Coding Style introduced by
$longest_match does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
687
        $match = '/';
688
689
        foreach (self::$app_root_dirs as $path => $alias) {
690
            if (empty($path)) {
691
                continue;
692
            }
693
694
            $path = array_values(array_filter(explode('/', str_replace('\\', '/', $path)), 'strlen'));
695
696
            if (array_slice($file, 0, count($path)) === $path && count($path) > $longest_match) {
0 ignored issues
show
Coding Style introduced by
$longest_match does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
697
                $longest_match = count($path);
0 ignored issues
show
Coding Style introduced by
$longest_match does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
698
                $match = $alias;
699
            }
700
        }
701
702
        if ($longest_match) {
0 ignored issues
show
Coding Style introduced by
$longest_match does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
703
            $file = array_merge(array($match), array_slice($file, $longest_match));
0 ignored issues
show
Coding Style introduced by
$longest_match does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
Coding Style introduced by
Consider using a different name than the parameter $file. This often makes code more readable.
Loading history...
704
705
            return implode('/', $file);
706
        } else {
707
            // fallback to find common path with Kint dir
708
            $kint = array_values(array_filter(explode('/', str_replace('\\', '/', KINT_DIR)), 'strlen'));
709
710
            foreach ($file as $i => $part) {
711
                if (!isset($kint[$i]) || $kint[$i] !== $part) {
712
                    return ($i ? '.../' : '/').implode('/', array_slice($file, $i));
713
                }
714
            }
715
716
            return '/'.implode('/', $file);
717
        }
718
    }
719
720
    public static function getIdeLink($file, $line)
721
    {
722
        return str_replace(array('%f', '%l'), array($file, $line), self::$file_link_format);
723
    }
724
}
725