Test Failed
Push — master ( 1c5165...b7ef6a )
by Kirill
03:37
created

Collection   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 41.03%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 4
dl 0
loc 118
ccs 16
cts 39
cp 0.4103
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A exportProxies() 0 10 2
A __callStatic() 0 15 3
A wrap() 0 13 3
A __call() 0 15 3
A __get() 0 9 2
1
<?php
2
/**
3
 * This file is part of Hydrogen package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace RDS\Hydrogen\Collection;
11
12
use Doctrine\Common\Collections\ArrayCollection;
13
use Illuminate\Support\Arr;
14
use Illuminate\Support\Collection as BaseCollection;
15
16
/**
17
 * Class Collection
18
 * @mixin BaseCollection
19
 */
20
class Collection extends ArrayCollection
21
{
22
    /**
23
     * @var array|string[]
24
     */
25
    private static $proxies;
26
27
    /**
28
     * @var BaseCollection
29
     */
30
    private $inner;
31
32
    /**
33
     * Collection constructor.
34
     * @param array|iterable $elements
35
     */
36 2
    public function __construct($elements = [])
37
    {
38 2
        $this->inner = BaseCollection::wrap($elements);
39
40 2
        parent::__construct($this->inner->toArray());
41
42 2
        $this->exportProxies();
43 2
    }
44
45
    /**
46
     * @return void
47
     */
48 2
    private function exportProxies(): void
49
    {
50 2
        if (static::$proxies === null) {
0 ignored issues
show
Bug introduced by
Since $proxies is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $proxies to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
51 1
            $class    = new \ReflectionClass($this->inner);
52 1
            $property = $class->getProperty('proxies');
53 1
            $property->setAccessible(true);
54
55 1
            static::$proxies = $property->getValue();
0 ignored issues
show
Bug introduced by
Since $proxies is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $proxies to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
56
        }
57 2
    }
58
59
    /**
60
     * @param string $name
61
     * @param array $arguments
62
     * @return mixed
63
     * @throws \BadMethodCallException
64
     */
65
    public static function __callStatic(string $name, array $arguments = [])
66
    {
67
        if (\method_exists(BaseCollection::class, $name)) {
68
            $result = BaseCollection::$name(...$arguments);
69
70
            if ($result instanceof BaseCollection) {
71
                return new static($result->toArray());
72
            }
73
74
            return $result;
75
        }
76
77
        $error = \sprintf('Call to undefined method %s::%s', static::class, $name);
78
        throw new \BadMethodCallException($error);
79
    }
80
81
    /**
82
     * Wrap the given value in a collection if applicable.
83
     *
84
     * @param mixed $value
85
     * @return static
86
     */
87 2
    public static function wrap($value): self
88
    {
89
        switch (true) {
90 2
            case $value instanceof self:
91
                return new static($value);
0 ignored issues
show
Documentation introduced by
$value is of type object<RDS\Hydrogen\Collection\Collection>, but the function expects a array|object<RDS\Hydrogen\Collection\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
92
93 2
            case $value instanceof BaseCollection:
94
                return new static($value);
0 ignored issues
show
Documentation introduced by
$value is of type object<Illuminate\Support\Collection>, but the function expects a array|object<RDS\Hydrogen\Collection\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
95
96
            default:
97 2
                return new static(Arr::wrap($value));
98
        }
99
    }
100
101
    /**
102
     * @param string $name
103
     * @param array $arguments
104
     * @return mixed
105
     * @throws \BadMethodCallException
106
     */
107
    public function __call(string $name, array $arguments = [])
108
    {
109
        if (\method_exists($this->inner, $name)) {
110
            $result = $this->inner->$name(...$arguments);
111
112
            if ($result instanceof BaseCollection) {
113
                return new static($result->toArray());
114
            }
115
116
            return $result;
117
        }
118
119
        $error = \sprintf('Call to undefined method %s::%s', static::class, $name);
120
        throw new \BadMethodCallException($error);
121
    }
122
123
    /**
124
     * @param string $key
125
     * @return HigherOrderCollectionProxy
126
     * @throws \InvalidArgumentException
127
     */
128
    public function __get(string $key): HigherOrderCollectionProxy
129
    {
130
        if (! \in_array($key, static::$proxies, true)) {
0 ignored issues
show
Bug introduced by
Since $proxies is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $proxies to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
131
            $error = "Property [{$key}] does not exist on this collection instance.";
132
            throw new \InvalidArgumentException($error);
133
        }
134
135
        return new HigherOrderCollectionProxy($this, $key);
136
    }
137
}
138