Passed
Push — master ( f7f7f6...4e1c41 )
by Atanas
02:10
created

HasAliasesTrait::setAlias()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 7
rs 10
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * @package   WPEmerge
4
 * @author    Atanas Angelov <[email protected]>
5
 * @copyright 2017-2019 Atanas Angelov
6
 * @license   https://www.gnu.org/licenses/gpl-2.0.html GPL-2.0
7
 * @link      https://wpemerge.com/
8
 */
9
10
namespace WPEmerge\Application;
11
12
use Closure;
13
use BadMethodCallException;
14
use WPEmerge\Support\Arr;
15
16
/**
17
 * Add methods to classes at runtime.
18
 * Loosely based on spatie/macroable.
19
 *
20
 * @codeCoverageIgnore
21
 */
22
trait HasAliasesTrait {
23
	/**
24
	 * Registered aliases.
25
	 *
26
	 * @var array<string, array>
27
	 */
28
	protected $aliases = [];
29
30
	/**
31
	 * Get whether an alias is registered.
32
	 *
33
	 * @param  string  $alias
34
	 * @return boolean
35
	 */
36
	public function hasAlias( $alias ) {
37
		return isset( $this->aliases[ $alias ] );
38
	}
39
40
	/**
41
	 * Get a registered alias.
42
	 *
43
	 * @param  string     $alias
44
	 * @return array|null
45
	 */
46
	public function getAlias( $alias ) {
47
		if ( ! $this->hasAlias( $alias ) ) {
48
			return null;
49
		}
50
51
		return $this->aliases[ $alias ];
52
	}
53
54
	/**
55
	 * Register an alias.
56
	 * Useful when passed the return value of getAlias() to restore
57
	 * a previously registered alias, for example.
58
	 *
59
	 * @param  array<string, mixed> $alias
60
	 * @return void
61
	 */
62
	public function setAlias( $alias ) {
63
		$name = Arr::get( $alias, 'name' );
64
65
		$this->aliases[ $name ] = [
66
			'name' => $name,
67
			'target' => Arr::get( $alias, 'target' ),
68
			'method' => Arr::get( $alias, 'method', '' ),
69
		];
70
	}
71
72
	/**
73
	 * Register an alias.
74
	 * Identical to setAlias but with a more user-friendly interface.
75
	 *
76
	 * @codeCoverageIgnore
77
	 * @param  string         $alias
78
	 * @param  string|Closure $target
79
	 * @param  string         $method
80
	 * @return void
81
	 */
82
	public function alias( $alias, $target, $method = '' ) {
83
		$this->setAlias( [
84
			'name' => $alias,
85
			'target' => $target,
86
			'method' => $method,
87
		] );
88
	}
89
90
	/**
91
	 * Call alias if registered.
92
	 *
93
	 * @param string $method
94
	 * @param array  $parameters
95
	 * @return mixed
96
	 */
97
	public function __call( $method, $parameters ) {
98
		if ( ! $this->hasAlias( $method ) ) {
99
			throw new BadMethodCallException( "Method {$method} does not exist." );
100
		}
101
102
		$alias = $this->aliases[ $method ];
103
104
		if ( $alias['target'] instanceof Closure ) {
105
			return call_user_func_array( $alias['target']->bindTo( $this, static::class ), $parameters );
106
		}
107
108
		$target = $this->resolve( $alias['target'] );
109
110
		if ( ! empty( $alias['method'] ) ) {
111
			return call_user_func_array( [$target, $alias['method']], $parameters );
112
		}
113
114
		return $target;
115
	}
116
117
	/**
118
	 * Resolve a dependency from the IoC container.
119
	 *
120
	 * @param  string     $key
121
	 * @return mixed|null
122
	 */
123
	abstract public function resolve( $key );
124
}
125