Completed
Push — master ( 293319...13cdbf )
by Mikołaj
01:32
created

App::setRequestUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Egzaminer;
4
5
use AltoRouter;
6
use Egzaminer\Controller\ErrorController;
7
use Exception;
8
use PDO;
9
use PDOException;
10
use RuntimeException;
11
use Tamtamchik\SimpleFlash\Flash;
12
use Whoops\Handler\PrettyPageHandler;
13
use Whoops\Run as Whoops;
14
15
class App
16
{
17
    const VERSION = '0.13.0';
18
19
    /**
20
     * @var string
21
     */
22
    private $url;
23
24
    /**
25
     * @var AltoRouter
26
     */
27
    private $router;
28
29
    /**
30
     * @var array
31
     */
32
    private $config;
33
34
    /**
35
     * @var array
36
     */
37
    private $container;
38
39
    public function __construct(string $url)
40
    {
41
        $this->config = $this->getConfig('site');
42
43
        try {
44
            if ($this->config['debug']) {
45
                $whoops = new Whoops();
46
                $whoops->pushHandler(new PrettyPageHandler());
0 ignored issues
show
Documentation introduced by
new \Whoops\Handler\PrettyPageHandler() is of type object<Whoops\Handler\PrettyPageHandler>, but the function expects a callable.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
47
                $whoops->register();
48
            }
49
50
            $this->container = [
51
                'config'  => $this->config,
52
                'dbh'     => $this->dbConnect($this->getConfig('db')),
53
                'dir'     => $this->getDir(),
54
                'flash'   => new Flash(),
55
                'request' => [
56
                    'get'     => $_GET,
57
                    'post'    => $_POST,
58
                    'session' => &$_SESSION,
59
                    'files'   => $_FILES,
60
                ],
61
                'rootDir' => \dirname(__DIR__),
62
                'version' => self::VERSION,
63
            ];
64
65
            $this->container['auth'] = new Auth($this->getConfig('users'), $this->container['request']);
66
        } catch (Exception $e) {
67
            http_response_code(500);
68
            echo $e->getMessage();
69
            $this->terminate();
70
        }
71
72
        $this->router = new AltoRouter();
73
        $this->setRequestUrl($url);
74
    }
75
76
    public function getConfig(string $name): array
77
    {
78
        $path = \dirname(__DIR__).'/config/'.$name.'.php';
79
80
        try {
81
            if (!file_exists($path)) {
82
                http_response_code(500);
83
84
                throw new RuntimeException('Config file '.$name.'.php does not exist');
85
            }
86
        } catch (Exception $e) {
87
            echo $e->getMessage();
88
            $this->terminate();
89
        }
90
91
        return include $path;
92
    }
93
94
    /**
95
     * Run app.
96
     *
97
     * @throws Exception
98
     */
99
    public function invoke()
100
    {
101
        $this->loadRoutes();
102
103
        $match = $this->router->match($this->url);
104
105
        try {
106
            // call closure or throw 404 status
107
            if ($match && \is_callable($match['target'])) {
108
                echo \call_user_func_array([
109
                    new $match['target'][0]($this->container), $match['target'][1],
110
                ], $match['params']);
111
            } else {
112
                throw new RuntimeException('Page not exist! No route match');
113
            }
114
        } catch (Exception $e) {
115
            if ($this->config['debug']) {
116
                throw new DebugException($e->getMessage());
117
            }
118
119
            echo (new ErrorController($this->container))->showAction();
120
121
            $this->terminate();
122
        }
123
    }
124
125
    /**
126
     * Load routes.
127
     *
128
     * @throws Exception
129
     *
130
     * @return void
131
     */
132
    public function loadRoutes()
133
    {
134
        $routesArray = (array) include __DIR__.'/routes.php';
135
136
        foreach ($routesArray as $key => $route) {
137
            if (2 === \count($route)) {
138
                $this->router->map(
139
                    $route[0][0],
140
                    $route[0][1],
141
                    [
142
                        'Egzaminer\Controller\\'.$route[0][2][0],
143
                        $route[0][2][1],
144
                    ],
145
                    $key.'/'.$route[0][0]
146
                );
147
                $route = $route[1];
148
            }
149
150
            $this->router->map(
151
                $route[0],
152
                $route[1],
153
                [
154
                    'Egzaminer\Controller\\'.$route[2][0],
155
                    $route[2][1],
156
                ],
157
                $key.'/'.$route[0]
158
            );
159
        }
160
    }
161
162
    /**
163
     * @param array $config
164
     *
165
     * @return PDO
166
     * @throws DebugException
167
     */
168
    private function dbConnect(array $config): PDO
169
    {
170
        $dbh = null;
171
172
        try {
173
            $dsn = 'mysql'
174
            .':dbname='.$config['name']
175
            .';host='.$config['host']
176
            .';charset=utf8';
177
178
            $user = $config['user'];
179
            $password = $config['pass'];
180
181
            $dbh = new PDO($dsn, $user, $password);
182
183
            if ($this->config['debug']) {
184
                $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
185
            }
186
        } catch (PDOException $e) {
187
            http_response_code(500);
188
189
            if ($this->config['debug']) {
190
                throw new DebugException($e->getMessage());
191
            }
192
193
            echo 'Error 500';
194
            $this->terminate();
195
        }
196
197
        return $dbh;
198
    }
199
200
    public function terminate($code = 1)
201
    {
202
        exit($code);
203
    }
204
205
    public function setRequestUrl(string $request)
206
    {
207
        $this->url = substr($request, \strlen($this->getDir()));
208
    }
209
210
    public function getDir(): string
211
    {
212
        if (\dirname($_SERVER['SCRIPT_NAME']) === '/') {
213
            return '';
214
        }
215
216
        return \dirname($_SERVER['SCRIPT_NAME']);
217
    }
218
}
219