Passed
Pull Request — master (#42)
by Raed
10:11
created

CallbackRegistrar::parseCallbacks()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
namespace LaraCrafts\GeoRoutes;
4
5
use Exception;
6
use Illuminate\Support\Str;
7
use InvalidArgumentException;
8
use ReflectionClass;
9
use ReflectionMethod;
10
11
class CallbackRegistrar
12
{
13
    /**
14
     * The callbacks' proxies.
15
     *
16
     * @var array
17
     */
18
    protected $proxies;
19
20
    /**
21
     * The default callback and its arguments.
22
     *
23
     * @var array
24
     */
25
    protected $default = [[Callbacks::class, 'unauthorized'], []];
26
27
    /**
28
     * Create a new CallbacksRegistrar instance.
29
     */
30 320
    public function __construct()
31
    {
32 320
        $this->proxies = [];
33 320
    }
34
35
    /**
36
     * Add a callback proxy from a given name and callable.
37
     *
38
     * @param string $name
39
     * @param callable $callback
40
     *
41
     * @return void
42
     */
43 96
    public function addCallback(string $name, callable $callback)
44
    {
45 96
        $this->proxies['or' . Str::studly($name)] = $callback;
46 96
    }
47
48
    /**
49
     * Load callbacks proxies from a given associative array.
50
     *
51
     * @param array $callbacks
52
     *
53
     * @return void
54
     */
55 192
    public function loadCallbacks(array $callbacks)
56
    {
57 192
        foreach ($callbacks as $key => $callback) {
58 80
            $this->addCallback($key, $callback);
59
        }
60 192
    }
61
62
    /**
63
     * Get or Load callbacks.
64
     *
65
     * If the callbacks parameter is present the callbacks
66
     * will be loaded, otherwise the current callbacks array
67
     * will be returned.
68
     *
69
     * @param array|null $callbacks
70
     *
71
     * @return array|null
72
     */
73 48
    public function callbacks(array $callbacks = null)
74
    {
75 48
        if ($callbacks) {
76 16
            return $this->loadCallbacks($callbacks);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->loadCallbacks($callbacks) returns the type void which is incompatible with the documented return type array|null.
Loading history...
Bug introduced by
Are you sure the usage of $this->loadCallbacks($callbacks) targeting LaraCrafts\GeoRoutes\Cal...istrar::loadCallbacks() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
77
        }
78
79 32
        return $this->proxies;
80
    }
81
82
    /**
83
     * Parse callbacks from a given class.
84
     *
85
     * This method will use reflection to loop through all of the static
86
     * methods.
87
     *
88
     * @param string $class
89
     *
90
     * @return void
91
     */
92 16
    public function parseCallbacks(string $class)
93
    {
94 16
        $reflection = new ReflectionClass($class);
95 16
        $callbacks = $reflection->getMethods(ReflectionMethod::IS_STATIC);
96
97 16
        foreach ($callbacks as $callback) {
98 16
            $this->addCallback($callback->getName(), $callback->getClosure());
99
        }
100 16
    }
101
102
    /**
103
     * Get/Set the callable for a given callback name.
104
     *
105
     * @param string $name
106
     * @param callable|null $callable
107
     *
108
     * @return mixed
109
     *
110
     * @throws \Exception
111
     */
112 16
    public function callback(string $name, callable $callable = null)
113
    {
114 16
        if (is_callable($callable)) {
115
            return $this->addCallback($name, $callable);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->addCallback($name, $callable) targeting LaraCrafts\GeoRoutes\Cal...egistrar::addCallback() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
It seems like $callable can also be of type null; however, parameter $callback of LaraCrafts\GeoRoutes\Cal...egistrar::addCallback() does only seem to accept callable, maybe add an additional type check? ( Ignorable by Annotation )

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

115
            return $this->addCallback($name, /** @scrutinizer ignore-type */ $callable);
Loading history...
116
        }
117
118 16
        if ($this->hasProxy($name)) {
119 16
            return $this->proxies[$name];
120
        }
121
122 16
        if ($this->hasCallback($name)) {
123 16
            return $this->proxies['or' . Str::ucfirst($name)];
124
        }
125
126
        throw new Exception("Undefined callback [$name]");
127
    }
128
129
    /**
130
     * Determine if a given callback exists.
131
     *
132
     * @param string $name
133
     *
134
     * @return boolean
135
     */
136 48
    public function hasCallback(string $name)
137
    {
138 48
        return array_key_exists('or' . Str::ucfirst($name), $this->proxies);
139
    }
140
141
    /**
142
     * Determine if a given proxy exists.
143
     *
144
     * @param string $proxy
145
     *
146
     * @return boolean
147
     */
148 48
    public function hasProxy(string $proxy)
149
    {
150 48
        return array_key_exists($proxy, $this->proxies);
151
    }
152
153
    /**
154
     * Set the default callback and its arguments.
155
     *
156
     * @param string|callable $callback
157
     * @param  mixed ...$arguments
158
     *
159
     * @return void
160
     */
161 112
    public function setDefault($callback, ...$arguments)
162
    {
163 112
        if (is_callable($callback)) {
164 80
            return $this->default = [$callback, $arguments];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->default = ...($callback, $arguments) returns the type array<integer,array<inte...mixed>|callable|string> which is incompatible with the documented return type void.
Loading history...
165
        }
166
        
167 32
        if (is_string($callback)) {
168 16
            return $this->default = [$this->callback($callback), $arguments];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->default = ...$callback), $arguments) returns the type array<integer,array<integer,mixed>|mixed> which is incompatible with the documented return type void.
Loading history...
169
        }
170
171 16
        throw new InvalidArgumentException(sprintf(
172 16
            "%s expects parameter 1 to be string or callable %s given",
173 16
            __FUNCTION__,
174 16
            gettype($callback)
175
        ));
176
    }
177
178
    /**
179
     * Get the default callback callable and its arguments.
180
     *
181
     * @return array
182
     */
183 16
    public function getDefault()
184
    {
185 16
        return $this->default;
186
    }
187
188
    /**
189
     * Invoke the default callback.
190
     *
191
     * @return mixed
192
     */
193 112
    public function invokeDefault()
194
    {
195 112
        return call_user_func_array(...$this->default);
196
    }
197
}
198