diff options
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; - } -} @@ -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')); + } +} |
