summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Database.php2
-rw-r--r--app/DebugBar.php10
-rw-r--r--app/Exceptions/Handler.php98
-rw-r--r--app/Helpers/functions.php2
-rw-r--r--app/Http/Controllers/Admin/ControlPanelController.php3
-rw-r--r--app/Http/Controllers/Admin/UpgradeController.php2
-rw-r--r--app/Http/Controllers/ErrorController.php93
-rw-r--r--app/Http/Controllers/PlaceHierarchyController.php2
-rw-r--r--app/Http/Controllers/SetupController.php9
-rw-r--r--app/Http/Middleware/CheckForMaintenanceMode.php7
-rw-r--r--app/Http/Middleware/DoHousekeeping.php3
-rw-r--r--app/Http/Middleware/HandleExceptions.php90
-rw-r--r--app/Http/Middleware/ModuleMiddleware.php2
-rw-r--r--app/Http/Middleware/PhpEnvironment.php48
-rw-r--r--app/Http/Middleware/RequestRouter.php4
-rw-r--r--app/Http/Middleware/UseDebugbar.php42
-rw-r--r--app/I18N.php4
-rw-r--r--app/Module/AbstractModule.php3
-rw-r--r--app/Module/FanChartModule.php3
-rw-r--r--app/Module/ModuleThemeTrait.php5
-rw-r--r--app/Module/PedigreeMapModule.php2
-rw-r--r--app/Module/PlacesModule.php2
-rw-r--r--app/Services/HousekeepingService.php4
-rw-r--r--app/Services/ModuleService.php2
-rw-r--r--app/Services/UpgradeService.php6
-rw-r--r--app/View.php2
-rw-r--r--app/Webtrees.php177
-rw-r--r--index.php96
-rw-r--r--resources/views/setup/step-4-database-sqlite.phtml5
-rw-r--r--tests/TestCase.php5
-rw-r--r--tests/app/Module/AhnentafelReportModuleTest.php3
-rw-r--r--tests/app/Module/BirthDeathMarriageReportModuleTest.php3
-rw-r--r--tests/app/Module/BirthReportModuleTest.php3
-rw-r--r--tests/app/Module/CemeteryReportModuleTest.php3
-rw-r--r--tests/app/Module/ChangeReportModuleTest.php3
-rw-r--r--tests/app/Module/DeathReportModuleTest.php3
-rw-r--r--tests/app/Module/DescendancyReportModuleTest.php3
-rw-r--r--tests/app/Module/FactSourcesReportModuleTest.php3
-rw-r--r--tests/app/Module/FamilyGroupReportModuleTest.php3
-rw-r--r--tests/app/Module/IndividualFamiliesReportModuleTest.php3
-rw-r--r--tests/app/Module/IndividualReportModuleTest.php3
-rw-r--r--tests/app/Module/MarriageReportModuleTest.php3
-rw-r--r--tests/app/Module/MissingFactsReportModuleTest.php3
-rw-r--r--tests/app/Module/OccupationReportModuleTest.php3
-rw-r--r--tests/app/Module/PedigreeReportModuleTest.php3
-rw-r--r--tests/app/Module/RelatedIndividualsReportModuleTest.php3
-rw-r--r--tests/app/WebtreesTest.php15
47 files changed, 414 insertions, 382 deletions
diff --git a/app/Database.php b/app/Database.php
index b5004f5623..d2d7022a80 100644
--- a/app/Database.php
+++ b/app/Database.php
@@ -37,7 +37,7 @@ class Database
$config['dbtype'] = $config['dbtype'] ?? 'mysql';
if ($config['dbtype'] === 'sqlite') {
- $config['dbname'] = WT_ROOT . 'data/' . $config['dbname'] . '.sqlite';
+ $config['dbname'] = Webtrees::ROOT_DIR . 'data/' . $config['dbname'] . '.sqlite';
}
$capsule = new DB();
diff --git a/app/DebugBar.php b/app/DebugBar.php
index 1fa24534d8..8df049566e 100644
--- a/app/DebugBar.php
+++ b/app/DebugBar.php
@@ -46,14 +46,12 @@ class DebugBar
*
* @return void
*/
- public static function init(bool $enable = true): void
+ public static function enable(): void
{
- if ($enable) {
- self::$debugbar = new StandardDebugBar();
- self::$debugbar->addCollector(new ViewCollector());
+ self::$debugbar = new StandardDebugBar();
+ self::$debugbar->addCollector(new ViewCollector());
- self::$renderer = self::$debugbar->getJavascriptRenderer('./vendor/maximebf/debugbar/src/DebugBar/Resources/');
- }
+ self::$renderer = self::$debugbar->getJavascriptRenderer('./vendor/maximebf/debugbar/src/DebugBar/Resources/');
}
/**
diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php
deleted file mode 100644
index ac8dc60932..0000000000
--- a/app/Exceptions/Handler.php
+++ /dev/null
@@ -1,98 +0,0 @@
-<?php
-/**
- * webtrees: online genealogy
- * Copyright (C) 2019 webtrees development team
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-declare(strict_types=1);
-
-namespace Fisharebest\Webtrees\Exceptions;
-
-use Closure;
-use ErrorException;
-use Fisharebest\Webtrees\Http\Controllers\ErrorController;
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use Symfony\Component\HttpKernel\Exception\HttpException;
-use Throwable;
-use function error_reporting;
-use function ob_end_clean;
-use function ob_get_level;
-
-/**
- * Convert an exception into an HTTP response
- */
-class Handler
-{
- /**
- * An error handler that can be passed to set_error_handler().
- * Converts errors to exceptions
- *
- * @return Closure
- */
- public static function phpErrorHandler(): Closure
- {
- return static function (int $errno, string $errstr, string $errfile, int $errline): bool {
- // Ignore errors that are silenced with '@'
- if (error_reporting() & $errno) {
- throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
- }
-
- return true;
- };
- }
-
- /**
- * A final exception handler that can be passed to set_exception_handler().
- * Display any exception that are not caught by the middleware exception handler.
- * Typically, this will be errors in index.php, errors in the exception handler
- * and errors while displaying errors.
- *
- * @return Closure
- */
- public static function phpExceptionHandler(): Closure
- {
- return static function (Throwable $ex): void {
- $trace = $ex->getMessage() . PHP_EOL . $ex->getTraceAsString();
- $trace = str_replace(WT_ROOT, '…/', $trace);
-
- while (ob_get_level() > 0) {
- ob_end_clean();
- }
-
- echo '<html lang="en"><head><title>Error</title><meta charset="UTF-8"></head><body><pre>' . $trace . '</pre></body></html>';
- };
- }
-
- /**
- * Render an exception into an HTTP response.
- *
- * @param ServerRequestInterface $request
- * @param Throwable $exception
- *
- * @return ResponseInterface
- */
- public function render(ServerRequestInterface $request, Throwable $exception): ResponseInterface
- {
- $controller = new ErrorController();
-
- if ($exception instanceof HttpException) {
- if ($request->getHeaderLine('X-Requested-With') !== '') {
- return $controller->ajaxErrorResponse($exception);
- }
-
- return $controller->errorResponse($exception);
- }
-
- return $controller->unhandledExceptionResponse($request, $exception);
- }
-}
diff --git a/app/Helpers/functions.php b/app/Helpers/functions.php
index 5d9fb57f30..d4ac3179ed 100644
--- a/app/Helpers/functions.php
+++ b/app/Helpers/functions.php
@@ -55,7 +55,7 @@ function asset(string $path): string
if (Webtrees::STABILITY === '') {
$version = Webtrees::VERSION;
} else {
- $version = filemtime(WT_ROOT . 'public/' . $path);
+ $version = filemtime(Webtrees::ROOT_DIR . 'public/' . $path);
}
return 'public/' . $path . '?v=' . $version;
diff --git a/app/Http/Controllers/Admin/ControlPanelController.php b/app/Http/Controllers/Admin/ControlPanelController.php
index 960916aa50..ae532c9ae4 100644
--- a/app/Http/Controllers/Admin/ControlPanelController.php
+++ b/app/Http/Controllers/Admin/ControlPanelController.php
@@ -43,6 +43,7 @@ use Fisharebest\Webtrees\Services\ServerCheckService;
use Fisharebest\Webtrees\Services\UpgradeService;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
@@ -73,7 +74,7 @@ class ControlPanelController extends AbstractAdminController
ServerCheckService $server_check_service,
UserService $user_service
): ResponseInterface {
- $filesystem = new Filesystem(new Local(WT_ROOT));
+ $filesystem = new Filesystem(new Local(Webtrees::ROOT_DIR));
$files_to_delete = $housekeeping_service->deleteOldWebtreesFiles($filesystem);
return $this->viewResponse('admin/control-panel', [
diff --git a/app/Http/Controllers/Admin/UpgradeController.php b/app/Http/Controllers/Admin/UpgradeController.php
index fea8b9332b..277d7bcfc7 100644
--- a/app/Http/Controllers/Admin/UpgradeController.php
+++ b/app/Http/Controllers/Admin/UpgradeController.php
@@ -90,7 +90,7 @@ class UpgradeController extends AbstractAdminController
$this->filesystem = $filesystem;
$this->upgrade_service = $upgrade_service;
- $this->root_filesystem = new Filesystem(new CachedAdapter(new Local(WT_ROOT), new Memory()));
+ $this->root_filesystem = new Filesystem(new CachedAdapter(new Local(Webtrees::ROOT_DIR), new Memory()));
$this->temporary_filesystem = new Filesystem(new ChrootAdapter($this->filesystem, self::UPGRADE_FOLDER));
}
diff --git a/app/Http/Controllers/ErrorController.php b/app/Http/Controllers/ErrorController.php
deleted file mode 100644
index b77e36736c..0000000000
--- a/app/Http/Controllers/ErrorController.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-/**
- * webtrees: online genealogy
- * Copyright (C) 2019 webtrees development team
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-declare(strict_types=1);
-
-namespace Fisharebest\Webtrees\Http\Controllers;
-
-use Fig\Http\Message\StatusCodeInterface;
-use Fisharebest\Webtrees\Auth;
-use Fisharebest\Webtrees\Log;
-use Fisharebest\Webtrees\Tree;
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use Symfony\Component\HttpKernel\Exception\HttpException;
-use Throwable;
-use function str_replace;
-
-/**
- * Controller for error handling.
- */
-class ErrorController extends AbstractBaseController implements StatusCodeInterface
-{
- /**
- * Convert an exception into an error message
- *
- * @param HttpException $ex
- *
- * @return ResponseInterface
- */
- public function errorResponse(HttpException $ex): ResponseInterface
- {
- return $this->viewResponse('components/alert-danger', [
- 'alert' => $ex->getMessage(),
- 'title' => $ex->getMessage(),
- ], $ex->getStatusCode());
- }
-
- /**
- * Convert an exception into an error message
- *
- * @param HttpException $ex
- *
- * @return ResponseInterface
- */
- public function ajaxErrorResponse(HttpException $ex): ResponseInterface
- {
- return response(view('components/alert-danger', [
- 'alert' => $ex->getMessage(),
- ]), $ex->getStatusCode());
- }
-
- /**
- * Convert an exception into an error message
- *
- * @param ServerRequestInterface $request
- * @param Throwable $ex
- *
- * @return ResponseInterface
- */
- public function unhandledExceptionResponse(ServerRequestInterface $request, Throwable $ex): ResponseInterface
- {
- // Create a stack dump for the exception
- $trace = $ex->getMessage() . PHP_EOL . $ex->getTraceAsString();
- $trace = str_replace(WT_ROOT, '…/', $trace);
-
- try {
- Log::addErrorLog($trace);
- } catch (Throwable $ex2) {
- // Must have been a problem with the database. Nothing we can do here.
- }
-
- if ($request->getHeaderLine('X-Requested-With') !== '') {
- return response(view('components/alert-danger', ['alert' => $trace]), self::STATUS_INTERNAL_SERVER_ERROR);
- }
-
- return $this->viewResponse('errors/unhandled-exception', [
- 'title' => 'Error',
- 'error' => $trace,
- ], self::STATUS_INTERNAL_SERVER_ERROR);
- }
-}
diff --git a/app/Http/Controllers/PlaceHierarchyController.php b/app/Http/Controllers/PlaceHierarchyController.php
index de0d582c80..b836760b75 100644
--- a/app/Http/Controllers/PlaceHierarchyController.php
+++ b/app/Http/Controllers/PlaceHierarchyController.php
@@ -271,7 +271,7 @@ class PlaceHierarchyController extends AbstractBaseController
$placeObj = new Place($reference, $tree);
$places = $placeObj->getChildPlaces();
$features = [];
- $flag_path = Webtrees::MODULES_PATH . 'openstreetmap/';
+ $flag_path = Webtrees::MODULES_DIR . 'openstreetmap/';
$showlink = true;
if (empty($places)) {
$places[] = $placeObj;
diff --git a/app/Http/Controllers/SetupController.php b/app/Http/Controllers/SetupController.php
index 453e0199ca..cb992c8979 100644
--- a/app/Http/Controllers/SetupController.php
+++ b/app/Http/Controllers/SetupController.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
namespace Fisharebest\Webtrees\Http\Controllers;
+use function app;
use function define;
use Exception;
use Fisharebest\Localization\Locale;
@@ -32,6 +33,8 @@ use Fisharebest\Webtrees\Services\ServerCheckService;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Session;
use Fisharebest\Webtrees\Webtrees;
+use Illuminate\Cache\ArrayStore;
+use Illuminate\Cache\Repository;
use Illuminate\Database\Capsule\Manager;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -100,8 +103,10 @@ class SetupController extends AbstractBaseController
*/
public function setup(ServerRequestInterface $request): ResponseInterface
{
- // Required by I18N.
+ // Mini "bootstrap"
define('WT_DATA_DIR', 'data/');
+ app()->instance(ServerRequestInterface::class, $request);
+ app()->instance('cache.array', new Repository(new ArrayStore()));
$data = $this->userData($request);
@@ -327,7 +332,7 @@ class SetupController extends AbstractBaseController
{
// Try to create the SQLite database, if it does not already exist.
if ($data['dbtype'] === 'sqlite') {
- touch(WT_ROOT . 'data/' . $data['dbname'] . '.sqlite');
+ touch(Webtrees::ROOT_DIR . 'data/' . $data['dbname'] . '.sqlite');
}
// Try to create the MySQL database, if it does not already exist.
diff --git a/app/Http/Middleware/CheckForMaintenanceMode.php b/app/Http/Middleware/CheckForMaintenanceMode.php
index 25be00b806..f134ef4ed3 100644
--- a/app/Http/Middleware/CheckForMaintenanceMode.php
+++ b/app/Http/Middleware/CheckForMaintenanceMode.php
@@ -18,6 +18,7 @@ declare(strict_types=1);
namespace Fisharebest\Webtrees\Http\Middleware;
use Fig\Http\Message\StatusCodeInterface;
+use Fisharebest\Webtrees\Webtrees;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
@@ -36,11 +37,9 @@ class CheckForMaintenanceMode implements MiddlewareInterface
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
- $file = WT_ROOT . 'data/offline.txt';
-
- if (file_exists($file)) {
+ if (file_exists(Webtrees::OFFLINE_FILE)) {
$html = view('layouts/offline', [
- 'message' => file_get_contents($file),
+ 'message' => file_get_contents(Webtrees::OFFLINE_FILE),
'url' => $request->getUri(),
]);
diff --git a/app/Http/Middleware/DoHousekeeping.php b/app/Http/Middleware/DoHousekeeping.php
index a1799d20e1..2c9139bc00 100644
--- a/app/Http/Middleware/DoHousekeeping.php
+++ b/app/Http/Middleware/DoHousekeeping.php
@@ -19,6 +19,7 @@ namespace Fisharebest\Webtrees\Http\Middleware;
use Fig\Http\Message\RequestMethodInterface;
use Fisharebest\Webtrees\Services\HousekeepingService;
+use Fisharebest\Webtrees\Webtrees;
use League\Flysystem\Adapter\Local;
use League\Flysystem\Filesystem;
use League\Flysystem\FilesystemInterface;
@@ -90,7 +91,7 @@ class DoHousekeeping implements MiddlewareInterface
private function runHousekeeping(): void
{
$data_filesystem = app(FilesystemInterface::class);
- $root_filesystem = new Filesystem(new Local(WT_ROOT));
+ $root_filesystem = new Filesystem(new Local(Webtrees::ROOT_DIR));
// Clear files in the (user-specified) data folder - which might not be local files
$this->housekeeping_service->deleteOldFiles($data_filesystem, 'cache', self::MAX_CACHE_AGE);
diff --git a/app/Http/Middleware/HandleExceptions.php b/app/Http/Middleware/HandleExceptions.php
index a43ad53ca8..415e139a45 100644
--- a/app/Http/Middleware/HandleExceptions.php
+++ b/app/Http/Middleware/HandleExceptions.php
@@ -17,50 +17,102 @@ declare(strict_types=1);
namespace Fisharebest\Webtrees\Http\Middleware;
-use Fisharebest\Webtrees\Http\Controllers\ErrorController;
+use Fig\Http\Message\StatusCodeInterface;
+use Fisharebest\Webtrees\Http\ViewResponseTrait;
+use Fisharebest\Webtrees\Log;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Throwable;
+use function dirname;
+use function response;
+use function str_replace;
+use function view;
+use const PHP_EOL;
/**
* Middleware to handle and render errors.
*/
-class HandleExceptions implements MiddlewareInterface
+class HandleExceptions implements MiddlewareInterface, StatusCodeInterface
{
- /** @var ErrorController */
- private $error_controller;
+ use ViewResponseTrait;
/**
- * ExceptionHandler constructor.
+ * @param ServerRequestInterface $request
+ * @param RequestHandlerInterface $handler
*
- * @param ErrorController $error_controller
+ * @return ResponseInterface
+ * @throws Throwable
*/
- public function __construct(ErrorController $error_controller)
+ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
- $this->error_controller = $error_controller;
+ try {
+ try {
+ return $handler->handle($request);
+ } catch (HttpException $exception) {
+ $original_exception = $exception;
+
+ return $this->httpExceptionResponse($request, $exception);
+ } catch (Throwable $exception) {
+ $original_exception = $exception;
+
+ return $this->unhandledExceptionResponse($request, $exception);
+ }
+ } catch (Throwable $exception) {
+ // If we can't handle the exception, rethrow it.
+ throw $original_exception;
+ }
}
/**
- * @param ServerRequestInterface $request
- * @param RequestHandlerInterface $handler
+ * @param ServerRequestInterface $request
+ * @param HttpException $exception
*
* @return ResponseInterface
*/
- public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+ private function httpExceptionResponse(ServerRequestInterface $request, HttpException $exception): ResponseInterface
{
- try {
- return $handler->handle($request);
- } catch (HttpException $exception) {
- if ($request->getHeaderLine('X-Requested-With') !== '') {
- return $this->error_controller->ajaxErrorResponse($exception);
- }
+ if ($request->getHeaderLine('X-Requested-With') !== '') {
+ return $this->viewResponse('components/alert-danger', [
+ 'alert' => $exception->getMessage(),
+ 'title' => $exception->getMessage(),
+ ], $exception->getStatusCode());
+ }
+
+ return response(view('components/alert-danger', [
+ 'alert' => $exception->getMessage(),
+ 'title' => $exception->getMessage(),
+ ]), $exception->getStatusCode());
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ * @param Throwable $exception
+ *
+ * @return ResponseInterface
+ */
+ private function unhandledExceptionResponse(ServerRequestInterface $request, Throwable $exception): ResponseInterface
+ {
+ // Create a stack dump for the exception
+ $base_path = dirname(__DIR__, 3);
+ $trace = $exception->getMessage() . PHP_EOL . $exception->getTraceAsString();
+ $trace = str_replace($base_path, '…', $trace);
- return $this->error_controller->errorResponse($exception);
+ try {
+ Log::addErrorLog($trace);
} catch (Throwable $exception) {
- return $this->error_controller->unhandledExceptionResponse($request, $exception);
+ // Must have been a problem with the database. Nothing we can do here.
}
+
+ if ($request->getHeaderLine('X-Requested-With') !== '') {
+ return response(view('components/alert-danger', ['alert' => $trace]), self::STATUS_INTERNAL_SERVER_ERROR);
+ }
+
+ return $this->viewResponse('errors/unhandled-exception', [
+ 'title' => 'Error',
+ 'error' => $trace,
+ ], self::STATUS_INTERNAL_SERVER_ERROR);
}
}
diff --git a/app/Http/Middleware/ModuleMiddleware.php b/app/Http/Middleware/ModuleMiddleware.php
index 0fd245c2c8..64efb7666c 100644
--- a/app/Http/Middleware/ModuleMiddleware.php
+++ b/app/Http/Middleware/ModuleMiddleware.php
@@ -40,8 +40,6 @@ class ModuleMiddleware implements MiddlewareInterface
}
/**
- * Update the database schema, if necessary.
- *
* @param ServerRequestInterface $request
* @param RequestHandlerInterface $handler
*
diff --git a/app/Http/Middleware/PhpEnvironment.php b/app/Http/Middleware/PhpEnvironment.php
new file mode 100644
index 0000000000..4f399403e0
--- /dev/null
+++ b/app/Http/Middleware/PhpEnvironment.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2019 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+declare(strict_types=1);
+
+namespace Fisharebest\Webtrees\Http\Middleware;
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use function date_default_timezone_set;
+use function mb_internal_encoding;
+
+/**
+ * Middleware to set set the PHP environment.
+ */
+class PhpEnvironment implements MiddlewareInterface
+{
+ /**
+ * @param ServerRequestInterface $request
+ * @param RequestHandlerInterface $handler
+ *
+ * @return ResponseInterface
+ */
+ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+ {
+ // All modern software uses UTF-8 encoding.
+ mb_internal_encoding('UTF-8');
+
+ // We use UTC internally and convert to local time when displaying datetimes.
+ date_default_timezone_set('UTC');
+
+ return $handler->handle($request);
+ }
+}
diff --git a/app/Http/Middleware/RequestRouter.php b/app/Http/Middleware/RequestRouter.php
index f7fa7228d0..ba3e4dc16f 100644
--- a/app/Http/Middleware/RequestRouter.php
+++ b/app/Http/Middleware/RequestRouter.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
namespace Fisharebest\Webtrees\Http\Middleware;
+use Fisharebest\Webtrees\DebugBar;
use Illuminate\Support\Str;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -50,6 +51,9 @@ class RequestRouter implements MiddlewareInterface
// Find the routing for the selected route.
$routing = $routes[$request->getMethod() . ':' . $route] ?? '';
+ // This timer gets stopped automatically when we generate the response.
+ DebugBar::startMeasure('controller_action');
+
// No route matched?
if ($routing === '') {
return $handler->handle($request);
diff --git a/app/Http/Middleware/UseDebugbar.php b/app/Http/Middleware/UseDebugbar.php
index 8410e4a2e1..aa2e080faa 100644
--- a/app/Http/Middleware/UseDebugbar.php
+++ b/app/Http/Middleware/UseDebugbar.php
@@ -17,15 +17,22 @@ declare(strict_types=1);
namespace Fisharebest\Webtrees\Http\Middleware;
+use DebugBar\StandardDebugBar;
use Fig\Http\Message\StatusCodeInterface;
use Fisharebest\Webtrees\DebugBar;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
+use function class_exists;
/**
* Middleware to add debugging info to the PHP debugbar.
+ * Use `composer install --dev` on a development build to enable.
+ * Note that you may need to increase the size of the fcgi buffers on nginx.
+ * e.g. add these lines to your fastcgi_params file:
+ * fastcgi_buffers 16 16m;
+ * fastcgi_buffer_size 32m;
*/
class UseDebugbar implements MiddlewareInterface, StatusCodeInterface
{
@@ -37,17 +44,14 @@ class UseDebugbar implements MiddlewareInterface, StatusCodeInterface
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
- if (class_exists(DebugBar::class)) {
- // This timer gets stopped automatically when we generate the response.
- DebugBar::startMeasure('controller_action');
+ if (class_exists(StandardDebugBar::class)) {
+ DebugBar::enable();
+
$response = $handler->handle($request);
- $status_code = $response->getStatusCode();
- if ($status_code === self::STATUS_FOUND || $status_code === self::STATUS_MOVED_PERMANENTLY) {
- // Show the debug data on the next page
+ if ($this->shouldSendDataOnNextPage($response)) {
DebugBar::stackData();
- } elseif ($request->getHeaderLine('X-Requested-With') !== '') {
- // Use HTTP headers and some jQuery to add debug to the current page.
+ } elseif ($this->shouldSendDataInHeaders($request)) {
DebugBar::sendDataInHeaders();
}
@@ -56,4 +60,26 @@ class UseDebugbar implements MiddlewareInterface, StatusCodeInterface
return $handler->handle($request);
}
+
+ /**
+ * @param ResponseInterface $response
+ *
+ * @return bool
+ */
+ private function shouldSendDataOnNextPage(ResponseInterface $response): bool
+ {
+ $status_code = $response->getStatusCode();
+
+ return $status_code === self::STATUS_FOUND || $status_code === self::STATUS_MOVED_PERMANENTLY;
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ *
+ * @return bool
+ */
+ private function shouldSendDataInHeaders(ServerRequestInterface $request): bool
+ {
+ return $request->getHeaderLine('X-Requested-With') !== '';
+ }
}
diff --git a/app/I18N.php b/app/I18N.php
index 48a5129868..43d45c26a6 100644
--- a/app/I18N.php
+++ b/app/I18N.php
@@ -316,7 +316,7 @@ class I18N
if ($code !== '') {
// Create the specified locale
self::$locale = Locale::create($code);
- } elseif (Session::has('language') && file_exists(WT_ROOT . 'resources/lang/' . Session::get('language') . '/messages.mo')) {
+ } elseif (Session::has('language') && file_exists(Webtrees::ROOT_DIR . 'resources/lang/' . Session::get('language') . '/messages.mo')) {
// Select a previously used locale
self::$locale = Locale::create(Session::get('language'));
} else {
@@ -349,7 +349,7 @@ class I18N
}
// Load the translation file
- $translation_file = WT_ROOT . 'resources/lang/' . self::$locale->languageTag() . '/messages.mo';
+ $translation_file = Webtrees::ROOT_DIR . 'resources/lang/' . self::$locale->languageTag() . '/messages.mo';
if (!file_exists($translation_file)) {
// Test and dev environments may not have the compiled translations
diff --git a/app/Module/AbstractModule.php b/app/Module/AbstractModule.php
index 23d0d575e0..9c63dc4156 100644
--- a/app/Module/AbstractModule.php
+++ b/app/Module/AbstractModule.php
@@ -20,6 +20,7 @@ namespace Fisharebest\Webtrees\Module;
use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Http\ViewResponseTrait;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Support\Collection;
use stdClass;
@@ -235,6 +236,6 @@ abstract class AbstractModule implements ModuleInterface
*/
public function resourcesFolder(): string
{
- return WT_ROOT . 'resources/';
+ return Webtrees::ROOT_DIR . 'resources/';
}
}
diff --git a/app/Module/FanChartModule.php b/app/Module/FanChartModule.php
index 28defada7d..0071badacf 100644
--- a/app/Module/FanChartModule.php
+++ b/app/Module/FanChartModule.php
@@ -24,6 +24,7 @@ use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Menu;
use Fisharebest\Webtrees\Services\ChartService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -307,7 +308,7 @@ class FanChartModule extends AbstractModule implements ModuleChartInterface
(int) $tx,
(int) $ty,
$foreground,
- WT_ROOT . 'resources/fonts/DejaVuSans.ttf',
+ Webtrees::ROOT_DIR . 'resources/fonts/DejaVuSans.ttf',
$text
);
diff --git a/app/Module/ModuleThemeTrait.php b/app/Module/ModuleThemeTrait.php
index f43f0ed197..bec64d4166 100644
--- a/app/Module/ModuleThemeTrait.php
+++ b/app/Module/ModuleThemeTrait.php
@@ -26,6 +26,7 @@ use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Menu;
use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
use Psr\Http\Message\ServerRequestInterface;
use function app;
@@ -46,13 +47,13 @@ trait ModuleThemeTrait
public function icon(Fact $fact): string
{
$asset = 'public/css/' . $this->name() . '/images/facts/' . $fact->getTag() . '.png';
- if (file_exists(WT_ROOT . 'public' . $asset)) {
+ if (file_exists(Webtrees::ROOT_DIR . 'public' . $asset)) {
return '<img src="' . e(asset($asset)) . '" title="' . GedcomTag::getLabel($fact->getTag()) . '">';
}
// Spacer image - for alignment - until we move to a sprite.
$asset = 'public/css/' . $this->name() . '/images/facts/NULL.png';
- if (file_exists(WT_ROOT . 'public' . $asset)) {
+ if (file_exists(Webtrees::ROOT_DIR . 'public' . $asset)) {
return '<img src="' . e(asset($asset)) . '">';
}
diff --git a/app/Module/PedigreeMapModule.php b/app/Module/PedigreeMapModule.php
index 3a6037e0f6..24c35a8550 100644
--- a/app/Module/PedigreeMapModule.php
+++ b/app/Module/PedigreeMapModule.php
@@ -316,7 +316,7 @@ class PedigreeMapModule extends AbstractModule implements ModuleChartInterface
private function getMapProviderData(ServerRequestInterface $request): ?array
{
if (self::$map_providers === null) {
- $providersFile = WT_ROOT . Webtrees::MODULES_PATH . 'openstreetmap/providers/providers.xml';
+ $providersFile = Webtrees::MODULES_DIR . 'openstreetmap/providers/providers.xml';
self::$map_selections = [
'provider' => $this->getPreference('provider', 'openstreetmap'),
'style' => $this->getPreference('provider_style', 'mapnik'),
diff --git a/app/Module/PlacesModule.php b/app/Module/PlacesModule.php
index 062dde1cdb..0918480a85 100644
--- a/app/Module/PlacesModule.php
+++ b/app/Module/PlacesModule.php
@@ -250,7 +250,7 @@ class PlacesModule extends AbstractModule implements ModuleTabInterface
private function getMapProviderData(ServerRequestInterface $request): ?array
{
if (self::$map_providers === null) {
- $providersFile = WT_ROOT . Webtrees::MODULES_PATH . 'openstreetmap/providers/providers.xml';
+ $providersFile = Webtrees::MODULES_DIR . 'openstreetmap/providers/providers.xml';
self::$map_selections = [
'provider' => $this->getPreference('provider', 'openstreetmap'),
'style' => $this->getPreference('provider_style', 'mapnik'),
diff --git a/app/Services/HousekeepingService.php b/app/Services/HousekeepingService.php
index 1c361a5c4c..81869b7808 100644
--- a/app/Services/HousekeepingService.php
+++ b/app/Services/HousekeepingService.php
@@ -46,12 +46,12 @@ class HousekeepingService
'manageservers.php',
'media.php',
'module_admin.php',
- //WT_ROOT.'modules', // Do not delete - users may have stored custom modules/data here
+ //'modules', // Do not delete - users may have stored custom modules/data here
'opensearch.php',
'PEAR.php',
'pgv_to_wt.php',
'places',
- //WT_ROOT.'robots.txt', // Do not delete this - it may contain user data
+ //'robots.txt', // Do not delete this - it may contain user data
'serviceClientTest.php',
'siteconfig.php',
'SOAP',
diff --git a/app/Services/ModuleService.php b/app/Services/ModuleService.php
index ad61873fff..a97d20d529 100644
--- a/app/Services/ModuleService.php
+++ b/app/Services/ModuleService.php
@@ -552,7 +552,7 @@ class ModuleService
*/
private function customModules(): Collection
{
- $pattern = WT_ROOT . Webtrees::MODULES_PATH . '*/module.php';
+ $pattern = Webtrees::MODULES_DIR . '*/module.php';
$filenames = glob($pattern, GLOB_NOSORT);
return Collection::make($filenames)
diff --git a/app/Services/UpgradeService.php b/app/Services/UpgradeService.php
index 6bf03aeec0..9283c5264f 100644
--- a/app/Services/UpgradeService.php
+++ b/app/Services/UpgradeService.php
@@ -252,13 +252,13 @@ class UpgradeService
{
$message = I18N::translate('This website is being upgraded. Try again in a few minutes.');
- file_put_contents(WT_ROOT . self::LOCK_FILE, $message);
+ file_put_contents(Webtrees::OFFLINE_FILE, $message);
}
public function endMaintenanceMode(): void
{
- if (file_exists(WT_ROOT . self::LOCK_FILE)) {
- unlink(WT_ROOT . self::LOCK_FILE);
+ if (file_exists(Webtrees::OFFLINE_FILE)) {
+ unlink(Webtrees::OFFLINE_FILE);
}
}
diff --git a/app/View.php b/app/View.php
index cd60b1749b..bde55e66b4 100644
--- a/app/View.php
+++ b/app/View.php
@@ -55,7 +55,7 @@ class View
* @var string[] Where do the templates live, for each namespace.
*/
private static $namespaces = [
- '' => WT_ROOT . 'resources/views/',
+ '' => Webtrees::ROOT_DIR . 'resources/views/',
];
/**
diff --git a/app/Webtrees.php b/app/Webtrees.php
index 6f661e0291..9912a47922 100644
--- a/app/Webtrees.php
+++ b/app/Webtrees.php
@@ -17,19 +17,68 @@ declare(strict_types=1);
namespace Fisharebest\Webtrees;
-use function date_default_timezone_set;
+use Closure;
+use DebugBar\StandardDebugBar;
+use ErrorException;
+use Fisharebest\Webtrees\Http\Middleware\BootModules;
+use Fisharebest\Webtrees\Http\Middleware\CheckCsrf;
+use Fisharebest\Webtrees\Http\Middleware\CheckForMaintenanceMode;
+use Fisharebest\Webtrees\Http\Middleware\DoHousekeeping;
+use Fisharebest\Webtrees\Http\Middleware\EmitResponse;
+use Fisharebest\Webtrees\Http\Middleware\HandleExceptions;
+use Fisharebest\Webtrees\Http\Middleware\ModuleMiddleware;
+use Fisharebest\Webtrees\Http\Middleware\NoRouteFound;
+use Fisharebest\Webtrees\Http\Middleware\PhpEnvironment;
+use Fisharebest\Webtrees\Http\Middleware\RequestRouter;
+use Fisharebest\Webtrees\Http\Middleware\UpdateDatabaseSchema;
+use Fisharebest\Webtrees\Http\Middleware\UseCache;
+use Fisharebest\Webtrees\Http\Middleware\UseDatabase;
+use Fisharebest\Webtrees\Http\Middleware\UseDebugbar;
+use Fisharebest\Webtrees\Http\Middleware\UseFilesystem;
+use Fisharebest\Webtrees\Http\Middleware\UseLocale;
+use Fisharebest\Webtrees\Http\Middleware\UseSession;
+use Fisharebest\Webtrees\Http\Middleware\UseTheme;
+use Fisharebest\Webtrees\Http\Middleware\UseTransaction;
+use Fisharebest\Webtrees\Http\Middleware\UseTree;
+use Fisharebest\Webtrees\Http\Request;
+use Nyholm\Psr7\Factory\Psr17Factory;
+use Nyholm\Psr7Server\ServerRequestCreator;
+use Psr\Http\Message\ResponseFactoryInterface;
+use Psr\Http\Message\ServerRequestFactoryInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\StreamFactoryInterface;
+use Psr\Http\Message\UploadedFileFactoryInterface;
+use Psr\Http\Message\UriFactoryInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Throwable;
+use function app;
+use function class_exists;
+use function dirname;
use function error_reporting;
-use Fisharebest\Webtrees\Exceptions\Handler;
+use function ob_end_clean;
+use function ob_get_level;
use function set_error_handler;
use function set_exception_handler;
+use function str_replace;
+use const PHP_EOL;
/**
* Definitions for the webtrees application.
*/
class Webtrees
{
+ // The root folder of this installation
+ public const ROOT_DIR = __DIR__ . '/../';
+
// Location of the file containing the database connection details.
- public const CONFIG_FILE = __DIR__ . '/../data/config.ini.php';
+ public const CONFIG_FILE = self::ROOT_DIR . '/data/config.ini.php';
+
+ // Location of the file that triggers maintenance mode.
+ public const OFFLINE_FILE = self::ROOT_DIR . '/data/offline.txt';
+
+ // Location of our modules.
+ public const MODULES_PATH = 'modules_v4';
+ public const MODULES_DIR = self::ROOT_DIR . self::MODULES_PATH;
// Enable debugging on development builds.
public const DEBUG = self::STABILITY !== '';
@@ -46,31 +95,129 @@ class Webtrees
// e.g. "dev", "alpha", "beta.3", etc.
public const STABILITY = 'alpha.5';
- // Project website.
- public const URL = 'https://www.webtrees.net/';
-
// Version number
public const VERSION = '2.0.0' . (self::STABILITY === '' ? '' : '-') . self::STABILITY;
- // Location of our modules.
- public const MODULES_PATH = 'modules_v4/';
+ // Project website.
+ public const URL = 'https://www.webtrees.net/';
/**
* Initialise the application.
*
* @return void
*/
- public static function init(): void
+ public function bootstrap(): void
{
- mb_internal_encoding('UTF-8');
-
// Show all errors and warnings in development, fewer in production.
error_reporting(self::ERROR_REPORTING);
- // PHP requires a time zone to be set. We'll set a better one later on.
- date_default_timezone_set('UTC');
+ set_error_handler($this->phpErrorHandler());
+ set_exception_handler($this->phpExceptionHandler());
+ }
+
+ /**
+ * An error handler that can be passed to set_error_handler().
+ *
+ * @return Closure
+ */
+ private function phpErrorHandler(): Closure
+ {
+ return static function (int $errno, string $errstr, string $errfile, int $errline): bool {
+ // Ignore errors that are silenced with '@'
+ if (error_reporting() & $errno) {
+ throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
+ }
+
+ return true;
+ };
+ }
+
+ /**
+ * An exception handler that can be passed to set_exception_handler().
+ * Display any exception that are not caught by the middleware exception handler.
+ *
+ * @return Closure
+ */
+ private function phpExceptionHandler(): Closure
+ {
+ return static function (Throwable $ex): void {
+ $base_path = dirname(__DIR__);
+ $trace = $ex->getMessage() . PHP_EOL . $ex->getTraceAsString();
+ $trace = str_replace($base_path, '…', $trace);
- set_error_handler(Handler::phpErrorHandler());
- set_exception_handler(Handler::phpExceptionHandler());
+ while (ob_get_level() > 0) {
+ ob_end_clean();
+ }
+
+ echo '<html lang="en"><head><title>Error</title><meta charset="UTF-8"></head><body><pre>' . $trace . '</pre></body></html>';
+ };
+ }
+
+ /**
+ * We can use any PSR-7 / PSR-17 compatible message factory.
+ *
+ * @return void
+ */
+ public function selectMessageFactory(): void
+ {
+ app()->bind(ResponseFactoryInterface::class, Psr17Factory::class);
+ app()->bind(ServerRequestFactoryInterface::class, Psr17Factory::class);
+ app()->bind(StreamFactoryInterface::class, Psr17Factory::class);
+ app()->bind(UploadedFileFactoryInterface::class, Psr17Factory::class);
+ app()->bind(UriFactoryInterface::class, Psr17Factory::class);
+ }
+
+ /**
+ * We can use any PSR-7 compatible requests.
+ *
+ * @return ServerRequestInterface
+ */
+ public function createServerRequest(): ServerRequestInterface
+ {
+ $server_request_creator = new ServerRequestCreator(
+ app(ServerRequestFactoryInterface::class),
+ app(UriFactoryInterface::class),
+ app(UploadedFileFactoryInterface::class),
+ app(StreamFactoryInterface::class)
+ );
+
+ // Until all the code is rewritten to use PSR-7 requests, we still need our hybrid request.
+ if (class_exists(Request::class)) {
+ return Request::createFromGlobals();
+ }
+
+ return $server_request_creator->fromGlobals();
+
+ }
+
+ /**
+ * The webtrees application is built from middleware.
+ *
+ * @return MiddlewareInterface[]
+ */
+ public function middleware(): array
+ {
+ return [
+ PhpEnvironment::class,
+ EmitResponse::class,
+ HandleExceptions::class,
+ CheckForMaintenanceMode::class,
+ UseDatabase::class,
+ UseDebugbar::class,
+ UpdateDatabaseSchema::class,
+ UseCache::class,
+ UseFilesystem::class,
+ UseSession::class,
+ UseTree::class,
+ UseLocale::class,
+ UseTheme::class,
+ DoHousekeeping::class,
+ CheckCsrf::class,
+ UseTransaction::class,
+ BootModules::class,
+ ModuleMiddleware::class,
+ RequestRouter::class,
+ NoRouteFound::class,
+ ];
}
}
diff --git a/index.php b/index.php
index 6c93aafde0..bdfbf90c39 100644
--- a/index.php
+++ b/index.php
@@ -16,99 +16,29 @@
*/
declare(strict_types=1);
-use Fisharebest\Webtrees\DebugBar;
-use Fisharebest\Webtrees\Http\Middleware\BootModules;
-use Fisharebest\Webtrees\Http\Middleware\CheckCsrf;
-use Fisharebest\Webtrees\Http\Middleware\CheckForMaintenanceMode;
-use Fisharebest\Webtrees\Http\Middleware\NoRouteFound;
-use Fisharebest\Webtrees\Http\Middleware\UseDebugbar;
-use Fisharebest\Webtrees\Http\Middleware\EmitResponse;
-use Fisharebest\Webtrees\Http\Middleware\HandleExceptions;
-use Fisharebest\Webtrees\Http\Middleware\DoHousekeeping;
-use Fisharebest\Webtrees\Http\Middleware\ModuleMiddleware;
-use Fisharebest\Webtrees\Http\Middleware\RequestRouter;
-use Fisharebest\Webtrees\Http\Middleware\UpdateDatabaseSchema;
-use Fisharebest\Webtrees\Http\Middleware\UseCache;
-use Fisharebest\Webtrees\Http\Middleware\UseDatabase;
-use Fisharebest\Webtrees\Http\Middleware\UseFilesystem;
-use Fisharebest\Webtrees\Http\Middleware\UseLocale;
-use Fisharebest\Webtrees\Http\Middleware\UseSession;
-use Fisharebest\Webtrees\Http\Middleware\UseTheme;
-use Fisharebest\Webtrees\Http\Middleware\UseTransaction;
-use Fisharebest\Webtrees\Http\Middleware\UseTree;
-use Fisharebest\Webtrees\Http\Request as SymfonyRequest;
-use Fisharebest\Webtrees\Webtrees;
+namespace Fisharebest\Webtrees;
+
use Middleland\Dispatcher;
-use Nyholm\Psr7\Factory\Psr17Factory;
-use Nyholm\Psr7Server\ServerRequestCreator;
-use Psr\Http\Message\ResponseFactoryInterface;
-use Psr\Http\Message\ServerRequestFactoryInterface;
-use Psr\Http\Message\StreamFactoryInterface;
-use Psr\Http\Message\UploadedFileFactoryInterface;
-use Psr\Http\Message\UriFactoryInterface;
-use DebugBar\StandardDebugBar;
require __DIR__ . '/vendor/autoload.php';
-const WT_ROOT = __DIR__ . DIRECTORY_SEPARATOR;
-
-Webtrees::init();
-
-// Use nyholm/psr7 for our PSR7 messages and PSR17 factory.
-app()->bind(ResponseFactoryInterface::class, Psr17Factory::class);
-app()->bind(ServerRequestFactoryInterface::class, Psr17Factory::class);
-app()->bind(StreamFactoryInterface::class, Psr17Factory::class);
-app()->bind(UploadedFileFactoryInterface::class, Psr17Factory::class);
-app()->bind(UriFactoryInterface::class, Psr17Factory::class);
+// Create the application.
+$application = new Webtrees();
-// Use nyholm/psr7-server to create a request from the PHP environment.
-$server_request_creator = new ServerRequestCreator(
- app(ServerRequestFactoryInterface::class),
- app(UriFactoryInterface::class),
- app(UploadedFileFactoryInterface::class),
- app(StreamFactoryInterface::class)
-);
+$application->bootstrap();
-// Create a PSR-7 request
-$request = $server_request_creator->fromGlobals();
+// Select a PSR message factory.
+$application->selectMessageFactory();
-// Initialise the DebugBar for development.
-// Use `composer install --dev` on a development build to enable.
-// Note that you may need to increase the size of the fcgi buffers on nginx.
-// e.g. add these lines to your fastcgi_params file:
-// fastcgi_buffers 16 16m;
-// fastcgi_buffer_size 32m;
-DebugBar::init(class_exists(StandardDebugBar::class));
-
-// Until all the code is rewritten to use PSR-7 requests, we still need our hybrid request.
-$request = SymfonyRequest::createFromGlobals();
+// Convert the GET, POST, COOKIE variables into a request.
+$request = $application->createServerRequest();
// Calculate the base URL, so we can generate absolute URLs.
// Remove any PHP script name and parameters.
define('WT_BASE_URL', preg_replace('/[^\/]+\.php(\?.*)?$/', '', $request->getUri()));
-$middleware = [
- EmitResponse::class,
- HandleExceptions::class,
- CheckForMaintenanceMode::class,
- UseDatabase::class,
- UseDebugbar::class,
- UpdateDatabaseSchema::class,
- UseCache::class,
- UseFilesystem::class,
- UseSession::class,
- UseTree::class,
- UseLocale::class,
- UseTheme::class,
- DoHousekeeping::class,
- CheckCsrf::class,
- UseTransaction::class,
- BootModules::class,
- ModuleMiddleware::class,
- RequestRouter::class,
- NoRouteFound::class,
-];
-
-$dispatcher = new Dispatcher($middleware, app());
-
+// The application is defined by a stack of middleware and a PSR-11 container.
+$middleware = $application->middleware();
+$container = app();
+$dispatcher = new Dispatcher($middleware, $container);
$dispatcher->dispatch($request);
diff --git a/resources/views/setup/step-4-database-sqlite.phtml b/resources/views/setup/step-4-database-sqlite.phtml
index dd493c78ec..92f9154da3 100644
--- a/resources/views/setup/step-4-database-sqlite.phtml
+++ b/resources/views/setup/step-4-database-sqlite.phtml
@@ -1,4 +1,5 @@
-<?php use Fisharebest\Webtrees\I18N; ?>
+<?php use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Webtrees; ?>
<form method="POST" autocomplete="off">
<input name="route" type="hidden" value="setup">
@@ -33,7 +34,7 @@
<div class="col-sm-9">
<div class="input-group" dir="ltr">
<div class="input-group-prepend">
- <span class="input-group-text"><?=e( WT_ROOT) ?>data/</span>
+ <span class="input-group-text"><?=e( realpath(Webtrees::ROOT_DIR)) ?>data/</span>
</div>
<input class="form-control" id="dbname" name="dbname" pattern="[a-zA-Z0-9_]+" type="text" value="<?= e($dbname) ?>">
diff --git a/tests/TestCase.php b/tests/TestCase.php
index b110d08882..190acb685a 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -88,14 +88,11 @@ class TestCase extends \PHPUnit\Framework\TestCase implements StatusCodeInterfac
app()->bind(ModuleThemeInterface::class, WebtreesTheme::class);
app()->bind(LocaleInterface::class, LocaleEnUs::class);
- defined('WT_ROOT') || define('WT_ROOT', dirname(__DIR__) . '/');
defined('WT_BASE_URL') || define('WT_BASE_URL', 'http://localhost/');
- defined('WT_DATA_DIR') || define('WT_DATA_DIR', WT_ROOT . 'data/');
+ defined('WT_DATA_DIR') || define('WT_DATA_DIR', Webtrees::ROOT_DIR . 'data/');
defined('WT_LOCALE') || define('WT_LOCALE', I18N::init('en-US', null, true));
if (static::$uses_database) {
- defined('WT_ROOT') || define('WT_ROOT', dirname(__DIR__) . '/');
-
static::createTestDatabase();
}
}
diff --git a/tests/app/Module/AhnentafelReportModuleTest.php b/tests/app/Module/AhnentafelReportModuleTest.php
index 7567a795bc..5ba73b6f38 100644
--- a/tests/app/Module/AhnentafelReportModuleTest.php
+++ b/tests/app/Module/AhnentafelReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class AhnentafelReportModule
@@ -78,7 +79,7 @@ class AhnentafelReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/ahnentafel_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/ahnentafel_report.xml';
$vars = [
'pid' => ['id' => 'X1030'],
'maxgen' => ['id' => '3'],
diff --git a/tests/app/Module/BirthDeathMarriageReportModuleTest.php b/tests/app/Module/BirthDeathMarriageReportModuleTest.php
index 26d59bb2b3..8ef5cfd9a9 100644
--- a/tests/app/Module/BirthDeathMarriageReportModuleTest.php
+++ b/tests/app/Module/BirthDeathMarriageReportModuleTest.php
@@ -21,6 +21,7 @@ use Fisharebest\Webtrees\Report\ReportHtml;
use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class BirthDeathMarriageReportModule
@@ -72,7 +73,7 @@ class BirthDeathMarriageReportModuleTest extends \Fisharebest\Webtrees\TestCase
{
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/bdm_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/bdm_report.xml';
$vars = [
'name' => ['id' => ''],
'bdmplace' => ['id' => ''],
diff --git a/tests/app/Module/BirthReportModuleTest.php b/tests/app/Module/BirthReportModuleTest.php
index 22d8950267..d4b731228d 100644
--- a/tests/app/Module/BirthReportModuleTest.php
+++ b/tests/app/Module/BirthReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class BirthReportModule
@@ -78,7 +79,7 @@ class BirthReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/birth_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/birth_report.xml';
$vars = [
'name' => ['id' => ''],
'birthplace' => ['id' => ''],
diff --git a/tests/app/Module/CemeteryReportModuleTest.php b/tests/app/Module/CemeteryReportModuleTest.php
index 38195bc092..9ca83fd41c 100644
--- a/tests/app/Module/CemeteryReportModuleTest.php
+++ b/tests/app/Module/CemeteryReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class CemeteryReportModule
@@ -78,7 +79,7 @@ class CemeteryReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/cemetery_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/cemetery_report.xml';
$vars = [
'deathplace' => ['id' => ''],
'adlist' => ['id' => 'none'],
diff --git a/tests/app/Module/ChangeReportModuleTest.php b/tests/app/Module/ChangeReportModuleTest.php
index ff7ebd3a49..d0ce71a2ad 100644
--- a/tests/app/Module/ChangeReportModuleTest.php
+++ b/tests/app/Module/ChangeReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
use Illuminate\Support\Carbon;
/**
@@ -79,7 +80,7 @@ class ChangeReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/change_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/change_report.xml';
$vars = [
'changeRangeStart' => ['id' => Carbon::now()->subMonths(1)->format('d M Y')],
'changeRangeEnd' => ['id' => Carbon::now()->format('d M Y')],
diff --git a/tests/app/Module/DeathReportModuleTest.php b/tests/app/Module/DeathReportModuleTest.php
index cc9ddb9022..bdf01bf6ab 100644
--- a/tests/app/Module/DeathReportModuleTest.php
+++ b/tests/app/Module/DeathReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class FactSourcesReportModule
@@ -78,7 +79,7 @@ class DeathReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/death_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/death_report.xml';
$vars = [
'name' => ['id' => ''],
'deathplace' => ['id' => ''],
diff --git a/tests/app/Module/DescendancyReportModuleTest.php b/tests/app/Module/DescendancyReportModuleTest.php
index 1b9f1a241d..9662b1560b 100644
--- a/tests/app/Module/DescendancyReportModuleTest.php
+++ b/tests/app/Module/DescendancyReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class DescendancyReportModule
@@ -78,7 +79,7 @@ class DescendancyReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/descendancy_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/descendancy_report.xml';
$vars = [
'pid' => ['id' => 'X1030'],
'maxgen' => ['id' => '3'],
diff --git a/tests/app/Module/FactSourcesReportModuleTest.php b/tests/app/Module/FactSourcesReportModuleTest.php
index 904162c3fd..32b5bded02 100644
--- a/tests/app/Module/FactSourcesReportModuleTest.php
+++ b/tests/app/Module/FactSourcesReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class FactSourcesReportModule
@@ -78,7 +79,7 @@ class FactSourcesReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/fact_sources.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/fact_sources.xml';
$vars = [
'id' => ['id' => 's1'],
'stype' => ['id' => 'facts'],
diff --git a/tests/app/Module/FamilyGroupReportModuleTest.php b/tests/app/Module/FamilyGroupReportModuleTest.php
index d2a5d26119..5b286a22b8 100644
--- a/tests/app/Module/FamilyGroupReportModuleTest.php
+++ b/tests/app/Module/FamilyGroupReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class FamilyGroupReportModule
@@ -78,7 +79,7 @@ class FamilyGroupReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/family_group_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/family_group_report.xml';
$vars = [
'id' => ['id' => 'f1'],
'sources' => ['id' => 'on'],
diff --git a/tests/app/Module/IndividualFamiliesReportModuleTest.php b/tests/app/Module/IndividualFamiliesReportModuleTest.php
index 50a61e3778..3ea62af057 100644
--- a/tests/app/Module/IndividualFamiliesReportModuleTest.php
+++ b/tests/app/Module/IndividualFamiliesReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class IndividualFamiliesReportModule
@@ -78,7 +79,7 @@ class IndividualFamiliesReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/individual_ext_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/individual_ext_report.xml';
$vars = [
'pid' => ['id' => 'X1030'],
'relatives' => ['id' => 'child-families'],
diff --git a/tests/app/Module/IndividualReportModuleTest.php b/tests/app/Module/IndividualReportModuleTest.php
index 713850d888..eba24b5eb7 100644
--- a/tests/app/Module/IndividualReportModuleTest.php
+++ b/tests/app/Module/IndividualReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class IndividualReportModule
@@ -79,7 +80,7 @@ class IndividualReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/individual_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/individual_report.xml';
$vars = [
'id' => ['id' => 'X1030'],
'sources' => ['id' => 'on'],
diff --git a/tests/app/Module/MarriageReportModuleTest.php b/tests/app/Module/MarriageReportModuleTest.php
index 4aaf1688c7..ed3f3e658e 100644
--- a/tests/app/Module/MarriageReportModuleTest.php
+++ b/tests/app/Module/MarriageReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class MarriageReportModule
@@ -78,7 +79,7 @@ class MarriageReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/marriage_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/marriage_report.xml';
$vars = [
'name' => ['id' => ''],
'marrplace' => ['id' => ''],
diff --git a/tests/app/Module/MissingFactsReportModuleTest.php b/tests/app/Module/MissingFactsReportModuleTest.php
index a7b248985c..7fa20574ff 100644
--- a/tests/app/Module/MissingFactsReportModuleTest.php
+++ b/tests/app/Module/MissingFactsReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class MissingFactsReportModule
@@ -78,7 +79,7 @@ class MissingFactsReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/missing_facts_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/missing_facts_report.xml';
$vars = [
'pid' => ['id' => 'X1030'],
'relatives' => ['id' => 'direct-ancestors'],
diff --git a/tests/app/Module/OccupationReportModuleTest.php b/tests/app/Module/OccupationReportModuleTest.php
index c86c10ff80..bfd710a017 100644
--- a/tests/app/Module/OccupationReportModuleTest.php
+++ b/tests/app/Module/OccupationReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class OccupationReportModule
@@ -78,7 +79,7 @@ class OccupationReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/occupation_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/occupation_report.xml';
$vars = [
'occupation' => ['id' => 'king'],
'pageSize' => ['id' => 'A4'],
diff --git a/tests/app/Module/PedigreeReportModuleTest.php b/tests/app/Module/PedigreeReportModuleTest.php
index 5ea92b82b5..d074cb732f 100644
--- a/tests/app/Module/PedigreeReportModuleTest.php
+++ b/tests/app/Module/PedigreeReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class PedigreeReportModule
@@ -78,7 +79,7 @@ class PedigreeReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/pedigree_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/pedigree_report.xml';
$vars = [
'pid' => ['id' => 'X1030'],
'spouses' => ['id' => 'on'],
diff --git a/tests/app/Module/RelatedIndividualsReportModuleTest.php b/tests/app/Module/RelatedIndividualsReportModuleTest.php
index 1bfff18829..8b467f0b57 100644
--- a/tests/app/Module/RelatedIndividualsReportModuleTest.php
+++ b/tests/app/Module/RelatedIndividualsReportModuleTest.php
@@ -23,6 +23,7 @@ use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportPdf;
use Fisharebest\Webtrees\Services\UserService;
use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\Webtrees;
/**
* Test harness for the class RelatedIndividualsReportModule
@@ -78,7 +79,7 @@ class RelatedIndividualsReportModuleTest extends \Fisharebest\Webtrees\TestCase
$tree = $this->importTree('demo.ged');
app()->instance(Tree::class, $tree);
- $xml = WT_ROOT . 'resources/xml/reports/relative_ext_report.xml';
+ $xml = Webtrees::ROOT_DIR . 'resources/xml/reports/relative_ext_report.xml';
$vars = [
'pid' => ['id' => 'X1030'],
'relatives' => ['id' => 'child-family'],
diff --git a/tests/app/WebtreesTest.php b/tests/app/WebtreesTest.php
index 68d51afcd7..a075ac742a 100644
--- a/tests/app/WebtreesTest.php
+++ b/tests/app/WebtreesTest.php
@@ -17,10 +17,10 @@ declare(strict_types=1);
namespace Fisharebest\Webtrees;
+use ErrorException;
use function date_default_timezone_get;
use function date_default_timezone_set;
use function error_reporting;
-use ErrorException;
use function set_error_handler;
/**
@@ -29,19 +29,16 @@ use function set_error_handler;
class WebtreesTest extends TestCase
{
/**
- * @covers \Fisharebest\Webtrees\Webtrees::init
+ * @covers \Fisharebest\Webtrees\Webtrees::bootstrap
* @return void
*/
public function testInit(): void
{
- date_default_timezone_set('Europe/London');
error_reporting(0);
set_error_handler(null);
- Webtrees::init();
-
- // webtrees always runs in UTC (and converts to local time on demand).
- $this->assertSame('UTC', date_default_timezone_get());
+ $webtrees = new Webtrees();
+ $webtrees->bootstrap();
// webtrees sets the error reporting level.
$this->assertNotSame(0, error_reporting());
@@ -49,13 +46,13 @@ class WebtreesTest extends TestCase
try {
// Trigger an error
- fopen(__DIR__ . '/no-such-file', 'r');
+ fopen(__DIR__ . '/no-such-file', 'rb');
} catch (ErrorException $ex) {
$this->assertSame(__FILE__, $ex->getFile());
}
// Disable error reporting (we could use "@"), and don't raise an exception.
error_reporting(0);
- fopen(__DIR__ . '/no-such-file', 'r');
+ fopen(__DIR__ . '/no-such-file', 'rb');
}
}