summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Functions/FunctionsEdit.php3
-rw-r--r--app/Functions/FunctionsPrintFacts.php3
-rw-r--r--app/Http/Controllers/Admin/ModuleController.php54
-rw-r--r--app/Http/Controllers/AdminController.php31
-rw-r--r--app/Http/Controllers/BranchesController.php14
-rw-r--r--app/Http/Controllers/EditGedcomRecordController.php10
-rw-r--r--app/Http/Controllers/HomePageController.php31
-rw-r--r--app/Http/Controllers/IndividualController.php22
-rw-r--r--app/Http/Controllers/ModuleController.php19
-rw-r--r--app/Http/Controllers/ReportEngineController.php21
-rw-r--r--app/Module/ChartsBlockModule.php23
-rw-r--r--app/Module/ChartsMenuModule.php19
-rw-r--r--app/Module/CookieWarningModule.php13
-rw-r--r--app/Module/IndividualFactsTabModule.php21
-rw-r--r--app/Module/ModuleThemeTrait.php9
-rw-r--r--app/Module/ReportsMenuModule.php18
-rw-r--r--app/Module/UserWelcomeModule.php17
-rw-r--r--app/Module/WelcomeBlockModule.php19
-rw-r--r--app/Services/ModuleService.php (renamed from app/Module.php)38
-rw-r--r--app/Statistics/Repository/FavoritesRepository.php9
-rw-r--r--app/Stats.php3
-rw-r--r--app/Theme.php47
-rw-r--r--index.php3
-rw-r--r--resources/views/layouts/default.phtml5
-rw-r--r--resources/views/lists/individuals-table.phtml4
-rw-r--r--resources/views/media-page-menu.phtml4
-rw-r--r--resources/views/modules/ckeditor/ckeditor-js.phtml4
-rw-r--r--tests/app/Http/Controllers/ModuleControllerTest.php13
-rw-r--r--tests/app/ModuleTest.php114
-rw-r--r--tests/app/Services/ModuleServiceTest.php126
30 files changed, 444 insertions, 273 deletions
diff --git a/app/Functions/FunctionsEdit.php b/app/Functions/FunctionsEdit.php
index c29f7b5ad6..4ca4541885 100644
--- a/app/Functions/FunctionsEdit.php
+++ b/app/Functions/FunctionsEdit.php
@@ -43,6 +43,7 @@ use Fisharebest\Webtrees\Module\CensusAssistantModule;
use Fisharebest\Webtrees\Note;
use Fisharebest\Webtrees\Repository;
use Fisharebest\Webtrees\Select2;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Source;
use Fisharebest\Webtrees\Tree;
use Fisharebest\Webtrees\User;
@@ -583,7 +584,7 @@ class FunctionsEdit
'census_places' => Census::censusPlaces(WT_LOCALE),
]);
- $census_assistant = Module::findByClass(CensusAssistantModule::class);
+ $census_assistant = app(ModuleService::class)->findByClass(CensusAssistantModule::class);
$record = Individual::getInstance($xref, $tree);
if ($census_assistant instanceof CensusAssistantModule && $record instanceof Individual) {
diff --git a/app/Functions/FunctionsPrintFacts.php b/app/Functions/FunctionsPrintFacts.php
index 9af82f7930..a9b6c1efb8 100644
--- a/app/Functions/FunctionsPrintFacts.php
+++ b/app/Functions/FunctionsPrintFacts.php
@@ -38,6 +38,7 @@ use Fisharebest\Webtrees\Module\RelationshipsChartModule;
use Fisharebest\Webtrees\Module\ModuleThemeInterface;
use Fisharebest\Webtrees\Note;
use Fisharebest\Webtrees\Repository;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Source;
use Fisharebest\Webtrees\Tree;
use Fisharebest\Webtrees\User;
@@ -532,7 +533,7 @@ class FunctionsPrintFacts
$values = ['<a href="' . e($person->url()) . '">' . $person->getFullName() . '</a>'];
- $module = Module::findByComponent('chart', $person->tree(), Auth::user())->first(function (ModuleInterface $module) {
+ $module = app(ModuleService::class)->findByComponent('chart', $person->tree(), Auth::user())->first(function (ModuleInterface $module) {
return $module instanceof RelationshipsChartModule;
});
diff --git a/app/Http/Controllers/Admin/ModuleController.php b/app/Http/Controllers/Admin/ModuleController.php
index a3593370d3..783e30fe4b 100644
--- a/app/Http/Controllers/Admin/ModuleController.php
+++ b/app/Http/Controllers/Admin/ModuleController.php
@@ -19,7 +19,6 @@ namespace Fisharebest\Webtrees\Http\Controllers\Admin;
use Fisharebest\Webtrees\FlashMessages;
use Fisharebest\Webtrees\I18N;
-use Fisharebest\Webtrees\Module;
use Fisharebest\Webtrees\Module\ModuleAnalyticsInterface;
use Fisharebest\Webtrees\Module\ModuleBlockInterface;
use Fisharebest\Webtrees\Module\ModuleChartInterface;
@@ -32,6 +31,7 @@ use Fisharebest\Webtrees\Module\ModuleReportInterface;
use Fisharebest\Webtrees\Module\ModuleSidebarInterface;
use Fisharebest\Webtrees\Module\ModuleTabInterface;
use Fisharebest\Webtrees\Module\ModuleThemeInterface;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Tree;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Support\Collection;
@@ -59,6 +59,21 @@ class ModuleController extends AbstractAdminController
'sidebar',
'tab',
];
+
+ /**
+ * @var ModuleService
+ */
+ private $module_service;
+
+ /**
+ * ModuleController constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service)
+ {
+ $this->module_service = $module_service;
+ }
/**
* Show the administrator a list of modules.
@@ -68,9 +83,9 @@ class ModuleController extends AbstractAdminController
public function list(): Response
{
return $this->viewResponse('admin/modules', [
- 'title' => I18N::translate('Module administration'),
- 'modules' => Module::all(),
- 'deleted_modules' => $this->deletedModuleNames(),
+ 'title' => I18N::translate('Module administration'),
+ 'modules' => $this->module_service->all(),
+ 'deleted_modules' => $this->deletedModuleNames(),
]);
}
@@ -83,7 +98,7 @@ class ModuleController extends AbstractAdminController
{
$database_modules = DB::table('module')->pluck('module_name');
- $disk_modules = Module::all()
+ $disk_modules = $this->module_service->all()
->map(function (ModuleInterface $module): string {
return $module->name();
});
@@ -220,6 +235,7 @@ class ModuleController extends AbstractAdminController
''
);
}
+
/**
* @return Response
*/
@@ -249,7 +265,7 @@ class ModuleController extends AbstractAdminController
return $this->viewResponse('admin/components', [
'component' => $component,
'description' => $description,
- 'modules' => Module::findByInterface($interface, true),
+ 'modules' => $this->module_service->findByInterface($interface, true),
'title' => $title,
'trees' => Tree::all(),
'uses_access' => $uses_access,
@@ -266,7 +282,7 @@ class ModuleController extends AbstractAdminController
*/
public function update(Request $request): RedirectResponse
{
- $modules = Module::all();
+ $modules = $this->module_service->all();
foreach ($modules as $module) {
$new_status = (bool) $request->get('status-' . $module->name());
@@ -295,7 +311,7 @@ class ModuleController extends AbstractAdminController
*/
public function updateAnalytics(Request $request): RedirectResponse
{
- $modules = Module::findByInterface(ModuleAnalyticsInterface::class, true);
+ $modules = $this->module_service->findByInterface(ModuleAnalyticsInterface::class, true);
$this->updateStatus($modules, $request);
@@ -309,7 +325,7 @@ class ModuleController extends AbstractAdminController
*/
public function updateBlocks(Request $request): RedirectResponse
{
- $modules = Module::findByInterface(ModuleBlockInterface::class, true);
+ $modules = $this->module_service->findByInterface(ModuleBlockInterface::class, true);
$this->updateStatus($modules, $request);
$this->updateAccessLevel($modules, 'block', $request);
@@ -324,7 +340,7 @@ class ModuleController extends AbstractAdminController
*/
public function updateCharts(Request $request): RedirectResponse
{
- $modules = Module::findByInterface(ModuleChartInterface::class, true);
+ $modules = $this->module_service->findByInterface(ModuleChartInterface::class, true);
$this->updateStatus($modules, $request);
$this->updateAccessLevel($modules, 'chart', $request);
@@ -339,7 +355,7 @@ class ModuleController extends AbstractAdminController
*/
public function updateFooters(Request $request): RedirectResponse
{
- $modules = Module::findByInterface(ModuleFooterInterface::class, true);
+ $modules = $this->module_service->findByInterface(ModuleFooterInterface::class, true);
$this->updateStatus($modules, $request);
$this->updateOrder($modules, 'footer_order', $request);
@@ -354,7 +370,7 @@ class ModuleController extends AbstractAdminController
*/
public function updateHistory(Request $request): RedirectResponse
{
- $modules = Module::findByInterface(ModuleHistoricEventsInterface::class, true);
+ $modules = $this->module_service->findByInterface(ModuleHistoricEventsInterface::class, true);
$this->updateStatus($modules, $request);
@@ -368,7 +384,7 @@ class ModuleController extends AbstractAdminController
*/
public function updateLanguages(Request $request): RedirectResponse
{
- $modules = Module::findByInterface(ModuleLanguageInterface::class, true);
+ $modules = $this->module_service->findByInterface(ModuleLanguageInterface::class, true);
$this->updateStatus($modules, $request);
@@ -382,7 +398,7 @@ class ModuleController extends AbstractAdminController
*/
public function updateMenus(Request $request): RedirectResponse
{
- $modules = Module::findByInterface(ModuleMenuInterface::class, true);
+ $modules = $this->module_service->findByInterface(ModuleMenuInterface::class, true);
$this->updateStatus($modules, $request);
$this->updateOrder($modules, 'menu_order', $request);
@@ -398,7 +414,7 @@ class ModuleController extends AbstractAdminController
*/
public function updateReports(Request $request): RedirectResponse
{
- $modules = Module::findByInterface(ModuleReportInterface::class, true);
+ $modules = $this->module_service->findByInterface(ModuleReportInterface::class, true);
$this->updateStatus($modules, $request);
$this->updateAccessLevel($modules, 'report', $request);
@@ -413,7 +429,7 @@ class ModuleController extends AbstractAdminController
*/
public function updateSidebars(Request $request): RedirectResponse
{
- $modules = Module::findByInterface(ModuleSidebarInterface::class, true);
+ $modules = $this->module_service->findByInterface(ModuleSidebarInterface::class, true);
$this->updateStatus($modules, $request);
$this->updateOrder($modules, 'sidebar_order', $request);
@@ -429,7 +445,7 @@ class ModuleController extends AbstractAdminController
*/
public function updateThemes(Request $request): RedirectResponse
{
- $modules = Module::findByInterface(ModuleThemeInterface::class, true);
+ $modules = $this->module_service->findByInterface(ModuleThemeInterface::class, true);
$this->updateStatus($modules, $request);
@@ -443,7 +459,7 @@ class ModuleController extends AbstractAdminController
*/
public function updateTabs(Request $request): RedirectResponse
{
- $modules = Module::findByInterface(ModuleTabInterface::class, true);
+ $modules = $this->module_service->findByInterface(ModuleTabInterface::class, true);
$this->updateStatus($modules, $request);
$this->updateOrder($modules, 'tab_order', $request);
@@ -470,7 +486,7 @@ class ModuleController extends AbstractAdminController
DB::table('module')
->where('module_name', '=', $module->name())
->update([
- $column => $order[$module->name()] ?? 0
+ $column => $order[$module->name()] ?? 0,
]);
}
}
diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php
index 4dac4db939..e8d1c3e55a 100644
--- a/app/Http/Controllers/AdminController.php
+++ b/app/Http/Controllers/AdminController.php
@@ -48,6 +48,7 @@ use Fisharebest\Webtrees\Note;
use Fisharebest\Webtrees\Repository;
use Fisharebest\Webtrees\Services\DatatablesService;
use Fisharebest\Webtrees\Services\HousekeepingService;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Services\UpgradeService;
use Fisharebest\Webtrees\Source;
use Fisharebest\Webtrees\Tree;
@@ -84,20 +85,22 @@ class AdminController extends AbstractBaseController
* @param HousekeepingService $housekeeping_service
* @param UpgradeService $upgrade_service
* @param Admin\ModuleController $module_controller
+ * @param ModuleService $module_service
*
* @return Response
*/
public function controlPanel(
HousekeepingService $housekeeping_service,
UpgradeService $upgrade_service,
- Admin\ModuleController $module_controller
+ Admin\ModuleController $module_controller,
+ ModuleService $module_service
): Response {
$filesystem = new Filesystem(new Local(WT_ROOT));
$files_to_delete = $housekeeping_service->deleteOldWebtreesFiles($filesystem);
$deleted_modules = $module_controller->deletedModuleNames();
// Analytics modules have their own configl so don't show them twice.
- $config_modules = Module::findByInterface(ModuleConfigInterface::class, true)
+ $config_modules = $module_service->findByInterface(ModuleConfigInterface::class, true)
->filter(function (ModuleConfigInterface $module): bool {
return !$module instanceof ModuleAnalyticsInterface;
});
@@ -121,20 +124,20 @@ class AdminController extends AbstractBaseController
'repositories' => $this->totalRepositories(),
'notes' => $this->totalNotes(),
'files_to_delete' => $files_to_delete,
- 'all_modules' => Module::all(),
+ 'all_modules' => $module_service->all(),
'deleted_modules' => $deleted_modules,
- 'analytics_modules' => Module::findByInterface(ModuleAnalyticsInterface::class, true),
- 'block_modules' => Module::findByInterface(ModuleBlockInterface::class, true),
- 'chart_modules' => Module::findByInterface(ModuleChartInterface::class, true),
+ 'analytics_modules' => $module_service->findByInterface(ModuleAnalyticsInterface::class, true),
+ 'block_modules' => $module_service->findByInterface(ModuleBlockInterface::class, true),
+ 'chart_modules' => $module_service->findByInterface(ModuleChartInterface::class, true),
'config_modules' => $config_modules,
- 'footer_modules' => Module::findByInterface(ModuleFooterInterface::class, true),
- 'history_modules' => Module::findByInterface(ModuleHistoricEventsInterface::class, true),
- 'language_modules' => Module::findByInterface(ModuleLanguageInterface::class, true),
- 'menu_modules' => Module::findByInterface(ModuleMenuInterface::class, true),
- 'report_modules' => Module::findByInterface(ModuleReportInterface::class, true),
- 'sidebar_modules' => Module::findByInterface(ModuleSidebarInterface::class, true),
- 'tab_modules' => Module::findByInterface(ModuleTabInterface::class, true),
- 'theme_modules' => Module::findByInterface(ModuleThemeInterface::class, true),
+ 'footer_modules' => $module_service->findByInterface(ModuleFooterInterface::class, true),
+ 'history_modules' => $module_service->findByInterface(ModuleHistoricEventsInterface::class, true),
+ 'language_modules' => $module_service->findByInterface(ModuleLanguageInterface::class, true),
+ 'menu_modules' => $module_service->findByInterface(ModuleMenuInterface::class, true),
+ 'report_modules' => $module_service->findByInterface(ModuleReportInterface::class, true),
+ 'sidebar_modules' => $module_service->findByInterface(ModuleSidebarInterface::class, true),
+ 'tab_modules' => $module_service->findByInterface(ModuleTabInterface::class, true),
+ 'theme_modules' => $module_service->findByInterface(ModuleThemeInterface::class, true),
]);
}
diff --git a/app/Http/Controllers/BranchesController.php b/app/Http/Controllers/BranchesController.php
index 25dcb8209f..b87f970b36 100644
--- a/app/Http/Controllers/BranchesController.php
+++ b/app/Http/Controllers/BranchesController.php
@@ -26,6 +26,7 @@ use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Module;
use Fisharebest\Webtrees\Module\ModuleInterface;
use Fisharebest\Webtrees\Module\RelationshipsChartModule;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Soundex;
use Fisharebest\Webtrees\Tree;
use Fisharebest\Webtrees\User;
@@ -40,6 +41,17 @@ use Symfony\Component\HttpFoundation\Response;
*/
class BranchesController extends AbstractBaseController
{
+ /** @var ModuleService */
+ protected $module_service;
+ /**
+ * BranchesController constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service)
+ {
+ $this->module_service = $module_service;
+ }
/**
* A form to request the page parameters.
*
@@ -238,7 +250,7 @@ class BranchesController extends AbstractBaseController
*/
private function getDescendantsHtml(Tree $tree, array $individuals, array $ancestors, string $surname, bool $soundex_dm, bool $soundex_std, Individual $individual, Family $parents = null)
{
- $module = Module::findByComponent('chart', $tree, Auth::user())->first(function (ModuleInterface $module) {
+ $module = $this->module_service->findByComponent('chart', $tree, Auth::user())->first(function (ModuleInterface $module) {
return $module instanceof RelationshipsChartModule;
});
diff --git a/app/Http/Controllers/EditGedcomRecordController.php b/app/Http/Controllers/EditGedcomRecordController.php
index 6b52df27fe..39a093293c 100644
--- a/app/Http/Controllers/EditGedcomRecordController.php
+++ b/app/Http/Controllers/EditGedcomRecordController.php
@@ -27,6 +27,7 @@ use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Module;
use Fisharebest\Webtrees\Module\CensusAssistantModule;
use Fisharebest\Webtrees\Services\ClipboardService;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Tree;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -355,12 +356,13 @@ class EditGedcomRecordController extends AbstractEditController
}
/**
- * @param Request $request
- * @param Tree $tree
+ * @param Request $request
+ * @param Tree $tree
+ * @param ModuleService $module_service
*
* @return RedirectResponse
*/
- public function updateFact(Request $request, Tree $tree): RedirectResponse
+ public function updateFact(Request $request, Tree $tree, ModuleService $module_service): RedirectResponse
{
$xref = $request->get('xref', '');
$fact_id = $request->get('fact_id', '');
@@ -428,7 +430,7 @@ class EditGedcomRecordController extends AbstractEditController
$newged = substr($newged, 1); // Remove leading newline
- $census_assistant = Module::findByClass(CensusAssistantModule::class);
+ $census_assistant = $module_service->findByClass(CensusAssistantModule::class);
if ($census_assistant instanceof CensusAssistantModule && $record instanceof Individual) {
$newged = $census_assistant->updateCensusAssistant($request, $record, $fact_id, $newged, $keep_chan);
}
diff --git a/app/Http/Controllers/HomePageController.php b/app/Http/Controllers/HomePageController.php
index b6a8e9a91a..3a92e0d95a 100644
--- a/app/Http/Controllers/HomePageController.php
+++ b/app/Http/Controllers/HomePageController.php
@@ -19,7 +19,6 @@ namespace Fisharebest\Webtrees\Http\Controllers;
use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\I18N;
-use Fisharebest\Webtrees\Module;
use Fisharebest\Webtrees\Module\FamilyTreeFavoritesModule;
use Fisharebest\Webtrees\Module\FamilyTreeNewsModule;
use Fisharebest\Webtrees\Module\FamilyTreeStatisticsModule;
@@ -34,6 +33,7 @@ use Fisharebest\Webtrees\Module\UserFavoritesModule;
use Fisharebest\Webtrees\Module\UserMessagesModule;
use Fisharebest\Webtrees\Module\UserWelcomeModule;
use Fisharebest\Webtrees\Module\WelcomeBlockModule;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Tree;
use Fisharebest\Webtrees\User;
use Illuminate\Database\Capsule\Manager as DB;
@@ -80,6 +80,21 @@ class HomePageController extends AbstractBaseController
];
/**
+ * @var ModuleService
+ */
+ private $module_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service)
+ {
+ $this->module_service = $module_service;
+ }
+
+ /**
* Show a form to edit block config options.
*
* @param Request $request
@@ -145,7 +160,7 @@ class HomePageController extends AbstractBaseController
throw new NotFoundHttpException();
}
- $module = Module::findByName($block->module_name);
+ $module = $this->module_service->findByName($block->module_name);
if (!$module instanceof ModuleBlockInterface) {
throw new NotFoundHttpException();
@@ -223,7 +238,7 @@ class HomePageController extends AbstractBaseController
throw new NotFoundHttpException('This block does not exist');
}
- $module = Module::findByName($block->module_name);
+ $module = $this->module_service->findByName($block->module_name);
if (!$module instanceof ModuleBlockInterface) {
throw new NotFoundHttpException($block->module_name . ' is not a block');
@@ -616,7 +631,7 @@ class HomePageController extends AbstractBaseController
*/
private function getBlockModule(Tree $tree, int $block_id): ModuleBlockInterface
{
- $active_blocks = Module::findByComponent('block', $tree, Auth::user());
+ $active_blocks = $this->module_service->findByComponent('block', $tree, Auth::user());
$module_name = DB::table('block')
->where('block_id', '=', $block_id)
@@ -640,7 +655,7 @@ class HomePageController extends AbstractBaseController
*/
private function availableTreeBlocks(): Collection
{
- return Module::findByInterface(ModuleBlockInterface::class)
+ return $this->module_service->findByInterface(ModuleBlockInterface::class)
->filter(function (ModuleBlockInterface $block): bool {
return $block->isTreeBlock();
})
@@ -656,7 +671,7 @@ class HomePageController extends AbstractBaseController
*/
private function availableUserBlocks(): Collection
{
- return Module::findByInterface(ModuleBlockInterface::class)
+ return $this->module_service->findByInterface(ModuleBlockInterface::class)
->filter(function (ModuleBlockInterface $block): bool {
return $block->isUserBlock();
})
@@ -699,7 +714,7 @@ class HomePageController extends AbstractBaseController
if (!$has_blocks) {
foreach (['main', 'side'] as $location) {
foreach (self::DEFAULT_TREE_PAGE_BLOCKS[$location] as $block_order => $class) {
- $module_name = Module::findByClass($class)->name();
+ $module_name = $this->module_service->findByClass($class)->name();
DB::table('block')->insert([
'gedcom_id' => -1,
@@ -746,7 +761,7 @@ class HomePageController extends AbstractBaseController
if (!$has_blocks) {
foreach (['main', 'side'] as $location) {
foreach (self::DEFAULT_USER_PAGE_BLOCKS[$location] as $block_order => $class) {
- $module_name = Module::findByClass($class)->name();
+ $module_name = $this->module_service->findByClass($class)->name();
DB::table('block')->insert([
'user_id' => -1,
diff --git a/app/Http/Controllers/IndividualController.php b/app/Http/Controllers/IndividualController.php
index 08e0414538..65ab925fa5 100644
--- a/app/Http/Controllers/IndividualController.php
+++ b/app/Http/Controllers/IndividualController.php
@@ -33,6 +33,7 @@ use Fisharebest\Webtrees\Media;
use Fisharebest\Webtrees\Module;
use Fisharebest\Webtrees\Module\ModuleSidebarInterface;
use Fisharebest\Webtrees\Module\ModuleTabInterface;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Tree;
use Fisharebest\Webtrees\User;
use Illuminate\Support\Collection;
@@ -77,6 +78,21 @@ class IndividualController extends AbstractBaseController
];
/**
+ * @var ModuleService
+ */
+ private $module_service;
+
+ /**
+ * IndividualController constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service)
+ {
+ $this->module_service = $module_service;
+ }
+
+ /**
* Show a individual's page.
*
* @param Request $request
@@ -163,7 +179,7 @@ class IndividualController extends AbstractBaseController
$xref = $request->get('xref', '');
$record = Individual::getInstance($xref, $tree);
$module_name = $request->get('module');
- $module = Module::findByName($module_name);
+ $module = $this->module_service->findByName($module_name);
Auth::checkIndividualAccess($record);
Auth::checkComponentAccess($module, 'tab', $tree, $user);
@@ -402,7 +418,7 @@ class IndividualController extends AbstractBaseController
*/
public function getSidebars(Individual $individual): Collection
{
- return Module::findByComponent('sidebar', $individual->tree(), Auth::user())
+ return $this->module_service->findByComponent('sidebar', $individual->tree(), Auth::user())
->filter(function (ModuleSidebarInterface $sidebar) use ($individual): bool {
return $sidebar->hasSidebarContent($individual);
});
@@ -418,7 +434,7 @@ class IndividualController extends AbstractBaseController
*/
public function getTabs(Individual $individual): Collection
{
- return Module::findByComponent('tab', $individual->tree(), Auth::user())
+ return $this->module_service->findByComponent('tab', $individual->tree(), Auth::user())
->filter(function (ModuleTabInterface $tab) use ($individual): bool {
return $tab->hasTabContent($individual);
});
diff --git a/app/Http/Controllers/ModuleController.php b/app/Http/Controllers/ModuleController.php
index ac4048b7f7..5d6714a4fe 100644
--- a/app/Http/Controllers/ModuleController.php
+++ b/app/Http/Controllers/ModuleController.php
@@ -18,7 +18,7 @@ declare(strict_types=1);
namespace Fisharebest\Webtrees\Http\Controllers;
use Fisharebest\Webtrees\Auth;
-use Fisharebest\Webtrees\Module;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\User;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -34,6 +34,21 @@ use function strtolower;
class ModuleController extends AbstractBaseController
{
/**
+ * @var ModuleService
+ */
+ private $module_service;
+
+ /**
+ * ModuleController constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service)
+ {
+ $this->module_service = $module_service;
+ }
+
+ /**
* Perform an HTTP action for one of the modules.
*
* @param Request $request
@@ -48,7 +63,7 @@ class ModuleController extends AbstractBaseController
// Check that the module is enabled.
// The module itself will need to check any tree-level access,
// which may be different for each component (tab, menu, etc.) of the module.
- $module = Module::findByName($module_name);
+ $module = $this->module_service->findByName($module_name);
// We'll call a function such as Module::getFooBarAction()
$verb = strtolower($request->getMethod());
diff --git a/app/Http/Controllers/ReportEngineController.php b/app/Http/Controllers/ReportEngineController.php
index 5104cfdbf2..8c1b05b80f 100644
--- a/app/Http/Controllers/ReportEngineController.php
+++ b/app/Http/Controllers/ReportEngineController.php
@@ -31,6 +31,7 @@ use Fisharebest\Webtrees\Report\ReportHtml;
use Fisharebest\Webtrees\Report\ReportParserGenerate;
use Fisharebest\Webtrees\Report\ReportParserSetup;
use Fisharebest\Webtrees\Report\ReportPdf;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Source;
use Fisharebest\Webtrees\Tree;
use Fisharebest\Webtrees\User;
@@ -45,6 +46,20 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class ReportEngineController extends AbstractBaseController
{
/**
+ * @var ModuleService
+ */
+ private $module_service;
+
+ /**
+ * ReportEngineController constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service) {
+ $this->module_service = $module_service;
+ }
+
+ /**
* A list of available reports.
*
* @param Tree $tree
@@ -57,7 +72,7 @@ class ReportEngineController extends AbstractBaseController
$title = I18N::translate('Choose a report to run');
return $this->viewResponse('report-select-page', [
- 'reports' => Module::findByComponent('report', $tree, $user),
+ 'reports' => $this->module_service->findByComponent('report', $tree, $user),
'title' => $title,
]);
}
@@ -75,7 +90,7 @@ class ReportEngineController extends AbstractBaseController
{
$pid = $request->get('xref', '');
$report = $request->get('report', '');
- $module = Module::findByName($report);
+ $module = $this->module_service->findByName($report);
if (!$module instanceof ModuleReportInterface) {
return $this->reportList($tree, $user);
@@ -192,7 +207,7 @@ class ReportEngineController extends AbstractBaseController
$varnames = $request->get('varnames', []);
$type = $request->get('type', []);
- $module = Module::findByName($report);
+ $module = $this->module_service->findByName($report);
if (!$module instanceof ModuleReportInterface) {
throw new NotFoundHttpException('Report ' . $report . ' not found.');
diff --git a/app/Module/ChartsBlockModule.php b/app/Module/ChartsBlockModule.php
index 576b64f5e7..0de56f0072 100644
--- a/app/Module/ChartsBlockModule.php
+++ b/app/Module/ChartsBlockModule.php
@@ -22,6 +22,7 @@ use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Module;
use Fisharebest\Webtrees\Module\InteractiveTree\TreeView;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Tree;
use Symfony\Component\HttpFoundation\Request;
@@ -33,6 +34,20 @@ class ChartsBlockModule extends AbstractModule implements ModuleBlockInterface
use ModuleBlockTrait;
/**
+ * @var ModuleService
+ */
+ private $module_service;
+
+ /**
+ * ChartsBlockModule constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service) {
+ $this->module_service = $module_service;
+ }
+
+ /**
* How should this module be labelled on tabs, menus, etc.?
*
* @return string
@@ -88,7 +103,7 @@ class ChartsBlockModule extends AbstractModule implements ModuleBlockInterface
default:
case 'pedigree':
/** @var PedigreeChartModule $module */
- $module = Module::findByClass(PedigreeChartModule::class);
+ $module = $this->module_service->findByClass(PedigreeChartModule::class);
$title = $module->chartTitle($person);
$chart_url = $module->chartUrl($person, [
'ajax' => true,
@@ -103,7 +118,7 @@ class ChartsBlockModule extends AbstractModule implements ModuleBlockInterface
case 'descendants':
/** @var DescendancyChartModule $module */
- $module = Module::findByClass(DescendancyChartModule::class);
+ $module = $this->module_service->findByClass(DescendancyChartModule::class);
$title = $module->chartTitle($person);
$chart_url = $module->chartUrl($person, [
'ajax' => true,
@@ -118,7 +133,7 @@ class ChartsBlockModule extends AbstractModule implements ModuleBlockInterface
case 'hourglass':
/** @var HourglassChartModule $module */
- $module = Module::findByClass(HourglassChartModule::class);
+ $module = $this->module_service->findByClass(HourglassChartModule::class);
$title = $module->chartTitle($person);
$chart_url = $module->chartUrl($person, [
'ajax' => true,
@@ -132,7 +147,7 @@ class ChartsBlockModule extends AbstractModule implements ModuleBlockInterface
case 'treenav':
/** @var InteractiveTreeModule $module */
- $module = Module::findByClass(InteractiveTreeModule::class);
+ $module = $this->module_service->findByClass(InteractiveTreeModule::class);
$title = I18N::translate('Interactive tree of %s', $person->getFullName());
$tv = new TreeView();
$content = '<script>$("head").append(\'<link rel="stylesheet" href="' . $module->css() . '" type="text/css" />\');</script>';
diff --git a/app/Module/ChartsMenuModule.php b/app/Module/ChartsMenuModule.php
index 6c72715a7f..7a9304855b 100644
--- a/app/Module/ChartsMenuModule.php
+++ b/app/Module/ChartsMenuModule.php
@@ -21,7 +21,7 @@ use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Menu;
-use Fisharebest\Webtrees\Module;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Tree;
use Symfony\Component\HttpFoundation\Request;
@@ -33,6 +33,21 @@ class ChartsMenuModule extends AbstractModule implements ModuleMenuInterface
use ModuleMenuTrait;
/**
+ * @var ModuleService
+ */
+ private $module_service;
+
+ /**
+ * ChartsMenuModule constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service)
+ {
+ $this->module_service = $module_service;
+ }
+
+ /**
* How should this module be labelled on tabs, menus, etc.?
*
* @return string
@@ -76,7 +91,7 @@ class ChartsMenuModule extends AbstractModule implements ModuleMenuInterface
$request = Request::createFromGlobals();
$xref = $request->get('xref', '');
$individual = Individual::getInstance($xref, $tree) ?? $tree->significantIndividual(Auth::user());
- $submenus = Module::findByComponent('chart', $tree, Auth::user())
+ $submenus = $this->module_service->findByComponent('chart', $tree, Auth::user())
->map(function (ModuleChartInterface $module) use ($individual): Menu {
return $module->chartMenu($individual);
});
diff --git a/app/Module/CookieWarningModule.php b/app/Module/CookieWarningModule.php
index 88676334e6..b354e9debe 100644
--- a/app/Module/CookieWarningModule.php
+++ b/app/Module/CookieWarningModule.php
@@ -19,6 +19,7 @@ namespace Fisharebest\Webtrees\Module;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Module;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Site;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
@@ -39,15 +40,21 @@ class CookieWarningModule extends AbstractModule implements ModuleFooterInterfac
MatomoAnalyticsModule::class,
StatcounterModule::class,
];
+ /**
+ * @var ModuleService
+ */
+ private $module_service;
/**
* Dependency injection.
*
- * @param Request $request
+ * @param Request $request
+ * @param ModuleService $module_service
*/
- public function __construct(Request $request)
+ public function __construct(Request $request, ModuleService $module_service)
{
$this->request = $request;
+ $this->module_service = $module_service;
}
/**
@@ -120,7 +127,7 @@ class CookieWarningModule extends AbstractModule implements ModuleFooterInterfac
}
foreach (self::TRACKING_MODULES as $class) {
- $module = Module::findByClass($class);
+ $module = $this->module_service->findByClass($class);
if ($module instanceof ModuleAnalyticsInterface) {
if ($module->analyticsCanShow()) {
diff --git a/app/Module/IndividualFactsTabModule.php b/app/Module/IndividualFactsTabModule.php
index 50b6cc740c..e6608d8c28 100644
--- a/app/Module/IndividualFactsTabModule.php
+++ b/app/Module/IndividualFactsTabModule.php
@@ -26,6 +26,7 @@ use Fisharebest\Webtrees\Gedcom;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Module;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Site;
use Illuminate\Support\Collection;
@@ -37,6 +38,20 @@ class IndividualFactsTabModule extends AbstractModule implements ModuleTabInterf
use ModuleTabTrait;
/**
+ * @var ModuleService
+ */
+ private $module_service;
+
+ /**
+ * UserWelcomeModule constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service) {
+ $this->module_service = $module_service;
+ }
+
+ /**
* How should this module be labelled on tabs, menus, etc.?
*
* @return string
@@ -95,7 +110,7 @@ class IndividualFactsTabModule extends AbstractModule implements ModuleTabInterf
break;
default:
- $use_extra_info_module = Module::findByComponent('sidebar', $individual->tree(), Auth::user())
+ $use_extra_info_module = $this->module_service->findByComponent('sidebar', $individual->tree(), Auth::user())
->filter(function (ModuleInterface $module): bool {
return $module instanceof ExtraInformationModule;
})->isNotEmpty();
@@ -445,9 +460,9 @@ class IndividualFactsTabModule extends AbstractModule implements ModuleTabInterf
*
* @return Fact[]
*/
- private static function historicalFacts(Individual $individual): array
+ private function historicalFacts(Individual $individual): array
{
- return Module::findByInterface(ModuleHistoricEventsInterface::class)
+ return $this->module_service->findByInterface(ModuleHistoricEventsInterface::class)
->map(function (ModuleHistoricEventsInterface $module) use ($individual): Collection {
return $module->historicEventsForIndividual($individual);
})
diff --git a/app/Module/ModuleThemeTrait.php b/app/Module/ModuleThemeTrait.php
index f484a9818d..d35425cf2a 100644
--- a/app/Module/ModuleThemeTrait.php
+++ b/app/Module/ModuleThemeTrait.php
@@ -25,6 +25,7 @@ use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Menu;
use Fisharebest\Webtrees\Module;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Site;
use Fisharebest\Webtrees\Theme;
use Fisharebest\Webtrees\Tree;
@@ -332,7 +333,7 @@ trait ModuleThemeTrait
public function individualBoxMenuCharts(Individual $individual): array
{
$menus = [];
- foreach (Module::findByComponent('chart', $this->tree, Auth::user()) as $chart) {
+ foreach (app(ModuleService::class)->findByComponent('chart', $this->tree, Auth::user()) as $chart) {
$menu = $chart->chartBoxMenu($individual);
if ($menu) {
$menus[] = $menu;
@@ -538,7 +539,7 @@ trait ModuleThemeTrait
{
$gedcomid = $this->tree->getUserPreference(Auth::user(), 'gedcomid');
- $pedigree_chart = Module::findByComponent('chart', $this->tree, Auth::user())
+ $pedigree_chart = app(ModuleService::class)->findByComponent('chart', $this->tree, Auth::user())
->filter(function (ModuleInterface $module): bool {
return $module instanceof PedigreeChartModule;
});
@@ -583,7 +584,7 @@ trait ModuleThemeTrait
*/
public function menuThemes()
{
- $themes = Module::findByInterface(ModuleThemeInterface::class);
+ $themes = app(ModuleService::class)->findByInterface(ModuleThemeInterface::class);
$current_theme = app()->make(ModuleThemeInterface::class);
@@ -633,7 +634,7 @@ trait ModuleThemeTrait
*/
public function primaryMenu(): array
{
- return Module::findByComponent('menu', $this->tree, Auth::user())
+ return app(ModuleService::class)->findByComponent('menu', $this->tree, Auth::user())
->map(function (ModuleMenuInterface $menu): ?Menu {
return $menu->getMenu($this->tree);
})
diff --git a/app/Module/ReportsMenuModule.php b/app/Module/ReportsMenuModule.php
index 214013c0d3..ebcc9e9c97 100644
--- a/app/Module/ReportsMenuModule.php
+++ b/app/Module/ReportsMenuModule.php
@@ -22,6 +22,7 @@ use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Menu;
use Fisharebest\Webtrees\Module;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Tree;
use Symfony\Component\HttpFoundation\Request;
@@ -33,6 +34,21 @@ class ReportsMenuModule extends AbstractModule implements ModuleMenuInterface
use ModuleMenuTrait;
/**
+ * @var ModuleService
+ */
+ private $module_service;
+
+ /**
+ * ChartsMenuModule constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service)
+ {
+ $this->module_service = $module_service;
+ }
+
+ /**
* How should this module be labelled on tabs, menus, etc.?
*
* @return string
@@ -77,7 +93,7 @@ class ReportsMenuModule extends AbstractModule implements ModuleMenuInterface
$request = Request::createFromGlobals();
$xref = $request->get('xref', '');
$individual = Individual::getInstance($xref, $tree) ?? $tree->significantIndividual(Auth::user());
- $submenus = Module::findByComponent('report', $tree, Auth::user())
+ $submenus = $this->module_service->findByComponent('report', $tree, Auth::user())
->map(function (ModuleReportInterface $module) use ($individual): Menu {
return $module->getReportMenu($individual);
});
diff --git a/app/Module/UserWelcomeModule.php b/app/Module/UserWelcomeModule.php
index 9d343b2f83..d223ba9122 100644
--- a/app/Module/UserWelcomeModule.php
+++ b/app/Module/UserWelcomeModule.php
@@ -21,6 +21,7 @@ use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Module;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Tree;
use Symfony\Component\HttpFoundation\Request;
@@ -32,6 +33,20 @@ class UserWelcomeModule extends AbstractModule implements ModuleBlockInterface
use ModuleBlockTrait;
/**
+ * @var ModuleService
+ */
+ private $module_service;
+
+ /**
+ * UserWelcomeModule constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service) {
+ $this->module_service = $module_service;
+ }
+
+ /**
* How should this module be labelled on tabs, menus, etc.?
*
* @return string
@@ -69,7 +84,7 @@ class UserWelcomeModule extends AbstractModule implements ModuleBlockInterface
$individual = Individual::getInstance($gedcomid, $tree);
$links = [];
- $pedigree_chart = Module::findByComponent('chart', $tree, Auth::user())
+ $pedigree_chart = $this->module_service->findByComponent('chart', $tree, Auth::user())
->filter(function (ModuleInterface $module): bool {
return $module instanceof PedigreeChartModule;
});
diff --git a/app/Module/WelcomeBlockModule.php b/app/Module/WelcomeBlockModule.php
index e64388db3d..e6edb671cf 100644
--- a/app/Module/WelcomeBlockModule.php
+++ b/app/Module/WelcomeBlockModule.php
@@ -19,7 +19,7 @@ namespace Fisharebest\Webtrees\Module;
use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\I18N;
-use Fisharebest\Webtrees\Module;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Site;
use Fisharebest\Webtrees\Tree;
use Symfony\Component\HttpFoundation\Request;
@@ -32,6 +32,21 @@ class WelcomeBlockModule extends AbstractModule implements ModuleBlockInterface
use ModuleBlockTrait;
/**
+ * @var ModuleService
+ */
+ private $module_service;
+
+ /**
+ * UserWelcomeModule constructor.
+ *
+ * @param ModuleService $module_service
+ */
+ public function __construct(ModuleService $module_service)
+ {
+ $this->module_service = $module_service;
+ }
+
+ /**
* How should this module be labelled on tabs, menus, etc.?
*
* @return string
@@ -69,7 +84,7 @@ class WelcomeBlockModule extends AbstractModule implements ModuleBlockInterface
$links = [];
- $pedigree_chart = Module::findByComponent('chart', $tree, Auth::user())
+ $pedigree_chart = $this->module_service->findByComponent('chart', $tree, Auth::user())
->filter(function (ModuleInterface $module): bool {
return $module instanceof PedigreeChartModule;
});
diff --git a/app/Module.php b/app/Services/ModuleService.php
index eca07dd81d..8212782e9a 100644
--- a/app/Module.php
+++ b/app/Services/ModuleService.php
@@ -15,9 +15,12 @@
*/
declare(strict_types=1);
-namespace Fisharebest\Webtrees;
+namespace Fisharebest\Webtrees\Services;
use Closure;
+use Fisharebest\Webtrees\Auth;
+use Fisharebest\Webtrees\FlashMessages;
+use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Module\AhnentafelReportModule;
use Fisharebest\Webtrees\Module\AlbumModule;
use Fisharebest\Webtrees\Module\AncestorsChartModule;
@@ -117,6 +120,9 @@ use Fisharebest\Webtrees\Module\WebtreesTheme;
use Fisharebest\Webtrees\Module\WelcomeBlockModule;
use Fisharebest\Webtrees\Module\XeneaTheme;
use Fisharebest\Webtrees\Module\YahrzeitModule;
+use Fisharebest\Webtrees\Tree;
+use Fisharebest\Webtrees\User;
+use Fisharebest\Webtrees\Webtrees;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
@@ -126,7 +132,7 @@ use Throwable;
/**
* Functions for managing and maintaining modules.
*/
-class Module
+class ModuleService
{
// Some types of module have different access levels in different trees.
private const COMPONENTS = [
@@ -237,7 +243,7 @@ class Module
*
* @return Collection
*/
- private static function coreModules(): Collection
+ private function coreModules(): Collection
{
$modules = new Collection(self::CORE_MODULES);
@@ -255,7 +261,7 @@ class Module
*
* @return Collection
*/
- private static function customModules(): Collection
+ private function customModules(): Collection
{
$pattern = WT_ROOT . Webtrees::MODULES_PATH . '*/module.php';
$filenames = glob($pattern);
@@ -296,7 +302,7 @@ class Module
*
* @return Collection|ModuleInterface[]
*/
- public static function all(): Collection
+ public function all(): Collection
{
return app('cache.array')->rememberForever('all_modules', function (): Collection {
// Modules have a default status, order etc.
@@ -347,7 +353,7 @@ class Module
*
* @return mixed
*/
- private static function load(string $filename)
+ private function load(string $filename)
{
return include $filename;
}
@@ -357,7 +363,7 @@ class Module
*
* @return Closure
*/
- private static function moduleSorter(): Closure
+ private function moduleSorter(): Closure
{
return function (ModuleInterface $x, ModuleInterface $y): int {
return I18N::strcasecmp($x->title(), $y->title());
@@ -369,7 +375,7 @@ class Module
*
* @return Closure
*/
- private static function footerSorter(): Closure
+ private function footerSorter(): Closure
{
return function (ModuleFooterInterface $x, ModuleFooterInterface $y): int {
return $x->getFooterOrder() <=> $y->getFooterOrder();
@@ -381,7 +387,7 @@ class Module
*
* @return Closure
*/
- private static function menuSorter(): Closure
+ private function menuSorter(): Closure
{
return function (ModuleMenuInterface $x, ModuleMenuInterface $y): int {
return $x->getMenuOrder() <=> $y->getMenuOrder();
@@ -393,7 +399,7 @@ class Module
*
* @return Closure
*/
- private static function sidebarSorter(): Closure
+ private function sidebarSorter(): Closure
{
return function (ModuleSidebarInterface $x, ModuleSidebarInterface $y): int {
return $x->getSidebarOrder() <=> $y->getSidebarOrder();
@@ -405,7 +411,7 @@ class Module
*
* @return Closure
*/
- private static function tabSorter(): Closure
+ private function tabSorter(): Closure
{
return function (ModuleTabInterface $x, ModuleTabInterface $y): int {
return $x->getTabOrder() <=> $y->getTabOrder();
@@ -419,9 +425,9 @@ class Module
* @param Tree $tree
* @param User $user
*
- * @return Collection|ModuleBlockInterface[]|ModuleChartInterface[]|ModuleMenuInterface[]|ModuleReportInterface[]|ModuleSidebarInterface[]|ModuleTabInterface[]
+ * @return Collection|ModuleInterface[]
*/
- public static function findByComponent(string $component, Tree $tree, User $user): Collection
+ public function findByComponent(string $component, Tree $tree, User $user): Collection
{
$interface = self::COMPONENTS[$component];
@@ -439,7 +445,7 @@ class Module
*
* @return Collection|ModuleInterface[]
*/
- public static function findByInterface(string $interface, $include_disabled = false): Collection
+ public function findByInterface(string $interface, $include_disabled = false): Collection
{
$modules = self::all()
->filter(function (ModuleInterface $module) use ($interface): bool {
@@ -473,7 +479,7 @@ class Module
*
* @return ModuleInterface|null
*/
- public static function findByName(string $module_name): ?ModuleInterface
+ public function findByName(string $module_name): ?ModuleInterface
{
return self::all()
->filter(function (ModuleInterface $module) use ($module_name): bool {
@@ -489,7 +495,7 @@ class Module
*
* @return ModuleInterface|null
*/
- public static function findByClass(string $class_name): ?ModuleInterface
+ public function findByClass(string $class_name): ?ModuleInterface
{
return self::all()
->filter(function (ModuleInterface $module) use ($class_name): bool {
diff --git a/app/Statistics/Repository/FavoritesRepository.php b/app/Statistics/Repository/FavoritesRepository.php
index e061742507..ec9b5cca66 100644
--- a/app/Statistics/Repository/FavoritesRepository.php
+++ b/app/Statistics/Repository/FavoritesRepository.php
@@ -22,6 +22,7 @@ use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Module;
use Fisharebest\Webtrees\Module\FamilyTreeFavoritesModule;
use Fisharebest\Webtrees\Module\UserFavoritesModule;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Statistics\Repository\Interfaces\FavoritesRepositoryInterface;
use Fisharebest\Webtrees\Tree;
@@ -50,7 +51,7 @@ class FavoritesRepository implements FavoritesRepositoryInterface
*/
public function gedcomFavorites(): string
{
- $module = Module::findByClass(FamilyTreeFavoritesModule::class);
+ $module = app(ModuleService::class)->findByClass(FamilyTreeFavoritesModule::class);
if ($module instanceof FamilyTreeFavoritesModule) {
return $module->getBlock($this->tree, 0);
@@ -64,7 +65,7 @@ class FavoritesRepository implements FavoritesRepositoryInterface
*/
public function userFavorites(): string
{
- $module = Module::findByClass(UserFavoritesModule::class);
+ $module = app(ModuleService::class)->findByClass(UserFavoritesModule::class);
if ($module instanceof UserFavoritesModule) {
return $module->getBlock($this->tree, 0);
@@ -79,7 +80,7 @@ class FavoritesRepository implements FavoritesRepositoryInterface
public function totalGedcomFavorites(): string
{
$count = 0;
- $module = Module::findByClass(FamilyTreeFavoritesModule::class);
+ $module = app(ModuleService::class)->findByClass(FamilyTreeFavoritesModule::class);
if ($module instanceof FamilyTreeFavoritesModule) {
$count = \count($module->getFavorites($this->tree));
@@ -94,7 +95,7 @@ class FavoritesRepository implements FavoritesRepositoryInterface
public function totalUserFavorites(): string
{
$count = 0;
- $module = Module::findByClass(UserFavoritesModule::class);
+ $module = app(ModuleService::class)->findByClass(UserFavoritesModule::class);
if ($module instanceof UserFavoritesModule) {
$count = \count($module->getFavorites($this->tree, Auth::user()));
diff --git a/app/Stats.php b/app/Stats.php
index fc635062b9..4b6afe598a 100644
--- a/app/Stats.php
+++ b/app/Stats.php
@@ -19,6 +19,7 @@ namespace Fisharebest\Webtrees;
use Fisharebest\Webtrees\Module\ModuleBlockInterface;
use Fisharebest\Webtrees\Module\ModuleInterface;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Statistics\Repository\BrowserRepository;
use Fisharebest\Webtrees\Statistics\Repository\ContactRepository;
use Fisharebest\Webtrees\Statistics\Repository\EventRepository;
@@ -2578,7 +2579,7 @@ class Stats implements
public function callBlock(string $block = '', ...$params): ?string
{
/** @var ModuleBlockInterface $module */
- $module = Module::findByComponent('block', $this->tree, Auth::user())
+ $module = app(ModuleService::class)->findByComponent('block', $this->tree, Auth::user())
->filter(function (ModuleInterface $module) use ($block): bool {
return $module->name() === $block && $module->name() !== 'html';
})
diff --git a/app/Theme.php b/app/Theme.php
deleted file mode 100644
index 17c90b0422..0000000000
--- a/app/Theme.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-/**
- * webtrees: online genealogy
- * Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
- */
-declare(strict_types=1);
-
-namespace Fisharebest\Webtrees;
-
-use Fisharebest\Webtrees\Module\ModuleThemeInterface;
-use Fisharebest\Webtrees\Module\WebtreesTheme;
-
-/**
- * Provide access to the current theme.
- */
-class Theme
-{
- /** @var ModuleThemeInterface The current theme */
- private static $theme;
-
- /**
- * An associative array of theme names, for <select> fields, etc.
- *
- * @return string[]
- */
- public static function themeNames(): array
- {
- $themes = Module::findByInterface(ModuleThemeInterface::class);
-
- $theme_names = [];
- foreach ($themes as $theme) {
- $theme_names[$theme->name()] = $theme->title();
- }
-
- return $theme_names;
- }
-}
diff --git a/index.php b/index.php
index e9134e9613..e4ac172942 100644
--- a/index.php
+++ b/index.php
@@ -31,6 +31,7 @@ use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Module;
use Fisharebest\Webtrees\Module\ModuleThemeInterface;
use Fisharebest\Webtrees\Module\WebtreesTheme;
+use Fisharebest\Webtrees\Services\ModuleService;
use Fisharebest\Webtrees\Services\TimeoutService;
use Fisharebest\Webtrees\Session;
use Fisharebest\Webtrees\Site;
@@ -229,7 +230,7 @@ try {
DebugBar::startMeasure('init theme');
- $themes = Module::findByInterface(ModuleThemeInterface::class);
+ $themes = app()->make(ModuleService::class)->findByInterface(ModuleThemeInterface::class);
// Last theme used?
$theme = $themes->get(Session::get('theme_id', ''));
diff --git a/resources/views/layouts/default.phtml b/resources/views/layouts/default.phtml
index 664e640755..e7e01e0b6b 100644
--- a/resources/views/layouts/default.phtml
+++ b/resources/views/layouts/default.phtml
@@ -6,6 +6,7 @@
<?php use Fisharebest\Webtrees\Module\ModuleAnalyticsInterface; ?>
<?php use Fisharebest\Webtrees\Module\ModuleFooterInterface; ?>
<?php use Fisharebest\Webtrees\Module\ModuleThemeInterface; ?>
+<?php use Fisharebest\Webtrees\Services\ModuleService; ?>
<?php use Fisharebest\Webtrees\View; ?>
<?php use Fisharebest\Webtrees\Webtrees; ?>
@@ -44,7 +45,7 @@
<?= View::stack('styles') ?>
- <?= Module::findByInterface(ModuleAnalyticsInterface::class)->filter(function (ModuleAnalyticsInterface $module): bool { return $module->analyticsCanShow(); })->map(function (ModuleAnalyticsInterface $module): string { return $module->analyticsSnippet($module->analyticsParameters()); })->implode('') ?>
+ <?= app()->make(ModuleService::class)->findByInterface(ModuleAnalyticsInterface::class)->filter(function (ModuleAnalyticsInterface $module): bool { return $module->analyticsCanShow(); })->map(function (ModuleAnalyticsInterface $module): string { return $module->analyticsSnippet($module->analyticsParameters()); })->implode('') ?>
<?= DebugBar::renderHead() ?>
</head>
@@ -120,7 +121,7 @@
<footer class="wt-footer-container">
<div class="wt-footer-content container d-print-none">
- <?= Module::findByInterface(ModuleFooterInterface::class)->map(function (ModuleFooterInterface $module) use ($tree): string { return app()->dispatch($module, 'getFooter'); })->implode('') ?>
+ <?= app()->make(ModuleService::class)->findByInterface(ModuleFooterInterface::class)->map(function (ModuleFooterInterface $module) use ($tree): string { return app()->dispatch($module, 'getFooter'); })->implode('') ?>
</div>
</footer>
diff --git a/resources/views/lists/individuals-table.phtml b/resources/views/lists/individuals-table.phtml
index 588710f130..73e7267bc0 100644
--- a/resources/views/lists/individuals-table.phtml
+++ b/resources/views/lists/individuals-table.phtml
@@ -2,9 +2,9 @@
<?php use Fisharebest\Webtrees\GedcomTag; ?>
<?php use Fisharebest\Webtrees\I18N; ?>
<?php use Fisharebest\Webtrees\Individual; ?>
-<?php use Fisharebest\Webtrees\Module; ?>
<?php use Fisharebest\Webtrees\Module\ModuleInterface; ?>
<?php use Fisharebest\Webtrees\Module\RelationshipsChartModule; ?>
+<?php use Fisharebest\Webtrees\Services\ModuleService; ?>
<?php use Fisharebest\Webtrees\Auth; ?>
<?php use Fisharebest\Webtrees\View; ?>
<?php use Ramsey\Uuid\Uuid; ?>
@@ -17,7 +17,7 @@ $table_id = 'table-indi-' . Uuid::uuid4()->toString();
$hundred_years_ago = new Date(date('Y') - 100);
$unique_indis = []; // Don't double-count indis with multiple names.
-$module = Module::findByComponent('chart', $tree, Auth::user())->first(function (ModuleInterface $module) {
+$module = app(ModuleService::class)->findByComponent('chart', $tree, Auth::user())->first(function (ModuleInterface $module) {
return $module instanceof RelationshipsChartModule;
});
?>
diff --git a/resources/views/media-page-menu.phtml b/resources/views/media-page-menu.phtml
index 86a8d4a085..ffbb618669 100644
--- a/resources/views/media-page-menu.phtml
+++ b/resources/views/media-page-menu.phtml
@@ -1,7 +1,7 @@
<?php use Fisharebest\Webtrees\Auth; ?>
<?php use Fisharebest\Webtrees\I18N; ?>
-<?php use Fisharebest\Webtrees\Module; ?>
<?php use Fisharebest\Webtrees\Module\CensusAssistantModule; ?>
+<?php use Fisharebest\Webtrees\Services\ModuleService; ?>
<div class="dropdown wt-page-menu">
<button class="btn btn-primary dropdown-toggle wt-page-menu-button" type="button" id="page-menu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@@ -10,7 +10,7 @@
</button>
<div class="dropdown-menu dropdown-menu-right wt-page-menu-items" aria-labelledby="page-menu">
- <?php if (false && Module::findByClass(CensusAssistantModule::class)) : ?>
+ <?php if (false && app()->make(ModuleService::class)->findByClass(CensusAssistantModule::class)) : ?>
<a class="dropdown-item menu-obje-link" href="#" onclick="return ilinkitem('<?= e($record->xref()) ?>','manage','<?= e($record->tree()->name()) ?>');">
<?= I18N::translate('Manage the links') ?>
</a>
diff --git a/resources/views/modules/ckeditor/ckeditor-js.phtml b/resources/views/modules/ckeditor/ckeditor-js.phtml
index c7feadcc3b..ece14fd238 100644
--- a/resources/views/modules/ckeditor/ckeditor-js.phtml
+++ b/resources/views/modules/ckeditor/ckeditor-js.phtml
@@ -1,8 +1,8 @@
-<?php use Fisharebest\Webtrees\Module; ?>
<?php use Fisharebest\Webtrees\Module\CkeditorModule; ?>
+<?php use Fisharebest\Webtrees\Services\ModuleService; ?>
<?php use Fisharebest\Webtrees\View; ?>
-<?php if (Module::findByClass(CkeditorModule::class)): ?>
+<?php if (app()->make(ModuleService::class)->findByClass(CkeditorModule::class)): ?>
<?php View::push('javascript') ?>
<script src="<?= e(CkeditorModule::CKEDITOR_PATH) ?>ckeditor.js"></script>
<script src="<?= e(CkeditorModule::CKEDITOR_PATH) ?>adapters/jquery.js"></script>
diff --git a/tests/app/Http/Controllers/ModuleControllerTest.php b/tests/app/Http/Controllers/ModuleControllerTest.php
index 87eaabf3b2..a2464086c1 100644
--- a/tests/app/Http/Controllers/ModuleControllerTest.php
+++ b/tests/app/Http/Controllers/ModuleControllerTest.php
@@ -19,6 +19,7 @@ namespace Fisharebest\Webtrees\Http\Controllers;
use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Application;
+use Fisharebest\Webtrees\Services\ModuleService;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -38,7 +39,7 @@ class ModuleControllerTest extends \Fisharebest\Webtrees\TestCase
public function testMissingModule(): void
{
$user = Auth::user();
- $controller = new ModuleController();
+ $controller = new ModuleController(new ModuleService());
$request = new Request(['route' => 'module']);
$controller->action($request, $user, new Application());
}
@@ -50,7 +51,7 @@ class ModuleControllerTest extends \Fisharebest\Webtrees\TestCase
public function testInvalidModule(): void
{
$user = Auth::user();
- $controller = new ModuleController();
+ $controller = new ModuleController(new ModuleService());
$request = new Request(['route' => 'module', 'module' => 'no-such-module']);
$controller->action($request, $user, new Application());
}
@@ -62,7 +63,7 @@ class ModuleControllerTest extends \Fisharebest\Webtrees\TestCase
public function testMissingAction(): void
{
$user = Auth::user();
- $controller = new ModuleController();
+ $controller = new ModuleController(new ModuleService());
$request = new Request(['route' => 'module', 'module' => 'sitemap']);
$controller->action($request, $user, new Application());
}
@@ -74,7 +75,7 @@ class ModuleControllerTest extends \Fisharebest\Webtrees\TestCase
public function testInvalidAction(): void
{
$user = Auth::user();
- $controller = new ModuleController();
+ $controller = new ModuleController(new ModuleService());
$request = new Request(['route' => 'module', 'module' => 'sitemap', 'action' => 'no-such-action']);
$controller->action($request, $user, new Application());
}
@@ -88,7 +89,7 @@ class ModuleControllerTest extends \Fisharebest\Webtrees\TestCase
//$tree = $this->importTree('demo.ged');
$user = Auth::user();
- $controller = new ModuleController();
+ $controller = new ModuleController(new ModuleService());
$request = new Request(['route' => 'module', 'module' => 'sitemap', 'action' => 'DoAdminStuff']);
$controller->action($request, $user, new Application());
@@ -100,7 +101,7 @@ class ModuleControllerTest extends \Fisharebest\Webtrees\TestCase
public function testSucessfulAction(): void
{
$user = Auth::user();
- $controller = new ModuleController();
+ $controller = new ModuleController(new ModuleService());
$request = new Request(['route' => 'module', 'module' => 'sitemap', 'action' => 'Index']);
$response = $controller->action($request, $user, new Application());
diff --git a/tests/app/ModuleTest.php b/tests/app/ModuleTest.php
deleted file mode 100644
index bbe694fed6..0000000000
--- a/tests/app/ModuleTest.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-/**
- * webtrees: online genealogy
- * Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
- */
-declare(strict_types=1);
-
-namespace Fisharebest\Webtrees;
-
-use Fisharebest\Webtrees\Module\ModuleAnalyticsInterface;
-use Fisharebest\Webtrees\Module\ModuleBlockInterface;
-use Fisharebest\Webtrees\Module\ModuleChartInterface;
-use Fisharebest\Webtrees\Module\ModuleConfigInterface;
-use Fisharebest\Webtrees\Module\ModuleHistoricEventsInterface;
-use Fisharebest\Webtrees\Module\ModuleInterface;
-use Fisharebest\Webtrees\Module\ModuleMenuInterface;
-use Fisharebest\Webtrees\Module\ModuleReportInterface;
-use Fisharebest\Webtrees\Module\ModuleSidebarInterface;
-use Fisharebest\Webtrees\Module\ModuleTabInterface;
-use Fisharebest\Webtrees\Module\ModuleThemeInterface;
-use Fisharebest\Webtrees\Module\TreesMenuModule;
-
-/**
- * Test the modules
- *
- * @coversNothing
- */
-class ModuleTest extends \Fisharebest\Webtrees\TestCase
-{
- protected static $uses_database = true;
-
- /**
- * @covers \Fisharebest\Webtrees\Module::all
- * @covers \Fisharebest\Webtrees\Module::coreModules
- * @covers \Fisharebest\Webtrees\Module::customModules
- * @covers \Fisharebest\Webtrees\Module::moduleSorter
- * @return void
- */
- public function testAll(): void
- {
- $this->assertNotEmpty(Module::all());
- }
-
- /**
- * @covers \Fisharebest\Webtrees\Module::findByComponent
- * @covers \Fisharebest\Webtrees\Module::menuSorter
- * @covers \Fisharebest\Webtrees\Module::sidebarSorter
- * @covers \Fisharebest\Webtrees\Module::tabSorter
- * @return void
- */
- public function testFindByComponent(): void
- {
- $tree = $this->importTree('demo.ged');
- $user = User::create('UserName', 'RealName', 'user@example.com', 'secret');
-
- $this->assertNotEmpty(Module::findByComponent('block', $tree, $user)->all());
- $this->assertNotEmpty(Module::findByComponent('chart', $tree, $user)->all());
- $this->assertNotEmpty(Module::findByComponent('menu', $tree, $user)->all());
- $this->assertNotEmpty(Module::findByComponent('report', $tree, $user)->all());
- $this->assertNotEmpty(Module::findByComponent('sidebar', $tree, $user)->all());
- $this->assertNotEmpty(Module::findByComponent('tab', $tree, $user)->all());
- }
-
- /**
- * @covers \Fisharebest\Webtrees\Module::findByInterface
- * @return void
- */
- public function testFindByInterface(): void
- {
- $this->assertNotEmpty(Module::findByInterface(ModuleAnalyticsInterface::class)->all());
- $this->assertNotEmpty(Module::findByInterface(ModuleBlockInterface::class)->all());
- $this->assertNotEmpty(Module::findByInterface(ModuleChartInterface::class)->all());
- $this->assertNotEmpty(Module::findByInterface(ModuleConfigInterface::class)->all());
- $this->assertNotEmpty(Module::findByInterface(ModuleMenuInterface::class)->all());
- $this->assertNotEmpty(Module::findByInterface(ModuleInterface::class)->all());
- $this->assertNotEmpty(Module::findByInterface(ModuleReportInterface::class)->all());
- $this->assertNotEmpty(Module::findByInterface(ModuleSidebarInterface::class)->all());
- $this->assertNotEmpty(Module::findByInterface(ModuleTabInterface::class)->all());
- $this->assertNotEmpty(Module::findByInterface(ModuleThemeInterface::class)->all());
-
- // THe core modules do not contain any of these.
- $this->assertEmpty(Module::findByInterface(ModuleHistoricEventsInterface::class)->all());
- }
-
- /**
- * @covers \Fisharebest\Webtrees\Module::findByClass
- * @return void
- */
- public function testFindByClass(): void
- {
- $this->assertNull(Module::findByClass('not-a-valid-class-name'));
- $this->assertInstanceOf(TreesMenuModule::class, Module::findByClass(TreesMenuModule::class));
- }
-
- /**
- * @covers \Fisharebest\Webtrees\Module::findByName
- * @return void
- */
- public function testFindByName(): void
- {
- $this->assertNull(Module::findByName('not-a-valid-module-name'));
- $this->assertInstanceOf(TreesMenuModule::class, Module::findByName('trees-menu'));
- }
-}
diff --git a/tests/app/Services/ModuleServiceTest.php b/tests/app/Services/ModuleServiceTest.php
new file mode 100644
index 0000000000..6f3f0f3a0b
--- /dev/null
+++ b/tests/app/Services/ModuleServiceTest.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
+ */
+declare(strict_types=1);
+
+namespace Fisharebest\Webtrees\Services;
+
+use Fisharebest\Webtrees\Module\ModuleAnalyticsInterface;
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Module\ModuleChartInterface;
+use Fisharebest\Webtrees\Module\ModuleConfigInterface;
+use Fisharebest\Webtrees\Module\ModuleHistoricEventsInterface;
+use Fisharebest\Webtrees\Module\ModuleInterface;
+use Fisharebest\Webtrees\Module\ModuleMenuInterface;
+use Fisharebest\Webtrees\Module\ModuleReportInterface;
+use Fisharebest\Webtrees\Module\ModuleSidebarInterface;
+use Fisharebest\Webtrees\Module\ModuleTabInterface;
+use Fisharebest\Webtrees\Module\ModuleThemeInterface;
+use Fisharebest\Webtrees\Module\TreesMenuModule;
+use Fisharebest\Webtrees\TestCase;
+use Fisharebest\Webtrees\User;
+
+/**
+ * Test the modules
+ *
+ * @coversNothing
+ */
+class ModuleServiceTest extends TestCase
+{
+ protected static $uses_database = true;
+
+ /**
+ * @covers \Fisharebest\Webtrees\Services\ModuleService::all
+ * @covers \Fisharebest\Webtrees\Services\ModuleService::coreModules
+ * @covers \Fisharebest\Webtrees\Services\ModuleService::customModules
+ * @covers \Fisharebest\Webtrees\Services\ModuleService::moduleSorter
+ * @return void
+ */
+ public function testAll(): void
+ {
+ $module_service = new ModuleService();
+
+ $this->assertNotEmpty($module_service->all());
+ }
+
+ /**
+ * @covers \Fisharebest\Webtrees\Services\ModuleService::findByComponent
+ * @covers \Fisharebest\Webtrees\Services\ModuleService::menuSorter
+ * @covers \Fisharebest\Webtrees\Services\ModuleService::sidebarSorter
+ * @covers \Fisharebest\Webtrees\Services\ModuleService::tabSorter
+ * @return void
+ */
+ public function testFindByComponent(): void
+ {
+ $module_service = new ModuleService();
+
+ $tree = $this->importTree('demo.ged');
+ $user = User::create('UserName', 'RealName', 'user@example.com', 'secret');
+
+ $this->assertNotEmpty($module_service->findByComponent('block', $tree, $user)->all());
+ $this->assertNotEmpty($module_service->findByComponent('chart', $tree, $user)->all());
+ $this->assertNotEmpty($module_service->findByComponent('menu', $tree, $user)->all());
+ $this->assertNotEmpty($module_service->findByComponent('report', $tree, $user)->all());
+ $this->assertNotEmpty($module_service->findByComponent('sidebar', $tree, $user)->all());
+ $this->assertNotEmpty($module_service->findByComponent('tab', $tree, $user)->all());
+ }
+
+ /**
+ * @covers \Fisharebest\Webtrees\Services\ModuleService::findByInterface
+ * @return void
+ */
+ public function testFindByInterface(): void
+ {
+ $module_service = new ModuleService();
+
+ $this->assertNotEmpty($module_service->findByInterface(ModuleAnalyticsInterface::class)->all());
+ $this->assertNotEmpty($module_service->findByInterface(ModuleBlockInterface::class)->all());
+ $this->assertNotEmpty($module_service->findByInterface(ModuleChartInterface::class)->all());
+ $this->assertNotEmpty($module_service->findByInterface(ModuleConfigInterface::class)->all());
+ $this->assertNotEmpty($module_service->findByInterface(ModuleMenuInterface::class)->all());
+ $this->assertNotEmpty($module_service->findByInterface(ModuleInterface::class)->all());
+ $this->assertNotEmpty($module_service->findByInterface(ModuleReportInterface::class)->all());
+ $this->assertNotEmpty($module_service->findByInterface(ModuleSidebarInterface::class)->all());
+ $this->assertNotEmpty($module_service->findByInterface(ModuleTabInterface::class)->all());
+ $this->assertNotEmpty($module_service->findByInterface(ModuleThemeInterface::class)->all());
+
+ // THe core modules do not contain any of these.
+ $this->assertEmpty($module_service->findByInterface(ModuleHistoricEventsInterface::class)->all());
+ }
+
+ /**
+ * @covers \Fisharebest\Webtrees\Services\ModuleService::findByClass
+ * @return void
+ */
+ public function testFindByClass(): void
+ {
+ $module_service = new ModuleService();
+
+ $this->assertNull($module_service->findByClass('not-a-valid-class-name'));
+ $this->assertInstanceOf(TreesMenuModule::class, $module_service->findByClass(TreesMenuModule::class));
+ }
+
+ /**
+ * @covers \Fisharebest\Webtrees\Services\ModuleService::findByName
+ * @return void
+ */
+ public function testFindByName(): void
+ {
+ $module_service = new ModuleService();
+
+ $this->assertNull($module_service->findByName('not-a-valid-module-name'));
+ $this->assertInstanceOf(TreesMenuModule::class, $module_service->findByName('trees-menu'));
+ }
+}