Test Setup Failed
Push — master ( f880df...17779b )
by Mehmet
04:43
created

Application::runController()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Selami;
5
6
use Psr\Container\ContainerInterface;
7
use Psr\Http\Message\ServerRequestInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Server\RequestHandlerInterface;
10
use Selami\Router\Route;
11
use Selami\Router\Router;
12
use Selami\View\ViewInterface;
13
use Zend\Config\Config;
14
15
class Application implements RequestHandlerInterface
16
{
17
18
    private $id;
19
    /**
20
     * @var ContainerInterface
21
     */
22
    private $container;
23
    /**
24
     * @var Config
25
     */
26
    private $config;
27
    /**
28
     * @var Router
29
     */
30
    private $router;
31
32
    /**
33
     * @var ApplicationResponse
34
     */
35
    private $response;
36
37
    /**
38
     * @var ServerRequestInterface
39
     */
40
    private $request;
41
    private $requestedMethod;
42
    private $requestedPath;
43
    private $route;
44
45
    public function __construct(
46
        string $id,
47
        ContainerInterface $container,
48
        Router $router,
49
        Config $config
50
    ) {
51
        $this->id = $id;
52
        $this->config = $config;
53
        $this->router = $router;
54
        $this->container  = $container;
55
    }
56
57
    public static function createWithContainer(ContainerInterface $container, ?string $id = 'selami-app') : self
58
    {
59
        return new self(
60
            $id,
61
            $container,
62
            $container->get(Router::class),
63
            $container->get(Config::class)
64
        );
65
    }
66
67
    public function handle(ServerRequestInterface $request) : ResponseInterface
68
    {
69
        $this->request = $request;
70
        $this->run();
71
        return $this->response->returnResponse();
72
    }
73
74
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
75
    : ResponseInterface
76
    {
77
        $this->request = $request;
78
        $this->run();
79
        return $this->response->returnResponse();
80
    }
81
82
    private function run() : void
83
    {
84
        $this->requestedMethod = $this->request->getMethod();
85
        $this->requestedPath = $this->request->getUri()->getPath();
86
        $route = $this->getRoute();
87
        $statusCode = $route->getStatusCode();
88
        switch ($statusCode) {
89
            case 405:
90
                $this->notFound(405, 'Method Not Allowed');
91
                break;
92
            case 200:
93
                $this->runController(
94
                    $route->getController(),
95
                    $route->getUriParameters()
96
                );
97
                break;
98
            case 404:
99
            default:
100
                $this->notFound($statusCode, 'Not Found');
101
                break;
102
        }
103
    }
104
105
    private function notFound($status, $message) : void
106
    {
107
        $errorHandlerClass = $this->container->get('http-error-handler');
108
        $errorHandler = new $errorHandlerClass($status, $message);
109
        $this->response = new ApplicationResponse(
110
            $errorHandlerClass,
111
            $errorHandler(),
112
            $this->config,
113
            $this->container->get(ViewInterface::class)
114
        );
115
    }
116
117
    private function getRoute() : Route
118
    {
119
        $this->router = $this->router
120
            ->withSubFolder($this->config->app->get('app_sub_folder', ''));
121
        $cacheFile = $this->config->app->get('router_cache_file-' . $this->id, null);
122
        if ((bool) $cacheFile) {
123
            $this->router = $this->router
124
                ->withCacheFile($cacheFile);
125
        }
126
        $this->addRoutes($this->config->routes);
127
        return $this->route ?? $this->router->getRoute();
128
    }
129
130
    private function addRoutes($routes) : void
131
    {
132
        foreach ($routes as $route) {
133
            if ($this->requestedMethod === $route[0] && $this->requestedPath === $route[1]) {
134
                $this->route = new Route($route[0], $route[1], 200,  $route[3], $route[2], []);
135
                break;
136
            }
137
            $this->router->add($route[0], $route[1], $route[2], $route[3], $route[4] ?? '');
138
        }
139
    }
140
141
    private function runController($controllerClass, array $args) : void
142
    {
143
        $controller = new FrontController($this->container, $controllerClass, $args);
144
        $this->response = new ApplicationResponse(
145
            $controllerClass,
146
            $controller->getControllerResponse(),
147
            $this->config,
148
            $this->container->get(ViewInterface::class)
149
        );
150
    }
151
}
152