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\Http\RequestHandlers; 21 22use Fisharebest\Webtrees\Auth; 23use Fisharebest\Webtrees\DB; 24use Fisharebest\Webtrees\FlashMessages; 25use Fisharebest\Webtrees\I18N; 26use Fisharebest\Webtrees\Validator; 27use PDOException; 28use Psr\Http\Message\ResponseInterface; 29use Psr\Http\Message\ServerRequestInterface; 30use Psr\Http\Server\RequestHandlerInterface; 31 32use function array_unique; 33use function e; 34use function implode; 35use function preg_replace; 36use function redirect; 37use function route; 38use function trim; 39 40/** 41 * Edit the tree preferences. 42 */ 43class TreePreferencesAction implements RequestHandlerInterface 44{ 45 /** 46 * @param ServerRequestInterface $request 47 * 48 * @return ResponseInterface 49 */ 50 public function handle(ServerRequestInterface $request): ResponseInterface 51 { 52 $tree = Validator::attributes($request)->tree(); 53 54 // For backwards compatibility with webtrees 1.x we store the two calendar formats in one variable 55 // e.g. "gregorian_and_jewish" 56 $calendar_format_0 = Validator::parsedBody($request)->string('CALENDAR_FORMAT0'); 57 $calendar_format_1 = Validator::parsedBody($request)->string('CALENDAR_FORMAT1'); 58 $calendar_format = implode('_and_', array_unique([$calendar_format_0, $calendar_format_1])); 59 $chart_box_tags = Validator::parsedBody($request)->array('CHART_BOX_TAGS'); 60 $contact_user_id = Validator::parsedBody($request)->integer('CONTACT_USER_ID', 0); 61 $expand_notes = Validator::parsedBody($request)->boolean('EXPAND_NOTES'); 62 $expand_sources = Validator::parsedBody($request)->boolean('EXPAND_SOURCES'); 63 $fam_facts_quick = Validator::parsedBody($request)->array('FAM_FACTS_QUICK'); 64 $format_text = Validator::parsedBody($request)->string('FORMAT_TEXT'); 65 $generate_uuids = Validator::parsedBody($request)->boolean('GENERATE_UIDS'); 66 $hide_gedcom_errors = Validator::parsedBody($request)->boolean('HIDE_GEDCOM_ERRORS'); 67 $indi_facts_quick = Validator::parsedBody($request)->array('INDI_FACTS_QUICK'); 68 $media_upload = Validator::parsedBody($request)->integer('MEDIA_UPLOAD'); 69 $meta_description = Validator::parsedBody($request)->string('META_DESCRIPTION'); 70 $meta_title = Validator::parsedBody($request)->string('META_TITLE'); 71 $no_update_chan = Validator::parsedBody($request)->boolean('NO_UPDATE_CHAN'); 72 $pedigree_root_id = Validator::parsedBody($request)->string('PEDIGREE_ROOT_ID'); 73 $quick_required_facts = Validator::parsedBody($request)->array('QUICK_REQUIRED_FACTS'); 74 $quick_required_famfacts = Validator::parsedBody($request)->array('QUICK_REQUIRED_FAMFACTS'); 75 $show_counter = Validator::parsedBody($request)->boolean('SHOW_COUNTER'); 76 $show_est_list_dates = Validator::parsedBody($request)->boolean('SHOW_EST_LIST_DATES'); 77 $show_fact_icons = Validator::parsedBody($request)->boolean('SHOW_FACT_ICONS'); 78 $show_gedcom_record = Validator::parsedBody($request)->boolean('SHOW_GEDCOM_RECORD'); 79 $show_highlight_images = Validator::parsedBody($request)->boolean('SHOW_HIGHLIGHT_IMAGES'); 80 $show_last_change = Validator::parsedBody($request)->boolean('SHOW_LAST_CHANGE'); 81 $show_media_download = Validator::parsedBody($request)->integer('SHOW_MEDIA_DOWNLOAD'); 82 $show_no_watermark = Validator::parsedBody($request)->integer('SHOW_NO_WATERMARK'); 83 $show_parents_age = Validator::parsedBody($request)->boolean('SHOW_PARENTS_AGE'); 84 $show_pedigree_places = Validator::parsedBody($request)->integer('SHOW_PEDIGREE_PLACES'); 85 $show_pedigree_places_suffix = Validator::parsedBody($request)->integer('SHOW_PEDIGREE_PLACES_SUFFIX'); 86 $show_relatives_events = Validator::parsedBody($request)->array('SHOW_RELATIVES_EVENTS'); 87 $sublist_trigger_i = Validator::parsedBody($request)->integer('SUBLIST_TRIGGER_I'); 88 $surname_list_style = Validator::parsedBody($request)->string('SURNAME_LIST_STYLE'); 89 $surname_tradition = Validator::parsedBody($request)->string('SURNAME_TRADITION'); 90 $use_silhouette = Validator::parsedBody($request)->boolean('USE_SILHOUETTE'); 91 $webmaster_user_id = Validator::parsedBody($request)->integer('WEBMASTER_USER_ID', 0); 92 $title = Validator::parsedBody($request)->string('title'); 93 94 $contact_user_id = $contact_user_id === 0 ? '' : (string) $contact_user_id; 95 $webmaster_user_id = $webmaster_user_id === 0 ? '' : (string) $webmaster_user_id; 96 97 $tree->setPreference('CALENDAR_FORMAT', $calendar_format); 98 $tree->setPreference('CHART_BOX_TAGS', implode(',', $chart_box_tags)); 99 $tree->setPreference('CONTACT_USER_ID', $contact_user_id); 100 $tree->setPreference('EXPAND_NOTES', (string) $expand_notes); 101 $tree->setPreference('EXPAND_SOURCES', (string) $expand_sources); 102 $tree->setPreference('FAM_FACTS_QUICK', implode(',', $fam_facts_quick)); 103 $tree->setPreference('FORMAT_TEXT', $format_text); 104 $tree->setPreference('GENERATE_UIDS', (string) $generate_uuids); 105 $tree->setPreference('HIDE_GEDCOM_ERRORS', (string) $hide_gedcom_errors); 106 $tree->setPreference('INDI_FACTS_QUICK', implode(',', $indi_facts_quick)); 107 $tree->setPreference('MEDIA_UPLOAD', (string) $media_upload); 108 $tree->setPreference('META_DESCRIPTION', $meta_description); 109 $tree->setPreference('META_TITLE', $meta_title); 110 $tree->setPreference('NO_UPDATE_CHAN', (string) $no_update_chan); 111 $tree->setPreference('PEDIGREE_ROOT_ID', $pedigree_root_id); 112 $tree->setPreference('QUICK_REQUIRED_FACTS', implode(',', $quick_required_facts)); 113 $tree->setPreference('QUICK_REQUIRED_FAMFACTS', implode(',', $quick_required_famfacts)); 114 $tree->setPreference('SHOW_COUNTER', (string) $show_counter); 115 $tree->setPreference('SHOW_EST_LIST_DATES', (string) $show_est_list_dates); 116 $tree->setPreference('SHOW_FACT_ICONS', (string) $show_fact_icons); 117 $tree->setPreference('SHOW_GEDCOM_RECORD', (string) $show_gedcom_record); 118 $tree->setPreference('SHOW_HIGHLIGHT_IMAGES', (string) $show_highlight_images); 119 $tree->setPreference('SHOW_LAST_CHANGE', (string) $show_last_change); 120 $tree->setPreference('SHOW_MEDIA_DOWNLOAD', (string) $show_media_download); 121 $tree->setPreference('SHOW_NO_WATERMARK', (string) $show_no_watermark); 122 $tree->setPreference('SHOW_PARENTS_AGE', (string) $show_parents_age); 123 $tree->setPreference('SHOW_PEDIGREE_PLACES', (string) $show_pedigree_places); 124 $tree->setPreference('SHOW_PEDIGREE_PLACES_SUFFIX', (string) $show_pedigree_places_suffix); 125 $tree->setPreference('SHOW_RELATIVES_EVENTS', implode(',', $show_relatives_events)); 126 $tree->setPreference('SUBLIST_TRIGGER_I', (string) $sublist_trigger_i); 127 $tree->setPreference('SURNAME_LIST_STYLE', $surname_list_style); 128 $tree->setPreference('SURNAME_TRADITION', $surname_tradition); 129 $tree->setPreference('USE_SILHOUETTE', (string) $use_silhouette); 130 $tree->setPreference('WEBMASTER_USER_ID', (string) $webmaster_user_id); 131 $tree->setPreference('title', $title); 132 133 $url = route(ManageTrees::class, ['tree' => $tree->name()]); 134 135 if (Auth::isAdmin()) { 136 // Only accept valid folders for MEDIA_DIRECTORY 137 $MEDIA_DIRECTORY = Validator::parsedBody($request)->string('MEDIA_DIRECTORY'); 138 $MEDIA_DIRECTORY = preg_replace('/[:\/\\\\]+/', '/', $MEDIA_DIRECTORY); 139 $MEDIA_DIRECTORY = trim($MEDIA_DIRECTORY, '/') . '/'; 140 141 $tree->setPreference('MEDIA_DIRECTORY', $MEDIA_DIRECTORY); 142 143 $gedcom = Validator::parsedBody($request)->isNotEmpty()->string('gedcom'); 144 145 if ($gedcom !== $tree->name()) { 146 try { 147 DB::table('gedcom') 148 ->where('gedcom_id', '=', $tree->id()) 149 ->update(['gedcom_name' => $gedcom]); 150 151 // Did we rename the default tree? 152 DB::table('site_setting') 153 ->where('setting_name', '=', 'DEFAULT_GEDCOM') 154 ->where('setting_value', '=', $tree->name()) 155 ->update(['setting_value' => $gedcom]); 156 157 $url = route(ManageTrees::class, ['tree' => $gedcom]); 158 } catch (PDOException) { 159 // Probably a duplicate name. 160 } 161 } 162 } 163 164 FlashMessages::addMessage(I18N::translate('The preferences for the family tree “%s” have been updated.', e($tree->title())), 'success'); 165 166 // Coming soon... 167 $all_trees = Validator::parsedBody($request)->boolean('all_trees', false); 168 $new_trees = Validator::parsedBody($request)->boolean('new_trees', false); 169 170 if ($all_trees) { 171 FlashMessages::addMessage(I18N::translate('The preferences for all family trees have been updated.'), 'success'); 172 } 173 174 if ($new_trees) { 175 FlashMessages::addMessage(I18N::translate('The preferences for new family trees have been updated.'), 'success'); 176 } 177 178 return redirect($url); 179 } 180} 181