diff options
| author | Greg Roach <fisharebest@webtrees.net> | 2019-03-02 08:12:34 +0000 |
|---|---|---|
| committer | Greg Roach <fisharebest@webtrees.net> | 2019-03-02 17:01:21 +0000 |
| commit | b5979037de52280b1023c9eb58518a3089e7d267 (patch) | |
| tree | 47bbc3e2dbaa37846d215d141df9486598d69e61 | |
| parent | 6a5d238b3a0931ab1cdc7d4ad56663e8eb272236 (diff) | |
| download | webtrees-b5979037de52280b1023c9eb58518a3089e7d267.tar.gz webtrees-b5979037de52280b1023c9eb58518a3089e7d267.tar.bz2 webtrees-b5979037de52280b1023c9eb58518a3089e7d267.zip | |
Tidy up initialisation
| -rw-r--r-- | app/Http/Middleware/UseLocale.php | 65 | ||||
| -rw-r--r-- | app/Http/Middleware/UseSession.php | 58 | ||||
| -rw-r--r-- | app/Http/Middleware/UseTheme.php | 102 | ||||
| -rw-r--r-- | app/Services/ModuleService.php | 17 | ||||
| -rw-r--r-- | index.php | 96 | ||||
| -rw-r--r-- | routes/web.php | 1 |
6 files changed, 259 insertions, 80 deletions
diff --git a/app/Http/Middleware/UseLocale.php b/app/Http/Middleware/UseLocale.php new file mode 100644 index 0000000000..c836f6097a --- /dev/null +++ b/app/Http/Middleware/UseLocale.php @@ -0,0 +1,65 @@ +<?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 Closure; +use Fisharebest\Localization\Locale as WebtreesLocale; +use Fisharebest\Localization\Locale\LocaleInterface; +use Fisharebest\Webtrees\I18N; +use Fisharebest\Webtrees\Session; +use Fisharebest\Webtrees\Tree; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Throwable; + +/** + * Middleware to set a global theme. + */ +class UseLocale implements MiddlewareInterface +{ + /** @var Tree|null */ + private $tree; + + /** + * UseTheme constructor. + * + * @param Tree|null $tree + */ + public function __construct(?Tree $tree) + { + $this->tree = $tree; + } + + /** + * @param Request $request + * @param Closure $next + * + * @return Response + * @throws Throwable + */ + public function handle(Request $request, Closure $next): Response + { + // Select a locale + define('WT_LOCALE', I18N::init('', $this->tree)); + Session::put('locale', WT_LOCALE); + + app()->instance(LocaleInterface::class, WebtreesLocale::create(WT_LOCALE)); + + return $next($request); + } +} diff --git a/app/Http/Middleware/UseSession.php b/app/Http/Middleware/UseSession.php new file mode 100644 index 0000000000..5a5faafa71 --- /dev/null +++ b/app/Http/Middleware/UseSession.php @@ -0,0 +1,58 @@ +<?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 Carbon\Carbon; +use Closure; +use Fisharebest\Webtrees\Auth; +use Fisharebest\Webtrees\Session; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Throwable; + +/** + * Middleware to activate sessions. + */ +class UseSession implements MiddlewareInterface +{ + /** + * @param Request $request + * @param Closure $next + * + * @return Response + * @throws Throwable + */ + public function handle(Request $request, Closure $next): Response + { + // Sessions + Session::start(); + + // Update the last-login time no more than once a minute. + $next_session_update = Carbon::createFromTimestamp((int) Session::get('session_time_updates'))->addMinute(); + if ($next_session_update < Carbon::now()) { + $timestamp_now = Carbon::now()->timestamp; + + if (Session::get('masquerade') === null) { + Auth::user()->setPreference('sessiontime', (string) $timestamp_now); + } + Session::put('session_time_updates', $timestamp_now); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/UseTheme.php b/app/Http/Middleware/UseTheme.php new file mode 100644 index 0000000000..5552c8bbdf --- /dev/null +++ b/app/Http/Middleware/UseTheme.php @@ -0,0 +1,102 @@ +<?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 Closure; +use Fisharebest\Webtrees\Module\ModuleThemeInterface; +use Fisharebest\Webtrees\Module\WebtreesTheme; +use Fisharebest\Webtrees\Services\ModuleService; +use Fisharebest\Webtrees\Session; +use Fisharebest\Webtrees\Site; +use Fisharebest\Webtrees\Tree; +use Generator; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Throwable; + +/** + * Middleware to set a global theme. + */ +class UseTheme implements MiddlewareInterface +{ + /** @var ModuleService */ + private $module_service; + + /** @var Tree|null */ + private $tree; + + /** + * UseTheme constructor. + * + * @param ModuleService $module_service + * @param Tree|null $tree + */ + public function __construct(ModuleService $module_service, ?Tree $tree) + { + $this->module_service = $module_service; + $this->tree = $tree; + } + + /** + * @param Request $request + * @param Closure $next + * + * @return Response + * @throws Throwable + */ + public function handle(Request $request, Closure $next): Response + { + foreach ($this->themes() as $theme) { + if ($theme instanceof ModuleThemeInterface) { + // Bind this theme into the container + app()->instance(ModuleThemeInterface::class, $theme); + + // Remember this setting + Session::put('theme_id', $theme->name()); + + break; + } + } + + return $next($request); + } + + /** + * The theme can be chosen in various ways. + * + * @return Generator + */ + private function themes(): Generator + { + $themes = $this->module_service->findByInterface(ModuleThemeInterface::class); + + // Last theme used + yield $themes->get(Session::get('theme_id', '')); + + // Default for tree + if ($this->tree instanceof Tree) { + yield $themes->get($this->tree->getPreference('THEME_DIR')); + } + + // Default for site + yield $themes->get(Site::getPreference('THEME_DIR')); + + // Default for application + yield app()->make(WebtreesTheme::class); + } +} diff --git a/app/Services/ModuleService.php b/app/Services/ModuleService.php index 98b00cec18..5f5e9ec306 100644 --- a/app/Services/ModuleService.php +++ b/app/Services/ModuleService.php @@ -373,8 +373,7 @@ class ModuleService } return $module; - }) - ->sort($this->moduleSorter()); + }); }); } @@ -501,7 +500,7 @@ class ModuleService */ public function findByComponent(string $interface, Tree $tree, UserInterface $user): Collection { - return $this->findByInterface($interface) + return $this->findByInterface($interface, false, true) ->filter(function (ModuleInterface $module) use ($interface, $tree, $user): bool { return $module->accessLevel($tree, $interface) >= Auth::accessLevel($tree, $user); }); @@ -512,10 +511,11 @@ class ModuleService * * @param string $interface * @param bool $include_disabled + * @param bool $sort * * @return Collection|ModuleInterface[] */ - public function findByInterface(string $interface, $include_disabled = false): Collection + public function findByInterface(string $interface, $include_disabled = false, $sort = false): Collection { $modules = $this->all() ->filter($this->interfaceFilter($interface)) @@ -533,9 +533,14 @@ class ModuleService case ModuleTabInterface::class: return $modules->sort($this->tabSorter()); - } - return $modules; + default: + if ($sort) { + return $modules->sort($this->moduleSorter()); + } + + return $modules; + } } /** @@ -15,9 +15,6 @@ */ declare(strict_types=1); -use Carbon\Carbon; -use Fisharebest\Localization\Locale as WebtreesLocale; -use Fisharebest\Localization\Locale\LocaleInterface; use Fisharebest\Webtrees\Auth; use Fisharebest\Webtrees\Contracts\UserInterface; use Fisharebest\Webtrees\Database; @@ -29,21 +26,20 @@ use Fisharebest\Webtrees\Http\Middleware\CheckForMaintenanceMode; use Fisharebest\Webtrees\Http\Middleware\DebugBarData; use Fisharebest\Webtrees\Http\Middleware\Housekeeping; use Fisharebest\Webtrees\Http\Middleware\MiddlewareInterface; +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\I18N; -use Fisharebest\Webtrees\Module\ModuleThemeInterface; -use Fisharebest\Webtrees\Module\WebtreesTheme; use Fisharebest\Webtrees\Services\MigrationService; use Fisharebest\Webtrees\Services\ModuleService; use Fisharebest\Webtrees\Services\TimeoutService; -use Fisharebest\Webtrees\Session; use Fisharebest\Webtrees\Site; use Fisharebest\Webtrees\Tree; use Fisharebest\Webtrees\View; use Fisharebest\Webtrees\Webtrees; use Illuminate\Cache\ArrayStore; use Illuminate\Cache\Repository; -use Illuminate\Support\Collection; use League\Flysystem\Adapter\Local; use League\Flysystem\Cached\CachedAdapter; use League\Flysystem\Cached\Storage\Memory; @@ -155,20 +151,6 @@ if ($max_execution_time !== '' && strpos(ini_get('disable_functions'), 'set_time set_time_limit((int) $max_execution_time); } -// Sessions -Session::start(); - -// Update the last-login time no more than once a minute. -$next_session_update = Carbon::createFromTimestamp((int) Session::get('session_time_updates'))->addMinute(); -if ($next_session_update < Carbon::now()) { - $timestamp_now = Carbon::now()->timestamp; - - if (Session::get('masquerade') === null) { - Auth::user()->setPreference('sessiontime', (string) $timestamp_now); - } - Session::put('session_time_updates', $timestamp_now); -} - try { // Most requests will need the current tree and user. $tree = Tree::findByName($request->get('ged')) ?? null; @@ -178,67 +160,18 @@ try { $tree = Tree::findByName(Site::getPreference('DEFAULT_GEDCOM')) ?? array_values(Tree::getAll())[0] ?? null; } - // Select a locale - define('WT_LOCALE', I18N::init('', $tree)); - Session::put('locale', WT_LOCALE); - // Most layouts will require a tree for the page header/footer View::share('tree', $tree); - DebugBar::startMeasure('routing'); - - // Load the route and routing table. - $route = $request->get('route'); - $routes = require 'routes/web.php'; - - // Find the controller and action for the selected route - $controller_action = $routes[$request->getMethod() . ':' . $route] ?? 'ErrorController@noRouteFound'; - [$controller_name, $action] = explode('@', $controller_action); - $controller_class = '\\Fisharebest\\Webtrees\\Http\\Controllers\\' . $controller_name; - app()->instance(Tree::class, $tree); app()->instance(UserInterface::class, Auth::user()); - app()->instance(LocaleInterface::class, WebtreesLocale::create(WT_LOCALE)); app()->instance(TimeoutService::class, new TimeoutService(microtime(true))); app()->instance(Filesystem::class, $filesystem); - $controller = app()->make($controller_class); - - DebugBar::stopMeasure('routing'); - - DebugBar::startMeasure('init theme'); - - /** @var Collection|ModuleThemeInterface[] $themes */ - $themes = app()->make(ModuleService::class)->findByInterface(ModuleThemeInterface::class); - - // Last theme used? - $theme = $themes->get(Session::get('theme_id', '')); - - // Default for tree? - if ($theme === null && $tree instanceof Tree) { - $theme = $themes->get($tree->getPreference('THEME_DIR')); - } - - // Default for site? - if ($theme === null) { - $theme = $themes->get(Site::getPreference('THEME_DIR')); - } - - // Default - if ($theme === null) { - $theme = app()->make(WebtreesTheme::class); - } - - // Bind this theme into the container - app()->instance(ModuleThemeInterface::class, $theme); - - // Remember this setting - Session::put('theme_id', $theme->name()); - - DebugBar::stopMeasure('init theme'); - $middleware_stack = [ CheckForMaintenanceMode::class, + UseSession::class, + UseLocale::class, ]; if (class_exists(DebugBar::class)) { @@ -247,6 +180,7 @@ try { if ($request->getMethod() === Request::METHOD_GET) { $middleware_stack[] = Housekeeping::class; + $middleware_stack[] = UseTheme::class; } if ($request->getMethod() === Request::METHOD_POST) { @@ -256,16 +190,30 @@ try { // Allow modules to provide middleware. foreach (app()->make(ModuleService::class)->findByInterface(MiddlewareInterface::class) as $middleware) { - $middleware[] = $middleware; + $middleware_stack[] = get_class($middleware); } + // We build the "onion" from the inside outwards, and some middleware (e.g. UseTheme) is dependant on others (e.g. UseLocale) + $middleware_stack = array_reverse($middleware_stack); + // Apply the middleware using the "onion" pattern. $pipeline = array_reduce($middleware_stack, function (Closure $next, string $middleware): Closure { // Create a closure to apply the middleware. return function (Request $request) use ($middleware, $next): Response { return app()->make($middleware)->handle($request, $next); }; - }, function (Request $request) use ($controller, $action): Response { + }, function (Request $request): Response { + // Load the route and routing table. + $route = $request->get('route'); + $routes = require 'routes/web.php'; + + // Find the controller and action for the selected route + $controller_action = $routes[$request->getMethod() . ':' . $route] ?? 'ErrorController@noRouteFound'; + [$controller_name, $action] = explode('@', $controller_action); + $controller_class = '\\Fisharebest\\Webtrees\\Http\\Controllers\\' . $controller_name; + + $controller = app()->make($controller_class); + return app()->dispatch($controller, $action); }); diff --git a/routes/web.php b/routes/web.php index 4e862f7031..760094bf9c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -18,6 +18,7 @@ declare(strict_types=1); namespace Fisharebest\Webtrees; /** @var Tree|null $tree */ +$tree = app()->make(Tree::class); $routes = []; |
