Test Failed
Push — master ( b17eba...69b436 )
by Kirill
06:37
created

Collection   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 4
dl 0
loc 111
ccs 0
cts 54
cp 0
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 9 2
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
     * @var BaseCollection
28
     */
29
    private $inner;
30
31
    /**
32
     * Collection constructor.
33
     * @param array|iterable $elements
34
     */
35
    public function __construct($elements = [])
36
    {
37
        $this->inner = BaseCollection::wrap($elements);
38
39
        parent::__construct($this->inner->toArray());
40
41
        $this->exportProxies();
42
    }
43
44
    /**
45
     * @return void
46
     */
47
    private function exportProxies(): void
48
    {
49
        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...
50
            $class    = new \ReflectionClass($this->inner);
51
            $property = $class->getProperty('proxies');
52
            $property->setAccessible(true);
53
54
            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...
55
        }
56
    }
57
58
    /**
59
     * @param string $name
60
     * @param array $arguments
61
     * @return mixed
62
     * @throws \BadMethodCallException
63
     */
64
    public static function __callStatic(string $name, array $arguments = [])
65
    {
66
        if (\method_exists(BaseCollection::class, $name)) {
67
            $result = BaseCollection::$name(...$arguments);
68
69
            if ($result instanceof BaseCollection) {
70
                return static::wrap($result);
71
            }
72
73
            return $result;
74
        }
75
76
        $error = \sprintf('Call to undefined method %s::%s', static::class, $name);
77
        throw new \BadMethodCallException($error);
78
    }
79
80
    /**
81
     * Wrap the given value in a collection if applicable.
82
     *
83
     * @param mixed $value
84
     * @return static
85
     */
86
    public static function wrap($value): self
87
    {
88
        switch (true) {
89
            case $value instanceof self:
90
                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...
91
92
            case $value instanceof BaseCollection:
93
                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...
94
95
            default:
96
                return new static(Arr::wrap($value));
97
        }
98
    }
99
100
    /**
101
     * @param string $name
102
     * @param array $arguments
103
     * @return mixed
104
     * @throws \BadMethodCallException
105
     */
106
    public function __call(string $name, array $arguments = [])
107
    {
108
        if (\method_exists($this->inner, $name)) {
109
            return $this->inner->$name(...$arguments);
110
        }
111
112
        $error = \sprintf('Call to undefined method %s::%s', static::class, $name);
113
        throw new \BadMethodCallException($error);
114
    }
115
116
    /**
117
     * @param string $key
118
     * @return HigherOrderCollectionProxy
119
     * @throws \InvalidArgumentException
120
     */
121
    public function __get(string $key): HigherOrderCollectionProxy
122
    {
123
        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...
124
            $error = "Property [{$key}] does not exist on this collection instance.";
125
            throw new \InvalidArgumentException($error);
126
        }
127
128
        return new HigherOrderCollectionProxy($this, $key);
129
    }
130
}
131