![]() System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /var/www/html/webtrees/app/Services/ |
Upload File : |
<?php /** * webtrees: online genealogy * Copyright (C) 2023 webtrees development team * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ declare(strict_types=1); namespace Fisharebest\Webtrees\Services; use Fisharebest\Webtrees\Family; use Fisharebest\Webtrees\GedcomRecord; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Location; use Fisharebest\Webtrees\Media; use Fisharebest\Webtrees\Note; use Fisharebest\Webtrees\Registry; use Fisharebest\Webtrees\Repository; use Fisharebest\Webtrees\Source; use Fisharebest\Webtrees\Submitter; use Illuminate\Database\Capsule\Manager as DB; use Illuminate\Database\Query\Builder; use Illuminate\Database\Query\Expression; use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; use function addcslashes; /** * Find records linked to other records */ class LinkedRecordService { /** * Find all records linked to a record. * * @param GedcomRecord $record * * @return Collection<int,Family> */ public function allLinkedRecords(GedcomRecord $record): Collection { $like = addcslashes($record->xref(), '\\%_'); $union = DB::table('change') ->where('gedcom_id', '=', $record->tree()->id()) ->where('new_gedcom', 'LIKE', '%@' . $like . '@%') ->where('new_gedcom', 'NOT LIKE', '0 @' . $like . '@%') ->whereIn('change_id', function (Builder $query) use ($record): void { $query ->select([new Expression('MAX(change_id)')]) ->from('change') ->where('gedcom_id', '=', $record->tree()->id()) ->where('status', '=', 'pending') ->groupBy(['xref']); }) ->select(['xref']); $xrefs = DB::table('link') ->where('l_file', '=', $record->tree()->id()) ->where('l_to', '=', $record->xref()) ->select(['l_from']) ->union($union) ->pluck('l_from'); return $xrefs->map(static fn (string $xref) => Registry::gedcomRecordFactory()->make($xref, $record->tree())); } /** * Find families linked to a record. * * @param GedcomRecord $record * @param string|null $link_type * * @return Collection<int,Family> */ public function linkedFamilies(GedcomRecord $record, ?string $link_type = null): Collection { $query = DB::table('families') ->join('link', static function (JoinClause $join): void { $join ->on('l_file', '=', 'f_file') ->on('l_from', '=', 'f_id'); }) ->where('f_file', '=', $record->tree()->id()) ->where('l_to', '=', $record->xref()); if ($link_type !== null) { $query->where('l_type', '=', $link_type); } return $query ->distinct() ->select(['families.*']) ->get() ->map(Registry::familyFactory()->mapper($record->tree())) ->filter(GedcomRecord::accessFilter()); } /** * Find individuals linked to a record. * * @param GedcomRecord $record * @param string|null $link_type * * @return Collection<int,Individual> */ public function linkedIndividuals(GedcomRecord $record, ?string $link_type = null): Collection { $query = DB::table('individuals') ->join('link', static function (JoinClause $join): void { $join ->on('l_file', '=', 'i_file') ->on('l_from', '=', 'i_id'); }) ->where('i_file', '=', $record->tree()->id()) ->where('l_to', '=', $record->xref()); if ($link_type !== null) { $query->where('l_type', '=', $link_type); } return $query ->distinct() ->select(['individuals.*']) ->get() ->map(Registry::individualFactory()->mapper($record->tree())) ->filter(GedcomRecord::accessFilter()); } /** * Find locations linked to a record. * * @param GedcomRecord $record * * @return Collection<int,Location> */ public function linkedLocations(GedcomRecord $record): Collection { return DB::table('other') ->join('link', static function (JoinClause $join): void { $join ->on('l_file', '=', 'o_file') ->on('l_from', '=', 'o_id'); }) ->where('o_file', '=', $record->tree()->id()) ->where('o_type', '=', Location::RECORD_TYPE) ->where('l_to', '=', $record->xref()) ->distinct() ->select(['other.*']) ->get() ->map(Registry::locationFactory()->mapper($record->tree())) ->filter(GedcomRecord::accessFilter()); } /** * Find media objects linked to a record. * * @param GedcomRecord $record * * @return Collection<int,Media> */ public function linkedMedia(GedcomRecord $record): Collection { return DB::table('media') ->join('link', static function (JoinClause $join): void { $join ->on('l_file', '=', 'm_file') ->on('l_from', '=', 'm_id'); }) ->where('m_file', '=', $record->tree()->id()) ->where('l_to', '=', $record->xref()) ->distinct() ->select(['media.*']) ->get() ->map(Registry::mediaFactory()->mapper($record->tree())) ->filter(GedcomRecord::accessFilter()); } /** * Find notes linked to a record. * * @param GedcomRecord $record * * @return Collection<int,Note> */ public function linkedNotes(GedcomRecord $record): Collection { return DB::table('other') ->join('link', static function (JoinClause $join): void { $join ->on('l_file', '=', 'o_file') ->on('l_from', '=', 'o_id'); }) ->where('o_file', '=', $record->tree()->id()) ->where('o_type', '=', Note::RECORD_TYPE) ->where('l_to', '=', $record->xref()) ->distinct() ->select(['other.*']) ->get() ->map(Registry::noteFactory()->mapper($record->tree())) ->filter(GedcomRecord::accessFilter()); } /** * Find repositories linked to a record. * * @param GedcomRecord $record * * @return Collection<int,Repository> */ public function linkedRepositories(GedcomRecord $record): Collection { return DB::table('other') ->join('link', static function (JoinClause $join): void { $join ->on('l_file', '=', 'o_file') ->on('l_from', '=', 'o_id'); }) ->where('o_file', '=', $record->tree()->id()) ->where('o_type', '=', Repository::RECORD_TYPE) ->where('l_to', '=', $record->xref()) ->distinct() ->select(['other.*']) ->get() ->map(Registry::repositoryFactory()->mapper($record->tree())) ->filter(GedcomRecord::accessFilter()); } /** * Find sources linked to a record. * * @param GedcomRecord $record * * @return Collection<int,Source> */ public function linkedSources(GedcomRecord $record): Collection { return DB::table('sources') ->join('link', static function (JoinClause $join): void { $join ->on('l_file', '=', 's_file') ->on('l_from', '=', 's_id'); }) ->where('s_file', '=', $record->tree()->id()) ->where('l_to', '=', $record->xref()) ->distinct() ->select(['sources.*']) ->get() ->map(Registry::sourceFactory()->mapper($record->tree())) ->filter(GedcomRecord::accessFilter()); } /** * Find submitters linked to a record. * * @param GedcomRecord $record * * @return Collection<int,Repository> */ public function linkedSubmitters(GedcomRecord $record): Collection { return DB::table('other') ->join('link', static function (JoinClause $join): void { $join ->on('l_file', '=', 'o_file') ->on('l_from', '=', 'o_id'); }) ->where('o_file', '=', $record->tree()->id()) ->where('o_type', '=', Submitter::RECORD_TYPE) ->where('l_to', '=', $record->xref()) ->distinct() ->select(['other.*']) ->distinct() ->get() ->map(Registry::repositoryFactory()->mapper($record->tree())) ->filter(GedcomRecord::accessFilter()); } }