1*63763244SGreg Roach<?php 2*63763244SGreg Roach 3*63763244SGreg Roach/** 4*63763244SGreg Roach * webtrees: online genealogy 5*63763244SGreg Roach * Copyright (C) 2020 webtrees development team 6*63763244SGreg Roach * This program is free software: you can redistribute it and/or modify 7*63763244SGreg Roach * it under the terms of the GNU General Public License as published by 8*63763244SGreg Roach * the Free Software Foundation, either version 3 of the License, or 9*63763244SGreg Roach * (at your option) any later version. 10*63763244SGreg Roach * This program is distributed in the hope that it will be useful, 11*63763244SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 12*63763244SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*63763244SGreg Roach * GNU General Public License for more details. 14*63763244SGreg Roach * You should have received a copy of the GNU General Public License 15*63763244SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 16*63763244SGreg Roach */ 17*63763244SGreg Roach 18*63763244SGreg Roachdeclare(strict_types=1); 19*63763244SGreg Roach 20*63763244SGreg Roachnamespace Fisharebest\Webtrees\Http\RequestHandlers; 21*63763244SGreg Roach 22*63763244SGreg Roachuse Fisharebest\Webtrees\Auth; 23*63763244SGreg Roachuse Fisharebest\Webtrees\GedcomRecord; 24*63763244SGreg Roachuse Fisharebest\Webtrees\Registry; 25*63763244SGreg Roachuse Fisharebest\Webtrees\Tree; 26*63763244SGreg Roachuse Illuminate\Database\Capsule\Manager as DB; 27*63763244SGreg Roachuse Illuminate\Database\Query\JoinClause; 28*63763244SGreg Roachuse Illuminate\Support\Collection; 29*63763244SGreg Roachuse Psr\Http\Message\ServerRequestInterface; 30*63763244SGreg Roach 31*63763244SGreg Roachuse function assert; 32*63763244SGreg Roachuse function preg_match_all; 33*63763244SGreg Roachuse function preg_quote; 34*63763244SGreg Roach 35*63763244SGreg Roach/** 36*63763244SGreg Roach * Autocomplete handler for source citations 37*63763244SGreg Roach */ 38*63763244SGreg Roachclass AutoCompleteCitation extends AbstractAutocompleteHandler 39*63763244SGreg Roach{ 40*63763244SGreg Roach protected function search(ServerRequestInterface $request): Collection 41*63763244SGreg Roach { 42*63763244SGreg Roach $tree = $request->getAttribute('tree'); 43*63763244SGreg Roach assert($tree instanceof Tree); 44*63763244SGreg Roach 45*63763244SGreg Roach $query = $request->getAttribute('query'); 46*63763244SGreg Roach $xref = $request->getQueryParams()['extra'] ?? ''; 47*63763244SGreg Roach $source = Registry::sourceFactory()->make($xref, $tree); 48*63763244SGreg Roach $source = Auth::checkSourceAccess($source); 49*63763244SGreg Roach 50*63763244SGreg Roach $regex_query = preg_quote(strtr($query, [' ' => '.+']), '/'); 51*63763244SGreg Roach 52*63763244SGreg Roach // Fetch all records with a link to this source 53*63763244SGreg Roach $individuals = DB::table('individuals') 54*63763244SGreg Roach ->join('link', static function (JoinClause $join): void { 55*63763244SGreg Roach $join 56*63763244SGreg Roach ->on('l_file', '=', 'i_file') 57*63763244SGreg Roach ->on('l_from', '=', 'i_id'); 58*63763244SGreg Roach }) 59*63763244SGreg Roach ->where('i_file', '=', $tree->id()) 60*63763244SGreg Roach ->where('l_to', '=', $source->xref()) 61*63763244SGreg Roach ->where('l_type', '=', 'SOUR') 62*63763244SGreg Roach ->distinct() 63*63763244SGreg Roach ->select(['individuals.*']) 64*63763244SGreg Roach ->get() 65*63763244SGreg Roach ->map(Registry::individualFactory()->mapper($tree)) 66*63763244SGreg Roach ->filter(GedcomRecord::accessFilter()); 67*63763244SGreg Roach 68*63763244SGreg Roach $families = DB::table('families') 69*63763244SGreg Roach ->join('link', static function (JoinClause $join): void { 70*63763244SGreg Roach $join 71*63763244SGreg Roach ->on('l_file', '=', 'f_file') 72*63763244SGreg Roach ->on('l_from', '=', 'f_id') 73*63763244SGreg Roach ->where('l_type', '=', 'SOUR'); 74*63763244SGreg Roach }) 75*63763244SGreg Roach ->where('f_file', '=', $tree->id()) 76*63763244SGreg Roach ->where('l_to', '=', $source->xref()) 77*63763244SGreg Roach ->where('l_type', '=', 'SOUR') 78*63763244SGreg Roach ->distinct() 79*63763244SGreg Roach ->select(['families.*']) 80*63763244SGreg Roach ->get() 81*63763244SGreg Roach ->map(Registry::familyFactory()->mapper($tree)) 82*63763244SGreg Roach ->filter(GedcomRecord::accessFilter()); 83*63763244SGreg Roach 84*63763244SGreg Roach $pages = new Collection(); 85*63763244SGreg Roach 86*63763244SGreg Roach foreach ($individuals->merge($families) as $record) { 87*63763244SGreg Roach if (preg_match_all('/\n1 SOUR @' . $source->xref() . '@(?:\n[2-9].*)*\n2 PAGE (.*' . $regex_query . '.*)/i', $record->gedcom(), $matches)) { 88*63763244SGreg Roach $pages = $pages->concat($matches[1]); 89*63763244SGreg Roach } 90*63763244SGreg Roach 91*63763244SGreg Roach if (preg_match_all('/\n2 SOUR @' . $source->xref() . '@(?:\n[3-9].*)*\n3 PAGE (.*' . $regex_query . '.*)/i', $record->gedcom(), $matches)) { 92*63763244SGreg Roach $pages = $pages->concat($matches[1]); 93*63763244SGreg Roach } 94*63763244SGreg Roach } 95*63763244SGreg Roach 96*63763244SGreg Roach return $pages->uniqueStrict(); 97*63763244SGreg Roach } 98*63763244SGreg Roach} 99