commit | author | age
|
15e03a
|
1 |
<?php |
F |
2 |
|
|
3 |
namespace Framework; |
|
4 |
|
|
5 |
use Framework\Exceptions\PageNotFoundException; |
|
6 |
use ReflectionMethod; |
|
7 |
use UnexpectedValueException; |
|
8 |
|
|
9 |
class Dispatcher { |
|
10 |
public function __construct(private Router $router, |
|
11 |
private Container $container, |
|
12 |
private array $middleware_classes) { } |
|
13 |
|
|
14 |
public function handle(Request $request): Response { |
|
15 |
|
|
16 |
$path = $this->getPath($request->uri); |
|
17 |
$params = $this->router->match($path, $request->method); |
|
18 |
|
|
19 |
if($params === false) { |
|
20 |
throw new PageNotFoundException("No route matched for '$path' with method '$request->method'"); |
|
21 |
} |
|
22 |
|
|
23 |
$controller = "App\Controllers\\" . ucwords($params["controller"]); |
|
24 |
|
|
25 |
$action = $this->getActionName($params); |
|
26 |
$controller = $this->getControllerName($params); |
|
27 |
|
|
28 |
$controller_object = $this->container->get($controller); |
|
29 |
|
|
30 |
$controller_object->setViewer($this->container->get(TemplateViewerInterface::class)); |
|
31 |
$controller_object->setResponse($this->container->get(Response::class)); |
|
32 |
|
|
33 |
$args = $this->getActionArguments($controller, $action, $params); |
|
34 |
$controller_handler = new ControllerRequestHandler($controller_object, $action, $args); |
|
35 |
|
|
36 |
$middleware = $this->getMiddleware($params); |
|
37 |
|
|
38 |
$middleware_handler = new MiddlewareRequestHandler($middleware, |
|
39 |
$controller_handler); |
|
40 |
|
|
41 |
return $middleware_handler->handle($request); |
|
42 |
} |
|
43 |
|
|
44 |
|
|
45 |
private function getMiddleware(array $params): array { |
|
46 |
if( !array_key_exists("middleware", $params)) { |
|
47 |
return []; |
|
48 |
} |
|
49 |
|
|
50 |
$middleware = explode("|" ,$params["middleware"]); |
|
51 |
|
|
52 |
array_walk($middleware, function(&$value) { |
|
53 |
if(!array_key_exists($value, $this->middleware_classes)) { |
|
54 |
throw new UnexpectedValueException("Middleware '$value' not found in config settings"); |
|
55 |
} |
|
56 |
|
|
57 |
$value = $this->container->get($this->middleware_classes[$value]); |
|
58 |
}); |
|
59 |
|
|
60 |
return $middleware; |
|
61 |
} |
|
62 |
|
|
63 |
private function getActionArguments(string $controller, string $action, array $params = []): array { |
|
64 |
$args = []; |
|
65 |
$method = new ReflectionMethod($controller, $action); |
|
66 |
foreach($method->getParameters() as $parameter) { |
|
67 |
|
|
68 |
$name = $parameter->getName(); |
|
69 |
$args[$name] = $params[$name]; |
|
70 |
} |
|
71 |
|
|
72 |
return($args); |
|
73 |
} |
|
74 |
|
|
75 |
private function getControllerName(array $params): string { |
|
76 |
$controller = $params["controller"]; |
|
77 |
$controller = str_replace("-", "", ucwords(strtolower($controller), "-")); |
|
78 |
$namespace = "App\Controllers"; |
|
79 |
|
|
80 |
if(array_key_exists("namespace", $params)) { |
|
81 |
$namespace .= "\\" . $params["namespace"]; |
|
82 |
} |
|
83 |
|
|
84 |
return $namespace . "\\" . $controller; |
|
85 |
|
|
86 |
} |
|
87 |
|
|
88 |
|
|
89 |
private function getActionName(array $params): string |
|
90 |
{ |
|
91 |
$action = $params["action"]; |
|
92 |
|
|
93 |
$action = lcfirst(str_replace("-", "", ucwords(strtolower($action), "-"))); |
|
94 |
|
|
95 |
return $action; |
|
96 |
} |
|
97 |
|
|
98 |
public function getPath(string $uri): string { |
|
99 |
$path = parse_url($uri, PHP_URL_PATH); |
|
100 |
if ($path === false) { |
|
101 |
throw new UnexpectedValueException("Malformed URL: {$uri}"); |
|
102 |
} |
|
103 |
return $path; |
|
104 |
} |
|
105 |
} |