diff options
29 files changed, 362 insertions, 205 deletions
diff --git a/app/Http/Controllers/Admin/AnalyticsController.php b/app/Http/Controllers/Admin/AnalyticsController.php deleted file mode 100644 index 15e05765ef..0000000000 --- a/app/Http/Controllers/Admin/AnalyticsController.php +++ /dev/null @@ -1,91 +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\Http\Controllers\Admin; - -use Fisharebest\Webtrees\FlashMessages; -use Fisharebest\Webtrees\I18N; -use Fisharebest\Webtrees\Module; -use Fisharebest\Webtrees\Module\ModuleAnalyticsInterface; -use Illuminate\Support\Collection; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Controller for configuring the tracking and analytics modules. - */ -class AnalyticsController extends AbstractAdminController -{ - /** - * @return Response - */ - public function list(): Response - { - /* I18N: e.g. http://www.google.com/analytics */ - $title = I18N::translate('Tracking and analytics'); - - return $this->viewResponse('admin/analytics/index', [ - 'modules' => Module::findByInterface(ModuleAnalyticsInterface::class), - 'title' => $title, - ]); - } - - /** - * @param Request $request - * - * @return Response - */ - public function edit(Request $request): Response - { - $module_name = $request->get('module', ''); - $module = Module::findByName($module_name); - - if ($module instanceof ModuleAnalyticsInterface) { - return $this->viewResponse('admin/analytics/edit', [ - 'module_name' => $module_name, - 'form_fields' => $module->analyticsFormFields(), - 'preview' => $module->analyticsSnippet($module->analyticsParameters()), - 'title' => $module->title(), - ]); - } - - return new RedirectResponse(route('analytics')); - } - - /** - * @param Request $request - * - * @return RedirectResponse - */ - public function save(Request $request): RedirectResponse - { - $module_name = $request->get('module', ''); - - $module = Module::findByName($module_name); - - if ($module instanceof ModuleAnalyticsInterface) { - foreach (array_keys($module->analyticsParameters()) as $setting_name) { - $module->setPreference($setting_name, $request->get($setting_name, '')); - } - - FlashMessages::addMessage(I18N::translate('The preferences for the module ā%sā have been updated.', $module->title()), 'success'); - } - - return new RedirectResponse(route('analytics')); - } -} diff --git a/app/Http/Controllers/Admin/ModuleController.php b/app/Http/Controllers/Admin/ModuleController.php index 2fbcfeb1c3..c55ff90413 100644 --- a/app/Http/Controllers/Admin/ModuleController.php +++ b/app/Http/Controllers/Admin/ModuleController.php @@ -20,9 +20,11 @@ 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; use Fisharebest\Webtrees\Module\ModuleFooterInterface; +use Fisharebest\Webtrees\Module\ModuleHistoricEventsInterface; use Fisharebest\Webtrees\Module\ModuleInterface; use Fisharebest\Webtrees\Module\ModuleMenuInterface; use Fisharebest\Webtrees\Module\ModuleReportInterface; @@ -90,9 +92,27 @@ class ModuleController extends AbstractAdminController /** * @return Response */ + public function listAnalytics(): Response + { + return $this->listComponents( + ModuleAnalyticsInterface::class, + 'analytics', + I18N::translate('Tracking and analytics'), + I18N::translate('If you use one of the following tracking and analytics services, webtrees can add the tracking codes automatically.') + ); + } + + /** + * @return Response + */ public function listBlocks(): Response { - return $this->listComponents(ModuleBlockInterface::class, 'block', I18N::translate('Blocks')); + return $this->listComponents( + ModuleBlockInterface::class, + 'block', + I18N::translate('Blocks'), + '' + ); } /** @@ -100,7 +120,12 @@ class ModuleController extends AbstractAdminController */ public function listCharts(): Response { - return $this->listComponents(ModuleChartInterface::class, 'chart', I18N::translate('Charts')); + return $this->listComponents( + ModuleChartInterface::class, + 'chart', + I18N::translate('Charts'), + '' + ); } /** @@ -108,7 +133,25 @@ class ModuleController extends AbstractAdminController */ public function listFooters(): Response { - return $this->listComponents(ModuleFooterInterface::class, 'footer', I18N::translate('Footers')); + return $this->listComponents( + ModuleFooterInterface::class, + 'footer', + I18N::translate('Footers'), + '' + ); + } + + /** + * @return Response + */ + public function listHistory(): Response + { + return $this->listComponents( + ModuleHistoricEventsInterface::class, + 'history', + I18N::translate('Historic events'), + '' + ); } /** @@ -116,7 +159,12 @@ class ModuleController extends AbstractAdminController */ public function listMenus(): Response { - return $this->listComponents(ModuleMenuInterface::class, 'menu', I18N::translate('Menus')); + return $this->listComponents( + ModuleMenuInterface::class, + 'menu', + I18N::translate('Menus'), + '' + ); } /** @@ -124,7 +172,12 @@ class ModuleController extends AbstractAdminController */ public function listReports(): Response { - return $this->listComponents(ModuleReportInterface::class, 'report', I18N::translate('Reports')); + return $this->listComponents( + ModuleReportInterface::class, + 'report', + I18N::translate('Reports'), + '' + ); } /** @@ -132,7 +185,12 @@ class ModuleController extends AbstractAdminController */ public function listSidebars(): Response { - return $this->listComponents(ModuleSidebarInterface::class, 'sidebar', I18N::translate('Sidebars')); + return $this->listComponents( + ModuleSidebarInterface::class, + 'sidebar', + I18N::translate('Sidebars'), + '' + ); } /** @@ -140,23 +198,30 @@ class ModuleController extends AbstractAdminController */ public function listTabs(): Response { - return $this->listComponents(ModuleTabInterface::class, 'tab', I18N::translate('Tabs')); + return $this->listComponents( + ModuleTabInterface::class, + 'tab', + I18N::translate('Tabs'), + '' + ); } /** * @param string $interface * @param string $component * @param string $title + * @param string $description * * @return Response */ - private function listComponents(string $interface, string $component, string $title): Response + private function listComponents(string $interface, string $component, string $title, string $description): Response { $uses_access = in_array($component, self::COMPONENTS_WITH_ACCESS); $uses_sorting = in_array($component, self::COMPONENTS_WITH_SORT); return $this->viewResponse('admin/components', [ 'component' => $component, + 'description' => $description, 'modules' => Module::findByInterface($interface, true), 'title' => $title, 'trees' => Tree::all(), @@ -201,6 +266,20 @@ class ModuleController extends AbstractAdminController * * @return RedirectResponse */ + public function updateAnalytics(Request $request): RedirectResponse + { + $modules = Module::findByInterface(ModuleAnalyticsInterface::class, true); + + $this->updateStatus($modules, $request); + + return new RedirectResponse(route('analytics')); + } + + /** + * @param Request $request + * + * @return RedirectResponse + */ public function updateBlocks(Request $request): RedirectResponse { $modules = Module::findByInterface(ModuleBlockInterface::class, true); @@ -246,6 +325,20 @@ class ModuleController extends AbstractAdminController * * @return RedirectResponse */ + public function updateHistory(Request $request): RedirectResponse + { + $modules = Module::findByInterface(ModuleHistoricEventsInterface::class, true); + + $this->updateStatus($modules, $request); + + return new RedirectResponse(route('history')); + } + + /** + * @param Request $request + * + * @return RedirectResponse + */ public function updateMenus(Request $request): RedirectResponse { $modules = Module::findByInterface(ModuleMenuInterface::class, true); diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index 81c8b46cd0..5ea4231c82 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -32,7 +32,16 @@ use Fisharebest\Webtrees\I18N; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Media; use Fisharebest\Webtrees\Module; +use Fisharebest\Webtrees\Module\ModuleAnalyticsInterface; +use Fisharebest\Webtrees\Module\ModuleBlockInterface; +use Fisharebest\Webtrees\Module\ModuleChartInterface; use Fisharebest\Webtrees\Module\ModuleConfigInterface; +use Fisharebest\Webtrees\Module\ModuleFooterInterface; +use Fisharebest\Webtrees\Module\ModuleHistoricEventsInterface; +use Fisharebest\Webtrees\Module\ModuleMenuInterface; +use Fisharebest\Webtrees\Module\ModuleReportInterface; +use Fisharebest\Webtrees\Module\ModuleSidebarInterface; +use Fisharebest\Webtrees\Module\ModuleTabInterface; use Fisharebest\Webtrees\Note; use Fisharebest\Webtrees\Repository; use Fisharebest\Webtrees\Services\DatatablesService; @@ -80,33 +89,49 @@ class AdminController extends AbstractBaseController HousekeepingService $housekeeping_service, UpgradeService $upgrade_service, Admin\ModuleController $module_controller - ): Response { + ): 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) + ->filter(function (ModuleConfigInterface $module): bool { + return !$module instanceof ModuleAnalyticsInterface; + }); + return $this->viewResponse('admin/control-panel', [ - 'title' => I18N::translate('Control panel'), - 'server_warnings' => $this->serverWarnings(), - 'latest_version' => $upgrade_service->latestVersion(), - 'all_users' => User::all(), - 'administrators' => User::administrators(), - 'managers' => User::managers(), - 'moderators' => User::moderators(), - 'unapproved' => User::unapproved(), - 'unverified' => User::unverified(), - 'all_trees' => Tree::getAll(), - 'changes' => $this->totalChanges(), - 'individuals' => $this->totalIndividuals(), - 'families' => $this->totalFamilies(), - 'sources' => $this->totalSources(), - 'media' => $this->totalMediaObjects(), - 'repositories' => $this->totalRepositories(), - 'notes' => $this->totalNotes(), - 'files_to_delete' => $files_to_delete, - 'all_modules' => Module::all(), - 'deleted_modules' => $deleted_modules, - 'config_modules' => Module::findByInterface(ModuleConfigInterface::class), + 'title' => I18N::translate('Control panel'), + 'server_warnings' => $this->serverWarnings(), + 'latest_version' => $upgrade_service->latestVersion(), + 'all_users' => User::all(), + 'administrators' => User::administrators(), + 'managers' => User::managers(), + 'moderators' => User::moderators(), + 'unapproved' => User::unapproved(), + 'unverified' => User::unverified(), + 'all_trees' => Tree::getAll(), + 'changes' => $this->totalChanges(), + 'individuals' => $this->totalIndividuals(), + 'families' => $this->totalFamilies(), + 'sources' => $this->totalSources(), + 'media' => $this->totalMediaObjects(), + 'repositories' => $this->totalRepositories(), + 'notes' => $this->totalNotes(), + 'files_to_delete' => $files_to_delete, + 'all_modules' => Module::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), + 'config_modules' => $config_modules, + 'footer_modules' => Module::findByInterface(ModuleFooterInterface::class, true), + 'history_modules' => Module::findByInterface(ModuleHistoricEventsInterface::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), ]); } diff --git a/app/Module/BingWebmasterToolsModule.php b/app/Module/BingWebmasterToolsModule.php index dd441bfdd4..4c35360159 100644 --- a/app/Module/BingWebmasterToolsModule.php +++ b/app/Module/BingWebmasterToolsModule.php @@ -20,9 +20,11 @@ namespace Fisharebest\Webtrees\Module; /** * Class BingWebmasterToolsModule - add support for Bing webmaster tools */ -class BingWebmasterToolsModule extends AbstractModule implements ModuleAnalyticsInterface +class BingWebmasterToolsModule extends AbstractModule implements ModuleAnalyticsInterface, ModuleConfigInterface, ModuleExternalUrlInterface { use ModuleAnalyticsTrait; + use ModuleConfigTrait; + use ModuleExternalUrlTrait; /** * How should this module be labelled on tabs, menus, etc.? @@ -41,7 +43,7 @@ class BingWebmasterToolsModule extends AbstractModule implements ModuleAnalytics */ public function analyticsFormFields(): string { - return view('admin/analytics/bing-webmaster-form', $this->analyticsParameters()); + return view('modules/bing-webmaster-tools/form', $this->analyticsParameters()); } /** @@ -49,7 +51,7 @@ class BingWebmasterToolsModule extends AbstractModule implements ModuleAnalytics * * @return string */ - public function analyticsHomePageUrl(): string + public function externalUrl(): string { return 'https://www.bing.com/toolbox/webmaster'; } @@ -75,6 +77,6 @@ class BingWebmasterToolsModule extends AbstractModule implements ModuleAnalytics */ public function analyticsSnippet(array $parameters): string { - return view('admin/analytics/bing-webmaster-snippet', $parameters); + return view('modules/bing-webmaster-tools/snippet', $parameters); } } diff --git a/app/Module/GoogleAnalyticsModule.php b/app/Module/GoogleAnalyticsModule.php index a2671cdab8..a8e3c2f8f7 100644 --- a/app/Module/GoogleAnalyticsModule.php +++ b/app/Module/GoogleAnalyticsModule.php @@ -24,9 +24,11 @@ use Fisharebest\Webtrees\User; /** * Class GoogleAnalyticsModule - add support for Google analytics. */ -class GoogleAnalyticsModule extends AbstractModule implements ModuleAnalyticsInterface +class GoogleAnalyticsModule extends AbstractModule implements ModuleAnalyticsInterface, ModuleConfigInterface, ModuleExternalUrlInterface { use ModuleAnalyticsTrait; + use ModuleConfigTrait; + use ModuleExternalUrlTrait; /** * How should this module be labelled on tabs, menus, etc.? @@ -45,7 +47,7 @@ class GoogleAnalyticsModule extends AbstractModule implements ModuleAnalyticsInt */ public function analyticsFormFields(): string { - return view('admin/analytics/google-analytics-form', $this->analyticsParameters()); + return view('modules/google-analytics/form', $this->analyticsParameters()); } /** @@ -53,7 +55,7 @@ class GoogleAnalyticsModule extends AbstractModule implements ModuleAnalyticsInt * * @return string */ - public function analyticsHomePageUrl(): string + public function externalUrl(): string { return 'https://www.google.com/analytics'; } @@ -88,6 +90,6 @@ class GoogleAnalyticsModule extends AbstractModule implements ModuleAnalyticsInt 'dimension2' => $tree instanceof Tree ? Auth::accessLevel($tree, $user) : '-', ]; - return view('admin/analytics/google-analytics-snippet', $parameters); + return view('modules/google-analytics/snippet', $parameters); } } diff --git a/app/Module/GoogleWebmasterToolsModule.php b/app/Module/GoogleWebmasterToolsModule.php index 0192e8e49d..50b459c545 100644 --- a/app/Module/GoogleWebmasterToolsModule.php +++ b/app/Module/GoogleWebmasterToolsModule.php @@ -20,9 +20,11 @@ namespace Fisharebest\Webtrees\Module; /** * Class GoogleWebmasterToolsModule - add support for Google webmaster tools. */ -class GoogleWebmasterToolsModule extends AbstractModule implements ModuleAnalyticsInterface +class GoogleWebmasterToolsModule extends AbstractModule implements ModuleAnalyticsInterface, ModuleConfigInterface, ModuleExternalUrlInterface { use ModuleAnalyticsTrait; + use ModuleConfigTrait; + use ModuleExternalUrlTrait; /** * How should this module be labelled on tabs, menus, etc.? @@ -41,7 +43,7 @@ class GoogleWebmasterToolsModule extends AbstractModule implements ModuleAnalyti */ public function analyticsFormFields(): string { - return view('admin/analytics/google-webmaster-form', $this->analyticsParameters()); + return view('modules/google-webmaster-tools/form', $this->analyticsParameters()); } /** @@ -49,7 +51,7 @@ class GoogleWebmasterToolsModule extends AbstractModule implements ModuleAnalyti * * @return string */ - public function analyticsHomePageUrl(): string + public function externalUrl(): string { return 'https://www.google.com/webmasters'; } @@ -75,6 +77,6 @@ class GoogleWebmasterToolsModule extends AbstractModule implements ModuleAnalyti */ public function analyticsSnippet(array $parameters): string { - return view('admin/analytics/google-webmaster-snippet', $parameters); + return view('modules/google-webmaster-tools/snippet', $parameters); } } diff --git a/app/Module/MatomoAnalyticsModule.php b/app/Module/MatomoAnalyticsModule.php index 57dd7d0b52..251d2ff823 100644 --- a/app/Module/MatomoAnalyticsModule.php +++ b/app/Module/MatomoAnalyticsModule.php @@ -20,9 +20,11 @@ namespace Fisharebest\Webtrees\Module; /** * Class MatomoAnalyticsModule - add support for Matomo analytics. */ -class MatomoAnalyticsModule extends AbstractModule implements ModuleAnalyticsInterface +class MatomoAnalyticsModule extends AbstractModule implements ModuleAnalyticsInterface, ModuleConfigInterface, ModuleExternalUrlInterface { use ModuleAnalyticsTrait; + use ModuleConfigTrait; + use ModuleExternalUrlTrait; /** * How should this module be labelled on tabs, menus, etc.? @@ -41,7 +43,7 @@ class MatomoAnalyticsModule extends AbstractModule implements ModuleAnalyticsInt */ public function analyticsFormFields(): string { - return view('admin/analytics/matomo-analytics-form', $this->analyticsParameters()); + return view('modules/matomo-analytics/form', $this->analyticsParameters()); } /** @@ -49,7 +51,7 @@ class MatomoAnalyticsModule extends AbstractModule implements ModuleAnalyticsInt * * @return string */ - public function analyticsHomePageUrl(): string + public function externalUrl(): string { return 'https://matomo.org'; } @@ -75,6 +77,6 @@ class MatomoAnalyticsModule extends AbstractModule implements ModuleAnalyticsInt */ public function analyticsSnippet(array $parameters): string { - return view('admin/analytics/matomo-analytics-snippet', $parameters); + return view('modules/matomo-analytics/snippet', $parameters); } } diff --git a/app/Module/ModuleAnalyticsInterface.php b/app/Module/ModuleAnalyticsInterface.php index f943b5ce8c..0d1c3ff6dc 100644 --- a/app/Module/ModuleAnalyticsInterface.php +++ b/app/Module/ModuleAnalyticsInterface.php @@ -17,6 +17,10 @@ declare(strict_types=1); namespace Fisharebest\Webtrees\Module; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + /** * Interface ModuleAnalyticsInterface - Classes and libraries for module system */ @@ -37,13 +41,6 @@ interface ModuleAnalyticsInterface extends ModuleInterface public function analyticsFormFields(): string; /** - * Home page for the service. - * - * @return string - */ - public function analyticsHomePageUrl(): string; - - /** * The parameters that need to be embedded in the snippet. * * @return string[] @@ -58,4 +55,16 @@ interface ModuleAnalyticsInterface extends ModuleInterface * @return string */ public function analyticsSnippet(array $parameters): string; + + /** + * @return Response + */ + public function getAdminAction(): Response; + + /** + * @param Request $request + * + * @return RedirectResponse + */ + public function postAdminAction(Request $request): RedirectResponse; } diff --git a/app/Module/ModuleAnalyticsTrait.php b/app/Module/ModuleAnalyticsTrait.php index d10afae301..008c36385e 100644 --- a/app/Module/ModuleAnalyticsTrait.php +++ b/app/Module/ModuleAnalyticsTrait.php @@ -18,7 +18,9 @@ declare(strict_types=1); namespace Fisharebest\Webtrees\Module; use Fisharebest\Webtrees\I18N; -use Illuminate\Support\Collection; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; /** * Trait ModuleAnalyticsTrait - default implementation of ModuleAnalyticsInterface @@ -26,6 +28,15 @@ use Illuminate\Support\Collection; trait ModuleAnalyticsTrait { /** + * @param $view_name + * @param $view_data + * @param $status + * + * @return Response + */ + abstract function viewResponse($view_name, $view_data, $status = Response::HTTP_OK): Response; + + /** * Should we add this tracker? * * @return bool @@ -62,16 +73,6 @@ trait ModuleAnalyticsTrait } /** - * Home page for the service. - * - * @return string - */ - public function analyticsHomePageURL(): string - { - return ''; - } - - /** * The parameters that need to be embedded in the snippet. * * @return string[] @@ -92,4 +93,29 @@ trait ModuleAnalyticsTrait { return ''; } + + + /** + * @return Response + */ + public function getAdminAction(): Response + { + $this->layout = 'layouts/administration'; + + return $this->viewResponse('admin/analytics-edit', [ + 'form_fields' => $this->analyticsFormFields(), + 'preview' => $this->analyticsSnippet($this->analyticsParameters()), + 'title' => $this->title(), + ]); + } + + /** + * @param Request $request + * + * @return RedirectResponse + */ + public function postAdminAction(Request $request): RedirectResponse + { + return new RedirectResponse(route('analytics')); + } } diff --git a/app/Module/ModuleExternalUrlInterface.php b/app/Module/ModuleExternalUrlInterface.php new file mode 100644 index 0000000000..48d95b7e14 --- /dev/null +++ b/app/Module/ModuleExternalUrlInterface.php @@ -0,0 +1,31 @@ +<?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\Module; + +/** + * Interface ModuleExternalUrlInterface - Classes and libraries for module system + */ +interface ModuleExternalUrlInterface extends ModuleInterface +{ + /** + * Home page for the service. + * + * @return string + */ + public function externalUrl(): string; +} diff --git a/app/Module/ModuleExternalUrlTrait.php b/app/Module/ModuleExternalUrlTrait.php new file mode 100644 index 0000000000..6da766152b --- /dev/null +++ b/app/Module/ModuleExternalUrlTrait.php @@ -0,0 +1,34 @@ +<?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\Module; + +/** + * Trait ModuleExternalUrlITrait - default implementation of ModuleExternalUrlIInterface + */ +trait ModuleExternalUrlTrait +{ + /** + * Home page for the service. + * + * @return string + */ + public function externalUrl(): string + { + return ''; + } +} diff --git a/app/Module/StatcounterModule.php b/app/Module/StatcounterModule.php index f39d7869ef..eb7044b1fd 100644 --- a/app/Module/StatcounterModule.php +++ b/app/Module/StatcounterModule.php @@ -20,9 +20,11 @@ namespace Fisharebest\Webtrees\Module; /** * Class StatcounterModule - add support for statcounter. */ -class StatcounterModule extends AbstractModule implements ModuleAnalyticsInterface +class StatcounterModule extends AbstractModule implements ModuleAnalyticsInterface, ModuleConfigInterface, ModuleExternalUrlInterface { use ModuleAnalyticsTrait; + use ModuleConfigTrait; + use ModuleExternalUrlTrait; /** * How should this module be labelled on tabs, menus, etc.? @@ -41,7 +43,7 @@ class StatcounterModule extends AbstractModule implements ModuleAnalyticsInterfa */ public function analyticsFormFields(): string { - return view('admin/analytics/statcounter-form', $this->analyticsParameters()); + return view('modules/statcounter/form', $this->analyticsParameters()); } /** @@ -49,7 +51,7 @@ class StatcounterModule extends AbstractModule implements ModuleAnalyticsInterfa * * @return string */ - public function analyticsHomePageUrl(): string + public function externalUrl(): string { return 'https://statcounter.com'; } @@ -76,6 +78,6 @@ class StatcounterModule extends AbstractModule implements ModuleAnalyticsInterfa */ public function analyticsSnippet(array $parameters): string { - return view('admin/analytics/statcounter-snippet', $parameters); + return view('modules/statcounter/snippet', $parameters); } } diff --git a/resources/views/admin/analytics/edit.phtml b/resources/views/admin/analytics-edit.phtml index ce9879b5c1..fc9b1353ba 100644 --- a/resources/views/admin/analytics/edit.phtml +++ b/resources/views/admin/analytics-edit.phtml @@ -1,6 +1,6 @@ <?php use Fisharebest\Webtrees\I18N; ?> -<?= view('components/breadcrumbs', ['links' => [route('admin-control-panel') => I18N::translate('Control panel'), route('analytics') => I18N::translate('Tracking and analytics'), $title]]) ?> +<?= view('components/breadcrumbs', ['links' => [route('admin-control-panel') => I18N::translate('Control panel'), route('modules') => I18N::translate('Modules'), route('analytics') => I18N::translate('Tracking and analytics'), $title]]) ?> <h1><?= $title ?></h1> diff --git a/resources/views/admin/analytics/index.phtml b/resources/views/admin/analytics/index.phtml deleted file mode 100644 index 1e31c27075..0000000000 --- a/resources/views/admin/analytics/index.phtml +++ /dev/null @@ -1,36 +0,0 @@ -<?php use Fisharebest\Webtrees\I18N; ?> -<?php use Fisharebest\Webtrees\Site; ?> - -<?= view('components/breadcrumbs', ['links' => [route('admin-control-panel') => I18N::translate('Control panel'), $title]]) ?> - -<h1><?= $title ?></h1> - -<p> - <?= I18N::translate('If you use one of the following tracking and analytics services, webtrees can add the tracking codes automatically.') ?> -</p> - -<p> - <?= I18N::translate('Tracking and analytics are not added to the control panel.') ?> -</p> - -<p> - <?= I18N::translate('Site verification codes do not work when webtrees is installed in a subfolder.') ?> -</p> - -<?php foreach ($modules as $module) : ?> - <h2> - <?= e($module->title()) ?> - </h2> - - <p> - <a class="btn btn-link" href="<?= e(route('analytics-edit', ['module' => $module->name()])) ?>"> - <?= view('icons/preferences') ?> - <?= I18N::translate('Preferences') ?> - </a> - - <a class="btn btn-link" href="<?= e($module->analyticsHomePageUrl()) ?>"> - <?= view('icons/information') ?> - <?= e($module->analyticsHomePageUrl()) ?> - </a> - </p> -<?php endforeach ?> diff --git a/resources/views/admin/components.phtml b/resources/views/admin/components.phtml index b90650c0d5..62aea3ed34 100644 --- a/resources/views/admin/components.phtml +++ b/resources/views/admin/components.phtml @@ -1,13 +1,16 @@ <?php use Fisharebest\Webtrees\Bootstrap4; ?> <?php use Fisharebest\Webtrees\Functions\FunctionsEdit; ?> <?php use Fisharebest\Webtrees\I18N; ?> -<?php use Fisharebest\Webtrees\Module\ModuleConfigInterface; -use Fisharebest\Webtrees\View; ?> +<?php use Fisharebest\Webtrees\Module\ModuleExternalUrlInterface; ?> +<?php use Fisharebest\Webtrees\Module\ModuleConfigInterface; ?> +<?php use Fisharebest\Webtrees\View; ?> <?= view('components/breadcrumbs', ['links' => [route('admin-control-panel') => I18N::translate('Control panel'), route('modules') => I18N::translate('Modules'), $title]]) ?> <h1><?= $title ?></h1> +<p><?= $description ?></p> + <form method="post"> <?= csrf_field() ?> <table class="table table-bordered wt-table-menu"> @@ -41,6 +44,12 @@ use Fisharebest\Webtrees\View; ?> </span> </a> <?php endif ?> + <?php if ($module instanceof ModuleExternalUrlInterface) : ?> + <br> + <a href="<?= e($module->externalUrl()) ?>"> + <?= e($module->externalUrl()) ?> + </a> + <?php endif ?> </th> <td class="text-center"> diff --git a/resources/views/admin/control-panel.phtml b/resources/views/admin/control-panel.phtml index 43b04710d1..d4dbe6313f 100644 --- a/resources/views/admin/control-panel.phtml +++ b/resources/views/admin/control-panel.phtml @@ -63,12 +63,6 @@ <?= I18N::translate('Languages') ?> </a> </li> - <li> - <span class="fa-li"><?= view('icons/wizard') ?></span> - <a href="<?= e(route('analytics')) ?>"> - <?= I18N::translate('Tracking and analytics') ?> - </a> - </li> </ul> </div> <div class="col-sm-6"> @@ -306,11 +300,13 @@ <a href="<?= e(route('menus')) ?>"> <?= I18N::translate('Menus') ?> </a> + <?= view('components/badge', ['count' => $menu_modules->count()]) ?> </li> <li> <span class="fa-li"><?= view('icons/tab') ?></span> <a href="<?= e(route('tabs')) ?>"> <?= I18N::translate('Tabs') ?> + <?= view('components/badge', ['count' => $tab_modules->count()]) ?> </a> </li> <li> @@ -318,30 +314,49 @@ <a href="<?= e(route('blocks')) ?>"> <?= I18N::translate('Blocks') ?> </a> + <?= view('components/badge', ['count' => $block_modules->count()]) ?> </li> <li> <span class="fa-li"><?= view('icons/sidebar') ?></span> <a href="<?= e(route('sidebars')) ?>"> <?= I18N::translate('Sidebars') ?> </a> + <?= view('components/badge', ['count' => $sidebar_modules->count()]) ?> </li> <li> <span class="fa-li"><?= view('icons/chart') ?></span> <a href="<?= e(route('charts')) ?>"> <?= I18N::translate('Charts') ?> </a> + <?= view('components/badge', ['count' => $chart_modules->count()]) ?> </li> <li> <span class="fa-li"><?= view('icons/report') ?></span> <a href="<?= e(route('reports')) ?>"> <?= I18N::translate('Reports') ?> </a> + <?= view('components/badge', ['count' => $report_modules->count()]) ?> </li> <li> <span class="fa-li"><?= view('icons/footer') ?></span> <a href="<?= e(route('footers')) ?>"> <?= I18N::translate('Footers') ?> </a> + <?= view('components/badge', ['count' => $footer_modules->count()]) ?> + </li> + <li> + <span class="fa-li"><?= view('icons/analytics') ?></span> + <a href="<?= e(route('analytics')) ?>"> + <?= I18N::translate('Tracking and analytics') ?> + </a> + <?= view('components/badge', ['count' => $analytics_modules->count()]) ?> + </li> + <li> + <span class="fa-li"><?= view('icons/history') ?></span> + <a href="<?= e(route('history')) ?>"> + <?= I18N::translate('Historic events') ?> + </a> + <?= view('components/badge', ['count' => $history_modules->count()]) ?> </li> </ul> </div> diff --git a/resources/views/admin/modules.phtml b/resources/views/admin/modules.phtml index 3fa125f73a..1e87715d58 100644 --- a/resources/views/admin/modules.phtml +++ b/resources/views/admin/modules.phtml @@ -5,6 +5,7 @@ <?php use Fisharebest\Webtrees\Module\ModuleChartInterface; ?> <?php use Fisharebest\Webtrees\Module\ModuleConfigInterface; ?> <?php use Fisharebest\Webtrees\Module\ModuleCustomInterface; ?> +<?php use Fisharebest\Webtrees\Module\ModuleExternalUrlInterface; ?> <?php use Fisharebest\Webtrees\Module\ModuleFooterInterface; ?> <?php use Fisharebest\Webtrees\Module\ModuleHistoricEventsInterface; ?> <?php use Fisharebest\Webtrees\Module\ModuleMenuInterface; ?> @@ -120,6 +121,12 @@ </a> <?php endif ?> <?php endif ?> + <?php if ($module instanceof ModuleExternalUrlInterface) : ?> + <br> + <a href="<?= e($module->externalUrl()) ?>"> + <?= e($module->externalUrl()) ?> + </a> + <?php endif ?> </td> <td class="text-center text-muted" title="<?= I18N::translate('Preferences') ?>"> <?php if ($module instanceof ModuleConfigInterface) : ?> diff --git a/resources/views/components/badge.phtml b/resources/views/components/badge.phtml new file mode 100644 index 0000000000..391ab5fc9b --- /dev/null +++ b/resources/views/components/badge.phtml @@ -0,0 +1,5 @@ +<?php use Fisharebest\Webtrees\I18N; ?> + +<span class="badge badge-<?= $context ?? 'primary' ?>"> + <?= I18N::number($count) ?> +</span> diff --git a/resources/views/admin/analytics/bing-webmaster-form.phtml b/resources/views/modules/bing-webmaster-tools/form.phtml index e483ede59a..8b41a3eb91 100644 --- a/resources/views/admin/analytics/bing-webmaster-form.phtml +++ b/resources/views/modules/bing-webmaster-tools/form.phtml @@ -10,3 +10,6 @@ </div> </div> +<p> + <?= I18N::translate('Site verification codes do not work when webtrees is installed in a subfolder.') ?> +</p> diff --git a/resources/views/admin/analytics/bing-webmaster-snippet.phtml b/resources/views/modules/bing-webmaster-tools/snippet.phtml index f78fb17c81..f78fb17c81 100644 --- a/resources/views/admin/analytics/bing-webmaster-snippet.phtml +++ b/resources/views/modules/bing-webmaster-tools/snippet.phtml diff --git a/resources/views/admin/analytics/google-analytics-form.phtml b/resources/views/modules/google-analytics/form.phtml index a246214c5c..a441cfcd31 100644 --- a/resources/views/admin/analytics/google-analytics-form.phtml +++ b/resources/views/modules/google-analytics/form.phtml @@ -9,3 +9,7 @@ <input type="text" class="form-control" id="GOOGLE_ANALYTICS_ID" name="GOOGLE_ANALYTICS_ID" value="<?= e($GOOGLE_ANALYTICS_ID ?? '') ?>" placeholder="UA-12345-6" maxlength="255" pattern="UA-[0-9]+-[0-9]+"> </div> </div> + +<p> + <?= I18N::translate('Tracking and analytics are not added to the control panel.') ?> +</p> diff --git a/resources/views/admin/analytics/google-analytics-snippet.phtml b/resources/views/modules/google-analytics/snippet.phtml index e55b77b528..e55b77b528 100644 --- a/resources/views/admin/analytics/google-analytics-snippet.phtml +++ b/resources/views/modules/google-analytics/snippet.phtml diff --git a/resources/views/admin/analytics/google-webmaster-form.phtml b/resources/views/modules/google-webmaster-tools/form.phtml index 4e3a7bd731..ba9baa8cca 100644 --- a/resources/views/admin/analytics/google-webmaster-form.phtml +++ b/resources/views/modules/google-webmaster-tools/form.phtml @@ -10,3 +10,6 @@ </div> </div> +<p> + <?= I18N::translate('Site verification codes do not work when webtrees is installed in a subfolder.') ?> +</p> diff --git a/resources/views/admin/analytics/google-webmaster-snippet.phtml b/resources/views/modules/google-webmaster-tools/snippet.phtml index 8728d9ada4..8728d9ada4 100644 --- a/resources/views/admin/analytics/google-webmaster-snippet.phtml +++ b/resources/views/modules/google-webmaster-tools/snippet.phtml diff --git a/resources/views/admin/analytics/matomo-analytics-form.phtml b/resources/views/modules/matomo-analytics/form.phtml index dcd4edfe92..8fce201551 100644 --- a/resources/views/admin/analytics/matomo-analytics-form.phtml +++ b/resources/views/modules/matomo-analytics/form.phtml @@ -19,3 +19,6 @@ </div> </div> +<p> + <?= I18N::translate('Tracking and analytics are not added to the control panel.') ?> +</p> diff --git a/resources/views/admin/analytics/matomo-analytics-snippet.phtml b/resources/views/modules/matomo-analytics/snippet.phtml index c81a17f402..c81a17f402 100644 --- a/resources/views/admin/analytics/matomo-analytics-snippet.phtml +++ b/resources/views/modules/matomo-analytics/snippet.phtml diff --git a/resources/views/admin/analytics/statcounter-form.phtml b/resources/views/modules/statcounter/form.phtml index 23a38294b0..3a64308348 100644 --- a/resources/views/admin/analytics/statcounter-form.phtml +++ b/resources/views/modules/statcounter/form.phtml @@ -18,3 +18,7 @@ <input type="text" class="form-control" id="STATCOUNTER_SECURITY_ID" name="STATCOUNTER_SECURITY_ID" value="<?= e($STATCOUNTER_SECURITY_ID ?? '') ?>" maxlength="255" pattern="[0-9a-zA-Z]+"> </div> </div> + +<p> + <?= I18N::translate('Tracking and analytics are not added to the control panel.') ?> +</p> diff --git a/resources/views/admin/analytics/statcounter-snippet.phtml b/resources/views/modules/statcounter/snippet.phtml index 13dfa49009..13dfa49009 100644 --- a/resources/views/admin/analytics/statcounter-snippet.phtml +++ b/resources/views/modules/statcounter/snippet.phtml diff --git a/routes/web.php b/routes/web.php index c86bfe93d3..9d4f58238c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -24,17 +24,20 @@ $routes = []; // Admin routes. if (Auth::isAdmin()) { $routes += [ - 'GET:analytics' => 'Admin\\AnalyticsController@list', 'GET:analytics-edit' => 'Admin\\AnalyticsController@edit', 'POST:analytics-edit' => 'Admin\\AnalyticsController@save', 'GET:modules' => 'Admin\\ModuleController@list', 'POST:modules' => 'Admin\\ModuleController@update', + 'GET:analytics' => 'Admin\\ModuleController@listAnalytics', + 'POST:analytics' => 'Admin\\ModuleController@updateAnalytics', 'GET:blocks' => 'Admin\\ModuleController@listBlocks', 'POST:blocks' => 'Admin\\ModuleController@updateBlocks', 'GET:charts' => 'Admin\\ModuleController@listCharts', 'POST:charts' => 'Admin\\ModuleController@updateCharts', 'GET:footers' => 'Admin\\ModuleController@listFooters', 'POST:footers' => 'Admin\\ModuleController@updateFooters', + 'GET:history' => 'Admin\\ModuleController@listHistory', + 'POST:history' => 'Admin\\ModuleController@updateHistory', 'GET:menus' => 'Admin\\ModuleController@listMenus', 'POST:menus' => 'Admin\\ModuleController@updateMenus', 'GET:reports' => 'Admin\\ModuleController@listReports', |
