Hoa central
Basic.php
Go to the documentation of this file.
1 <?php
2 
37 namespace Hoa\Dispatcher;
38 
39 use Hoa\Router;
40 use Hoa\View;
41 
51 class Basic extends Dispatcher
52 {
62  protected function resolve(
63  Array $rule,
64  Router $router,
65  View\Viewable $view = null
66  ) {
67  $called = null;
68  $variables = &$rule[Router::RULE_VARIABLES];
69  $call = isset($variables['controller'])
70  ? $variables['controller']
71  : (isset($variables['_call'])
72  ? $variables['_call']
73  : $rule[Router::RULE_CALL]);
74  $able = isset($variables['action'])
75  ? $variables['action']
76  : (isset($variables['_able'])
77  ? $variables['_able']
78  : $rule[Router::RULE_ABLE]);
79  $rtv = [$router, $this, $view];
80  $arguments = [];
81  $reflection = null;
82 
83  if ($call instanceof \Closure) {
84  $kitname = $this->getKitName();
85 
86  if (!empty($kitname)) {
87  $kit = dnew($this->getKitName(), $rtv);
88 
89  if (!($kit instanceof Kit)) {
90  throw new Exception(
91  'Your kit %s must extend Hoa\Dispatcher\Kit.',
92  0,
93  $kitname
94  );
95  }
96 
97  $variables['_this'] = $kit;
98  }
99 
100  $called = $call;
101  $reflection = new \ReflectionMethod($call, '__invoke');
102 
103  foreach ($reflection->getParameters() as $parameter) {
104  $name = strtolower($parameter->getName());
105 
106  if (true === array_key_exists($name, $variables)) {
107  $arguments[$name] = $variables[$name];
108 
109  continue;
110  }
111 
112  if (false === $parameter->isOptional()) {
113  throw new Exception(
114  'The closured action for the rule with pattern %s needs ' .
115  'a value for the parameter $%s and this value does not ' .
116  'exist.',
117  1,
118  [$rule[Router::RULE_PATTERN], $name]
119  );
120  }
121  }
122  } elseif (is_string($call) && null === $able) {
123  $kitname = $this->getKitName();
124 
125  if (!empty($kitname)) {
126  $kit = dnew($this->getKitName(), $rtv);
127 
128  if (!($kit instanceof Kit)) {
129  throw new Exception(
130  'Your kit %s must extend Hoa\Dispatcher\Kit.',
131  2,
132  $kitname
133  );
134  }
135 
136  $variables['_this'] = $kit;
137  }
138 
139  $reflection = new \ReflectionFunction($call);
140 
141  foreach ($reflection->getParameters() as $parameter) {
142  $name = strtolower($parameter->getName());
143 
144  if (true === array_key_exists($name, $variables)) {
145  $arguments[$name] = $variables[$name];
146 
147  continue;
148  }
149 
150  if (false === $parameter->isOptional()) {
151  throw new Exception(
152  'The functional action for the rule with pattern %s needs ' .
153  'a value for the parameter $%s and this value does not ' .
154  'exist.',
155  3,
156  [$rule[Router::RULE_PATTERN], $name]
157  );
158  }
159  }
160  } else {
161  $async = $router->isAsynchronous();
162  $controller = $call;
163  $action = $able;
164 
165  if (!is_object($call)) {
166  if (false === $async) {
167  $_controller = 'synchronous.call';
168  $_action = 'synchronous.able';
169  } else {
170  $_controller = 'asynchronous.call';
171  $_action = 'asynchronous.able';
172  }
173 
174  $this->_parameters->setKeyword('call', $controller);
175  $this->_parameters->setKeyword('able', $action);
176 
177  $controller = $this->_parameters->getFormattedParameter($_controller);
178  $action = $this->_parameters->getFormattedParameter($_action);
179 
180  try {
181  $controller = dnew($controller, $rtv);
182  } catch (\Exception $e) {
183  throw new Exception(
184  'Controller %s is not found ' .
185  '(method: %s, asynchronous: %s).',
186  4,
187  [
188  $controller,
189  strtoupper($router->getMethod()),
190  true === $async
191  ? 'true'
192  : 'false'
193  ],
194  $e
195  );
196  }
197 
198  $kitname = $this->getKitName();
199 
200  if (!empty($kitname)) {
201  $variables['_this'] = dnew($kitname, $rtv);
202  }
203 
204  if (method_exists($controller, 'construct')) {
205  $controller->construct();
206  }
207  }
208 
209  if (!method_exists($controller, $action)) {
210  throw new Exception(
211  'Action %s does not exist on the controller %s ' .
212  '(method: %s, asynchronous: %s).',
213  5,
214  [
215  $action,
216  get_class($controller),
217  strtoupper($router->getMethod()),
218  true === $async
219  ? 'true'
220  : 'false'
221  ]
222  );
223  }
224 
225  $called = $controller;
226  $reflection = new \ReflectionMethod($controller, $action);
227 
228  foreach ($reflection->getParameters() as $parameter) {
229  $name = strtolower($parameter->getName());
230 
231  if (true === array_key_exists($name, $variables)) {
232  $arguments[$name] = $variables[$name];
233 
234  continue;
235  }
236 
237  if (false === $parameter->isOptional()) {
238  throw new Exception(
239  'The action %s on the controller %s needs a value for ' .
240  'the parameter $%s and this value does not exist.',
241  6,
242  [
243  $action,
244  get_class($controller),
245  $name
246  ]
247  );
248  }
249  }
250  }
251 
252  if ($reflection instanceof \ReflectionFunction) {
253  $return = $reflection->invokeArgs($arguments);
254  } elseif ($reflection instanceof \ReflectionMethod) {
255  $return = $reflection->invokeArgs($called, $arguments);
256  }
257 
258  return $return;
259  }
260 }
resolve(Array $rule, Router $router, View\Viewable $view=null)
Definition: Basic.php:62
const RULE_VARIABLES
Definition: Router.php:112
const RULE_PATTERN
Definition: Router.php:91
const RULE_CALL
Definition: Router.php:98