diff options
Diffstat (limited to 'app')
23 files changed, 265 insertions, 129 deletions
diff --git a/app/Family.php b/app/Family.php index 0c4027bac8..f80330085e 100644 --- a/app/Family.php +++ b/app/Family.php @@ -70,12 +70,14 @@ class Family extends GedcomRecord /** * A closure which will create a record from a database row. * + * @param Tree $tree + * * @return Closure */ - public static function rowMapper(): Closure + public static function rowMapper(Tree $tree): Closure { - return static function (stdClass $row): Family { - return Family::getInstance($row->f_id, Tree::findById((int) $row->f_file), $row->f_gedcom); + return static function (stdClass $row) use ($tree): Family { + return Family::getInstance($row->f_id, $tree, $row->f_gedcom); }; } diff --git a/app/Functions/FunctionsExport.php b/app/Functions/FunctionsExport.php index d6c899fcc1..a28c857af5 100644 --- a/app/Functions/FunctionsExport.php +++ b/app/Functions/FunctionsExport.php @@ -181,7 +181,7 @@ class FunctionsExport ->where('m_file', '=', $tree->id()) ->orderBy('m_id') ->get() - ->map(Media::rowMapper()) + ->map(Media::rowMapper($tree)) ->map(static function (Media $record) use ($access_level): string { return $record->privatizeGedcom($access_level); }) @@ -193,7 +193,7 @@ class FunctionsExport ->where('s_file', '=', $tree->id()) ->orderBy('s_id') ->get() - ->map(Source::rowMapper()) + ->map(Source::rowMapper($tree)) ->map(static function (Source $record) use ($access_level): string { return $record->privatizeGedcom($access_level); }); @@ -203,7 +203,7 @@ class FunctionsExport ->whereNotIn('o_type', ['HEAD', 'TRLR']) ->orderBy('o_id') ->get() - ->map(GedcomRecord::rowMapper()) + ->map(GedcomRecord::rowMapper($tree)) ->map(static function (GedcomRecord $record) use ($access_level): string { return $record->privatizeGedcom($access_level); }); @@ -212,7 +212,7 @@ class FunctionsExport ->where('i_file', '=', $tree->id()) ->orderBy('i_id') ->get() - ->map(Individual::rowMapper()) + ->map(Individual::rowMapper($tree)) ->map(static function (Individual $record) use ($access_level): string { return $record->privatizeGedcom($access_level); }); @@ -221,7 +221,7 @@ class FunctionsExport ->where('f_file', '=', $tree->id()) ->orderBy('f_id') ->get() - ->map(Family::rowMapper()) + ->map(Family::rowMapper($tree)) ->map(static function (Family $record) use ($access_level): string { return $record->privatizeGedcom($access_level); }); diff --git a/app/GedcomRecord.php b/app/GedcomRecord.php index 3e93b64633..0353b17079 100644 --- a/app/GedcomRecord.php +++ b/app/GedcomRecord.php @@ -85,12 +85,14 @@ class GedcomRecord /** * A closure which will create a record from a database row. * + * @param Tree $tree + * * @return Closure */ - public static function rowMapper(): Closure + public static function rowMapper(Tree $tree): Closure { - return static function (stdClass $row): GedcomRecord { - return GedcomRecord::getInstance($row->o_id, Tree::findById((int) $row->o_file), $row->o_gedcom); + return static function (stdClass $row) use ($tree): GedcomRecord { + return GedcomRecord::getInstance($row->o_id, $tree, $row->o_gedcom); }; } @@ -696,7 +698,7 @@ class GedcomRecord ->where('l_to', '=', $this->xref) ->select(['individuals.*']) ->get() - ->map(Individual::rowMapper()) + ->map(Individual::rowMapper($this->tree)) ->filter(self::accessFilter()); } @@ -720,7 +722,7 @@ class GedcomRecord ->where('l_to', '=', $this->xref) ->select(['families.*']) ->get() - ->map(Family::rowMapper()) + ->map(Family::rowMapper($this->tree)) ->filter(self::accessFilter()); } @@ -744,7 +746,7 @@ class GedcomRecord ->where('l_to', '=', $this->xref) ->select(['sources.*']) ->get() - ->map(Source::rowMapper()) + ->map(Source::rowMapper($this->tree)) ->filter(self::accessFilter()); } @@ -768,7 +770,7 @@ class GedcomRecord ->where('l_to', '=', $this->xref) ->select(['media.*']) ->get() - ->map(Media::rowMapper()) + ->map(Media::rowMapper($this->tree)) ->filter(self::accessFilter()); } @@ -793,7 +795,7 @@ class GedcomRecord ->where('l_to', '=', $this->xref) ->select(['other.*']) ->get() - ->map(Note::rowMapper()) + ->map(Note::rowMapper($this->tree)) ->filter(self::accessFilter()); } @@ -818,7 +820,7 @@ class GedcomRecord ->where('l_to', '=', $this->xref) ->select(['other.*']) ->get() - ->map(Repository::rowMapper()) + ->map(Repository::rowMapper($this->tree)) ->filter(self::accessFilter()); } diff --git a/app/Http/Controllers/Admin/FixLevel0MediaController.php b/app/Http/Controllers/Admin/FixLevel0MediaController.php index ef8290fc3a..924107a404 100644 --- a/app/Http/Controllers/Admin/FixLevel0MediaController.php +++ b/app/Http/Controllers/Admin/FixLevel0MediaController.php @@ -24,7 +24,7 @@ use Fisharebest\Webtrees\I18N; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Media; use Fisharebest\Webtrees\Services\DatatablesService; -use Fisharebest\Webtrees\Tree; +use Fisharebest\Webtrees\Services\TreeService; use Illuminate\Database\Capsule\Manager as DB; use Illuminate\Database\Query\Expression; use Illuminate\Database\Query\JoinClause; @@ -41,14 +41,19 @@ class FixLevel0MediaController extends AbstractAdminController /** @var DatatablesService */ private $datatables_service; + /** @var TreeService */ + private $tree_service; + /** * FixLevel0MediaController constructor. * * @param DatatablesService $datatables_service + * @param TreeService $tree_service */ - public function __construct(DatatablesService $datatables_service) + public function __construct(DatatablesService $datatables_service, TreeService $tree_service) { $this->datatables_service = $datatables_service; + $this->tree_service = $tree_service; } /** @@ -80,7 +85,7 @@ class FixLevel0MediaController extends AbstractAdminController $obje_xref = $request->getParsedBody()['obje_xref']; $tree_id = (int) $request->getParsedBody()['tree_id']; - $tree = Tree::findById($tree_id); + $tree = $this->tree_service->find($tree_id); $individual = Individual::getInstance($indi_xref, $tree); $media = Media::getInstance($obje_xref, $tree); @@ -147,8 +152,8 @@ class FixLevel0MediaController extends AbstractAdminController ->orderBy('media.m_id') ->select(['media.m_file', 'media.m_id', 'media.m_gedcom', 'individuals.i_id', 'individuals.i_gedcom']); - return $this->datatables_service->handleQuery($request, $query, [], [], static function (stdClass $datum) use ($ignore_facts): array { - $tree = Tree::findById((int) $datum->m_file); + return $this->datatables_service->handleQuery($request, $query, [], [], function (stdClass $datum) use ($ignore_facts): array { + $tree = $this->tree_service->find((int) $datum->m_file); $media = Media::getInstance($datum->m_id, $tree, $datum->m_gedcom); $individual = Individual::getInstance($datum->i_id, $tree, $datum->i_gedcom); diff --git a/app/Http/Controllers/Admin/ImportThumbnailsController.php b/app/Http/Controllers/Admin/ImportThumbnailsController.php index f74c1543b1..8141786097 100644 --- a/app/Http/Controllers/Admin/ImportThumbnailsController.php +++ b/app/Http/Controllers/Admin/ImportThumbnailsController.php @@ -22,11 +22,9 @@ namespace Fisharebest\Webtrees\Http\Controllers\Admin; use Fisharebest\Webtrees\I18N; use Fisharebest\Webtrees\Media; use Fisharebest\Webtrees\Services\PendingChangesService; +use Fisharebest\Webtrees\Services\SearchService; use Fisharebest\Webtrees\Services\TreeService; use Fisharebest\Webtrees\Webtrees; -use Illuminate\Database\Capsule\Manager as DB; -use Illuminate\Database\Query\Expression; -use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; use Intervention\Image\ImageManager; use League\Flysystem\Filesystem; @@ -41,21 +39,29 @@ use function assert; */ class ImportThumbnailsController extends AbstractAdminController { - /** @var TreeService */ - private $tree_service; - /** @var PendingChangesService */ private $pending_changes_service; + /** @var SearchService */ + private $search_service; + + /** @var TreeService */ + private $tree_service; + /** * ImportThumbnailsController constructor. * * @param PendingChangesService $pending_changes_service + * @param SearchService $search_service * @param TreeService $tree_service */ - public function __construct(PendingChangesService $pending_changes_service, TreeService $tree_service) - { + public function __construct( + PendingChangesService $pending_changes_service, + SearchService $search_service, + TreeService $tree_service + ) { $this->pending_changes_service = $pending_changes_service; + $this->search_service = $search_service; $this->tree_service = $tree_service; } @@ -191,7 +197,7 @@ class ImportThumbnailsController extends AbstractAdminController $original_path = substr($original, strlen(WT_DATA_DIR)); $thumbnail_path = substr($thumbnail, strlen(WT_DATA_DIR)); - $media = $this->findMediaObjectsForMediaFile($original_path); + $media = $this->search_service->findMediaObjectsForMediaFile($original_path); $media_links = array_map(static function (Media $media): string { return '<a href="' . e($media->url()) . '">' . $media->fullName() . '</a>'; @@ -247,30 +253,6 @@ class ImportThumbnailsController extends AbstractAdminController } /** - * Find the media object that uses a particular media file. - * - * @param string $file - * - * @return Media[] - */ - private function findMediaObjectsForMediaFile(string $file): array - { - return DB::table('media') - ->join('media_file', static function (JoinClause $join): void { - $join - ->on('media_file.m_file', '=', 'media.m_file') - ->on('media_file.m_id', '=', 'media.m_id'); - }) - ->join('gedcom_setting', 'media.m_file', '=', 'gedcom_setting.gedcom_id') - ->where(new Expression('setting_value || multimedia_file_refn'), '=', $file) - ->select(['media.*']) - ->distinct() - ->get() - ->map(Media::rowMapper()) - ->all(); - } - - /** * Compare two images, and return a quantified difference. * 0 (different) ... 100 (same) * diff --git a/app/Http/Controllers/Admin/MediaController.php b/app/Http/Controllers/Admin/MediaController.php index 7e2242c4b3..90b712b1dd 100644 --- a/app/Http/Controllers/Admin/MediaController.php +++ b/app/Http/Controllers/Admin/MediaController.php @@ -29,6 +29,7 @@ use Fisharebest\Webtrees\Media; use Fisharebest\Webtrees\MediaFile; use Fisharebest\Webtrees\Services\DatatablesService; use Fisharebest\Webtrees\Services\MediaFileService; +use Fisharebest\Webtrees\Services\TreeService; use Illuminate\Database\Capsule\Manager as DB; use Illuminate\Database\Query\Builder; use Illuminate\Database\Query\Expression; @@ -74,16 +75,24 @@ class MediaController extends AbstractAdminController /** @var MediaFileService */ private $media_file_service; + /** @var TreeService */ + private $tree_service; + /** * MediaController constructor. * * @param DatatablesService $datatables_service * @param MediaFileService $media_file_service + * @param TreeService $tree_service */ - public function __construct(DatatablesService $datatables_service, MediaFileService $media_file_service) - { + public function __construct( + DatatablesService $datatables_service, + MediaFileService $media_file_service, + TreeService $tree_service + ) { $this->datatables_service = $datatables_service; $this->media_file_service = $media_file_service; + $this->tree_service = $tree_service; } /** @@ -158,7 +167,9 @@ class MediaController extends AbstractAdminController // Convert a row from the database into a row for datatables $callback = function (stdClass $row): array { /** @var Media $media */ - $media = Media::rowMapper()($row); + $tree = $this->tree_service->find((int) $row->m_file); + $media = Media::getInstance($row->m_id, $tree, $row->m_gedcom); + assert($media instanceof Media); $media_files = $media->mediaFiles() ->filter(static function (MediaFile $media_file) use ($row): bool { diff --git a/app/Http/Controllers/AutocompleteController.php b/app/Http/Controllers/AutocompleteController.php index 8708476b29..62c6b2e2d0 100644 --- a/app/Http/Controllers/AutocompleteController.php +++ b/app/Http/Controllers/AutocompleteController.php @@ -137,7 +137,7 @@ class AutocompleteController extends AbstractBaseController ->distinct() ->select(['individuals.*']) ->get() - ->map(Individual::rowMapper()) + ->map(Individual::rowMapper($tree)) ->filter(GedcomRecord::accessFilter()); $families = DB::table('families') @@ -153,7 +153,7 @@ class AutocompleteController extends AbstractBaseController ->distinct() ->select(['families.*']) ->get() - ->map(Family::rowMapper()) + ->map(Family::rowMapper($tree)) ->filter(GedcomRecord::accessFilter()); $pages = new Collection(); diff --git a/app/Http/Controllers/BranchesController.php b/app/Http/Controllers/BranchesController.php index 0692e90d91..58fdd40ba1 100644 --- a/app/Http/Controllers/BranchesController.php +++ b/app/Http/Controllers/BranchesController.php @@ -214,7 +214,7 @@ class BranchesController extends AbstractBaseController ->select(['individuals.*']) ->distinct() ->get() - ->map(Individual::rowMapper()) + ->map(Individual::rowMapper($tree)) ->filter(GedcomRecord::accessFilter()) ->all(); diff --git a/app/Http/Controllers/ListController.php b/app/Http/Controllers/ListController.php index 3b42c60fd0..1ce9cc1667 100644 --- a/app/Http/Controllers/ListController.php +++ b/app/Http/Controllers/ListController.php @@ -616,7 +616,7 @@ class ListController extends AbstractBaseController return $query ->get() - ->map(Media::rowMapper()) + ->map(Media::rowMapper($tree)) ->filter(GedcomRecord::accessFilter()) ->all(); } @@ -634,7 +634,7 @@ class ListController extends AbstractBaseController ->where('o_file', '=', $tree->id()) ->where('o_type', '=', 'NOTE') ->get() - ->map(Note::rowMapper()) + ->map(Note::rowMapper($tree)) ->filter(GedcomRecord::accessFilter()); } @@ -651,7 +651,7 @@ class ListController extends AbstractBaseController ->where('o_file', '=', $tree->id()) ->where('o_type', '=', 'REPO') ->get() - ->map(Repository::rowMapper()) + ->map(Repository::rowMapper($tree)) ->filter(GedcomRecord::accessFilter()); } @@ -667,7 +667,7 @@ class ListController extends AbstractBaseController return DB::table('sources') ->where('s_file', '=', $tree->id()) ->get() - ->map(Source::rowMapper()) + ->map(Source::rowMapper($tree)) ->filter(GedcomRecord::accessFilter()); } diff --git a/app/Http/Controllers/PlaceHierarchyController.php b/app/Http/Controllers/PlaceHierarchyController.php index d370bca6b4..3d9c6db68e 100644 --- a/app/Http/Controllers/PlaceHierarchyController.php +++ b/app/Http/Controllers/PlaceHierarchyController.php @@ -213,7 +213,7 @@ class PlaceHierarchyController extends AbstractBaseController ->select(['individuals.*']) ->distinct() ->get() - ->map(Individual::rowMapper()) + ->map(Individual::rowMapper($tree)) ->filter(Individual::accessFilter()) ->all(); @@ -228,7 +228,7 @@ class PlaceHierarchyController extends AbstractBaseController ->select(['families.*']) ->distinct() ->get() - ->map(Family::rowMapper()) + ->map(Family::rowMapper($tree)) ->filter(Family::accessFilter()) ->all(); diff --git a/app/Http/RequestHandlers/ExportGedcomClient.php b/app/Http/RequestHandlers/ExportGedcomClient.php index cc1b70510a..615e028001 100644 --- a/app/Http/RequestHandlers/ExportGedcomClient.php +++ b/app/Http/RequestHandlers/ExportGedcomClient.php @@ -118,7 +118,7 @@ class ExportGedcomClient implements RequestHandlerInterface $records = DB::table('media') ->where('m_file', '=', $tree->id()) ->get() - ->map(Media::rowMapper()) + ->map(Media::rowMapper($tree)) ->filter(GedcomRecord::accessFilter()); foreach ($records as $record) { diff --git a/app/Http/RequestHandlers/UpdatePlacesAction.php b/app/Http/RequestHandlers/UpdatePlacesAction.php index 1a1499029a..281e3f8574 100644 --- a/app/Http/RequestHandlers/UpdatePlacesAction.php +++ b/app/Http/RequestHandlers/UpdatePlacesAction.php @@ -63,14 +63,14 @@ class UpdatePlacesAction implements RequestHandlerInterface ->whereContains('i_gedcom', $search) ->select(['individuals.*']) ->get() - ->map(Individual::rowMapper()); + ->map(Individual::rowMapper($tree)); $family_changes = DB::table('families') ->where('f_file', '=', $tree->id()) ->whereContains('f_gedcom', $search) ->select(['families.*']) ->get() - ->map(Family::rowMapper()); + ->map(Family::rowMapper($tree)); $changes = $individual_changes->merge($family_changes) ->mapWithKeys(static function (GedcomRecord $record) use ($search, $replace): array { diff --git a/app/Individual.php b/app/Individual.php index 78cebb2247..0400bbdfa8 100644 --- a/app/Individual.php +++ b/app/Individual.php @@ -49,14 +49,19 @@ class Individual extends GedcomRecord /** * A closure which will create a record from a database row. * + * @param Tree $tree + * * @return Closure */ - public static function rowMapper(): Closure + public static function rowMapper(Tree $tree): Closure { - return static function (stdClass $row): Individual { - $individual = Individual::getInstance($row->i_id, Tree::findById((int) $row->i_file), $row->i_gedcom); + return static function (stdClass $row) use ($tree): Individual { + $individual = Individual::getInstance($row->i_id, $tree, $row->i_gedcom); + assert($individual instanceof Individual); - if ($row->n_num ?? null) { + // Some queries include the names table. + // For these we must select the specified name. + if (($row->n_num ?? null) !== null) { $individual = clone $individual; $individual->setPrimaryName($row->n_num); diff --git a/app/Media.php b/app/Media.php index 00a08cee29..dd9ff06624 100644 --- a/app/Media.php +++ b/app/Media.php @@ -39,12 +39,14 @@ class Media extends GedcomRecord /** * A closure which will create a record from a database row. * + * @param Tree $tree + * * @return Closure */ - public static function rowMapper(): Closure + public static function rowMapper(Tree $tree): Closure { - return static function (stdClass $row): Media { - return Media::getInstance($row->m_id, Tree::findById((int) $row->m_file), $row->m_gedcom); + return static function (stdClass $row) use ($tree): Media { + return Media::getInstance($row->m_id, $tree, $row->m_gedcom); }; } diff --git a/app/Module/ResearchTaskModule.php b/app/Module/ResearchTaskModule.php index 32cab10a3e..b8b99a2ff1 100644 --- a/app/Module/ResearchTaskModule.php +++ b/app/Module/ResearchTaskModule.php @@ -218,7 +218,7 @@ class ResearchTaskModule extends AbstractModule implements ModuleBlockInterface ->select(['families.*']) ->distinct() ->get() - ->map(Family::rowMapper()) + ->map(Family::rowMapper($tree)) ->filter(GedcomRecord::accessFilter()); } @@ -242,7 +242,7 @@ class ResearchTaskModule extends AbstractModule implements ModuleBlockInterface ->select(['individuals.*']) ->distinct() ->get() - ->map(Individual::rowMapper()) + ->map(Individual::rowMapper($tree)) ->filter(GedcomRecord::accessFilter()); } } diff --git a/app/Module/SiteMapModule.php b/app/Module/SiteMapModule.php index bc8778b509..23be12c852 100644 --- a/app/Module/SiteMapModule.php +++ b/app/Module/SiteMapModule.php @@ -221,7 +221,7 @@ class SiteMapModule extends AbstractModule implements ModuleConfigInterface if ($timestamp > $expiry_time) { $content = $this->getPreference('sitemap-' . $file . '.xml'); } else { - $tree = Tree::findById((int) $match[1]); + $tree = $this->tree_service->find((int) $match[1]); if ($tree === null) { throw new NotFoundHttpException('No such tree'); @@ -295,7 +295,7 @@ class SiteMapModule extends AbstractModule implements ModuleConfigInterface ->skip($offset) ->take($limit) ->get() - ->map(Individual::rowMapper()); + ->map(Individual::rowMapper($tree)); } /** @@ -313,7 +313,7 @@ class SiteMapModule extends AbstractModule implements ModuleConfigInterface ->skip($offset) ->take($limit) ->get() - ->map(Media::rowMapper()); + ->map(Media::rowMapper($tree)); } /** @@ -332,7 +332,7 @@ class SiteMapModule extends AbstractModule implements ModuleConfigInterface ->skip($offset) ->take($limit) ->get() - ->map(Note::rowMapper()); + ->map(Note::rowMapper($tree)); } /** @@ -351,7 +351,7 @@ class SiteMapModule extends AbstractModule implements ModuleConfigInterface ->skip($offset) ->take($limit) ->get() - ->map(Repository::rowMapper()); + ->map(Repository::rowMapper($tree)); } /** @@ -369,6 +369,6 @@ class SiteMapModule extends AbstractModule implements ModuleConfigInterface ->skip($offset) ->take($limit) ->get() - ->map(Source::rowMapper()); + ->map(Source::rowMapper($tree)); } } diff --git a/app/Note.php b/app/Note.php index cd01e130f2..81bdeab96c 100644 --- a/app/Note.php +++ b/app/Note.php @@ -38,12 +38,14 @@ class Note extends GedcomRecord /** * A closure which will create a record from a database row. * + * @param Tree $tree + * * @return Closure */ - public static function rowMapper(): Closure + public static function rowMapper(Tree $tree): Closure { - return static function (stdClass $row): Note { - return Note::getInstance($row->o_id, Tree::findById((int) $row->o_file), $row->o_gedcom); + return static function (stdClass $row) use ($tree): Note { + return Note::getInstance($row->o_id, $tree, $row->o_gedcom); }; } diff --git a/app/Repository.php b/app/Repository.php index c5eb61c5da..157f24f074 100644 --- a/app/Repository.php +++ b/app/Repository.php @@ -37,12 +37,14 @@ class Repository extends GedcomRecord /** * A closure which will create a record from a database row. * + * @param Tree $tree + * * @return Closure */ - public static function rowMapper(): Closure + public static function rowMapper(Tree $tree): Closure { - return static function (stdClass $row): Repository { - return Repository::getInstance($row->o_id, Tree::findById((int) $row->o_file), $row->o_gedcom); + return static function (stdClass $row) use ($tree): Repository { + return Repository::getInstance($row->o_id, $tree, $row->o_gedcom); }; } diff --git a/app/Services/SearchService.php b/app/Services/SearchService.php index d71350389a..0441865f43 100644 --- a/app/Services/SearchService.php +++ b/app/Services/SearchService.php @@ -48,6 +48,19 @@ use function mb_stripos; */ class SearchService { + /** @var TreeService */ + private $tree_service; + + /** + * SearchService constructor. + * + * @param TreeService $tree_service + */ + public function __construct(TreeService $tree_service) + { + $this->tree_service = $tree_service; + } + /** * @param Tree[] $trees * @param string[] $search @@ -64,7 +77,7 @@ class SearchService return $query ->get() ->each($this->rowLimiter()) - ->map(Family::rowMapper()) + ->map($this->familyRowMapper()) ->filter(GedcomRecord::accessFilter()) ->filter($this->rawGedcomFilter($search)); } @@ -107,7 +120,7 @@ class SearchService ->select(['families.*', 'husb_name.n_sort', 'wife_name.n_sort']) ->distinct(); - return $this->paginateQuery($query, Family::rowMapper(), GedcomRecord::accessFilter(), $offset, $limit); + return $this->paginateQuery($query, $this->familyRowMapper(), GedcomRecord::accessFilter(), $offset, $limit); } /** @@ -126,7 +139,7 @@ class SearchService return $query ->get() ->each($this->rowLimiter()) - ->map(Individual::rowMapper()) + ->map($this->individualRowMapper()) ->filter(GedcomRecord::accessFilter()) ->filter($this->rawGedcomFilter($search)); } @@ -155,7 +168,7 @@ class SearchService $this->whereTrees($query, 'i_file', $trees); $this->whereSearch($query, 'n_full', $search); - return $this->paginateQuery($query, Individual::rowMapper(), GedcomRecord::accessFilter(), $offset, $limit); + return $this->paginateQuery($query, $this->individualRowMapper(), GedcomRecord::accessFilter(), $offset, $limit); } /** @@ -175,7 +188,7 @@ class SearchService $this->whereTrees($query, 'media.m_file', $trees); $this->whereSearch($query, 'm_gedcom', $search); - return $this->paginateQuery($query, Media::rowMapper(), GedcomRecord::accessFilter(), $offset, $limit); + return $this->paginateQuery($query, $this->mediaRowMapper(), GedcomRecord::accessFilter(), $offset, $limit); } /** @@ -196,7 +209,7 @@ class SearchService $this->whereTrees($query, 'o_file', $trees); $this->whereSearch($query, 'o_gedcom', $search); - return $this->paginateQuery($query, Note::rowMapper(), GedcomRecord::accessFilter(), $offset, $limit); + return $this->paginateQuery($query, $this->noteRowMapper(), GedcomRecord::accessFilter(), $offset, $limit); } /** @@ -217,7 +230,7 @@ class SearchService $this->whereTrees($query, 'o_file', $trees); $this->whereSearch($query, 'o_gedcom', $search); - return $this->paginateQuery($query, Repository::rowMapper(), GedcomRecord::accessFilter(), $offset, $limit); + return $this->paginateQuery($query, $this->repositoryRowMapper(), GedcomRecord::accessFilter(), $offset, $limit); } /** @@ -237,7 +250,7 @@ class SearchService $this->whereTrees($query, 's_file', $trees); $this->whereSearch($query, 's_gedcom', $search); - return $this->paginateQuery($query, Source::rowMapper(), GedcomRecord::accessFilter(), $offset, $limit); + return $this->paginateQuery($query, $this->sourceRowMapper(), GedcomRecord::accessFilter(), $offset, $limit); } /** @@ -258,7 +271,7 @@ class SearchService $this->whereTrees($query, 's_file', $trees); $this->whereSearch($query, 's_name', $search); - return $this->paginateQuery($query, Source::rowMapper(), GedcomRecord::accessFilter(), $offset, $limit); + return $this->paginateQuery($query, $this->sourceRowMapper(), GedcomRecord::accessFilter(), $offset, $limit); } /** @@ -279,7 +292,7 @@ class SearchService $this->whereTrees($query, 'o_file', $trees); $this->whereSearch($query, 'o_gedcom', $search); - return $this->paginateQuery($query, GedcomRecord::rowMapper(), GedcomRecord::accessFilter(), $offset, $limit); + return $this->paginateQuery($query, $this->submitterRowMapper(), GedcomRecord::accessFilter(), $offset, $limit); } /** @@ -695,7 +708,7 @@ class SearchService return $query ->get() ->each($this->rowLimiter()) - ->map(Individual::rowMapper()) + ->map($this->individualRowMapper()) ->filter(GedcomRecord::accessFilter()) ->filter(static function (Individual $individual) use ($fields): bool { // Check for searches which were only partially matched by SQL @@ -825,7 +838,7 @@ class SearchService return $query ->get() ->each($this->rowLimiter()) - ->map(Individual::rowMapper()) + ->map($this->individualRowMapper()) ->filter(GedcomRecord::accessFilter()); } @@ -918,6 +931,31 @@ class SearchService $query->whereIn($tree_id_field, $tree_ids); } + + /** + * Find the media object that uses a particular media file. + * + * @param string $file + * + * @return Media[] + */ + public function findMediaObjectsForMediaFile(string $file): array + { + return DB::table('media') + ->join('media_file', static function (JoinClause $join): void { + $join + ->on('media_file.m_file', '=', 'media.m_file') + ->on('media_file.m_id', '=', 'media.m_id'); + }) + ->join('gedcom_setting', 'media.m_file', '=', 'gedcom_setting.gedcom_id') + ->where(new Expression('setting_value || multimedia_file_refn'), '=', $file) + ->select(['media.*']) + ->distinct() + ->get() + ->map($this->mediaRowMapper()) + ->all(); + } + /** * A closure to filter records by privacy-filtered GEDCOM data. * @@ -964,4 +1002,102 @@ class SearchService } }; } + + /** + * Convert a row from any tree in the families table into a family object. + * + * @return Closure + */ + private function familyRowMapper(): Closure + { + return function (stdClass $row): Family { + $tree = $this->tree_service->find((int) $row->f_file); + + return Family::getInstance($row->f_id, $tree, $row->f_gedcom); + }; + } + + /** + * Convert a row from any tree in the individuals table into an individual object. + * + * @return Closure + */ + private function individualRowMapper(): Closure + { + return function (stdClass $row): Individual { + $tree = $this->tree_service->find((int) $row->i_file); + + return Individual::getInstance($row->i_id, $tree, $row->i_gedcom); + }; + } + + /** + * Convert a row from any tree in the media table into an media object. + * + * @return Closure + */ + private function mediaRowMapper(): Closure + { + return function (stdClass $row): Media { + $tree = $this->tree_service->find((int) $row->m_file); + + return Media::getInstance($row->m_id, $tree, $row->m_gedcom); + }; + } + + /** + * Convert a row from any tree in the other table into a note object. + * + * @return Closure + */ + private function noteRowMapper(): Closure + { + return function (stdClass $row): Note { + $tree = $this->tree_service->find((int) $row->o_file); + + return Note::getInstance($row->o_id, $tree, $row->o_gedcom); + }; + } + + /** + * Convert a row from any tree in the other table into a repository object. + * + * @return Closure + */ + private function repositoryRowMapper(): Closure + { + return function (stdClass $row): Repository { + $tree = $this->tree_service->find((int) $row->o_file); + + return Repository::getInstance($row->o_id, $tree, $row->o_gedcom); + }; + } + + /** + * Convert a row from any tree in the sources table into a source object. + * + * @return Closure + */ + private function sourceRowMapper(): Closure + { + return function (stdClass $row): Source { + $tree = $this->tree_service->find((int) $row->s_file); + + return Source::getInstance($row->s_id, $tree, $row->s_gedcom); + }; + } + + /** + * Convert a row from any tree in the other table into a submitter object. + * + * @return Closure + */ + private function submitterRowMapper(): Closure + { + return function (stdClass $row): GedcomRecord { + $tree = $this->tree_service->find((int) $row->o_file); + + return GedcomRecord::getInstance($row->o_id, $tree, $row->o_gedcom); + }; + } } diff --git a/app/Source.php b/app/Source.php index fba2fbfea1..13a2b13a37 100644 --- a/app/Source.php +++ b/app/Source.php @@ -37,12 +37,14 @@ class Source extends GedcomRecord /** * A closure which will create a record from a database row. * + * @param Tree $tree + * * @return Closure */ - public static function rowMapper(): Closure + public static function rowMapper(Tree $tree): Closure { - return static function (stdClass $row): Source { - return Source::getInstance($row->s_id, Tree::findById((int) $row->s_file), $row->s_gedcom); + return static function (stdClass $row) use ($tree): Source { + return Source::getInstance($row->s_id, $tree, $row->s_gedcom); }; } diff --git a/app/Statistics/Repository/FamilyRepository.php b/app/Statistics/Repository/FamilyRepository.php index aa3474e0a6..466d93bcbe 100644 --- a/app/Statistics/Repository/FamilyRepository.php +++ b/app/Statistics/Repository/FamilyRepository.php @@ -79,7 +79,7 @@ class FamilyRepository } /** @var Family $family */ - $family = Family::rowMapper()($row); + $family = Family::rowMapper($this->tree)($row); if (!$family->canShow()) { return I18N::translate('This information is private and cannot be shown.'); @@ -160,7 +160,7 @@ class FamilyRepository ->select(['families.*']) ->limit($total) ->get() - ->map(Family::rowMapper()) + ->map(Family::rowMapper($this->tree)) ->filter(GedcomRecord::accessFilter()) ->map(static function (Family $family): array { $count = 0; @@ -242,7 +242,7 @@ class FamilyRepository ->where('f_file', '=', $this->tree->id()) ->where('f_numchil', '=', 0) ->get() - ->map(Family::rowMapper()) + ->map(Family::rowMapper($this->tree)) ->filter(GedcomRecord::accessFilter()); $top10 = []; @@ -619,7 +619,7 @@ class FamilyRepository ->orderBy('f_numchil', 'DESC') ->limit($total) ->get() - ->map(Family::rowMapper()) + ->map(Family::rowMapper($this->tree)) ->filter(GedcomRecord::accessFilter()) ->map(static function (Family $family): array { return [ @@ -1287,7 +1287,7 @@ class FamilyRepository ->select(['families.*']) ->take($total) ->get() - ->map(Family::rowMapper()) + ->map(Family::rowMapper($this->tree)) ->filter(GedcomRecord::accessFilter()) ->map(function (Family $family) use ($age_dir): array { $husb_birt_jd = $family->husband()->getBirthDate()->minimumJulianDay(); diff --git a/app/Statistics/Repository/IndividualRepository.php b/app/Statistics/Repository/IndividualRepository.php index e57ff2834a..0ea0e26bc9 100644 --- a/app/Statistics/Repository/IndividualRepository.php +++ b/app/Statistics/Repository/IndividualRepository.php @@ -830,7 +830,7 @@ class IndividualRepository implements IndividualRepositoryInterface } /** @var Individual $individual */ - $individual = Individual::rowMapper()($row); + $individual = Individual::rowMapper($this->tree)($row); if (!$individual->canShow()) { return I18N::translate('This information is private and cannot be shown.'); @@ -981,7 +981,7 @@ class IndividualRepository implements IndividualRepositoryInterface $top10 = []; foreach ($rows as $row) { /** @var Individual $individual */ - $individual = Individual::rowMapper()($row); + $individual = Individual::rowMapper($this->tree)($row); if ($individual->canShow()) { $top10[] = [ @@ -1123,7 +1123,7 @@ class IndividualRepository implements IndividualRepositoryInterface ->select(['individuals.*']) ->take($total) ->get() - ->map(Individual::rowMapper()) + ->map(Individual::rowMapper($this->tree)) ->filter(GedcomRecord::accessFilter()) ->map(function (Individual $individual): array { return [ diff --git a/app/Tree.php b/app/Tree.php index 6357fac388..cd1e7800aa 100644 --- a/app/Tree.php +++ b/app/Tree.php @@ -123,21 +123,6 @@ class Tree } /** - * Find the tree with a specific ID. - * - * @param int $tree_id - * - * @return Tree - * @deprecated - */ - public static function findById(int $tree_id): Tree - { - return app(TreeService::class)->all()->first(static function (Tree $tree) use ($tree_id): bool { - return $tree->id() === $tree_id; - }); - } - - /** * Set the tree’s configuration settings. * * @param string $setting_name |
