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