xref: /webtrees/app/Http/RequestHandlers/ControlPanel.php (revision fcfa147e10aaa6c7ff580c29bd6e5b88666befc1)
10c0910bfSGreg Roach<?php
20c0910bfSGreg Roach
30c0910bfSGreg Roach/**
40c0910bfSGreg Roach * webtrees: online genealogy
50c0910bfSGreg Roach * Copyright (C) 2019 webtrees development team
60c0910bfSGreg Roach * This program is free software: you can redistribute it and/or modify
70c0910bfSGreg Roach * it under the terms of the GNU General Public License as published by
80c0910bfSGreg Roach * the Free Software Foundation, either version 3 of the License, or
90c0910bfSGreg Roach * (at your option) any later version.
100c0910bfSGreg Roach * This program is distributed in the hope that it will be useful,
110c0910bfSGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
120c0910bfSGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
130c0910bfSGreg Roach * GNU General Public License for more details.
140c0910bfSGreg Roach * You should have received a copy of the GNU General Public License
150c0910bfSGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
160c0910bfSGreg Roach */
17*fcfa147eSGreg Roach
180c0910bfSGreg Roachdeclare(strict_types=1);
190c0910bfSGreg Roach
200c0910bfSGreg Roachnamespace Fisharebest\Webtrees\Http\RequestHandlers;
210c0910bfSGreg Roach
220c0910bfSGreg Roachuse Fisharebest\Webtrees\Http\ViewResponseTrait;
230c0910bfSGreg Roachuse Fisharebest\Webtrees\I18N;
240c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\FamilyListModule;
250c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\IndividualListModule;
260c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\MediaListModule;
270c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleAnalyticsInterface;
280c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleBlockInterface;
290c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleChartInterface;
300c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleFooterInterface;
310c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleHistoricEventsInterface;
320c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleLanguageInterface;
330c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleListInterface;
340c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleMenuInterface;
350c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleReportInterface;
360c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleSidebarInterface;
370c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleTabInterface;
380c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\ModuleThemeInterface;
390c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\NoteListModule;
400c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\RepositoryListModule;
410c0910bfSGreg Roachuse Fisharebest\Webtrees\Module\SourceListModule;
420c0910bfSGreg Roachuse Fisharebest\Webtrees\Services\HousekeepingService;
430c0910bfSGreg Roachuse Fisharebest\Webtrees\Services\ModuleService;
440c0910bfSGreg Roachuse Fisharebest\Webtrees\Services\ServerCheckService;
450c0910bfSGreg Roachuse Fisharebest\Webtrees\Services\TreeService;
460c0910bfSGreg Roachuse Fisharebest\Webtrees\Services\UpgradeService;
470c0910bfSGreg Roachuse Fisharebest\Webtrees\Services\UserService;
480c0910bfSGreg Roachuse Fisharebest\Webtrees\Webtrees;
490c0910bfSGreg Roachuse Illuminate\Database\Capsule\Manager as DB;
500c0910bfSGreg Roachuse Illuminate\Database\Query\Expression;
510c0910bfSGreg Roachuse Illuminate\Database\Query\JoinClause;
520c0910bfSGreg Roachuse Illuminate\Support\Collection;
530c0910bfSGreg Roachuse League\Flysystem\Adapter\Local;
540c0910bfSGreg Roachuse League\Flysystem\Filesystem;
550c0910bfSGreg Roachuse Psr\Http\Message\ResponseInterface;
560c0910bfSGreg Roachuse Psr\Http\Message\ServerRequestInterface;
570c0910bfSGreg Roachuse Psr\Http\Server\RequestHandlerInterface;
580c0910bfSGreg Roach
590c0910bfSGreg Roach/**
600c0910bfSGreg Roach * The control panel shows a summary of the site and links to admin functions.
610c0910bfSGreg Roach */
620c0910bfSGreg Roachclass ControlPanel implements RequestHandlerInterface
630c0910bfSGreg Roach{
640c0910bfSGreg Roach    use ViewResponseTrait;
650c0910bfSGreg Roach
660c0910bfSGreg Roach    /** @var ModuleService */
670c0910bfSGreg Roach    private $module_service;
680c0910bfSGreg Roach
690c0910bfSGreg Roach    /** @var HousekeepingService */
700c0910bfSGreg Roach    private $housekeeping_service;
710c0910bfSGreg Roach
720c0910bfSGreg Roach    /** @var ServerCheckService */
730c0910bfSGreg Roach    private $server_check_service;
740c0910bfSGreg Roach
750c0910bfSGreg Roach    /** @var TreeService */
760c0910bfSGreg Roach    private $tree_service;
770c0910bfSGreg Roach
780c0910bfSGreg Roach    /** @var UpgradeService */
790c0910bfSGreg Roach    private $upgrade_service;
800c0910bfSGreg Roach
810c0910bfSGreg Roach    /** @var UserService */
820c0910bfSGreg Roach    private $user_service;
830c0910bfSGreg Roach
840c0910bfSGreg Roach    /**
850c0910bfSGreg Roach     * ControlPanel constructor.
860c0910bfSGreg Roach     *
870c0910bfSGreg Roach     * @param HousekeepingService $housekeeping_service
880c0910bfSGreg Roach     * @param ModuleService       $module_service
890c0910bfSGreg Roach     * @param ServerCheckService  $server_check_service
900c0910bfSGreg Roach     * @param TreeService         $tree_service
910c0910bfSGreg Roach     * @param UpgradeService      $upgrade_service
920c0910bfSGreg Roach     * @param UserService         $user_service
930c0910bfSGreg Roach     */
940c0910bfSGreg Roach    public function __construct(
950c0910bfSGreg Roach        HousekeepingService $housekeeping_service,
960c0910bfSGreg Roach        ModuleService $module_service,
970c0910bfSGreg Roach        ServerCheckService $server_check_service,
980c0910bfSGreg Roach        TreeService $tree_service,
990c0910bfSGreg Roach        UpgradeService $upgrade_service,
1000c0910bfSGreg Roach        UserService $user_service
1010c0910bfSGreg Roach    ) {
1020c0910bfSGreg Roach        $this->module_service       = $module_service;
1030c0910bfSGreg Roach        $this->housekeeping_service = $housekeeping_service;
1040c0910bfSGreg Roach        $this->server_check_service = $server_check_service;
1050c0910bfSGreg Roach        $this->tree_service         = $tree_service;
1060c0910bfSGreg Roach        $this->upgrade_service      = $upgrade_service;
1070c0910bfSGreg Roach        $this->user_service         = $user_service;
1080c0910bfSGreg Roach    }
1090c0910bfSGreg Roach
1100c0910bfSGreg Roach    /**
1110c0910bfSGreg Roach     * @param ServerRequestInterface $request
1120c0910bfSGreg Roach     *
1130c0910bfSGreg Roach     * @return ResponseInterface
1140c0910bfSGreg Roach     */
1150c0910bfSGreg Roach    public function handle(ServerRequestInterface $request): ResponseInterface
1160c0910bfSGreg Roach    {
1170c0910bfSGreg Roach        $this->layout = 'layouts/administration';
1180c0910bfSGreg Roach
1190c0910bfSGreg Roach        $filesystem      = new Filesystem(new Local(Webtrees::ROOT_DIR));
1200c0910bfSGreg Roach        $files_to_delete = $this->housekeeping_service->deleteOldWebtreesFiles($filesystem);
1210c0910bfSGreg Roach
1220c0910bfSGreg Roach        return $this->viewResponse('admin/control-panel', [
1230c0910bfSGreg Roach            'title'                      => I18N::translate('Control panel'),
1240c0910bfSGreg Roach            'server_errors'              => $this->server_check_service->serverErrors(),
1250c0910bfSGreg Roach            'server_warnings'            => $this->server_check_service->serverWarnings(),
1260c0910bfSGreg Roach            'latest_version'             => $this->upgrade_service->latestVersion(),
1270c0910bfSGreg Roach            'all_users'                  => $this->user_service->all(),
1280c0910bfSGreg Roach            'administrators'             => $this->user_service->administrators(),
1290c0910bfSGreg Roach            'managers'                   => $this->user_service->managers(),
1300c0910bfSGreg Roach            'moderators'                 => $this->user_service->moderators(),
1310c0910bfSGreg Roach            'unapproved'                 => $this->user_service->unapproved(),
1320c0910bfSGreg Roach            'unverified'                 => $this->user_service->unverified(),
1330c0910bfSGreg Roach            'all_trees'                  => $this->tree_service->all(),
1340c0910bfSGreg Roach            'changes'                    => $this->totalChanges(),
1350c0910bfSGreg Roach            'individuals'                => $this->totalIndividuals(),
1360c0910bfSGreg Roach            'families'                   => $this->totalFamilies(),
1370c0910bfSGreg Roach            'sources'                    => $this->totalSources(),
1380c0910bfSGreg Roach            'media'                      => $this->totalMediaObjects(),
1390c0910bfSGreg Roach            'repositories'               => $this->totalRepositories(),
1400c0910bfSGreg Roach            'notes'                      => $this->totalNotes(),
1410c0910bfSGreg Roach            'individual_list_module'     => $this->module_service->findByInterface(IndividualListModule::class)->first(),
1420c0910bfSGreg Roach            'family_list_module'         => $this->module_service->findByInterface(FamilyListModule::class)->first(),
1430c0910bfSGreg Roach            'media_list_module'          => $this->module_service->findByInterface(MediaListModule::class)->first(),
1440c0910bfSGreg Roach            'note_list_module'           => $this->module_service->findByInterface(NoteListModule::class)->first(),
1450c0910bfSGreg Roach            'repository_list_module'     => $this->module_service->findByInterface(RepositoryListModule::class)->first(),
1460c0910bfSGreg Roach            'source_list_module'         => $this->module_service->findByInterface(SourceListModule::class)->first(),
1470c0910bfSGreg Roach            'files_to_delete'            => $files_to_delete,
1480c0910bfSGreg Roach            'all_modules_disabled'       => $this->module_service->all(true),
1490c0910bfSGreg Roach            'all_modules_enabled'        => $this->module_service->all(),
1500c0910bfSGreg Roach            'deleted_modules'            => $this->module_service->deletedModules(),
1510c0910bfSGreg Roach            'analytics_modules_disabled' => $this->module_service->findByInterface(ModuleAnalyticsInterface::class, true),
1520c0910bfSGreg Roach            'analytics_modules_enabled'  => $this->module_service->findByInterface(ModuleAnalyticsInterface::class),
1530c0910bfSGreg Roach            'block_modules_disabled'     => $this->module_service->findByInterface(ModuleBlockInterface::class, true),
1540c0910bfSGreg Roach            'block_modules_enabled'      => $this->module_service->findByInterface(ModuleBlockInterface::class),
1550c0910bfSGreg Roach            'chart_modules_disabled'     => $this->module_service->findByInterface(ModuleChartInterface::class, true),
1560c0910bfSGreg Roach            'chart_modules_enabled'      => $this->module_service->findByInterface(ModuleChartInterface::class),
1570c0910bfSGreg Roach            'other_modules'              => $this->module_service->otherModules(true),
1580c0910bfSGreg Roach            'footer_modules_disabled'    => $this->module_service->findByInterface(ModuleFooterInterface::class, true),
1590c0910bfSGreg Roach            'footer_modules_enabled'     => $this->module_service->findByInterface(ModuleFooterInterface::class),
1600c0910bfSGreg Roach            'history_modules_disabled'   => $this->module_service->findByInterface(ModuleHistoricEventsInterface::class, true),
1610c0910bfSGreg Roach            'history_modules_enabled'    => $this->module_service->findByInterface(ModuleHistoricEventsInterface::class),
1620c0910bfSGreg Roach            'language_modules_disabled'  => $this->module_service->findByInterface(ModuleLanguageInterface::class, true),
1630c0910bfSGreg Roach            'language_modules_enabled'   => $this->module_service->findByInterface(ModuleLanguageInterface::class),
1640c0910bfSGreg Roach            'list_modules_disabled'      => $this->module_service->findByInterface(ModuleListInterface::class, true),
1650c0910bfSGreg Roach            'list_modules_enabled'       => $this->module_service->findByInterface(ModuleListInterface::class),
1660c0910bfSGreg Roach            'menu_modules_disabled'      => $this->module_service->findByInterface(ModuleMenuInterface::class, true),
1670c0910bfSGreg Roach            'menu_modules_enabled'       => $this->module_service->findByInterface(ModuleMenuInterface::class),
1680c0910bfSGreg Roach            'report_modules_disabled'    => $this->module_service->findByInterface(ModuleReportInterface::class, true),
1690c0910bfSGreg Roach            'report_modules_enabled'     => $this->module_service->findByInterface(ModuleReportInterface::class),
1700c0910bfSGreg Roach            'sidebar_modules_disabled'   => $this->module_service->findByInterface(ModuleSidebarInterface::class, true),
1710c0910bfSGreg Roach            'sidebar_modules_enabled'    => $this->module_service->findByInterface(ModuleSidebarInterface::class),
1720c0910bfSGreg Roach            'tab_modules_disabled'       => $this->module_service->findByInterface(ModuleTabInterface::class, true),
1730c0910bfSGreg Roach            'tab_modules_enabled'        => $this->module_service->findByInterface(ModuleTabInterface::class),
1740c0910bfSGreg Roach            'theme_modules_disabled'     => $this->module_service->findByInterface(ModuleThemeInterface::class, true),
1750c0910bfSGreg Roach            'theme_modules_enabled'      => $this->module_service->findByInterface(ModuleThemeInterface::class),
1760c0910bfSGreg Roach        ]);
1770c0910bfSGreg Roach    }
1780c0910bfSGreg Roach
1790c0910bfSGreg Roach    /**
1800c0910bfSGreg Roach     * Count the number of pending changes in each tree.
1810c0910bfSGreg Roach     *
1820c0910bfSGreg Roach     * @return string[]
1830c0910bfSGreg Roach     */
1840c0910bfSGreg Roach    private function totalChanges(): array
1850c0910bfSGreg Roach    {
1860c0910bfSGreg Roach        return DB::table('gedcom')
1870c0910bfSGreg Roach            ->leftJoin('change', static function (JoinClause $join): void {
1880c0910bfSGreg Roach                $join
1890c0910bfSGreg Roach                    ->on('change.gedcom_id', '=', 'gedcom.gedcom_id')
1900c0910bfSGreg Roach                    ->where('change.status', '=', 'pending');
1910c0910bfSGreg Roach            })
1920c0910bfSGreg Roach            ->groupBy(['gedcom.gedcom_id'])
1930c0910bfSGreg Roach            ->pluck(new Expression('COUNT(change_id)'), 'gedcom.gedcom_id')
1940c0910bfSGreg Roach            ->all();
1950c0910bfSGreg Roach    }
1960c0910bfSGreg Roach
1970c0910bfSGreg Roach    /**
1980c0910bfSGreg Roach     * Count the number of individuals in each tree.
1990c0910bfSGreg Roach     *
2000c0910bfSGreg Roach     * @return Collection
2010c0910bfSGreg Roach     */
2020c0910bfSGreg Roach    private function totalIndividuals(): Collection
2030c0910bfSGreg Roach    {
2040c0910bfSGreg Roach        return DB::table('gedcom')
2050c0910bfSGreg Roach            ->leftJoin('individuals', 'i_file', '=', 'gedcom_id')
2060c0910bfSGreg Roach            ->groupBy(['gedcom_id'])
2070c0910bfSGreg Roach            ->pluck(new Expression('COUNT(i_id)'), 'gedcom_id')
2080c0910bfSGreg Roach            ->map(static function (string $count) {
2090c0910bfSGreg Roach                return (int) $count;
2100c0910bfSGreg Roach            });
2110c0910bfSGreg Roach    }
2120c0910bfSGreg Roach
2130c0910bfSGreg Roach    /**
2140c0910bfSGreg Roach     * Count the number of families in each tree.
2150c0910bfSGreg Roach     *
2160c0910bfSGreg Roach     * @return Collection
2170c0910bfSGreg Roach     */
2180c0910bfSGreg Roach    private function totalFamilies(): Collection
2190c0910bfSGreg Roach    {
2200c0910bfSGreg Roach        return DB::table('gedcom')
2210c0910bfSGreg Roach            ->leftJoin('families', 'f_file', '=', 'gedcom_id')
2220c0910bfSGreg Roach            ->groupBy(['gedcom_id'])
2230c0910bfSGreg Roach            ->pluck(new Expression('COUNT(f_id)'), 'gedcom_id')
2240c0910bfSGreg Roach            ->map(static function (string $count) {
2250c0910bfSGreg Roach                return (int) $count;
2260c0910bfSGreg Roach            });
2270c0910bfSGreg Roach    }
2280c0910bfSGreg Roach
2290c0910bfSGreg Roach    /**
2300c0910bfSGreg Roach     * Count the number of sources in each tree.
2310c0910bfSGreg Roach     *
2320c0910bfSGreg Roach     * @return Collection
2330c0910bfSGreg Roach     */
2340c0910bfSGreg Roach    private function totalSources(): Collection
2350c0910bfSGreg Roach    {
2360c0910bfSGreg Roach        return DB::table('gedcom')
2370c0910bfSGreg Roach            ->leftJoin('sources', 's_file', '=', 'gedcom_id')
2380c0910bfSGreg Roach            ->groupBy(['gedcom_id'])
2390c0910bfSGreg Roach            ->pluck(new Expression('COUNT(s_id)'), 'gedcom_id')
2400c0910bfSGreg Roach            ->map(static function (string $count) {
2410c0910bfSGreg Roach                return (int) $count;
2420c0910bfSGreg Roach            });
2430c0910bfSGreg Roach    }
2440c0910bfSGreg Roach
2450c0910bfSGreg Roach    /**
2460c0910bfSGreg Roach     * Count the number of media objects in each tree.
2470c0910bfSGreg Roach     *
2480c0910bfSGreg Roach     * @return Collection
2490c0910bfSGreg Roach     */
2500c0910bfSGreg Roach    private function totalMediaObjects(): Collection
2510c0910bfSGreg Roach    {
2520c0910bfSGreg Roach        return DB::table('gedcom')
2530c0910bfSGreg Roach            ->leftJoin('media', 'm_file', '=', 'gedcom_id')
2540c0910bfSGreg Roach            ->groupBy(['gedcom_id'])
2550c0910bfSGreg Roach            ->pluck(new Expression('COUNT(m_id)'), 'gedcom_id')
2560c0910bfSGreg Roach            ->map(static function (string $count) {
2570c0910bfSGreg Roach                return (int) $count;
2580c0910bfSGreg Roach            });
2590c0910bfSGreg Roach    }
2600c0910bfSGreg Roach
2610c0910bfSGreg Roach    /**
2620c0910bfSGreg Roach     * Count the number of repositorie in each tree.
2630c0910bfSGreg Roach     *
2640c0910bfSGreg Roach     * @return Collection
2650c0910bfSGreg Roach     */
2660c0910bfSGreg Roach    private function totalRepositories(): Collection
2670c0910bfSGreg Roach    {
2680c0910bfSGreg Roach        return DB::table('gedcom')
2690c0910bfSGreg Roach            ->leftJoin('other', static function (JoinClause $join): void {
2700c0910bfSGreg Roach                $join
2710c0910bfSGreg Roach                    ->on('o_file', '=', 'gedcom_id')
2720c0910bfSGreg Roach                    ->where('o_type', '=', 'REPO');
2730c0910bfSGreg Roach            })
2740c0910bfSGreg Roach            ->groupBy(['gedcom_id'])
2750c0910bfSGreg Roach            ->pluck(new Expression('COUNT(o_id)'), 'gedcom_id')
2760c0910bfSGreg Roach            ->map(static function (string $count) {
2770c0910bfSGreg Roach                return (int) $count;
2780c0910bfSGreg Roach            });
2790c0910bfSGreg Roach    }
2800c0910bfSGreg Roach
2810c0910bfSGreg Roach    /**
2820c0910bfSGreg Roach     * Count the number of notes in each tree.
2830c0910bfSGreg Roach     *
2840c0910bfSGreg Roach     * @return Collection
2850c0910bfSGreg Roach     */
2860c0910bfSGreg Roach    private function totalNotes(): Collection
2870c0910bfSGreg Roach    {
2880c0910bfSGreg Roach        return DB::table('gedcom')
2890c0910bfSGreg Roach            ->leftJoin('other', static function (JoinClause $join): void {
2900c0910bfSGreg Roach                $join
2910c0910bfSGreg Roach                    ->on('o_file', '=', 'gedcom_id')
2920c0910bfSGreg Roach                    ->where('o_type', '=', 'NOTE');
2930c0910bfSGreg Roach            })
2940c0910bfSGreg Roach            ->groupBy(['gedcom_id'])
2950c0910bfSGreg Roach            ->pluck(new Expression('COUNT(o_id)'), 'gedcom_id')
2960c0910bfSGreg Roach            ->map(static function (string $count) {
2970c0910bfSGreg Roach                return (int) $count;
2980c0910bfSGreg Roach            });
2990c0910bfSGreg Roach    }
3000c0910bfSGreg Roach}
301