Passed
Push — master ( 41e096...62e39f )
by Greg
14:53
created

Webtrees::createServerRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * webtrees: online genealogy
4
 * Copyright (C) 2019 webtrees development team
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
 * GNU General Public License for more details.
13
 * You should have received a copy of the GNU General Public License
14
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15
 */
16
declare(strict_types=1);
17
18
namespace Fisharebest\Webtrees;
19
20
use Closure;
21
use ErrorException;
22
use Fisharebest\Webtrees\Http\Middleware\BootModules;
23
use Fisharebest\Webtrees\Http\Middleware\CheckCsrf;
24
use Fisharebest\Webtrees\Http\Middleware\CheckForMaintenanceMode;
25
use Fisharebest\Webtrees\Http\Middleware\DoHousekeeping;
26
use Fisharebest\Webtrees\Http\Middleware\EmitResponse;
27
use Fisharebest\Webtrees\Http\Middleware\HandleExceptions;
28
use Fisharebest\Webtrees\Http\Middleware\ModuleMiddleware;
29
use Fisharebest\Webtrees\Http\Middleware\NoRouteFound;
30
use Fisharebest\Webtrees\Http\Middleware\PhpEnvironment;
31
use Fisharebest\Webtrees\Http\Middleware\ReadConfigIni;
32
use Fisharebest\Webtrees\Http\Middleware\UpdateDatabaseSchema;
33
use Fisharebest\Webtrees\Http\Middleware\UseCache;
34
use Fisharebest\Webtrees\Http\Middleware\UseDatabase;
35
use Fisharebest\Webtrees\Http\Middleware\UseDebugbar;
36
use Fisharebest\Webtrees\Http\Middleware\UseFilesystem;
37
use Fisharebest\Webtrees\Http\Middleware\UseLocale;
38
use Fisharebest\Webtrees\Http\Middleware\UseSession;
39
use Fisharebest\Webtrees\Http\Middleware\UseTheme;
40
use Fisharebest\Webtrees\Http\Middleware\UseTransaction;
41
use Fisharebest\Webtrees\Http\Middleware\UseTree;
42
use Fisharebest\Webtrees\Http\Middleware\WebEnvironment;
43
use Nyholm\Psr7\Factory\Psr17Factory;
44
use Psr\Http\Message\ResponseFactoryInterface;
45
use Psr\Http\Message\ServerRequestFactoryInterface;
46
use Psr\Http\Message\StreamFactoryInterface;
47
use Psr\Http\Message\UploadedFileFactoryInterface;
48
use Psr\Http\Message\UriFactoryInterface;
49
use Throwable;
50
use function app;
51
use function dirname;
52
use function error_reporting;
53
use function ob_end_clean;
54
use function ob_get_level;
55
use function set_error_handler;
56
use function set_exception_handler;
57
use function str_replace;
58
use const PHP_EOL;
59
60
/**
61
 * Definitions for the webtrees application.
62
 */
63
class Webtrees
64
{
65
    // The root folder of this installation
66
    public const ROOT_DIR = __DIR__ . '/../';
67
68
    // Location of the file containing the database connection details.
69
    public const CONFIG_FILE = self::ROOT_DIR . 'data/config.ini.php';
70
71
    // Location of the file that triggers maintenance mode.
72
    public const OFFLINE_FILE = self::ROOT_DIR . 'data/offline.txt';
73
74
    // Location of our modules.
75
    public const MODULES_PATH = 'modules_v4/';
76
    public const MODULES_DIR  = self::ROOT_DIR . self::MODULES_PATH;
77
78
    // Enable debugging on development builds.
79
    public const DEBUG = self::STABILITY !== '';
80
81
    // We want to know about all PHP errors during development, and fewer in production.
82
    public const ERROR_REPORTING = self::DEBUG ? E_ALL | E_STRICT | E_NOTICE | E_DEPRECATED : E_ALL;
83
84
    // The name of the application.
85
    public const NAME = 'webtrees';
86
87
    // Required version of database tables/columns/indexes/etc.
88
    public const SCHEMA_VERSION = 43;
89
90
    // e.g. "dev", "alpha", "beta", etc.
91
    public const STABILITY = 'beta.4';
92
93
    // Version number
94
    public const VERSION = '2.0.0' . (self::STABILITY === '' ? '' : '-') . self::STABILITY;
95
96
    // Project website.
97
    public const URL = 'https://www.webtrees.net/';
98
99
    /**
100
     * Initialise the application.
101
     *
102
     * @return void
103
     */
104
    public function bootstrap(): void
105
    {
106
        // Show all errors and warnings in development, fewer in production.
107
        error_reporting(self::ERROR_REPORTING);
108
109
        set_error_handler($this->phpErrorHandler());
110
        set_exception_handler($this->phpExceptionHandler());
111
    }
112
113
    /**
114
     * An error handler that can be passed to set_error_handler().
115
     *
116
     * @return Closure
117
     */
118
    private function phpErrorHandler(): Closure
119
    {
120
        return static function (int $errno, string $errstr, string $errfile, int $errline): bool {
121
            // Ignore errors that are silenced with '@'
122
            if (error_reporting() & $errno) {
123
                throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
124
            }
125
126
            return true;
127
        };
128
    }
129
130
    /**
131
     * An exception handler that can be passed to set_exception_handler().
132
     * Display any exception that are not caught by the middleware exception handler.
133
     *
134
     * @return Closure
135
     */
136
    private function phpExceptionHandler(): Closure
137
    {
138
        return static function (Throwable $ex): void {
139
            $base_path = dirname(__DIR__);
140
            $trace     = $ex->getMessage() . ' ' . $ex->getFile() . ':' . $ex->getLine() . PHP_EOL . $ex->getTraceAsString();
141
            $trace     = str_replace($base_path, '…', $trace);
142
143
            while (ob_get_level() > 0) {
144
                ob_end_clean();
145
            }
146
147
            echo '<html lang="en"><head><title>Error</title><meta charset="UTF-8"></head><body><pre>' . $trace . '</pre></body></html>';
148
        };
149
    }
150
151
    /**
152
     * We can use any PSR-7 / PSR-17 compatible message factory.
153
     *
154
     * @return void
155
     */
156
    public function selectMessageFactory(): void
157
    {
158
        app()->bind(ResponseFactoryInterface::class, Psr17Factory::class);
159
        app()->bind(ServerRequestFactoryInterface::class, Psr17Factory::class);
160
        app()->bind(StreamFactoryInterface::class, Psr17Factory::class);
161
        app()->bind(UploadedFileFactoryInterface::class, Psr17Factory::class);
162
        app()->bind(UriFactoryInterface::class, Psr17Factory::class);
163
    }
164
165
    /**
166
     * The webtrees application is built from middleware.
167
     *
168
     * @return string[]
169
     */
170
    public function middleware(): array
171
    {
172
        return [
173
            PhpEnvironment::class,
174
            EmitResponse::class,
175
            HandleExceptions::class,
176
            ReadConfigIni::class,
177
            WebEnvironment::class,
178
            UseDatabase::class,
179
            UseDebugbar::class,
180
            UpdateDatabaseSchema::class,
181
            UseCache::class,
182
            UseFilesystem::class,
183
            UseSession::class,
184
            UseTree::class,
185
            UseLocale::class,
186
            CheckForMaintenanceMode::class,
187
            UseTheme::class,
188
            DoHousekeeping::class,
189
            CheckCsrf::class,
190
            UseTransaction::class,
191
            BootModules::class,
192
            ModuleMiddleware::class,
193
            Router::class,
194
            NoRouteFound::class,
195
        ];
196
    }
197
}
198