1
|
|
|
<?php namespace nyx\utils\traits; |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Extendable |
5
|
|
|
* |
6
|
|
|
* An Extendable object is one that can be dynamically extended with additional methods during runtime. |
7
|
|
|
* |
8
|
|
|
* If you extend the object with Closures instead of other callables, remember that you can also bind them |
9
|
|
|
* to the scope ($this) of the object you're extending, giving you easier access to it. While it is possible |
10
|
|
|
* to automatically invoke extending Closures in this scope, the decision about the scope is by design left |
11
|
|
|
* to the extension, also to provide consistency with other types of callables for which this is not possible. |
12
|
|
|
* |
13
|
|
|
* Do, however, note that this relies on the magic __call() method which introduces considerable overhead |
14
|
|
|
* for each call, especially for very simple code. If possible, extend the exhibitors of this trait casually |
15
|
|
|
* to avoid the performance hit. |
16
|
|
|
* |
17
|
|
|
* @package Nyx\Utils |
18
|
|
|
* @version 0.1.0 |
19
|
|
|
* @author Michal Chojnacki <[email protected]> |
20
|
|
|
* @copyright 2012-2016 Nyx Dev Team |
21
|
|
|
* @link http://docs.muyo.io/nyx/utils/index.html |
22
|
|
|
*/ |
23
|
|
|
trait Extendable |
24
|
|
|
{ |
25
|
|
|
/** |
26
|
|
|
* @var array The registered methods. |
27
|
|
|
*/ |
28
|
|
|
private $extensions = []; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Registers an additional method. |
32
|
|
|
* |
33
|
|
|
* @param string|array $name The name the name should be made available as or an array of |
34
|
|
|
* name => callable pairs. |
35
|
|
|
* @param callable $callable The actual code that should be called. |
36
|
|
|
* @throws \InvalidArgumentException When the first parameter is not an array and the second is not given or |
37
|
|
|
* when an array is given and its values are not callables. |
38
|
|
|
*/ |
39
|
|
|
public function extend($name, callable $callable = null) |
40
|
|
|
{ |
41
|
|
View Code Duplication |
if (!is_array($name)) { |
|
|
|
|
42
|
|
|
if (null === $callable) { |
43
|
|
|
throw new \InvalidArgumentException("A callable must be given as second parameter if the first is not an array."); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
$this->extensions[$name] = $callable; |
47
|
|
|
return; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
View Code Duplication |
foreach ($name as $method => $callable) { |
|
|
|
|
51
|
|
|
if (!is_callable($callable)) { |
52
|
|
|
throw new \InvalidArgumentException("The values of an array passed to the extend() method must be callables."); |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
$this->extensions[$method] = $callable; |
56
|
|
|
} |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Dynamically handles calls to the to the extended methods. |
61
|
|
|
* |
62
|
|
|
* @param string $method The name of the method being called. |
63
|
|
|
* @param array $parameters The parameters to call the method with. |
64
|
|
|
* @return mixed |
65
|
|
|
* @throws \BadMethodCallException When no extension method with the given name exists. |
66
|
|
|
*/ |
67
|
|
|
public function __call($method, array $parameters) |
68
|
|
|
{ |
69
|
|
|
if (isset($this->extensions[$method])) { |
70
|
|
|
return call_user_func($this->extensions[$method], ...$parameters); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
throw new \BadMethodCallException("The method [$method] does not exist."); |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
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.