xref: /webtrees/app/Module/ColorsTheme.php (revision bedf83da798d605df6e0cd217b04ee39d614702d)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2021 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
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Module;
21
22use Fisharebest\Webtrees\Auth;
23use Fisharebest\Webtrees\Contracts\UserInterface;
24use Fisharebest\Webtrees\I18N;
25use Fisharebest\Webtrees\Menu;
26use Fisharebest\Webtrees\Session;
27use Fisharebest\Webtrees\Site;
28use Fisharebest\Webtrees\Tree;
29use Psr\Http\Message\ResponseInterface;
30use Psr\Http\Message\ServerRequestInterface;
31
32use function assert;
33use function asset;
34use function response;
35use function uasort;
36
37/**
38 * The colors theme.
39 */
40class ColorsTheme extends CloudsTheme
41{
42    // If no valid palette has been selected, use this one.
43    private const DEFAULT_PALETTE = 'ash';
44
45    /**
46     * How should this module be identified in the control panel, etc.?
47     *
48     * @return string
49     */
50    public function title(): string
51    {
52        /* I18N: Name of a theme. */
53        return I18N::translate('colors');
54    }
55
56    /**
57     * Generate a list of items for the user menu.
58     *
59     * @param Tree|null $tree
60     *
61     * @return Menu[]
62     */
63    public function userMenu(?Tree $tree): array
64    {
65        return array_filter([
66            $this->menuPendingChanges($tree),
67            $this->menuMyPages($tree),
68            $this->menuThemes(),
69            $this->menuPalette(),
70            $this->menuLanguages(),
71            $this->menuLogin(),
72            $this->menuLogout(),
73        ]);
74    }
75
76    /**
77     * Switch to a new palette
78     *
79     * @param ServerRequestInterface $request
80     *
81     * @return ResponseInterface
82     */
83    public function postPaletteAction(ServerRequestInterface $request): ResponseInterface
84    {
85        $user = $request->getAttribute('user');
86        assert($user instanceof UserInterface);
87
88        $palette = $request->getQueryParams()['palette'];
89        assert(array_key_exists($palette, $this->palettes()));
90
91        $user->setPreference('themecolor', $palette);
92
93        // If we are the admin, then use our selection as the site default.
94        if (Auth::isAdmin($user)) {
95            Site::setPreference('DEFAULT_COLOR_PALETTE', $palette);
96        }
97
98        Session::put('palette', $palette);
99
100        return response();
101    }
102
103    /**
104     * A list of CSS files to include for this page.
105     *
106     * @return array<string>
107     */
108    public function stylesheets(): array
109    {
110        return [
111            asset('css/colors.min.css'),
112            asset('css/colors/' . $this->palette() . '.min.css'),
113        ];
114    }
115
116    /**
117     * Create a menu of palette options
118     *
119     * @return Menu
120     */
121    protected function menuPalette(): Menu
122    {
123        /* I18N: A colour scheme */
124        $menu = new Menu(I18N::translate('Palette'), '#', 'menu-color');
125
126        $palette = $this->palette();
127
128        foreach ($this->palettes() as $palette_id => $palette_name) {
129            $url = route('module', ['module' => $this->name(), 'action' => 'Palette', 'palette' => $palette_id]);
130
131            $submenu = new Menu(
132                $palette_name,
133                '#',
134                'menu-color-' . $palette_id . ($palette === $palette_id ? ' active' : ''),
135                [
136                    'data-post-url' => $url,
137                ]
138            );
139
140            $menu->addSubmenu($submenu);
141        }
142
143        return $menu;
144    }
145
146    /**
147     * @return array<string>
148     */
149    private function palettes(): array
150    {
151        $palettes = [
152            /* I18N: The name of a colour-scheme */
153            'aquamarine'       => I18N::translate('Aqua Marine'),
154            /* I18N: The name of a colour-scheme */
155            'ash'              => I18N::translate('Ash'),
156            /* I18N: The name of a colour-scheme */
157            'belgianchocolate' => I18N::translate('Belgian Chocolate'),
158            /* I18N: The name of a colour-scheme */
159            'bluelagoon'       => I18N::translate('Blue Lagoon'),
160            /* I18N: The name of a colour-scheme */
161            'bluemarine'       => I18N::translate('Blue Marine'),
162            /* I18N: The name of a colour-scheme */
163            'coffeeandcream'   => I18N::translate('Coffee and Cream'),
164            /* I18N: The name of a colour-scheme */
165            'coldday'          => I18N::translate('Cold Day'),
166            /* I18N: The name of a colour-scheme */
167            'greenbeam'        => I18N::translate('Green Beam'),
168            /* I18N: The name of a colour-scheme */
169            'mediterranio'     => I18N::translate('Mediterranio'),
170            /* I18N: The name of a colour-scheme */
171            'mercury'          => I18N::translate('Mercury'),
172            /* I18N: The name of a colour-scheme */
173            'nocturnal'        => I18N::translate('Nocturnal'),
174            /* I18N: The name of a colour-scheme */
175            'olivia'           => I18N::translate('Olivia'),
176            /* I18N: The name of a colour-scheme */
177            'pinkplastic'      => I18N::translate('Pink Plastic'),
178            /* I18N: The name of a colour-scheme */
179            'sage'             => I18N::translate('Sage'),
180            /* I18N: The name of a colour-scheme */
181            'shinytomato'      => I18N::translate('Shiny Tomato'),
182            /* I18N: The name of a colour-scheme */
183            'tealtop'          => I18N::translate('Teal Top'),
184        ];
185
186        uasort($palettes, I18N::comparator());
187
188        return $palettes;
189    }
190
191    /**
192     * @return string
193     */
194    private function palette(): string
195    {
196        // If we are logged in, use our preference
197        $palette = Auth::user()->getPreference('themecolor', '');
198
199        // If not logged in or no preference, use one we selected earlier in the session.
200        if ($palette === '') {
201            $palette = Session::get('palette', '');
202        }
203
204        // We haven't selected one this session? Use the site default
205        if ($palette === '') {
206            $palette = Site::getPreference('DEFAULT_COLOR_PALETTE', self::DEFAULT_PALETTE);
207        }
208
209        return $palette;
210    }
211}
212