Completed
Pull Request — master (#42)
by Raed
15:58
created

CallbackRegistrar::setDefault()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 14
ccs 0
cts 0
cp 0
rs 10
cc 3
nc 3
nop 2
crap 12
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 128
     *
23
     * @var array
24 128
     */
25 128
    protected $default = [[Callbacks::class, 'unauthorized'], []];
26
27
    /**
28
     * Create a new CallbacksRegistrar instance.
29
     */
30
    public function __construct()
31
    {
32
        $this->proxies = [];
33
    }
34
35 80
    /**
36
     * Add a callback proxy from a given name and callable.
37 80
     *
38 80
     * @param string $name
39
     * @param callable $callback
40
     *
41
     * @return void
42
     */
43
    public function addCallback(string $name, callable $callback)
44
    {
45
        $this->proxies['or' . Str::studly($name)] = $callback;
46
    }
47 80
48
    /**
49 80
     * Load callbacks proxies from a given associative array.
50 64
     *
51
     * @param array $callbacks
52 80
     *
53
     * @return void
54
     */
55
    public function loadCallbacks(array $callbacks)
56
    {
57
        foreach ($callbacks as $key => $callback) {
58
            $this->addCallback($key, $callback);
59
        }
60
    }
61
62
    /**
63
     * Get or Load callbacks.
64
     *
65 48
     * If the callbacks parameter is present the callbacks
66
     * will be loaded, otherwise the current callbacks array
67 48
     * will be returned.
68 16
     *
69
     * @param array|null $callbacks
70
     *
71 32
     * @return array|null
72
     */
73
    public function callbacks(array $callbacks = null)
74
    {
75
        if ($callbacks) {
76
            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
        return $this->proxies;
80
    }
81
82
    /**
83
     * Parse callbacks from a given class.
84 16
     *
85
     * This method will use reflection to loop through all of the static
86 16
     * methods.
87 16
     *
88
     * @param string $class
89 16
     *
90 16
     * @return void
91
     */
92 16
    public function parseCallbacks(string $class)
93
    {
94
        $reflection = new ReflectionClass($class);
95
        $callbacks = $reflection->getMethods(ReflectionMethod::IS_STATIC);
96
97
        foreach ($callbacks as $callback) {
98
            $this->addCallback($callback->getName(), $callback->getClosure());
99
        }
100
    }
101
102
    /**
103
     * Get/Set the callable for a given callback name.
104 16
     *
105
     * @param string $name
106 16
     * @param callable|null $callable
107
     *
108
     * @return mixed
109
     *
110 16
     * @throws \Exception
111 16
     */
112
    public function callback(string $name, callable $callable = null)
113
    {
114 16
        if (is_callable($callable)) {
115 16
            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
        if ($this->hasProxy($name)) {
119
            return $this->proxies[$name];
120
        }
121
122
        if ($this->hasCallback($name)) {
123
            return $this->proxies['or' . Str::ucfirst($name)];
124
        }
125
126
        throw new Exception("Undefined callback [$name]");
127
    }
128 48
129
    /**
130 48
     * Determine if a given callback exists.
131
     *
132
     * @param string $name
133
     *
134
     * @return boolean
135
     */
136
    public function hasCallback(string $name)
137
    {
138
        return array_key_exists('or' . Str::ucfirst($name), $this->proxies);
139
    }
140 48
141
    /**
142 48
     * Determine if a given proxy exists.
143
     *
144
     * @param string $proxy
145
     *
146
     * @return boolean
147
     */
148
    public function hasProxy(string $proxy)
149
    {
150
        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
    public function setDefault($callback, ...$arguments)
162
    {
163
        if (is_callable($callback)) {
164
            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
        if (is_string($callback)) {
168
            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
        throw new InvalidArgumentException(sprintf(
172
            "%s expects parameter 1 to be string or callable %s given",
173
            __FUNCTION__,
174
            gettype($callback)
175
        ));
176
    }
177
178
    /**
179
     * Get the default callback callable and its arguments.
180
     *
181
     * @return array
182
     */
183
    public function getDefault()
184
    {
185
        return $this->default;
186
    }
187
188
    /**
189
     * Invoke the default callback.
190
     *
191
     * @return mixed
192
     */
193
    public function invokeDefaultCallback()
194
    {
195
        return call_user_func_array(...$this->default);
196
    }
197
}
198