xref: /webtrees/app/Http/Middleware/UseTheme.php (revision b5979037de52280b1023c9eb58518a3089e7d267)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2019 webtrees development team
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16declare(strict_types=1);
17
18namespace Fisharebest\Webtrees\Http\Middleware;
19
20use Closure;
21use Fisharebest\Webtrees\Module\ModuleThemeInterface;
22use Fisharebest\Webtrees\Module\WebtreesTheme;
23use Fisharebest\Webtrees\Services\ModuleService;
24use Fisharebest\Webtrees\Session;
25use Fisharebest\Webtrees\Site;
26use Fisharebest\Webtrees\Tree;
27use Generator;
28use Symfony\Component\HttpFoundation\Request;
29use Symfony\Component\HttpFoundation\Response;
30use Throwable;
31
32/**
33 * Middleware to set a global theme.
34 */
35class UseTheme implements MiddlewareInterface
36{
37    /** @var ModuleService */
38    private $module_service;
39
40    /** @var Tree|null */
41    private $tree;
42
43    /**
44     * UseTheme constructor.
45     *
46     * @param ModuleService $module_service
47     * @param Tree|null     $tree
48     */
49    public function __construct(ModuleService $module_service, ?Tree $tree)
50    {
51        $this->module_service = $module_service;
52        $this->tree           = $tree;
53    }
54
55    /**
56     * @param Request $request
57     * @param Closure $next
58     *
59     * @return Response
60     * @throws Throwable
61     */
62    public function handle(Request $request, Closure $next): Response
63    {
64        foreach ($this->themes() as $theme) {
65            if ($theme instanceof ModuleThemeInterface) {
66                // Bind this theme into the container
67                app()->instance(ModuleThemeInterface::class, $theme);
68
69                // Remember this setting
70                Session::put('theme_id', $theme->name());
71
72                break;
73            }
74        }
75
76        return $next($request);
77    }
78
79    /**
80     * The theme can be chosen in various ways.
81     *
82     * @return Generator
83     */
84    private function themes(): Generator
85    {
86        $themes = $this->module_service->findByInterface(ModuleThemeInterface::class);
87
88        // Last theme used
89        yield $themes->get(Session::get('theme_id', ''));
90
91        // Default for tree
92        if ($this->tree instanceof Tree) {
93            yield $themes->get($this->tree->getPreference('THEME_DIR'));
94        }
95
96        // Default for site
97        yield $themes->get(Site::getPreference('THEME_DIR'));
98
99        // Default for application
100        yield app()->make(WebtreesTheme::class);
101    }
102}
103