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 is_string; 35use function response; 36use function uasort; 37 38/** 39 * The colors theme. 40 */ 41class ColorsTheme extends CloudsTheme 42{ 43 // If no valid palette has been selected, use this one. 44 private const DEFAULT_PALETTE = 'ash'; 45 46 /** 47 * How should this module be identified in the control panel, etc.? 48 * 49 * @return string 50 */ 51 public function title(): string 52 { 53 /* I18N: Name of a theme. */ 54 return I18N::translate('colors'); 55 } 56 57 /** 58 * Generate a list of items for the user menu. 59 * 60 * @param Tree|null $tree 61 * 62 * @return array<Menu> 63 */ 64 public function userMenu(?Tree $tree): array 65 { 66 return array_filter([ 67 $this->menuPendingChanges($tree), 68 $this->menuMyPages($tree), 69 $this->menuThemes(), 70 $this->menuPalette(), 71 $this->menuLanguages(), 72 $this->menuLogin(), 73 $this->menuLogout(), 74 ]); 75 } 76 77 /** 78 * Switch to a new palette 79 * 80 * @param ServerRequestInterface $request 81 * 82 * @return ResponseInterface 83 */ 84 public function postPaletteAction(ServerRequestInterface $request): ResponseInterface 85 { 86 $user = $request->getAttribute('user'); 87 assert($user instanceof UserInterface); 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