summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Family.php8
-rw-r--r--app/Functions/FunctionsExport.php10
-rw-r--r--app/GedcomRecord.php20
-rw-r--r--app/Http/Controllers/Admin/FixLevel0MediaController.php15
-rw-r--r--app/Http/Controllers/Admin/ImportThumbnailsController.php48
-rw-r--r--app/Http/Controllers/Admin/MediaController.php17
-rw-r--r--app/Http/Controllers/AutocompleteController.php4
-rw-r--r--app/Http/Controllers/BranchesController.php2
-rw-r--r--app/Http/Controllers/ListController.php8
-rw-r--r--app/Http/Controllers/PlaceHierarchyController.php4
-rw-r--r--app/Http/RequestHandlers/ExportGedcomClient.php2
-rw-r--r--app/Http/RequestHandlers/UpdatePlacesAction.php4
-rw-r--r--app/Individual.php13
-rw-r--r--app/Media.php8
-rw-r--r--app/Module/ResearchTaskModule.php4
-rw-r--r--app/Module/SiteMapModule.php12
-rw-r--r--app/Note.php8
-rw-r--r--app/Repository.php8
-rw-r--r--app/Services/SearchService.php160
-rw-r--r--app/Source.php8
-rw-r--r--app/Statistics/Repository/FamilyRepository.php10
-rw-r--r--app/Statistics/Repository/IndividualRepository.php6
-rw-r--r--app/Tree.php15
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