Completed
Push — master ( 5b37e3...33118b )
by Mehmet
04:46
created

App::selamiApplicationFactory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 0
cts 10
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 1
crap 2
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * Selami Application
6
 *
7
 * @link    https://github.com/selamiphp/core
8
 * @license https://github.com/selamiphp/core/blob/master/LICENSE (MIT License)
9
 */
10
11
12
namespace Selami\Core;
13
14
use Selami\Router;
15
use Psr\Container\ContainerInterface;
16
use Psr\Http\Message\ServerRequestInterface;
17
use Psr\Http\Message\ResponseInterface;
18
use Symfony\Component\HttpFoundation\Session\Session as SymfonySession;
19
use Selami\Http\Psr7Response;
20
use Zend\Config\Config as ZendConfig;
21
22
23
class App
24
{
25
26
    /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
27
    private $config = [
28
        'base_dir'      => null,
29
        'app_dir'       => '/var/lib/www/app',
30
        'app_data_dir'  => '/tmp',
31
        'base_url'      => null,
32
        'app_namespace' => 'SelamiApp',
33
        'app_name'      => 'www',
34
        'default_return_type'   => 'html',
35
        'template_engine'       => 'Twig',
36
        'bypass_error_handlers' => true,
37
        'aliases'       => []
38
    ];
39
    */
40
41
    private $container;
42
    private $config;
43
    /**
44
     * ServerRequest
45
     *
46
     * @var ServerRequestInterface
47
     */
48
    private $request;
49
    private $route;
50
    private $session;
51
    private $response;
52
53
    public function __construct(
54
        ZendConfig $config,
55
        ServerRequestInterface $request,
56
        Router $router,
57
        SymfonySession $session,
58
        ContainerInterface $container
59
    ) {
60
    
61
        $this->request = $request;
62
        $this->config = $config;
63
        $this->route = $router->getRoute();
64
        $this->session = $session;
65
        $this->container  = $container;
66
    }
67
68
    public static function selamiApplicationFactory(ContainerInterface $container) : App
69
    {
70
        return new App(
71
            $container->get(ZendConfig::class),
72
            $container->get(ServerRequestInterface::class),
73
            $container->get(Router::class),
74
            $container->get(SymfonySession::class),
75
            $container
76
        );
77
    }
78
79
    public function __invoke(
80
        ServerRequestInterface $request,
81
        ResponseInterface $response,
82
        callable $next = null
83
    ) : ResponseInterface {
84
        $this->request = $request;
85
        $this->run();
86
        $psr7Response  = new Psr7Response;
87
        $response = $psr7Response($response, $this->response);
88
        if ($next !== null) {
89
            $response  = $next($request, $response);
90
        }
91
        return $response;
92
    }
93
94
    private function run() : void
95
    {
96
        $this->startSession();
97
        $this->runDispatcher($this->route['route']);
98
    }
99
100
    private function startSession() :void
101
    {
102
        ini_set('session.use_cookies', '1');
103
        ini_set('session.use_only_cookies', '1');
104
        ini_set('session.cookie_httponly', '1');
105
        ini_set('session.name', 'SELAMISESSID');
106
        if (!$this->session->isStarted()) {
107
            $this->session->start();
108
        }
109
    }
110
111
    private function runDispatcher(array $route) : void
112
    {
113
        $this->response = new Result($this->container, $this->session);
114
        $defaultReturnType = $this->config->app->get('default_return_type', 'html');
115
        switch ($route['status']) {
116
        case 405:
117
            $this->response->notFound(405, $defaultReturnType, 'Method Not Allowed');
118
            break;
119
        case 200:
120
            $this->runRoute($route['controller'], $route['returnType'], $route['args']);
121
            break;
122
        case 404:
123
        default:
124
            $this->response->notFound(404, $defaultReturnType, 'Not Found');
125
            break;
126
        }
127
    }
128
129
    private function runRoute(string $controller, string $returnType = 'html', ?array $args) : void
130
    {
131
        if (!class_exists($controller)) {
132
            $message = "Controller has not class name as {$controller}";
133
            throw new \BadMethodCallException($message);
134
        }
135
        $controllerInstance = new $controller($this->container, $args);
136
        if (method_exists($controllerInstance, 'applicationLoad')) {
137
            $controllerInstance->applicationLoad();
138
        }
139
        if (method_exists($controllerInstance, 'controllerLoad')) {
140
            $controllerInstance->controllerLoad();
141
        }
142
        $functionOutput = $controllerInstance();
143
144
        $returnFunction = 'return' . ucfirst($returnType);
145
        $this->response->$returnFunction($functionOutput, $controller);
146
    }
147
148
    public function getResponse() : array
149
    {
150
        $this->run();
151
        return $this->response->getResponse();
152
    }
153
154
    public function sendResponse() : void
155
    {
156
        $this->run();
157
        $this->response->sendResponse();
158
    }
159
}
160