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\Helpers; |
||||
11 | |||||
12 | use Closure; |
||||
13 | use WPEmerge\Application\GenericFactory; |
||||
14 | use WPEmerge\Exceptions\ClassNotFoundException; |
||||
15 | use WPEmerge\Exceptions\ConfigurationException; |
||||
16 | use WPEmerge\Support\Arr; |
||||
17 | |||||
18 | /** |
||||
19 | * Represent a generic handler - a Closure or a class method to be resolved from the service container |
||||
20 | */ |
||||
21 | class Handler { |
||||
22 | /** |
||||
23 | * Injection Factory. |
||||
24 | * |
||||
25 | * @var GenericFactory |
||||
26 | */ |
||||
27 | protected $factory = null; |
||||
28 | |||||
29 | /** |
||||
30 | * Parsed handler |
||||
31 | * |
||||
32 | * @var array|Closure |
||||
33 | */ |
||||
34 | protected $handler = null; |
||||
35 | |||||
36 | /** |
||||
37 | * Constructor |
||||
38 | * |
||||
39 | * @param GenericFactory $factory |
||||
40 | * @param string|Closure $raw_handler |
||||
41 | * @param string $default_method |
||||
42 | * @param string $namespace |
||||
43 | */ |
||||
44 | 15 | public function __construct( GenericFactory $factory, $raw_handler, $default_method = '', $namespace = '' ) { |
|||
45 | 15 | $this->factory = $factory; |
|||
46 | |||||
47 | 15 | $handler = $this->parse( $raw_handler, $default_method, $namespace ); |
|||
48 | |||||
49 | 15 | if ( $handler === null ) { |
|||
50 | 5 | throw new ConfigurationException( 'No or invalid handler provided.' ); |
|||
51 | } |
||||
52 | |||||
53 | 10 | $this->handler = $handler; |
|||
54 | 10 | } |
|||
55 | |||||
56 | /** |
||||
57 | * Parse a raw handler to a Closure or a [class, method, namespace] array |
||||
58 | * |
||||
59 | * @param string|Closure $raw_handler |
||||
60 | * @param string $default_method |
||||
61 | * @param string $namespace |
||||
62 | * @return array|Closure|null |
||||
63 | */ |
||||
64 | 14 | protected function parse( $raw_handler, $default_method, $namespace ) { |
|||
65 | 14 | if ( $raw_handler instanceof Closure ) { |
|||
66 | 1 | return $raw_handler; |
|||
67 | } |
||||
68 | |||||
69 | 13 | if ( is_array( $raw_handler ) ) { |
|||
0 ignored issues
–
show
introduced
by
![]() |
|||||
70 | 9 | return $this->parseFromArray( $raw_handler, $default_method, $namespace ); |
|||
71 | } |
||||
72 | |||||
73 | 4 | return $this->parseFromString( $raw_handler, $default_method, $namespace ); |
|||
74 | } |
||||
75 | |||||
76 | /** |
||||
77 | * Parse a [Class::class, 'method'] array handler to a [class, method, namespace] array |
||||
78 | * |
||||
79 | * @param string $raw_handler |
||||
80 | * @param string $default_method |
||||
81 | * @param string $namespace |
||||
82 | * @return array|null |
||||
83 | */ |
||||
84 | 9 | protected function parseFromArray( $raw_handler, $default_method, $namespace ) { |
|||
85 | 9 | $class = Arr::get( $raw_handler, 0, '' ); |
|||
0 ignored issues
–
show
$raw_handler of type string is incompatible with the type ArrayAccess|array expected by parameter $array of WPEmerge\Support\Arr::get() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
86 | 9 | $class = preg_replace( '/^\\\\+/', '', $class ); |
|||
87 | 9 | $method = Arr::get( $raw_handler, 1, $default_method ); |
|||
88 | |||||
89 | 9 | if ( empty( $class ) ) { |
|||
90 | 2 | return null; |
|||
91 | } |
||||
92 | |||||
93 | 7 | if ( empty( $method ) ) { |
|||
94 | 2 | return null; |
|||
95 | } |
||||
96 | |||||
97 | return [ |
||||
98 | 5 | 'class' => $class, |
|||
99 | 5 | 'method' => $method, |
|||
100 | 5 | 'namespace' => $namespace, |
|||
101 | ]; |
||||
102 | } |
||||
103 | |||||
104 | /** |
||||
105 | * Parse a 'Controller@method' or 'Controller::method' string handler to a [class, method, namespace] array |
||||
106 | * |
||||
107 | * @param string $raw_handler |
||||
108 | * @param string $default_method |
||||
109 | * @param string $namespace |
||||
110 | * @return array|null |
||||
111 | */ |
||||
112 | 4 | protected function parseFromString( $raw_handler, $default_method, $namespace ) { |
|||
113 | 4 | return $this->parseFromArray( preg_split( '/@|::/', $raw_handler, 2 ), $default_method, $namespace ); |
|||
0 ignored issues
–
show
preg_split('/@|::/', $raw_handler, 2) of type false|string[] is incompatible with the type string expected by parameter $raw_handler of WPEmerge\Helpers\Handler::parseFromArray() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
114 | } |
||||
115 | |||||
116 | /** |
||||
117 | * Get the parsed handler |
||||
118 | * |
||||
119 | * @return array|Closure |
||||
120 | */ |
||||
121 | 1 | public function get() { |
|||
122 | 1 | return $this->handler; |
|||
123 | } |
||||
124 | |||||
125 | /** |
||||
126 | * Make an instance of the handler. |
||||
127 | * |
||||
128 | * @return object |
||||
129 | */ |
||||
130 | 4 | public function make() { |
|||
131 | 4 | $handler = $this->get(); |
|||
132 | |||||
133 | 4 | if ( $handler instanceof Closure ) { |
|||
134 | 1 | return $handler; |
|||
135 | } |
||||
136 | |||||
137 | 3 | $namespace = $handler['namespace']; |
|||
138 | 3 | $class = $handler['class']; |
|||
139 | |||||
140 | try { |
||||
141 | 3 | $instance = $this->factory->make( $class ); |
|||
142 | 2 | } catch ( ClassNotFoundException $e ) { |
|||
143 | try { |
||||
144 | 2 | $instance = $this->factory->make( $namespace . $class ); |
|||
145 | 1 | } catch ( ClassNotFoundException $e ) { |
|||
146 | 1 | throw new ClassNotFoundException( 'Class not found - tried: ' . $class . ', ' . $namespace . $class ); |
|||
147 | } |
||||
148 | } |
||||
149 | |||||
150 | 2 | return $instance; |
|||
151 | } |
||||
152 | |||||
153 | /** |
||||
154 | * Execute the parsed handler with any provided arguments and return the result. |
||||
155 | * |
||||
156 | * @param mixed ,...$arguments |
||||
157 | * @return mixed |
||||
158 | */ |
||||
159 | 2 | public function execute() { |
|||
160 | 2 | $arguments = func_get_args(); |
|||
161 | 2 | $instance = $this->make(); |
|||
162 | |||||
163 | 2 | if ( $instance instanceof Closure ) { |
|||
164 | 1 | return call_user_func_array( $instance, $arguments ); |
|||
165 | } |
||||
166 | |||||
167 | 1 | return call_user_func_array( [$instance, $this->get()['method']], $arguments ); |
|||
168 | } |
||||
169 | } |
||||
170 |