Test Setup Failed
Push — test ( 3bf7a5...16e845 )
by Jonathan
03:34
created

Parser::sortObjectProperties()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 2
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Kint\Parser;
4
5
use Exception;
6
use Kint\Object\BasicObject;
7
use Kint\Object\BlobObject;
8
use Kint\Object\InstanceObject;
9
use Kint\Object\Representation\Representation;
10
use Kint\Object\ResourceObject;
11
use ReflectionObject;
12
13
class Parser
0 ignored issues
show
Coding Style introduced by
The property $caller_class 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 $depth_limit 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 $object_hashes 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 $parse_break 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...
14
{
15
    protected $caller_class = null;
0 ignored issues
show
Coding Style introduced by
$caller_class 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...
16
    protected $depth_limit = false;
0 ignored issues
show
Coding Style introduced by
$depth_limit 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...
17
    protected $marker;
18
    protected $object_hashes = array();
0 ignored issues
show
Coding Style introduced by
$object_hashes 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...
19
    protected $parse_break = false;
0 ignored issues
show
Coding Style introduced by
$parse_break 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...
20
    protected $plugins = array();
21
22
    /**
23
     * Plugin triggers.
24
     *
25
     * These are constants indicating trigger points for plugins
26
     *
27
     * BEGIN: Before normal parsing
28
     * SUCCESS: After successful parsing
29
     * RECURSION: After parsing cancelled by recursion
30
     * DEPTH_LIMIT: After parsing cancelled by depth limit
31
     * COMPLETE: SUCCESS | RECURSION | DEPTH_LIMIT
32
     *
33
     * While a plugin's getTriggers may return any of these
34
     */
35
    const TRIGGER_NONE = 0;
36
    const TRIGGER_BEGIN = 1;
37
    const TRIGGER_SUCCESS = 2;
38
    const TRIGGER_RECURSION = 4;
39
    const TRIGGER_DEPTH_LIMIT = 8;
40
    const TRIGGER_COMPLETE = 14;
41
42
    /**
43
     * @param bool|int $depth_limit Maximum depth to parse data
44
     * @param string   $caller      Caller class name
0 ignored issues
show
Documentation introduced by
Should the type for parameter $caller not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
45
     */
46
    public function __construct($depth_limit = false, $caller = null)
0 ignored issues
show
Coding Style introduced by
$depth_limit 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 Naming introduced by
The parameter $depth_limit is not named in camelCase.

This check marks parameter 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...
47
    {
48
        $this->marker = uniqid("kint\0", true);
49
50
        if ($caller) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $caller of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
51
            $this->caller_class = $caller;
52
        }
53
54
        if ($depth_limit) {
0 ignored issues
show
Coding Style introduced by
$depth_limit 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...
55
            $this->depth_limit = $depth_limit;
0 ignored issues
show
Coding Style introduced by
$depth_limit 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...
Documentation Bug introduced by
It seems like $depth_limit can also be of type integer. However, the property $depth_limit is declared as type boolean. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
56
        }
57
    }
58
59
    /**
60
     * Disables the depth limit and parses a variable.
61
     *
62
     * This should not be used unless you know what you're doing!
63
     *
64
     * @param mixed       $var The input variable
65
     * @param BasicObject $o   The base object
66
     *
67
     * @return BasicObject
68
     */
69
    public function parseDeep(&$var, BasicObject $o)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $o. 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...
70
    {
71
        $depth_limit = $this->depth_limit;
0 ignored issues
show
Coding Style introduced by
$depth_limit 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...
72
        $this->depth_limit = false;
73
74
        $out = $this->parse($var, $o);
75
76
        $this->depth_limit = $depth_limit;
0 ignored issues
show
Coding Style introduced by
$depth_limit 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...
77
78
        return $out;
79
    }
80
81
    /**
82
     * Parses a variable into a Kint object structure.
83
     *
84
     * @param mixed       $var The input variable
85
     * @param BasicObject $o   The base object
86
     *
87
     * @return BasicObject
88
     */
89
    public function parse(&$var, BasicObject $o)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $o. 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...
90
    {
91
        $o->type = strtolower(gettype($var));
92
93
        if (!$this->applyPlugins($var, $o, self::TRIGGER_BEGIN)) {
94
            return $o;
95
        }
96
97
        switch ($o->type) {
98
            case 'array':
99
                return $this->parseArray($var, $o);
100
            case 'boolean':
101
            case 'double':
102
            case 'integer':
103
            case 'null':
104
                return $this->parseGeneric($var, $o);
105
            case 'object':
106
                return $this->parseObject($var, $o);
107
            case 'resource':
108
                return $this->parseResource($var, $o);
109
            case 'string':
110
                return $this->parseString($var, $o);
111
            default:
112
                return $this->parseUnknown($var, $o);
113
        }
114
    }
115
116
    private function parseGeneric(&$var, BasicObject $o)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $o. 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...
117
    {
118
        $rep = new Representation('Contents');
119
        $rep->contents = $var;
120
        $rep->implicit_label = true;
121
        $o->addRepresentation($rep);
122
        $o->value = $rep;
123
124
        $this->applyPlugins($var, $o, self::TRIGGER_SUCCESS);
125
126
        return $o;
127
    }
128
129
    /**
130
     * Parses a string into a Kint BlobObject structure.
131
     *
132
     * @param string      $var The input variable
133
     * @param BasicObject $o   The base object
134
     *
135
     * @return BlobObject
136
     */
137
    private function parseString(&$var, BasicObject $o)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $o. 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...
138
    {
139
        $string = $o->transplant(new BlobObject());
140
        $string->encoding = BlobObject::detectEncoding($var);
0 ignored issues
show
Bug introduced by
The property encoding does not seem to exist in Kint\Object\BasicObject.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
141
        $string->size = BlobObject::strlen($var, $string->encoding);
142
143
        $rep = new Representation('Contents');
144
        $rep->contents = $var;
0 ignored issues
show
Documentation Bug introduced by
It seems like $var of type string is incompatible with the declared type array of property $contents.

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...
145
        $rep->implicit_label = true;
146
147
        $string->addRepresentation($rep);
148
        $string->value = $rep;
149
150
        $this->applyPlugins($var, $string, self::TRIGGER_SUCCESS);
151
152
        return $string;
153
    }
154
155
    /**
156
     * Parses an array into a Kint object structure.
157
     *
158
     * @param array       $var The input variable
159
     * @param BasicObject $o   The base object
160
     *
161
     * @return BasicObject
162
     */
163
    private function parseArray(array &$var, BasicObject $o)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $o. 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...
164
    {
165
        $array = $o->transplant(new BasicObject());
166
        $array->size = count($var);
167
168 View Code Duplication
        if (isset($var[$this->marker])) {
0 ignored issues
show
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...
169
            --$array->size;
170
            $array->hints[] = 'recursion';
171
172
            $this->applyPlugins($var, $array, self::TRIGGER_RECURSION);
173
174
            return $array;
175
        }
176
177
        $rep = new Representation('Contents');
178
        $rep->implicit_label = true;
179
        $array->addRepresentation($rep);
180
        $array->value = $rep;
181
182
        if ($array->size) {
183 View Code Duplication
            if ($this->depth_limit && $o->depth >= $this->depth_limit) {
0 ignored issues
show
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...
184
                $array->hints[] = 'depth_limit';
185
186
                $this->applyPlugins($var, $array, self::TRIGGER_DEPTH_LIMIT);
187
188
                return $array;
189
            }
190
191
            $copy = array_values($var);
192
193
            // It's really really hard to access numeric string keys in arrays,
194
            // and it's really really hard to access integer properties in
195
            // objects, so we just use array_values and index by counter to get
196
            // at it reliably for reference testing. This also affects access
197
            // paths since it's pretty much impossible to access these things
198
            // without complicated stuff you should never need to do.
199
            $i = 0;
200
201
            // Set the marker for recursion
202
            $var[$this->marker] = $array->depth;
203
204
            foreach ($var as $key => &$val) {
205
                if ($key === $this->marker) {
206
                    continue;
207
                }
208
209
                $child = new BasicObject();
210
                $child->name = $key;
211
                $child->depth = $array->depth + 1;
212
                $child->access = BasicObject::ACCESS_NONE;
213
                $child->operator = BasicObject::OPERATOR_ARRAY;
214
215
                if ($array->access_path !== null) {
216
                    if (is_string($key) && (string) (int) $key === $key) {
217
                        $child->access_path = 'array_values('.$array->access_path.')['.$i.']';
218
                    } else {
219
                        $child->access_path = $array->access_path.'['.var_export($key, true).']';
220
                    }
221
                }
222
223
                $stash = $val;
224
                $copy[$i] = $this->marker;
225
                if ($val === $this->marker) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $val (integer) and $this->marker (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
226
                    $child->reference = true;
227
                    $val = $stash;
228
                }
229
230
                $rep->contents[] = $this->parse($val, $child);
231
                ++$i;
232
            }
233
234
            $this->applyPlugins($var, $array, self::TRIGGER_SUCCESS);
235
            unset($var[$this->marker]);
236
237
            return $array;
238
        } else {
239
            $this->applyPlugins($var, $array, self::TRIGGER_SUCCESS);
240
241
            return $array;
242
        }
243
    }
244
245
    /**
246
     * Parses an object into a Kint InstanceObject structure.
247
     *
248
     * @param object      $var The input variable
249
     * @param BasicObject $o   The base object
250
     *
251
     * @return InstanceObject
252
     */
253
    private function parseObject(&$var, BasicObject $o)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $o. 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...
254
    {
255
        $hash = spl_object_hash($var);
256
        $values = (array) $var;
257
258
        $object = $o->transplant(new InstanceObject());
259
        $object->classname = get_class($var);
0 ignored issues
show
Bug introduced by
The property classname does not seem to exist in Kint\Object\BasicObject.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
260
        $object->hash = $hash;
0 ignored issues
show
Bug introduced by
The property hash does not seem to exist in Kint\Object\BasicObject.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
261
        $object->size = count($values);
262
263 View Code Duplication
        if (isset($this->object_hashes[$hash])) {
0 ignored issues
show
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...
264
            $object->hints[] = 'recursion';
265
266
            $this->applyPlugins($var, $object, self::TRIGGER_RECURSION);
267
268
            return $object;
269
        }
270
271
        $this->object_hashes[$hash] = $object;
272
273 View Code Duplication
        if ($this->depth_limit && $o->depth >= $this->depth_limit) {
0 ignored issues
show
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...
274
            $object->hints[] = 'depth_limit';
275
276
            $this->applyPlugins($var, $object, self::TRIGGER_DEPTH_LIMIT);
277
            unset($this->object_hashes[$hash]);
278
279
            return $object;
280
        }
281
282
        $reflector = new ReflectionObject($var);
283
284
        if ($reflector->isUserDefined()) {
285
            $object->filename = $reflector->getFileName();
0 ignored issues
show
Bug introduced by
The property filename does not seem to exist in Kint\Object\BasicObject.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
286
            $object->startline = $reflector->getStartLine();
0 ignored issues
show
Bug introduced by
The property startline does not seem to exist in Kint\Object\BasicObject.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
287
        }
288
289
        $rep = new Representation('Properties');
290
291
        $copy = array_values($values);
292
293
        $i = 0;
294
295
        // Reflection will not show parent classes private properties, and if a
296
        // property was unset it will happly trigger a notice looking for it.
297
        foreach ($values as $key => &$val) {
298
            // Casting object to array:
299
            // private properties show in the form "\0$owner_class_name\0$property_name";
300
            // protected properties show in the form "\0*\0$property_name";
301
            // public properties show in the form "$property_name";
302
            // http://www.php.net/manual/en/language.types.array.php#language.types.array.casting
303
304
            $child = new BasicObject();
305
            $child->depth = $object->depth + 1;
306
            $child->owner_class = $object->classname;
307
            $child->operator = BasicObject::OPERATOR_OBJECT;
308
            $child->access = BasicObject::ACCESS_PUBLIC;
309
310
            $split_key = explode("\0", $key, 3);
0 ignored issues
show
Coding Style introduced by
$split_key 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...
311
312
            if (count($split_key) === 3 && $split_key[0] === '') {
0 ignored issues
show
Coding Style introduced by
$split_key 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...
313
                $child->name = $split_key[2];
0 ignored issues
show
Coding Style introduced by
$split_key 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...
314
                if ($split_key[1] === '*') {
0 ignored issues
show
Coding Style introduced by
$split_key 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...
315
                    $child->access = BasicObject::ACCESS_PROTECTED;
316
                } else {
317
                    $child->access = BasicObject::ACCESS_PRIVATE;
318
                    $child->owner_class = $split_key[1];
0 ignored issues
show
Coding Style introduced by
$split_key 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...
319
                }
320
            } elseif (KINT_PHP72) {
321
                $child->name = (string) $key; // @codeCoverageIgnore
322
            } else {
323
                $child->name = $key;
324
            }
325
326
            if ($this->childHasPath($object, $child)) {
0 ignored issues
show
Compatibility introduced by
$object of type object<Kint\Object\BasicObject> is not a sub-type of object<Kint\Object\InstanceObject>. It seems like you assume a child class of the class Kint\Object\BasicObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
327
                $child->access_path = $object->access_path;
328
329
                if (!KINT_PHP72 && is_int($child->name)) {
330
                    $child->access_path = 'array_values((array) '.$child->access_path.')['.$i.']';
331
                } elseif (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $child->name)) {
332
                    $child->access_path .= '->'.$child->name;
333
                } else {
334
                    $child->access_path .= '->{'.var_export((string) $child->name, true).'}';
335
                }
336
            }
337
338
            $stash = $val;
339
            $copy[$i] = $this->marker;
340
            if ($val === $this->marker) {
341
                $child->reference = true;
342
                $val = $stash;
343
            }
344
345
            $rep->contents[] = $this->parse($val, $child);
346
            ++$i;
347
        }
348
349
        $object->addRepresentation($rep);
350
        $object->value = $rep;
351
        $this->applyPlugins($var, $object, self::TRIGGER_SUCCESS);
352
        unset($this->object_hashes[$hash]);
353
354
        return $object;
355
    }
356
357
    /**
358
     * Parses a resource into a Kint ResourceObject structure.
359
     *
360
     * @param resource    $var The input variable
361
     * @param BasicObject $o   The base object
362
     *
363
     * @return ResourceObject
364
     */
365
    private function parseResource(&$var, BasicObject $o)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $o. 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...
366
    {
367
        $resource = $o->transplant(new ResourceObject());
368
        $resource->resource_type = get_resource_type($var);
0 ignored issues
show
Bug introduced by
The property resource_type does not seem to exist in Kint\Object\BasicObject.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
369
370
        $this->applyPlugins($var, $resource, self::TRIGGER_SUCCESS);
371
372
        return $resource;
373
    }
374
375
    /**
376
     * Parses an unknown into a Kint object structure.
377
     *
378
     * @param mixed       $var The input variable
379
     * @param BasicObject $o   The base object
380
     *
381
     * @return BasicObject
382
     */
383
    private function parseUnknown(&$var, BasicObject $o)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $o. 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...
384
    {
385
        $o->type = 'unknown';
386
        $this->applyPlugins($var, $o, self::TRIGGER_SUCCESS);
387
388
        return $o;
389
    }
390
391
    public function addPlugin(Plugin $p)
0 ignored issues
show
Coding Style introduced by
function addPlugin() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

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...
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...
392
    {
393
        if (!$types = $p->getTypes()) {
394
            return false;
395
        }
396
397
        if (!$triggers = $p->getTriggers()) {
398
            return false;
399
        }
400
401
        $p->setParser($this);
402
403
        foreach ($types as $type) {
404
            if (!isset($this->plugins[$type])) {
405
                $this->plugins[$type] = array(
406
                    self::TRIGGER_BEGIN => array(),
407
                    self::TRIGGER_SUCCESS => array(),
408
                    self::TRIGGER_RECURSION => array(),
409
                    self::TRIGGER_DEPTH_LIMIT => array(),
410
                );
411
            }
412
413
            foreach ($this->plugins[$type] as $trigger => &$pool) {
414
                if ($triggers & $trigger) {
415
                    $pool[] = $p;
416
                }
417
            }
418
        }
419
420
        return true;
421
    }
422
423
    public function clearPlugins()
424
    {
425
        $this->plugins = array();
426
    }
427
428
    /**
429
     * Applies plugins for an object type.
430
     *
431
     * @param mixed       $var     variable
432
     * @param BasicObject $o       Kint object parsed so far
433
     * @param int         $trigger The trigger to check for the plugins
434
     *
435
     * @return bool Continue parsing
436
     */
437
    private function applyPlugins(&$var, BasicObject &$o, $trigger)
0 ignored issues
show
Coding Style introduced by
function applyPlugins() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

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...
Comprehensibility introduced by
Avoid variables with short names like $o. 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...
438
    {
439
        $break_stash = $this->parse_break;
0 ignored issues
show
Coding Style introduced by
$break_stash 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...
440
        $this->parse_break = false;
441
442
        $plugins = array();
443
444
        if (isset($this->plugins[$o->type][$trigger])) {
445
            $plugins = $this->plugins[$o->type][$trigger];
446
        }
447
448
        foreach ($plugins as $plugin) {
449
            try {
450
                $plugin->parse($var, $o, $trigger);
451
            } catch (Exception $e) {
452
                trigger_error(
453
                    'An exception ('.get_class($e).') was thrown in '.$e->getFile().' on line '.$e->getLine().' while executing Kint Parser Plugin "'.get_class($plugin).'". Error message: '.$e->getMessage(),
454
                    E_USER_WARNING
455
                );
456
            }
457
458
            if ($this->parse_break) {
459
                $this->parse_break = $break_stash;
0 ignored issues
show
Coding Style introduced by
$break_stash 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...
460
461
                return false;
462
            }
463
        }
464
465
        $this->parse_break = $break_stash;
0 ignored issues
show
Coding Style introduced by
$break_stash 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...
466
467
        return true;
468
    }
469
470
    public function haltParse()
471
    {
472
        $this->parse_break = true;
473
    }
474
475
    public function childHasPath(InstanceObject $parent, BasicObject $child)
0 ignored issues
show
Coding Style introduced by
function childHasPath() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

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...
476
    {
477
        if ($parent->type === 'object' && ($parent->access_path !== null || $child->static || $child->const)) {
478
            if ($child->access === BasicObject::ACCESS_PUBLIC) {
479
                return true;
480
            } elseif ($child->access === BasicObject::ACCESS_PRIVATE && $this->caller_class) {
481
                if ($this->caller_class === $child->owner_class) {
482
                    return true;
483
                }
484
            } elseif ($child->access === BasicObject::ACCESS_PROTECTED && $this->caller_class) {
485
                if ($this->caller_class === $child->owner_class) {
486
                    return true;
487
                }
488
                if (is_subclass_of($this->caller_class, $child->owner_class)) {
489
                    return true;
490
                }
491
                if (is_subclass_of($child->owner_class, $this->caller_class)) {
492
                    return true;
493
                }
494
            }
495
        }
496
497
        return false;
498
    }
499
500
    /**
501
     * Returns an array without the recursion marker in it.
502
     *
503
     * DO NOT pass an array that has had it's marker removed back
504
     * into the parser, it will result in an extra recursion
505
     *
506
     * @param array $array Array potentially containing a recursion marker
507
     *
508
     * @return array Array with recursion marker removed
509
     */
510
    public function getCleanArray(array $array)
511
    {
512
        unset($array[$this->marker]);
513
514
        return $array;
515
    }
516
517
    public function getCallerClass()
518
    {
519
        return $this->caller_class;
520
    }
521
522
    public function getDepthLimit()
0 ignored issues
show
Coding Style introduced by
function getDepthLimit() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

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...
523
    {
524
        return $this->depth_limit;
525
    }
526
}
527