Passed
Push — 2.1 ( 41b9d0...eea2c1 )
by Greg
15:57 queued 07:26
created

ColorsTheme::headContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2025 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
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Module;
21
22
use Fisharebest\Webtrees\Auth;
23
use Fisharebest\Webtrees\I18N;
24
use Fisharebest\Webtrees\Menu;
25
use Fisharebest\Webtrees\Session;
26
use Fisharebest\Webtrees\Site;
27
use Fisharebest\Webtrees\Tree;
28
use Fisharebest\Webtrees\Validator;
29
use Psr\Http\Message\ResponseInterface;
30
use Psr\Http\Message\ServerRequestInterface;
31
32
use function asset;
33
use function is_string;
34
use function response;
35
use function uasort;
36
37
/**
38
 * The colors theme.
39
 */
40
class ColorsTheme extends CloudsTheme implements ModuleGlobalInterface
41
{
42
    use ModuleGlobalTrait;
43
44
    // If no valid palette has been selected, use this one.
45
    private const DEFAULT_PALETTE = 'ash';
46
47
    private const CSS = [
48
        'aquamarine'       => ':root{--color-1:#007e94;--color-2:#085360;--color-3:#00a9c7;--color-4:#dcf2f9;--color-5:#ffffff;--color-6:#ffffff;}',
49
        'ash'              => ':root{--color-1:#5d6779;--color-2:#2a2b2d;--color-3:#9da5b4;--color-4:#ededee;--color-5:#ffffff;--color-6:#ffffff;}',
50
        'belgianchocolate' => ':root{--color-1:#971702;--color-2:#311900;--color-3:#af2604;--color-4:#f6edd5;--color-5:#ffffff;--color-6:#ffffff;}',
51
        'bluelagoon'       => ':root{--color-1:#5ab5ee;--color-2:#2385c2;--color-3:#5ab5ee;--color-4:#e6f5ff;--color-5:#ffffff;--color-6:#ffffff;}',
52
        'bluemarine'       => ':root{--color-1:#6598cb;--color-2:#98badd;--color-3:#6598cb;--color-4:#e0e7ff;--color-5:#ffffff;--color-6:#ffffff;}',
53
        'coffeeandcream'   => ':root{--color-1:#d4c7a7;--color-2:#93724f;--color-3:#93724f;--color-4:#f4ead1;--color-5:#553e2f;--color-6:#ffffff;}',
54
        'coldday'          => ':root{--color-1:#1a1575;--color-2:#4d91ff;--color-3:#5997e3;--color-4:#e6e1ff;--color-5:#ffffff;--color-6:#ffffff;}',
55
        'greenbeam'        => ':root{--color-1:#03961e;--color-2:#7be000;--color-3:#04af23;--color-4:#e6ffc7;--color-5:#ffffff;--color-6:#ffffff;}',
56
        'mediterranio'     => ':root{--color-1:#a30f42;--color-2:#fc6d1d;--color-3:#d23014;--color-4:#fef9dc;--color-5:#ffffff;--color-6:#ffffff;}',
57
        'mercury'          => ':root{--color-1:#d4d4d4;--color-2:#a9adbc;--color-3:#c6c8d2;--color-4:#f0f2f5;--color-5:#707070;--color-6:#707070;}',
58
        'nocturnal'        => ':root{--color-1:#0a2352;--color-2:#9fa8d5;--color-3:#6a78be;--color-4:#e0e1f0;--color-5:#ffffff;--color-6:#ffffff;}',
59
        'olivia'           => ':root{--color-1:#7db323;--color-2:#b5d52a;--color-3:#7db323;--color-4:#eef9dc;--color-5:#ffffff;--color-6:#ffffff;}',
60
        'pinkplastic'      => ':root{--color-1:#f41063;--color-2:#f391c6;--color-3:#f75993;--color-4:#fbdaed;--color-5:#ffffff;--color-6:#ffffff;}',
61
        'sage'             => ':root{--color-1:#767647;--color-2:#ccccaa;--color-3:#ccccaa;--color-4:#eeeedd;--color-5:#ffffff;--color-6:#333333;}',
62
        'shinytomato'      => ':root{--color-1:#f21107;--color-2:#a1443a;--color-3:#f96058;--color-4:#f0eaf0;--color-5:#ffffff;--color-6:#ffffff;}',
63
        'tealtop'          => ':root{--color-1:#34775a;--color-2:#52bf90;--color-3:#51b389;--color-4:#d2f4e6;--color-5:#ffffff;--color-6:#ffffff;}',
64
    ];
65
66
    public function title(): string
67
    {
68
        /* I18N: Name of a theme. */
69
        return I18N::translate('colors');
70
    }
71
72
    /**
73
     * Generate a list of items for the user menu.
74
     *
75
     * @param Tree|null $tree
76
     *
77
     * @return array<Menu>
78
     */
79
    public function userMenu(?Tree $tree): array
80
    {
81
        return array_filter([
82
            $this->menuPendingChanges($tree),
83
            $this->menuMyPages($tree),
84
            $this->menuThemes(),
85
            $this->menuPalette(),
86
            $this->menuLanguages(),
87
            $this->menuLogin(),
88
            $this->menuLogout(),
89
        ]);
90
    }
91
92
    /**
93
     * Switch to a new palette
94
     *
95
     * @param ServerRequestInterface $request
96
     *
97
     * @return ResponseInterface
98
     */
99
    public function postPaletteAction(ServerRequestInterface $request): ResponseInterface
100
    {
101
        $user    = Validator::attributes($request)->user();
102
        $palette = Validator::queryParams($request)->isInArrayKeys($this->palettes())->string('palette');
103
104
        $user->setPreference('themecolor', $palette);
105
106
        // If we are the admin, then use our selection as the site default.
107
        if (Auth::isAdmin($user)) {
108
            Site::setPreference('DEFAULT_COLOR_PALETTE', $palette);
109
        }
110
111
        Session::put('palette', $palette);
112
113
        return response();
114
    }
115
116
    /**
117
     * A list of CSS files to include for this page.
118
     *
119
     * @return array<string>
120
     */
121
    public function stylesheets(): array
122
    {
123
        return [
124
            asset('css/colors.min.css'),
125
        ];
126
    }
127
128
    public function headContent(): string
129
    {
130
        return '<style>' . self::CSS[$this->palette()] . '</style>';
131
    }
132
133
    /**
134
     * Create a menu of palette options
135
     *
136
     * @return Menu
137
     */
138
    protected function menuPalette(): Menu
139
    {
140
        /* I18N: A colour scheme */
141
        $menu = new Menu(I18N::translate('Palette'), '#', 'menu-color');
142
143
        $palette = $this->palette();
144
145
        foreach ($this->palettes() as $palette_id => $palette_name) {
146
            $url = route('module', ['module' => $this->name(), 'action' => 'Palette', 'palette' => $palette_id]);
147
148
            $submenu = new Menu(
149
                $palette_name,
150
                '#',
151
                'menu-color-' . $palette_id . ($palette === $palette_id ? ' active' : ''),
152
                [
153
                    'data-wt-post-url' => $url,
154
                ]
155
            );
156
157
            $menu->addSubmenu($submenu);
158
        }
159
160
        return $menu;
161
    }
162
163
    /**
164
     * @return array<string>
165
     */
166
    private function palettes(): array
167
    {
168
        $palettes = [
169
            /* I18N: The name of a colour-scheme */
170
            'aquamarine'       => I18N::translate('Aqua Marine'),
171
            /* I18N: The name of a colour-scheme */
172
            'ash'              => I18N::translate('Ash'),
173
            /* I18N: The name of a colour-scheme */
174
            'belgianchocolate' => I18N::translate('Belgian Chocolate'),
175
            /* I18N: The name of a colour-scheme */
176
            'bluelagoon'       => I18N::translate('Blue Lagoon'),
177
            /* I18N: The name of a colour-scheme */
178
            'bluemarine'       => I18N::translate('Blue Marine'),
179
            /* I18N: The name of a colour-scheme */
180
            'coffeeandcream'   => I18N::translate('Coffee and Cream'),
181
            /* I18N: The name of a colour-scheme */
182
            'coldday'          => I18N::translate('Cold Day'),
183
            /* I18N: The name of a colour-scheme */
184
            'greenbeam'        => I18N::translate('Green Beam'),
185
            /* I18N: The name of a colour-scheme */
186
            'mediterranio'     => I18N::translate('Mediterranio'),
187
            /* I18N: The name of a colour-scheme */
188
            'mercury'          => I18N::translate('Mercury'),
189
            /* I18N: The name of a colour-scheme */
190
            'nocturnal'        => I18N::translate('Nocturnal'),
191
            /* I18N: The name of a colour-scheme */
192
            'olivia'           => I18N::translate('Olivia'),
193
            /* I18N: The name of a colour-scheme */
194
            'pinkplastic'      => I18N::translate('Pink Plastic'),
195
            /* I18N: The name of a colour-scheme */
196
            'sage'             => I18N::translate('Sage'),
197
            /* I18N: The name of a colour-scheme */
198
            'shinytomato'      => I18N::translate('Shiny Tomato'),
199
            /* I18N: The name of a colour-scheme */
200
            'tealtop'          => I18N::translate('Teal Top'),
201
        ];
202
203
        uasort($palettes, I18N::comparator());
204
205
        return $palettes;
206
    }
207
208
    /**
209
     * @return string
210
     */
211
    private function palette(): string
212
    {
213
        // If we are logged in, use our preference
214
        $palette = Auth::user()->getPreference('themecolor');
215
216
        // If not logged in or no preference, use one we selected earlier in the session.
217
        if ($palette === '') {
218
            $palette = Session::get('palette');
219
            $palette = is_string($palette) ? $palette : '';
220
        }
221
222
        // We haven't selected one this session? Use the site default
223
        if ($palette === '') {
224
            $palette = Site::getPreference('DEFAULT_COLOR_PALETTE');
225
        }
226
227
        if ($palette === '') {
228
            $palette = self::DEFAULT_PALETTE;
229
        }
230
231
        return $palette;
232
    }
233
}
234