xref: /webtrees/app/Http/RequestHandlers/AutoCompleteCitation.php (revision 63763244e313b0e5dc598319721f6a7aa399e128)
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