Passed
Push — master ( 33118b...5ca5e8 )
by Mehmet
06:00
created

App::__invoke()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 0
cts 13
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 11
nc 2
nop 3
crap 6
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\Foundation;
13
14
use Selami\Router;
15
use Psr\Container\ContainerInterface;
16
use Psr\Http\Message\ServerRequestInterface;
17
use Psr\Http\Message\ResponseInterface;
18
use Selami\Http\Psr7Response;
19
use Zend\Config\Config as ZendConfig;
20
21
22
class App
23
{
24
25
    /*
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...
26
    private $config = [
27
        'base_dir'      => null,
28
        'app_dir'       => '/var/lib/www/app',
29
        'app_data_dir'  => '/tmp',
30
        'base_url'      => null,
31
        'app_namespace' => 'SelamiApp',
32
        'app_name'      => 'www',
33
        'default_return_type'   => 'html',
34
        'template_engine'       => 'Twig',
35
        'bypass_error_handlers' => true,
36
        'aliases'       => []
37
    ];
38
    */
39
    /**
40
     * @var ContainerInterface
41
     */
42
    private $container;
43
    /**
44
     * @var ZendConfig
45
     */
46
    private $config;
47
    /**
48
     * @var array
49
     */
50
    private $route;
51
52
    /**
53
     * @var array
54
     */
55
    private $response;
56
57
    public function __construct(
58
        ZendConfig $config,
59
        Router $router,
60
        ContainerInterface $container
61
    ) {
62
63
        $this->config = $config;
64
        $this->route = $router->getRoute();
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(Router::class),
73
            $container
74
        );
75
    }
76
77
    public function __invoke(
78
        ServerRequestInterface $request,
79
        ResponseInterface $response,
80
        callable $next = null
81
    ) : ResponseInterface {
82
        $this->run();
83
        $psr7Response  = new Psr7Response;
84
        $response = $psr7Response($response, $this->response);
85
        if ($next !== null) {
86
            $response  = $next($request, $response);
87
        }
88
        return $response;
89
    }
90
91
    private function run() : void
92
    {
93
        $this->runDispatcher($this->route['route']);
94
    }
95
96
97
98
    private function runDispatcher(array $route) : void
99
    {
100
        $this->response = new Response($this->container);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Selami\Foundation\Response($this->container) of type object<Selami\Foundation\Response> is incompatible with the declared type array of property $response.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
101
        $defaultReturnType = $this->config->app->get('default_return_type', 'html');
102
        switch ($route['status']) {
103
        case 405:
104
            $this->response->notFound(405, $defaultReturnType, 'Method Not Allowed');
105
            break;
106
        case 200:
107
            $this->runRoute($route['controller'], $route['returnType'], $route['args']);
108
            break;
109
        case 404:
110
        default:
111
            $this->response->notFound(404, $defaultReturnType, 'Not Found');
112
            break;
113
        }
114
    }
115
116
    private function runRoute(string $controllerClass, string $returnType = 'html', ?array $args) : void
117
    {
118
        if (!class_exists($controllerClass)) {
119
            $message = "Controller has not class name as {$controllerClass}";
120
            throw new \BadMethodCallException($message);
121
        }
122
        $controller = $controllerClass::factory($this->container, $args);
123
        $functionOutput = $controller->respond();
124
        $returnFunction = 'return' . ucfirst($returnType);
125
        $this->response->$returnFunction($functionOutput, $controllerClass);
0 ignored issues
show
Bug introduced by
The method $returnFunction cannot be called on $this->response (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
126
    }
127
128
    public function getResponse() : array
129
    {
130
        $this->run();
131
        return $this->response->getResponse();
0 ignored issues
show
Bug introduced by
The method getResponse cannot be called on $this->response (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
132
    }
133
134
    public function sendResponse() : void
135
    {
136
        $this->run();
137
        $this->response->sendResponse();
0 ignored issues
show
Bug introduced by
The method sendResponse cannot be called on $this->response (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
138
    }
139
}
140