Completed
Push — master ( b36efb...11b790 )
by Mr
02:17
created

App::initRequest()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
nc 3
nop 0
dl 0
loc 9
c 0
b 0
f 0
cc 2
rs 9.6666
1
<?php
2
3
namespace DrMVC\Framework;
4
5
use DrMVC\Router\RouterInterface;
6
use Zend\Diactoros\ServerRequestFactory;
7
use Zend\Diactoros\ServerRequest;
8
use Zend\Diactoros\Response;
9
10
use DrMVC\Config\ConfigInterface;
11
use DrMVC\Router;
12
use DrMVC\Controllers\Error;
13
14
/**
15
 * Class App
16
 * @package DrMVC\Framework
17
 * @method App options(string $pattern, callable $callable): App
18
 * @method App get(string $pattern, callable $callable): App
19
 * @method App head(string $pattern, callable $callable): App
20
 * @method App post(string $pattern, callable $callable): App
21
 * @method App put(string $pattern, callable $callable): App
22
 * @method App delete(string $pattern, callable $callable): App
23
 * @method App trace(string $pattern, callable $callable): App
24
 * @method App connect(string $pattern, callable $callable): App
25
 * @since 3.0
26
 */
27
class App implements AppInterface
28
{
29
    /**
30
     * @var ContainersInterface
31
     */
32
    private $_containers;
33
34
    /**
35
     * App constructor.
36
     * @param ConfigInterface $config
37
     */
38
    public function __construct(ConfigInterface $config)
39
    {
40
        // Initiate PSR-11 containers
41
        $this->initContainers();
42
43
        // Save configuration
44
        $this->initConfig($config);
45
46
        // Initiate router
47
        $this
48
            ->initRequest()
49
            ->initResponse()
50
            ->initRouter();
51
    }
52
53
    /**
54
     * Initialize containers object
55
     *
56
     * @return  App
57
     */
58
    private function initContainers(): App
59
    {
60
        if (null === $this->_containers) {
61
            $this->_containers = new Containers();
62
        }
63
        return $this;
64
    }
65
66
    /**
67
     * Put config object into the containers class
68
     *
69
     * @param   ConfigInterface $config
70
     * @return  App
71
     */
72
    private function initConfig(ConfigInterface $config): App
73
    {
74
        $this->containers()->set('config', $config);
0 ignored issues
show
Bug introduced by
$config of type DrMVC\Config\ConfigInterface is incompatible with the type string expected by parameter $object of DrMVC\Framework\ContainersInterface::set(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

74
        $this->containers()->set('config', /** @scrutinizer ignore-type */ $config);
Loading history...
75
        return $this;
76
    }
77
78
    /**
79
     * Initiate PSR-7 request object
80
     *
81
     * @return  App
82
     */
83
    private function initRequest(): App
84
    {
85
        try {
86
            $request = ServerRequestFactory::fromGlobals();
87
            $this->containers()->set('request', $request);
0 ignored issues
show
Bug introduced by
$request of type Zend\Diactoros\ServerRequest is incompatible with the type string expected by parameter $object of DrMVC\Framework\ContainersInterface::set(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

87
            $this->containers()->set('request', /** @scrutinizer ignore-type */ $request);
Loading history...
88
        } catch (\InvalidArgumentException $e) {
89
            new Exception($e);
90
        }
91
        return $this;
92
    }
93
94
    /**
95
     * Initiate PSR-7 response object
96
     *
97
     * @return  App
98
     */
99
    private function initResponse(): App
100
    {
101
        try {
102
            $response = new Response();
103
            $this->containers()->set('response', $response);
0 ignored issues
show
Bug introduced by
$response of type Zend\Diactoros\Response is incompatible with the type string expected by parameter $object of DrMVC\Framework\ContainersInterface::set(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
            $this->containers()->set('response', /** @scrutinizer ignore-type */ $response);
Loading history...
104
        } catch (\InvalidArgumentException $e) {
105
            new Exception($e);
106
        }
107
        return $this;
108
    }
109
110
    /**
111
     * Put route into the container of classes
112
     *
113
     * @return  App
114
     */
115
    private function initRouter(): App
116
    {
117
        $request = $this->container('request');
118
        $response = $this->container('response');
119
        $router = new Router($request, $response);
120
        $router->setError(Error::class);
121
122
        $this->containers()->set('router', $router);
0 ignored issues
show
Bug introduced by
$router of type DrMVC\Router is incompatible with the type string expected by parameter $object of DrMVC\Framework\ContainersInterface::set(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

122
        $this->containers()->set('router', /** @scrutinizer ignore-type */ $router);
Loading history...
123
        return $this;
124
    }
125
126
    /**
127
     * Get custom container by name
128
     *
129
     * @param   string $name
130
     * @return  mixed
131
     */
132
    public function container(string $name)
133
    {
134
        return $this->_containers->get($name);
135
    }
136
137
    /**
138
     * Get all available containers
139
     *
140
     * @return  ContainersInterface
141
     */
142
    public function containers(): ContainersInterface
143
    {
144
        return $this->_containers;
145
    }
146
147
    /**
148
     * Magic method for work with calls
149
     *
150
     * @param   string $method
151
     * @param   array $args
152
     * @return  RouterInterface
153
     */
154
    public function __call(string $method, array $args): RouterInterface
155
    {
156
        $router = $this->container('router');
157
        if (\in_array($method, Router::METHODS, false)) {
158
            $router->set([$method], $args);
159
        }
160
        return $router;
161
    }
162
163
    /**
164
     * If any route is provided
165
     *
166
     * @param   string $pattern
167
     * @param   callable|string $callable
168
     * @return  RouterInterface
169
     */
170
    public function any(string $pattern, $callable): RouterInterface
171
    {
172
        $router = $this->container('router');
173
        $router->any($pattern, $callable);
174
        return $router;
175
    }
176
177
    /**
178
     * Set the error callback of class
179
     *
180
     * @param   callable|string $callable
181
     * @return  RouterInterface
182
     */
183
    public function error($callable): RouterInterface
184
    {
185
        $router = $this->container('router');
186
        $router->error($callable);
187
        return $router;
188
    }
189
190
    /**
191
     * Few methods provided
192
     *
193
     * @param   array $methods
194
     * @param   string $pattern
195
     * @param   callable|string $callable
196
     * @return  RouterInterface
197
     */
198
    public function map(array $methods, string $pattern, $callable): RouterInterface
199
    {
200
        $router = $this->container('router');
201
        $router->map($methods, $pattern, $callable);
202
        return $router;
203
    }
204
205
    public function run(): bool
206
    {
207
        $router = $this->container('router');
208
        return $router->getRoute();
209
    }
210
}
211