1f5402f3dSGreg Roach<?php 2f5402f3dSGreg Roach 3f5402f3dSGreg Roach/** 4f5402f3dSGreg Roach * webtrees: online genealogy 5f5402f3dSGreg Roach * Copyright (C) 2019 webtrees development team 6f5402f3dSGreg Roach * This program is free software: you can redistribute it and/or modify 7f5402f3dSGreg Roach * it under the terms of the GNU General Public License as published by 8f5402f3dSGreg Roach * the Free Software Foundation, either version 3 of the License, or 9f5402f3dSGreg Roach * (at your option) any later version. 10f5402f3dSGreg Roach * This program is distributed in the hope that it will be useful, 11f5402f3dSGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 12f5402f3dSGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13f5402f3dSGreg Roach * GNU General Public License for more details. 14f5402f3dSGreg Roach * You should have received a copy of the GNU General Public License 15f5402f3dSGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 16f5402f3dSGreg Roach */ 17f5402f3dSGreg Roach 18f5402f3dSGreg Roachdeclare(strict_types=1); 19f5402f3dSGreg Roach 20f5402f3dSGreg Roachnamespace Fisharebest\Webtrees\Http\RequestHandlers; 21f5402f3dSGreg Roach 22f5402f3dSGreg Roachuse Fisharebest\Webtrees\GedcomTag; 23f5402f3dSGreg Roachuse Fisharebest\Webtrees\Http\ViewResponseTrait; 24f5402f3dSGreg Roachuse Fisharebest\Webtrees\I18N; 25f5402f3dSGreg Roachuse Fisharebest\Webtrees\Services\SearchService; 26f5402f3dSGreg Roachuse Fisharebest\Webtrees\Tree; 27f5402f3dSGreg Roachuse InvalidArgumentException; 28f5402f3dSGreg Roachuse Psr\Http\Message\ResponseInterface; 29f5402f3dSGreg Roachuse Psr\Http\Message\ServerRequestInterface; 30f5402f3dSGreg Roachuse Psr\Http\Server\RequestHandlerInterface; 31f5402f3dSGreg Roach 32f5402f3dSGreg Roach/** 33f5402f3dSGreg Roach * Search for genealogy data 34f5402f3dSGreg Roach */ 35f5402f3dSGreg Roachclass SearchAdvancedPage implements RequestHandlerInterface 36f5402f3dSGreg Roach{ 37f5402f3dSGreg Roach use ViewResponseTrait; 38f5402f3dSGreg Roach 39f5402f3dSGreg Roach private const DEFAULT_ADVANCED_FIELDS = [ 40f5402f3dSGreg Roach 'NAME:GIVN', 41f5402f3dSGreg Roach 'NAME:SURN', 42f5402f3dSGreg Roach 'BIRT:DATE', 43f5402f3dSGreg Roach 'BIRT:PLAC', 44f5402f3dSGreg Roach 'FAMS:MARR:DATE', 45f5402f3dSGreg Roach 'FAMS:MARR:PLAC', 46f5402f3dSGreg Roach 'DEAT:DATE', 47f5402f3dSGreg Roach 'DEAT:PLAC', 48f5402f3dSGreg Roach 'FAMC:HUSB:NAME:GIVN', 49f5402f3dSGreg Roach 'FAMC:HUSB:NAME:SURN', 50f5402f3dSGreg Roach 'FAMC:WIFE:NAME:GIVN', 51f5402f3dSGreg Roach 'FAMC:WIFE:NAME:SURN', 52f5402f3dSGreg Roach ]; 53f5402f3dSGreg Roach 54f5402f3dSGreg Roach private const OTHER_ADVANCED_FIELDS = [ 55f5402f3dSGreg Roach 'ADOP:DATE', 56f5402f3dSGreg Roach 'ADOP:PLAC', 57f5402f3dSGreg Roach 'AFN', 58f5402f3dSGreg Roach 'BAPL:DATE', 59f5402f3dSGreg Roach 'BAPL:PLAC', 60f5402f3dSGreg Roach 'BAPM:DATE', 61f5402f3dSGreg Roach 'BAPM:PLAC', 62f5402f3dSGreg Roach 'BARM:DATE', 63f5402f3dSGreg Roach 'BARM:PLAC', 64f5402f3dSGreg Roach 'BASM:DATE', 65f5402f3dSGreg Roach 'BASM:PLAC', 66f5402f3dSGreg Roach 'BLES:DATE', 67f5402f3dSGreg Roach 'BLES:PLAC', 68f5402f3dSGreg Roach 'BURI:DATE', 69f5402f3dSGreg Roach 'BURI:PLAC', 70f5402f3dSGreg Roach 'CAST', 71f5402f3dSGreg Roach 'CENS:DATE', 72f5402f3dSGreg Roach 'CENS:PLAC', 73f5402f3dSGreg Roach 'CHAN:DATE', 74f5402f3dSGreg Roach 'CHAN:_WT_USER', 75f5402f3dSGreg Roach 'CHR:DATE', 76f5402f3dSGreg Roach 'CHR:PLAC', 77f5402f3dSGreg Roach 'CREM:DATE', 78f5402f3dSGreg Roach 'CREM:PLAC', 79f5402f3dSGreg Roach 'DSCR', 80f5402f3dSGreg Roach 'EMAIL', 81f5402f3dSGreg Roach 'EMIG:DATE', 82f5402f3dSGreg Roach 'EMIG:PLAC', 83f5402f3dSGreg Roach 'ENDL:DATE', 84f5402f3dSGreg Roach 'ENDL:PLAC', 85f5402f3dSGreg Roach 'EVEN', 86f5402f3dSGreg Roach 'EVEN:TYPE', 87f5402f3dSGreg Roach 'EVEN:DATE', 88f5402f3dSGreg Roach 'EVEN:PLAC', 89f5402f3dSGreg Roach 'FACT', 90f5402f3dSGreg Roach 'FACT:TYPE', 91f5402f3dSGreg Roach 'FAMS:CENS:DATE', 92f5402f3dSGreg Roach 'FAMS:CENS:PLAC', 93f5402f3dSGreg Roach 'FAMS:DIV:DATE', 94f5402f3dSGreg Roach 'FAMS:NOTE', 95f5402f3dSGreg Roach 'FAMS:SLGS:DATE', 96f5402f3dSGreg Roach 'FAMS:SLGS:PLAC', 97f5402f3dSGreg Roach 'FAX', 98f5402f3dSGreg Roach 'FCOM:DATE', 99f5402f3dSGreg Roach 'FCOM:PLAC', 100f5402f3dSGreg Roach 'IMMI:DATE', 101f5402f3dSGreg Roach 'IMMI:PLAC', 102f5402f3dSGreg Roach 'NAME:NICK', 103f5402f3dSGreg Roach 'NAME:_MARNM', 104f5402f3dSGreg Roach 'NAME:_HEB', 105f5402f3dSGreg Roach 'NAME:ROMN', 106f5402f3dSGreg Roach 'NATI', 107f5402f3dSGreg Roach 'NATU:DATE', 108f5402f3dSGreg Roach 'NATU:PLAC', 109f5402f3dSGreg Roach 'NOTE', 110f5402f3dSGreg Roach 'OCCU', 111f5402f3dSGreg Roach 'ORDN:DATE', 112f5402f3dSGreg Roach 'ORDN:PLAC', 113f5402f3dSGreg Roach 'REFN', 114f5402f3dSGreg Roach 'RELI', 115f5402f3dSGreg Roach 'RESI', 116f5402f3dSGreg Roach 'RESI:DATE', 117f5402f3dSGreg Roach 'RESI:PLAC', 118f5402f3dSGreg Roach 'SLGC:DATE', 119f5402f3dSGreg Roach 'SLGC:PLAC', 120f5402f3dSGreg Roach 'TITL', 121f5402f3dSGreg Roach '_BRTM:DATE', 122f5402f3dSGreg Roach '_BRTM:PLAC', 123f5402f3dSGreg Roach '_MILI', 124f5402f3dSGreg Roach ]; 125f5402f3dSGreg Roach 126f5402f3dSGreg Roach /** @var SearchService */ 127f5402f3dSGreg Roach private $search_service; 128f5402f3dSGreg Roach 129f5402f3dSGreg Roach /** 130f5402f3dSGreg Roach * SearchController constructor. 131f5402f3dSGreg Roach * 132f5402f3dSGreg Roach * @param SearchService $search_service 133f5402f3dSGreg Roach */ 134f5402f3dSGreg Roach public function __construct(SearchService $search_service) 135f5402f3dSGreg Roach { 136f5402f3dSGreg Roach $this->search_service = $search_service; 137f5402f3dSGreg Roach } 138f5402f3dSGreg Roach 139f5402f3dSGreg Roach /** 140f5402f3dSGreg Roach * A structured search. 141f5402f3dSGreg Roach * 142f5402f3dSGreg Roach * @param ServerRequestInterface $request 143f5402f3dSGreg Roach * 144f5402f3dSGreg Roach * @return ResponseInterface 145f5402f3dSGreg Roach */ 146f5402f3dSGreg Roach public function handle(ServerRequestInterface $request): ResponseInterface 147f5402f3dSGreg Roach { 148f5402f3dSGreg Roach $tree = $request->getAttribute('tree'); 149f5402f3dSGreg Roach assert($tree instanceof Tree, new InvalidArgumentException()); 150f5402f3dSGreg Roach 151f5402f3dSGreg Roach $default_fields = array_fill_keys(self::DEFAULT_ADVANCED_FIELDS, ''); 152f5402f3dSGreg Roach 153f5402f3dSGreg Roach $params = $request->getQueryParams(); 154f5402f3dSGreg Roach 155f5402f3dSGreg Roach $fields = $params['fields'] ?? $default_fields; 156f5402f3dSGreg Roach $modifiers = $params['modifiers'] ?? []; 157f5402f3dSGreg Roach 158f5402f3dSGreg Roach $other_fields = $this->otherFields($fields); 159f5402f3dSGreg Roach $date_options = $this->dateOptions(); 160f5402f3dSGreg Roach $name_options = $this->nameOptions(); 161f5402f3dSGreg Roach 162*a91af26aSGreg Roach if (array_filter($fields) !== []) { 163f5402f3dSGreg Roach $individuals = $this->search_service->searchIndividualsAdvanced([$tree], $fields, $modifiers); 164f5402f3dSGreg Roach } else { 165f5402f3dSGreg Roach $individuals = []; 166f5402f3dSGreg Roach } 167f5402f3dSGreg Roach 168f5402f3dSGreg Roach $title = I18N::translate('Advanced search'); 169f5402f3dSGreg Roach 170f5402f3dSGreg Roach return $this->viewResponse('search-advanced-page', [ 171f5402f3dSGreg Roach 'date_options' => $date_options, 172f5402f3dSGreg Roach 'fields' => $fields, 173f5402f3dSGreg Roach 'individuals' => $individuals, 174f5402f3dSGreg Roach 'modifiers' => $modifiers, 175f5402f3dSGreg Roach 'name_options' => $name_options, 176f5402f3dSGreg Roach 'other_fields' => $other_fields, 177f5402f3dSGreg Roach 'title' => $title, 178f5402f3dSGreg Roach ]); 179f5402f3dSGreg Roach } 180f5402f3dSGreg Roach 181f5402f3dSGreg Roach /** 182f5402f3dSGreg Roach * Extra search fields to add to the advanced search 183f5402f3dSGreg Roach * 184f5402f3dSGreg Roach * @param string[] $fields 185f5402f3dSGreg Roach * 186f5402f3dSGreg Roach * @return string[] 187f5402f3dSGreg Roach */ 188f5402f3dSGreg Roach private function otherFields(array $fields): array 189f5402f3dSGreg Roach { 190f5402f3dSGreg Roach $unused = array_diff(self::OTHER_ADVANCED_FIELDS, array_keys($fields)); 191f5402f3dSGreg Roach 192f5402f3dSGreg Roach $other_fields = []; 193f5402f3dSGreg Roach 194f5402f3dSGreg Roach foreach ($unused as $tag) { 195f5402f3dSGreg Roach $other_fields[$tag] = GedcomTag::getLabel($tag); 196f5402f3dSGreg Roach } 197f5402f3dSGreg Roach 198f5402f3dSGreg Roach return $other_fields; 199f5402f3dSGreg Roach } 200f5402f3dSGreg Roach 201f5402f3dSGreg Roach /** 202f5402f3dSGreg Roach * For the advanced search 203f5402f3dSGreg Roach * 204f5402f3dSGreg Roach * @return string[] 205f5402f3dSGreg Roach */ 206f5402f3dSGreg Roach private function dateOptions(): array 207f5402f3dSGreg Roach { 208f5402f3dSGreg Roach return [ 209f5402f3dSGreg Roach 0 => I18N::translate('Exact date'), 210f5402f3dSGreg Roach 2 => I18N::plural('±%s year', '±%s years', 2, I18N::number(2)), 211f5402f3dSGreg Roach 5 => I18N::plural('±%s year', '±%s years', 5, I18N::number(5)), 212f5402f3dSGreg Roach 10 => I18N::plural('±%s year', '±%s years', 10, I18N::number(10)), 213f5402f3dSGreg Roach ]; 214f5402f3dSGreg Roach } 215f5402f3dSGreg Roach 216f5402f3dSGreg Roach /** 217f5402f3dSGreg Roach * For the advanced search 218f5402f3dSGreg Roach * 219f5402f3dSGreg Roach * @return string[] 220f5402f3dSGreg Roach */ 221f5402f3dSGreg Roach private function nameOptions(): array 222f5402f3dSGreg Roach { 223f5402f3dSGreg Roach return [ 224f5402f3dSGreg Roach 'EXACT' => I18N::translate('Exact'), 225f5402f3dSGreg Roach 'BEGINS' => I18N::translate('Begins with'), 226f5402f3dSGreg Roach 'CONTAINS' => I18N::translate('Contains'), 227f5402f3dSGreg Roach 'SDX' => I18N::translate('Sounds like'), 228f5402f3dSGreg Roach ]; 229f5402f3dSGreg Roach } 230f5402f3dSGreg Roach} 231