Passed
Push — main ( d9ea0e...d43b95 )
by Greg
06:36
created

Webtrees::container()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2023 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 Closure;
23
use ErrorException;
24
use Fisharebest\Webtrees\Contracts\ContainerInterface;
25
use Fisharebest\Webtrees\Factories\CacheFactory;
26
use Fisharebest\Webtrees\Factories\CalendarDateFactory;
27
use Fisharebest\Webtrees\Factories\ElementFactory;
28
use Fisharebest\Webtrees\Factories\EncodingFactory;
29
use Fisharebest\Webtrees\Factories\FamilyFactory;
30
use Fisharebest\Webtrees\Factories\FilesystemFactory;
31
use Fisharebest\Webtrees\Factories\GedcomRecordFactory;
32
use Fisharebest\Webtrees\Factories\HeaderFactory;
33
use Fisharebest\Webtrees\Factories\IdFactory;
34
use Fisharebest\Webtrees\Factories\ImageFactory;
35
use Fisharebest\Webtrees\Factories\IndividualFactory;
36
use Fisharebest\Webtrees\Factories\LocationFactory;
37
use Fisharebest\Webtrees\Factories\MarkdownFactory;
38
use Fisharebest\Webtrees\Factories\MediaFactory;
39
use Fisharebest\Webtrees\Factories\NoteFactory;
40
use Fisharebest\Webtrees\Factories\RepositoryFactory;
41
use Fisharebest\Webtrees\Factories\ResponseFactory;
42
use Fisharebest\Webtrees\Factories\RouteFactory;
43
use Fisharebest\Webtrees\Factories\SharedNoteFactory;
44
use Fisharebest\Webtrees\Factories\SlugFactory;
45
use Fisharebest\Webtrees\Factories\SourceFactory;
46
use Fisharebest\Webtrees\Factories\SubmissionFactory;
47
use Fisharebest\Webtrees\Factories\SubmitterFactory;
48
use Fisharebest\Webtrees\Factories\SurnameTraditionFactory;
49
use Fisharebest\Webtrees\Factories\TimeFactory;
50
use Fisharebest\Webtrees\Factories\TimestampFactory;
51
use Fisharebest\Webtrees\Factories\XrefFactory;
52
use Fisharebest\Webtrees\GedcomFilters\GedcomEncodingFilter;
53
use Fisharebest\Webtrees\Http\Middleware\BadBotBlocker;
54
use Fisharebest\Webtrees\Http\Middleware\BaseUrl;
55
use Fisharebest\Webtrees\Http\Middleware\BootModules;
56
use Fisharebest\Webtrees\Http\Middleware\CheckForMaintenanceMode;
57
use Fisharebest\Webtrees\Http\Middleware\CheckForNewVersion;
58
use Fisharebest\Webtrees\Http\Middleware\ClientIp;
59
use Fisharebest\Webtrees\Http\Middleware\CompressResponse;
60
use Fisharebest\Webtrees\Http\Middleware\ContentLength;
61
use Fisharebest\Webtrees\Http\Middleware\DoHousekeeping;
62
use Fisharebest\Webtrees\Http\Middleware\EmitResponse;
63
use Fisharebest\Webtrees\Http\Middleware\HandleExceptions;
64
use Fisharebest\Webtrees\Http\Middleware\LoadRoutes;
65
use Fisharebest\Webtrees\Http\Middleware\NoRouteFound;
66
use Fisharebest\Webtrees\Http\Middleware\PublicFiles;
67
use Fisharebest\Webtrees\Http\Middleware\ReadConfigIni;
68
use Fisharebest\Webtrees\Http\Middleware\RegisterGedcomTags;
69
use Fisharebest\Webtrees\Http\Middleware\Router;
70
use Fisharebest\Webtrees\Http\Middleware\SecurityHeaders;
71
use Fisharebest\Webtrees\Http\Middleware\UpdateDatabaseSchema;
72
use Fisharebest\Webtrees\Http\Middleware\UseDatabase;
73
use Fisharebest\Webtrees\Http\Middleware\UseLanguage;
74
use Fisharebest\Webtrees\Http\Middleware\UseSession;
75
use Fisharebest\Webtrees\Http\Middleware\UseTheme;
76
use Fisharebest\Webtrees\Http\Middleware\UseTransaction;
77
use Middleland\Dispatcher;
78
use Nyholm\Psr7\Factory\Psr17Factory;
79
use Nyholm\Psr7Server\ServerRequestCreator;
80
use Psr\Http\Message\ResponseFactoryInterface;
81
use Psr\Http\Message\ResponseInterface;
82
use Psr\Http\Message\ServerRequestFactoryInterface;
83
use Psr\Http\Message\StreamFactoryInterface;
84
use Psr\Http\Message\UploadedFileFactoryInterface;
85
use Psr\Http\Message\UriFactoryInterface;
86
87
use function date_default_timezone_set;
88
use function error_reporting;
89
use function mb_internal_encoding;
90
use function set_error_handler;
91
use function stream_filter_register;
92
93
use const E_ALL;
94
use const E_DEPRECATED;
95
use const E_USER_DEPRECATED;
96
use const PHP_SAPI;
97
98
/**
99
 * Definitions for the webtrees application.
100
 */
101
class Webtrees
102
{
103
    // The root folder of this installation
104
    public const ROOT_DIR = __DIR__ . '/../';
105
106
    // This is the location of system data, such as temporary and cache files.
107
    // The system files are always in this location.
108
    // It is also the default location of user data, such as media and GEDCOM files.
109
    // The user files could be anywhere supported by Flysystem.
110
    public const DATA_DIR = self::ROOT_DIR . 'data/';
111
112
    // Location of the file containing the database connection details.
113
    public const CONFIG_FILE = self::DATA_DIR . 'config.ini.php';
114
115
    // Location of the file that triggers maintenance mode.
116
    public const OFFLINE_FILE = self::DATA_DIR . 'offline.txt';
117
118
    // Location of our modules.
119
    public const MODULES_PATH = 'modules_v4/';
120
    public const MODULES_DIR  = self::ROOT_DIR . self::MODULES_PATH;
121
122
    // Enable debugging on development builds.
123
    public const DEBUG = self::STABILITY !== '';
124
125
    // We want to know about all PHP errors during development, and fewer in production.
126
    public const ERROR_REPORTING = self::DEBUG ? E_ALL : E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED;
127
128
    // Page layouts for various page types.
129
    public const LAYOUT_ADMINISTRATION = 'layouts/administration';
130
    public const LAYOUT_AJAX           = 'layouts/ajax';
131
    public const LAYOUT_DEFAULT        = 'layouts/default';
132
    public const LAYOUT_ERROR          = 'layouts/error';
133
134
    // The name of the application.
135
    public const NAME = 'webtrees';
136
137
    // Required version of database tables/columns/indexes/etc.
138
    public const SCHEMA_VERSION = 45;
139
140
    // e.g. "-dev", "-alpha", "-beta", etc.
141
    public const STABILITY = '-dev';
142
143
    // Version number.
144
    public const VERSION = '2.2.0' . self::STABILITY;
145
146
    // Project website.
147
    public const URL = 'https://webtrees.net/';
148
149
    // FAQ links.
150
    public const URL_FAQ_EMAIL = 'https://webtrees.net/faq/email';
151
152
    // GEDCOM specification.
153
    public const GEDCOM_PDF = 'https://webtrees.net/downloads/gedcom-5-5-1.pdf';
154
155
    private const MIDDLEWARE = [
156
        EmitResponse::class,
157
        SecurityHeaders::class,
158
        ReadConfigIni::class,
159
        BaseUrl::class,
160
        HandleExceptions::class,
161
        PublicFiles::class,
162
        ClientIp::class,
163
        ContentLength::class,
164
        CompressResponse::class,
165
        BadBotBlocker::class,
166
        UseDatabase::class,
167
        UpdateDatabaseSchema::class,
168
        UseSession::class,
169
        UseLanguage::class,
170
        CheckForMaintenanceMode::class,
171
        UseTheme::class,
172
        DoHousekeeping::class,
173
        UseTransaction::class,
174
        CheckForNewVersion::class,
175
        LoadRoutes::class,
176
        RegisterGedcomTags::class,
177
        BootModules::class,
178
        Router::class,
179
        NoRouteFound::class,
180
    ];
181
182
    /**
183
     * Initialise the application.
184
     *
185
     * @return static
186
     */
187
    public function bootstrap(): static
188
    {
189
        // Show all errors and warnings in development, fewer in production.
190
        error_reporting(self::ERROR_REPORTING);
191
        set_error_handler($this->phpErrorHandler());
192
193
        // All modern software uses UTF-8 encoding.
194
        mb_internal_encoding('UTF-8');
195
196
        // Use UTC internally and convert to local time when displaying datetimes.
197
        date_default_timezone_set('UTC');
198
199
        // Factory objects
200
        Registry::cache(new CacheFactory());
201
        Registry::calendarDateFactory(new CalendarDateFactory());
202
        Registry::container(new Container());
0 ignored issues
show
Bug introduced by
The type Fisharebest\Webtrees\Container was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
203
        Registry::elementFactory(new ElementFactory());
204
        Registry::encodingFactory(new EncodingFactory());
205
        Registry::familyFactory(new FamilyFactory());
206
        Registry::filesystem(new FilesystemFactory());
207
        Registry::gedcomRecordFactory(new GedcomRecordFactory());
208
        Registry::headerFactory(new HeaderFactory());
209
        Registry::idFactory(new IdFactory());
210
        Registry::imageFactory(new ImageFactory());
211
        Registry::individualFactory(new IndividualFactory());
212
        Registry::locationFactory(new LocationFactory());
213
        Registry::markdownFactory(new MarkdownFactory());
214
        Registry::mediaFactory(new MediaFactory());
215
        Registry::noteFactory(new NoteFactory());
216
        Registry::repositoryFactory(new RepositoryFactory());
217
        Registry::responseFactory(new ResponseFactory(new Psr17Factory(), new Psr17Factory()));
218
        Registry::routeFactory(new RouteFactory());
219
        Registry::sharedNoteFactory(new SharedNoteFactory());
220
        Registry::slugFactory(new SlugFactory());
221
        Registry::sourceFactory(new SourceFactory());
222
        Registry::submissionFactory(new SubmissionFactory());
223
        Registry::submitterFactory(new SubmitterFactory());
224
        Registry::surnameTraditionFactory(new SurnameTraditionFactory());
225
        Registry::timeFactory(new TimeFactory());
226
        Registry::timestampFactory(new TimestampFactory());
227
        Registry::xrefFactory(new XrefFactory());
228
229
        // PSR7 messages and PSR17 message-factories
230
        Registry::container()
231
            ->set(ResponseFactoryInterface::class, new Psr17Factory())
232
            ->set(ServerRequestFactoryInterface::class, new Psr17Factory())
233
            ->set(StreamFactoryInterface::class, new Psr17Factory())
234
            ->set(UploadedFileFactoryInterface::class, new Psr17Factory())
235
            ->set(UriFactoryInterface::class, new Psr17Factory());
236
237
        stream_filter_register(GedcomEncodingFilter::class, GedcomEncodingFilter::class);
238
239
        return $this;
240
    }
241
242
    /**
243
     * Run the application.
244
     *
245
     * @return void
246
     */
247
    public function run(): void
248
    {
249
        if (PHP_SAPI === 'cli') {
250
            $this->cliRequest();
251
        } else {
252
            $this->httpRequest();
253
        };
254
    }
255
256
    /**
257
     * Respond to a CLI request.
258
     *
259
     * @return void
260
     */
261
    public function cliRequest(): void
262
    {
263
        // CLI handler will go here.
264
    }
265
266
    /**
267
     * Respond to an HTTP request.
268
     *
269
     * @return ResponseInterface
270
     */
271
    public function httpRequest(): ResponseInterface
272
    {
273
        $server_request_creator = new ServerRequestCreator(
274
            Registry::container()->get(ServerRequestFactoryInterface::class),
275
            Registry::container()->get(UriFactoryInterface::class),
276
            Registry::container()->get(UploadedFileFactoryInterface::class),
277
            Registry::container()->get(StreamFactoryInterface::class)
278
        );
279
280
        $request = $server_request_creator->fromGlobals();
281
282
        $dispatcher = new Dispatcher(self::MIDDLEWARE, Registry::container());
283
284
        return $dispatcher->dispatch($request);
285
    }
286
287
    /**
288
     * An error handler that can be passed to set_error_handler().
289
     *
290
     * @return Closure(int,string,string,int):bool
291
     */
292
    private function phpErrorHandler(): Closure
293
    {
294
        return static function (int $errno, string $errstr, string $errfile, int $errline): bool {
295
            // Ignore errors that are silenced with '@'
296
            if (error_reporting() & $errno) {
297
                throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
298
            }
299
300
            return true;
301
        };
302
    }
303
}
304