Passed
Push — master ( ead0c7...50ee3e )
by Atanas
02:24
created

Handler::make()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 4
nop 0
dl 0
loc 21
ccs 12
cts 12
cp 1
crap 4
rs 9.8333
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package   WPEmerge
4
 * @author    Atanas Angelov <[email protected]>
5
 * @copyright 2018 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\Helpers;
11
12
use Closure;
13
use WPEmerge\Application\InjectionFactory;
14
use WPEmerge\Exceptions\ClassNotFoundException;
15
use WPEmerge\Exceptions\ConfigurationException;
16
17
/**
18
 * Represent a generic handler - a Closure or a class method to be resolved from the service container
19
 */
20
class Handler {
21
	/**
22
	 * Injection Factory.
23
	 *
24
	 * @var InjectionFactory
25
	 */
26
	protected $injection_factory = null;
27
28
	/**
29
	 * Parsed handler
30
	 *
31
	 * @var array|Closure|null
32
	 */
33
	protected $handler = null;
34
35
	/**
36
	 * Constructor
37
	 *
38
	 * @param InjectionFactory $injection_factory
39
	 * @param string|Closure   $raw_handler
40
	 * @param string           $default_method
41
	 * @param string           $namespace
42
	 */
43 7
	public function __construct( InjectionFactory $injection_factory, $raw_handler, $default_method = '', $namespace = '' ) {
44 7
		$this->injection_factory = $injection_factory;
45
46 7
		$handler = $this->parse( $raw_handler, $default_method, $namespace );
47
48 7
		if ( $handler === null ) {
49 2
			throw new ConfigurationException( 'No or invalid handler provided.' );
50
		}
51
52 5
		$this->handler = $handler;
53 5
	}
54
55
	/**
56
	 * Parse a raw handler to a Closure or a [class, method] array
57
	 *
58
	 * @param  string|Closure     $raw_handler
59
	 * @param  string             $default_method
60
	 * @param  string             $namespace
61
	 * @return array|Closure|null
62
	 */
63 6
	protected function parse( $raw_handler, $default_method, $namespace ) {
64 6
		if ( $raw_handler instanceof Closure ) {
65 1
			return $raw_handler;
66
		}
67
68 5
		return $this->parseFromString( $raw_handler, $default_method, $namespace );
69
	}
70
71
	/**
72
	 * Parse a raw string handler to a [class, method] array
73
	 *
74
	 * @param  string     $raw_handler
75
	 * @param  string     $default_method
76
	 * @param  string     $namespace
77
	 * @return array|null
78
	 */
79 5
	protected function parseFromString( $raw_handler, $default_method, $namespace ) {
80 5
		list( $class, $method ) = array_pad( preg_split( '/@|::/', $raw_handler, 2 ), 2, '' );
81
82 5
		if ( empty( $method ) ) {
83 3
			$method = $default_method;
84
		}
85
86 5
		if ( ! empty( $class ) && ! empty( $method ) ) {
87
			return [
88 3
				'class' => $class,
89 3
				'method' => $method,
90 3
				'namespace' => $namespace,
91
			];
92
		}
93
94 2
		return null;
95
	}
96
97
	/**
98
	 * Get the parsed handler
99
	 *
100
	 * @return array|Closure|null
101
	 */
102 1
	public function get() {
103 1
		return $this->handler;
104
	}
105
106
	/**
107
	 * Make an instance of the handler.
108
	 *
109
	 * @return object
110
	 */
111 4
	public function make() {
112 4
		$handler = $this->get();
113
114 4
		if ( $handler instanceof Closure ) {
115 1
			return $handler;
116
		}
117
118 3
		$namespace = $handler['namespace'];
119 3
		$class = $handler['class'];
120
121
		try {
122 3
			$instance = $this->injection_factory->make( $class );
123 2
		} catch ( ClassNotFoundException $e ) {
124
			try {
125 2
				$instance = $this->injection_factory->make( $namespace . $class );
126 1
			} catch ( ClassNotFoundException $e ) {
127 1
				throw new ClassNotFoundException( 'Class not found - tried: ' . $class . ', ' . $namespace . $class );
128
			}
129
		}
130
131 2
		return $instance;
132
	}
133
134
	/**
135
	 * Execute the parsed handler with any provided arguments and return the result.
136
	 *
137
	 * @param  mixed ,...$arguments
138
	 * @return mixed
139
	 */
140 2
	public function execute() {
141 2
		$arguments = func_get_args();
142 2
		$instance = $this->make();
143
144 2
		if ( $instance instanceof Closure ) {
145 1
			return call_user_func_array( $instance, $arguments );
146
		}
147
148 1
		return call_user_func_array( [$instance, $this->get()['method']], $arguments );
149
	}
150
}
151