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\DB; 23use Fisharebest\Webtrees\FlashMessages; 24use Fisharebest\Webtrees\I18N; 25use Fisharebest\Webtrees\Validator; 26use Psr\Http\Message\ResponseInterface; 27use Psr\Http\Message\ServerRequestInterface; 28use Psr\Http\Server\RequestHandlerInterface; 29 30use function e; 31use function redirect; 32use function round; 33 34/** 35 * Controller for maintaining geographic data. 36 */ 37class MapDataSave implements RequestHandlerInterface 38{ 39 /** 40 * @param ServerRequestInterface $request 41 * 42 * @return ResponseInterface 43 */ 44 public function handle(ServerRequestInterface $request): ResponseInterface 45 { 46 $parent_id = Validator::parsedBody($request)->string('parent_id'); 47 $place_id = Validator::parsedBody($request)->string('place_id'); 48 $latitude = Validator::parsedBody($request)->string('new_place_lati'); 49 $longitude = Validator::parsedBody($request)->string('new_place_long'); 50 $name = Validator::parsedBody($request)->string('new_place_name'); 51 $url = Validator::parsedBody($request)->isLocalUrl()->string('url'); 52 53 $name = mb_substr($name, 0, 120); 54 $place_id = $place_id === '' ? null : $place_id; 55 $parent_id = $parent_id === '' ? null : $parent_id; 56 57 if ($latitude === '' || $longitude === '') { 58 $latitude = null; 59 $longitude = null; 60 } else { 61 // 5 decimal places (locate to within about 1 metre) 62 $latitude = round((float) $latitude, 5); 63 $longitude = round((float) $longitude, 5); 64 65 // 0,0 is only allowed at the top level 66 if ($parent_id !== null && $latitude === 0.0 && $longitude === 0.0) { 67 $latitude = null; 68 $longitude = null; 69 } 70 } 71 72 if ($place_id === null) { 73 $exists_query = DB::table('place_location')->where('place', '=', $name); 74 75 if ($parent_id === null) { 76 $exists_query->whereNull('parent_id'); 77 } else { 78 $exists_query->where('parent_id', '=', $parent_id); 79 } 80 81 if (!$exists_query->exists()) { 82 DB::table('place_location')->insert([ 83 'parent_id' => $parent_id, 84 'place' => $name, 85 'latitude' => $latitude, 86 'longitude' => $longitude, 87 ]); 88 89 $message = I18N::translate('The location has been created', e($name)); 90 FlashMessages::addMessage($message, 'success'); 91 } 92 } else { 93 DB::table('place_location') 94 ->where('id', '=', $place_id) 95 ->update([ 96 'place' => $name, 97 'latitude' => $latitude, 98 'longitude' => $longitude, 99 ]); 100 101 $message = I18N::translate('The details for “%s” have been updated.', e($name)); 102 FlashMessages::addMessage($message, 'success'); 103 } 104 105 return redirect($url); 106 } 107} 108