xref: /webtrees/app/Module/ColorsTheme.php (revision d11be7027e34e3121be11cc025421873364403f9)
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
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Module;
21
22use Fisharebest\Webtrees\Auth;
23use Fisharebest\Webtrees\I18N;
24use Fisharebest\Webtrees\Menu;
25use Fisharebest\Webtrees\Session;
26use Fisharebest\Webtrees\Site;
27use Fisharebest\Webtrees\Tree;
28use Fisharebest\Webtrees\Validator;
29use Psr\Http\Message\ResponseInterface;
30use Psr\Http\Message\ServerRequestInterface;
31
32use function asset;
33use function is_string;
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 array<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    = Validator::attributes($request)->user();
86        $palette = Validator::queryParams($request)->isInArrayKeys($this->palettes())->string('palette');
87
88        $user->setPreference('themecolor', $palette);
89
90        // If we are the admin, then use our selection as the site default.
91        if (Auth::isAdmin($user)) {
92            Site::setPreference('DEFAULT_COLOR_PALETTE', $palette);
93        }
94
95        Session::put('palette', $palette);
96
97        return response();
98    }
99
100    /**
101     * A list of CSS files to include for this page.
102     *
103     * @return array<string>
104     */
105    public function stylesheets(): array
106    {
107        return [
108            asset('css/colors.min.css'),
109            asset('css/colors/' . $this->palette() . '.min.css'),
110        ];
111    }
112
113    /**
114     * Create a menu of palette options
115     *
116     * @return Menu
117     */
118    protected function menuPalette(): Menu
119    {
120        /* I18N: A colour scheme */
121        $menu = new Menu(I18N::translate('Palette'), '#', 'menu-color');
122
123        $palette = $this->palette();
124
125        foreach ($this->palettes() as $palette_id => $palette_name) {
126            $url = route('module', ['module' => $this->name(), 'action' => 'Palette', 'palette' => $palette_id]);
127
128            $submenu = new Menu(
129                $palette_name,
130                '#',
131                'menu-color-' . $palette_id . ($palette === $palette_id ? ' active' : ''),
132                [
133                    'data-wt-post-url' => $url,
134                ]
135            );
136
137            $menu->addSubmenu($submenu);
138        }
139
140        return $menu;
141    }
142
143    /**
144     * @return array<string>
145     */
146    private function palettes(): array
147    {
148        $palettes = [
149            /* I18N: The name of a colour-scheme */
150            'aquamarine'       => I18N::translate('Aqua Marine'),
151            /* I18N: The name of a colour-scheme */
152            'ash'              => I18N::translate('Ash'),
153            /* I18N: The name of a colour-scheme */
154            'belgianchocolate' => I18N::translate('Belgian Chocolate'),
155            /* I18N: The name of a colour-scheme */
156            'bluelagoon'       => I18N::translate('Blue Lagoon'),
157            /* I18N: The name of a colour-scheme */
158            'bluemarine'       => I18N::translate('Blue Marine'),
159            /* I18N: The name of a colour-scheme */
160            'coffeeandcream'   => I18N::translate('Coffee and Cream'),
161            /* I18N: The name of a colour-scheme */
162            'coldday'          => I18N::translate('Cold Day'),
163            /* I18N: The name of a colour-scheme */
164            'greenbeam'        => I18N::translate('Green Beam'),
165            /* I18N: The name of a colour-scheme */
166            'mediterranio'     => I18N::translate('Mediterranio'),
167            /* I18N: The name of a colour-scheme */
168            'mercury'          => I18N::translate('Mercury'),
169            /* I18N: The name of a colour-scheme */
170            'nocturnal'        => I18N::translate('Nocturnal'),
171            /* I18N: The name of a colour-scheme */
172            'olivia'           => I18N::translate('Olivia'),
173            /* I18N: The name of a colour-scheme */
174            'pinkplastic'      => I18N::translate('Pink Plastic'),
175            /* I18N: The name of a colour-scheme */
176            'sage'             => I18N::translate('Sage'),
177            /* I18N: The name of a colour-scheme */
178            'shinytomato'      => I18N::translate('Shiny Tomato'),
179            /* I18N: The name of a colour-scheme */
180            'tealtop'          => I18N::translate('Teal Top'),
181        ];
182
183        uasort($palettes, I18N::comparator());
184
185        return $palettes;
186    }
187
188    /**
189     * @return string
190     */
191    private function palette(): string
192    {
193        // If we are logged in, use our preference
194        $palette = Auth::user()->getPreference('themecolor');
195
196        // If not logged in or no preference, use one we selected earlier in the session.
197        if ($palette === '') {
198            $palette = Session::get('palette');
199            $palette = is_string($palette) ? $palette : '';
200        }
201
202        // We haven't selected one this session? Use the site default
203        if ($palette === '') {
204            $palette = Site::getPreference('DEFAULT_COLOR_PALETTE');
205        }
206
207        if ($palette === '') {
208            $palette = self::DEFAULT_PALETTE;
209        }
210
211        return $palette;
212    }
213}
214