Issues (2559)

app/Webtrees.php (1 issue)

Labels
Severity
1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2025 webtrees development team
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees;
21
22
use Fisharebest\Webtrees\Cli\Console;
23
use Fisharebest\Webtrees\Factories\CacheFactory;
24
use Fisharebest\Webtrees\Factories\CalendarDateFactory;
25
use Fisharebest\Webtrees\Factories\ElementFactory;
26
use Fisharebest\Webtrees\Factories\EncodingFactory;
27
use Fisharebest\Webtrees\Factories\FamilyFactory;
28
use Fisharebest\Webtrees\Factories\FilesystemFactory;
29
use Fisharebest\Webtrees\Factories\GedcomRecordFactory;
30
use Fisharebest\Webtrees\Factories\HeaderFactory;
31
use Fisharebest\Webtrees\Factories\IdFactory;
32
use Fisharebest\Webtrees\Factories\ImageFactory;
33
use Fisharebest\Webtrees\Factories\IndividualFactory;
34
use Fisharebest\Webtrees\Factories\LocationFactory;
35
use Fisharebest\Webtrees\Factories\MarkdownFactory;
36
use Fisharebest\Webtrees\Factories\MediaFactory;
37
use Fisharebest\Webtrees\Factories\NoteFactory;
38
use Fisharebest\Webtrees\Factories\RepositoryFactory;
39
use Fisharebest\Webtrees\Factories\ResponseFactory;
40
use Fisharebest\Webtrees\Factories\RouteFactory;
41
use Fisharebest\Webtrees\Factories\SharedNoteFactory;
42
use Fisharebest\Webtrees\Factories\SlugFactory;
43
use Fisharebest\Webtrees\Factories\SourceFactory;
44
use Fisharebest\Webtrees\Factories\SubmissionFactory;
45
use Fisharebest\Webtrees\Factories\SubmitterFactory;
46
use Fisharebest\Webtrees\Factories\SurnameTraditionFactory;
47
use Fisharebest\Webtrees\Factories\TimeFactory;
48
use Fisharebest\Webtrees\Factories\TimestampFactory;
49
use Fisharebest\Webtrees\Factories\XrefFactory;
50
use Fisharebest\Webtrees\GedcomFilters\GedcomEncodingFilter;
51
use Fisharebest\Webtrees\Http\Dispatcher;
52
use Fisharebest\Webtrees\Http\Middleware\BadBotBlocker;
53
use Fisharebest\Webtrees\Http\Middleware\BaseUrl;
54
use Fisharebest\Webtrees\Http\Middleware\BootModules;
55
use Fisharebest\Webtrees\Http\Middleware\CheckForMaintenanceMode;
56
use Fisharebest\Webtrees\Http\Middleware\CheckForNewVersion;
57
use Fisharebest\Webtrees\Http\Middleware\ClientIp;
58
use Fisharebest\Webtrees\Http\Middleware\CompressResponse;
59
use Fisharebest\Webtrees\Http\Middleware\ContentLength;
60
use Fisharebest\Webtrees\Http\Middleware\DoHousekeeping;
61
use Fisharebest\Webtrees\Http\Middleware\EmitResponse;
62
use Fisharebest\Webtrees\Http\Middleware\ErrorHandler;
63
use Fisharebest\Webtrees\Http\Middleware\HandleExceptions;
64
use Fisharebest\Webtrees\Http\Middleware\LoadRoutes;
65
use Fisharebest\Webtrees\Http\Middleware\PublicFiles;
66
use Fisharebest\Webtrees\Http\Middleware\ReadConfigIni;
67
use Fisharebest\Webtrees\Http\Middleware\RegisterGedcomTags;
68
use Fisharebest\Webtrees\Http\Middleware\Router;
69
use Fisharebest\Webtrees\Http\Middleware\SecurityHeaders;
70
use Fisharebest\Webtrees\Http\Middleware\UpdateDatabaseSchema;
71
use Fisharebest\Webtrees\Http\Middleware\UseDatabase;
72
use Fisharebest\Webtrees\Http\Middleware\UseLanguage;
73
use Fisharebest\Webtrees\Http\Middleware\UseSession;
74
use Fisharebest\Webtrees\Http\Middleware\UseTheme;
75
use Fisharebest\Webtrees\Http\Middleware\UseTransaction;
76
use Fisharebest\Webtrees\Services\PhpService;
77
use Nyholm\Psr7\Factory\Psr17Factory;
78
use Nyholm\Psr7Server\ServerRequestCreator;
79
use Psr\Http\Message\ResponseFactoryInterface;
80
use Psr\Http\Message\ResponseInterface;
81
use Psr\Http\Message\ServerRequestFactoryInterface;
82
use Psr\Http\Message\StreamFactoryInterface;
83
use Psr\Http\Message\UploadedFileFactoryInterface;
84
use Psr\Http\Message\UriFactoryInterface;
85
86
use function date_default_timezone_set;
87
use function error_reporting;
88
use function mb_internal_encoding;
89
use function stream_filter_register;
90
91
use const E_ALL;
92
use const E_DEPRECATED;
93
use const E_USER_DEPRECATED;
94
95
/**
96
 * Definitions for the webtrees application.
97
 */
98
class Webtrees
99
{
100
    // The root folder of this installation
101
    public const string ROOT_DIR = __DIR__ . '/../';
0 ignored issues
show
A parse error occurred: Syntax error, unexpected T_STRING, expecting '=' on line 101 at column 24
Loading history...
102
103
    // This is the location of system data, such as temporary and cache files.
104
    // The system files are always in this location.
105
    // It is also the default location of user data, such as media and GEDCOM files.
106
    // The user files could be anywhere supported by Flysystem.
107
    public const string DATA_DIR = self::ROOT_DIR . 'data/';
108
109
    // Location of the file containing the database connection details.
110
    public const string CONFIG_FILE = self::DATA_DIR . 'config.ini.php';
111
112
    // Location of our modules.
113
    public const string MODULES_PATH = 'modules_v4/';
114
    public const string MODULES_DIR  = self::ROOT_DIR . self::MODULES_PATH;
115
116
    // Enable debugging on development builds.
117
    public const bool DEBUG = self::STABILITY !== '';
118
119
    // We want to know about all PHP errors during development, and fewer in production.
120
    public const int ERROR_REPORTING = self::DEBUG ? E_ALL : E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED;
121
122
    // Page layouts for various page types.
123
    public const string LAYOUT_ADMINISTRATION = 'layouts/administration';
124
    public const string LAYOUT_AJAX    = 'layouts/ajax';
125
    public const string LAYOUT_DEFAULT = 'layouts/default';
126
    public const string LAYOUT_ERROR   = 'layouts/error';
127
128
    // The name of the application.
129
    public const string NAME = 'webtrees';
130
131
    // Required version of database tables/columns/indexes/etc.
132
    public const int SCHEMA_VERSION = 45;
133
134
    // e.g. "-dev", "-alpha", "-beta", etc.
135
    public const string STABILITY = '-dev';
136
137
    // Version number.
138
    public const string VERSION = '2.2.5' . self::STABILITY;
139
140
    // Project website.
141
    public const string URL = 'https://webtrees.net/';
142
143
    // FAQ links.
144
    public const string URL_FAQ_EMAIL = 'https://webtrees.net/faq/email';
145
146
    // GEDCOM specification.
147
    public const string GEDCOM_PDF = 'https://webtrees.net/downloads/gedcom-5-5-1.pdf';
148
149
    private const array MIDDLEWARE = [
150
        ErrorHandler::class,
151
        EmitResponse::class,
152
        ReadConfigIni::class,
153
        BaseUrl::class,
154
        SecurityHeaders::class,
155
        HandleExceptions::class,
156
        PublicFiles::class,
157
        ClientIp::class,
158
        ContentLength::class,
159
        CompressResponse::class,
160
        BadBotBlocker::class,
161
        UseDatabase::class,
162
        UpdateDatabaseSchema::class,
163
        UseSession::class,
164
        UseLanguage::class,
165
        CheckForMaintenanceMode::class,
166
        UseTheme::class,
167
        DoHousekeeping::class,
168
        UseTransaction::class,
169
        CheckForNewVersion::class,
170
        LoadRoutes::class,
171
        RegisterGedcomTags::class,
172
        BootModules::class,
173
        Router::class,
174
    ];
175
176
    public static function new(): self
177
    {
178
        return new self();
179
    }
180
181
    /**
182
     * Initialise the application.
183
     */
184
    public function bootstrap(): self
185
    {
186
        // Show all errors and warnings in development, fewer in production.
187
        error_reporting(self::ERROR_REPORTING);
188
189
        // All modern software uses UTF-8 encoding.
190
        mb_internal_encoding('UTF-8');
191
192
        // Use UTC internally and convert to local time when displaying datetimes.
193
        date_default_timezone_set('UTC');
194
195
        // Factory objects
196
        Registry::cache(new CacheFactory());
197
        Registry::calendarDateFactory(new CalendarDateFactory());
198
        Registry::container(new Container());
199
        Registry::elementFactory(new ElementFactory());
200
        Registry::encodingFactory(new EncodingFactory());
201
        Registry::familyFactory(new FamilyFactory());
202
        Registry::filesystem(new FilesystemFactory());
203
        Registry::gedcomRecordFactory(new GedcomRecordFactory());
204
        Registry::headerFactory(new HeaderFactory());
205
        Registry::idFactory(new IdFactory());
206
        Registry::imageFactory(new ImageFactory(new PhpService()));
207
        Registry::individualFactory(new IndividualFactory());
208
        Registry::locationFactory(new LocationFactory());
209
        Registry::markdownFactory(new MarkdownFactory());
210
        Registry::mediaFactory(new MediaFactory());
211
        Registry::noteFactory(new NoteFactory());
212
        Registry::repositoryFactory(new RepositoryFactory());
213
        Registry::responseFactory(new ResponseFactory(new Psr17Factory(), new Psr17Factory()));
214
        Registry::routeFactory(new RouteFactory());
215
        Registry::sharedNoteFactory(new SharedNoteFactory());
216
        Registry::slugFactory(new SlugFactory(new PhpService()));
217
        Registry::sourceFactory(new SourceFactory());
218
        Registry::submissionFactory(new SubmissionFactory());
219
        Registry::submitterFactory(new SubmitterFactory());
220
        Registry::surnameTraditionFactory(new SurnameTraditionFactory());
221
        Registry::timeFactory(new TimeFactory());
222
        Registry::timestampFactory(new TimestampFactory());
223
        Registry::xrefFactory(new XrefFactory());
224
225
        // PSR7 messages and PSR17 message-factories
226
        Registry::container()
227
            ->set(ResponseFactoryInterface::class, new Psr17Factory())
228
            ->set(ServerRequestFactoryInterface::class, new Psr17Factory())
229
            ->set(StreamFactoryInterface::class, new Psr17Factory())
230
            ->set(UploadedFileFactoryInterface::class, new Psr17Factory())
231
            ->set(UriFactoryInterface::class, new Psr17Factory());
232
233
        stream_filter_register(GedcomEncodingFilter::class, GedcomEncodingFilter::class);
234
235
        return $this;
236
    }
237
238
    /**
239
     * Run the application.
240
     */
241
    public function run(string $php_sapi): int|ResponseInterface
242
    {
243
        if ($php_sapi === 'cli') {
244
            return $this->bootstrap()->cliRequest();
245
        }
246
247
        return $this->bootstrap()->httpRequest();
248
    }
249
250
    /**
251
     * Respond to a CLI request.
252
     */
253
    public function cliRequest(): int
254
    {
255
        $console = new Console();
256
257
        return $console->loadCommands()->bootstrap()->run();
258
    }
259
260
    /**
261
     * Respond to an HTTP request.
262
     */
263
    public function httpRequest(): ResponseInterface
264
    {
265
        $server_request_creator = new ServerRequestCreator(
266
            Registry::container()->get(ServerRequestFactoryInterface::class),
267
            Registry::container()->get(UriFactoryInterface::class),
268
            Registry::container()->get(UploadedFileFactoryInterface::class),
269
            Registry::container()->get(StreamFactoryInterface::class)
270
        );
271
272
        $request = $server_request_creator->fromGlobals();
273
274
        return Dispatcher::dispatch(middleware: self::MIDDLEWARE, request: $request);
275
    }
276
}
277