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