summaryrefslogtreecommitdiff
path: root/app/Http/RequestHandlers
diff options
context:
space:
mode:
authorGreg Roach <fisharebest@webtrees.net>2019-12-16 17:11:51 +0000
committerGreg Roach <fisharebest@webtrees.net>2019-12-16 17:35:39 +0000
commit8e0e1b25d26151378cec98290280e1e3dc075ff7 (patch)
tree0163a8e0ff2808df438d9e7443886e2036613ca4 /app/Http/RequestHandlers
parenta81c3e0b0cca26e3735ca8816483a596d658f157 (diff)
downloadwebtrees-8e0e1b25d26151378cec98290280e1e3dc075ff7.tar.gz
webtrees-8e0e1b25d26151378cec98290280e1e3dc075ff7.tar.bz2
webtrees-8e0e1b25d26151378cec98290280e1e3dc075ff7.zip
Convert home page controller into request handlers and a service
Diffstat (limited to 'app/Http/RequestHandlers')
-rw-r--r--app/Http/RequestHandlers/ContactAction.php2
-rw-r--r--app/Http/RequestHandlers/HomePage.php4
-rw-r--r--app/Http/RequestHandlers/LoginPage.php2
-rw-r--r--app/Http/RequestHandlers/MessageAction.php2
-rw-r--r--app/Http/RequestHandlers/PendingChanges.php2
-rw-r--r--app/Http/RequestHandlers/TreePage.php95
-rw-r--r--app/Http/RequestHandlers/TreePageBlock.php79
-rw-r--r--app/Http/RequestHandlers/TreePageBlockEdit.php78
-rw-r--r--app/Http/RequestHandlers/TreePageBlockUpdate.php70
-rw-r--r--app/Http/RequestHandlers/TreePageDefaultEdit.php83
-rw-r--r--app/Http/RequestHandlers/TreePageDefaultUpdate.php68
-rw-r--r--app/Http/RequestHandlers/TreePageEdit.php85
-rw-r--r--app/Http/RequestHandlers/TreePageUpdate.php86
-rw-r--r--app/Http/RequestHandlers/UserPage.php96
-rw-r--r--app/Http/RequestHandlers/UserPageBlock.php80
-rw-r--r--app/Http/RequestHandlers/UserPageBlockEdit.php78
-rw-r--r--app/Http/RequestHandlers/UserPageBlockUpdate.php70
-rw-r--r--app/Http/RequestHandlers/UserPageDefaultEdit.php82
-rw-r--r--app/Http/RequestHandlers/UserPageDefaultUpdate.php68
-rw-r--r--app/Http/RequestHandlers/UserPageEdit.php85
-rw-r--r--app/Http/RequestHandlers/UserPageUpdate.php86
21 files changed, 1295 insertions, 6 deletions
diff --git a/app/Http/RequestHandlers/ContactAction.php b/app/Http/RequestHandlers/ContactAction.php
index 1d69d45c57..38509c0fc0 100644
--- a/app/Http/RequestHandlers/ContactAction.php
+++ b/app/Http/RequestHandlers/ContactAction.php
@@ -126,7 +126,7 @@ class ContactAction implements RequestHandlerInterface
if ($this->message_service->deliverMessage($sender, $to_user, $subject, $body, $url, $ip)) {
FlashMessages::addMessage(I18N::translate('The message was successfully sent to %s.', e($to_user->realName())), 'success');
- $url = $url ?: route('tree-page', ['tree' => $tree->name()]);
+ $url = $url ?: route(TreePage::class, ['tree' => $tree->name()]);
return redirect($url);
}
diff --git a/app/Http/RequestHandlers/HomePage.php b/app/Http/RequestHandlers/HomePage.php
index 10f88be4bc..0eae53171b 100644
--- a/app/Http/RequestHandlers/HomePage.php
+++ b/app/Http/RequestHandlers/HomePage.php
@@ -67,11 +67,11 @@ class HomePage implements RequestHandlerInterface
if ($tree->getPreference('imported') === '1') {
// Logged in? Go to the user's page.
if ($user instanceof User) {
- return redirect(route('user-page', ['tree' => $tree->name()]));
+ return redirect(route(UserPage::class, ['tree' => $tree->name()]));
}
// Not logged in? Go to the tree's page.
- return redirect(route('tree-page', ['tree' => $tree->name()]));
+ return redirect(route(TreePage::class, ['tree' => $tree->name()]));
}
if (Auth::isManager($tree, $user)) {
diff --git a/app/Http/RequestHandlers/LoginPage.php b/app/Http/RequestHandlers/LoginPage.php
index 869760438a..132e639e35 100644
--- a/app/Http/RequestHandlers/LoginPage.php
+++ b/app/Http/RequestHandlers/LoginPage.php
@@ -58,7 +58,7 @@ class LoginPage extends AbstractBaseController
// Already logged in?
if ($user instanceof User) {
- return redirect(route('user-page', ['tree' => $tree instanceof Tree ? $tree->name() : '']));
+ return redirect(route(UserPage::class, ['tree' => $tree instanceof Tree ? $tree->name() : '']));
}
$url = $request->getQueryParams()['url'] ?? '';
diff --git a/app/Http/RequestHandlers/MessageAction.php b/app/Http/RequestHandlers/MessageAction.php
index 1eaf1df44a..6ea75fefa9 100644
--- a/app/Http/RequestHandlers/MessageAction.php
+++ b/app/Http/RequestHandlers/MessageAction.php
@@ -97,7 +97,7 @@ class MessageAction implements RequestHandlerInterface
if ($this->message_service->deliverMessage($user, $to_user, $subject, $body, $url, $ip)) {
FlashMessages::addMessage(I18N::translate('The message was successfully sent to %s.', e($to_user->realName())), 'success');
- $url = $url ?: route('tree-page', ['tree' => $tree->name()]);
+ $url = $url ?: route(TreePage::class, ['tree' => $tree->name()]);
return redirect($url);
}
diff --git a/app/Http/RequestHandlers/PendingChanges.php b/app/Http/RequestHandlers/PendingChanges.php
index 79f73c8b6b..c35e045f76 100644
--- a/app/Http/RequestHandlers/PendingChanges.php
+++ b/app/Http/RequestHandlers/PendingChanges.php
@@ -72,7 +72,7 @@ class PendingChanges implements RequestHandlerInterface
$tree = $request->getAttribute('tree');
assert($tree instanceof Tree);
- $url = $request->getQueryParams()['url'] ?? route('tree-page', ['tree' => $tree->name()]);
+ $url = $request->getQueryParams()['url'] ?? route(TreePage::class, ['tree' => $tree->name()]);
$rows = DB::table('change')
->join('user', 'user.user_id', '=', 'change.user_id')
diff --git a/app/Http/RequestHandlers/TreePage.php b/app/Http/RequestHandlers/TreePage.php
new file mode 100644
index 0000000000..c9a998fe68
--- /dev/null
+++ b/app/Http/RequestHandlers/TreePage.php
@@ -0,0 +1,95 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Http\ViewResponseTrait;
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Illuminate\Database\Capsule\Manager as DB;
+use Illuminate\Database\Query\Builder;
+use Illuminate\Database\Query\Expression;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function e;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class TreePage implements RequestHandlerInterface
+{
+ use ViewResponseTrait;
+
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Show a tree's page.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $has_blocks = DB::table('block')
+ ->where('gedcom_id', '=', $tree->id())
+ ->exists();
+
+ if (!$has_blocks) {
+ $this->home_page_service->checkDefaultTreeBlocksExist();
+
+ // Copy the defaults
+ (new Builder(DB::connection()))->from('block')->insertUsing(
+ ['gedcom_id', 'location', 'block_order', 'module_name'],
+ static function (Builder $query) use ($tree): void {
+ $query
+ ->select([new Expression($tree->id()), 'location', 'block_order', 'module_name'])
+ ->from('block')
+ ->where('gedcom_id', '=', -1);
+ }
+ );
+ }
+
+ return $this->viewResponse('tree-page', [
+ 'main_blocks' => $this->home_page_service->treeBlocks($tree->id(), ModuleBlockInterface::MAIN_BLOCKS),
+ 'side_blocks' => $this->home_page_service->treeBlocks($tree->id(), ModuleBlockInterface::SIDE_BLOCKS),
+ 'title' => e($tree->title()),
+ 'tree' => $tree,
+ 'meta_robots' => 'index,follow',
+ ]);
+ }
+}
diff --git a/app/Http/RequestHandlers/TreePageBlock.php b/app/Http/RequestHandlers/TreePageBlock.php
new file mode 100644
index 0000000000..5ce056f220
--- /dev/null
+++ b/app/Http/RequestHandlers/TreePageBlock.php
@@ -0,0 +1,79 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Illuminate\Database\Capsule\Manager as DB;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function response;
+use function view;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class TreePageBlock implements RequestHandlerInterface
+{
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Load block asynchronously.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $block_id = $request->getQueryParams()['block_id'];
+
+ $block_id = (int) DB::table('block')
+ ->where('block_id', '=', $block_id)
+ ->where('gedcom_id', '=', $tree->id())
+ ->value('block_id');
+
+ $module = $this->home_page_service->getBlockModule($tree, $block_id);
+
+ $html = view('layouts/ajax', [
+ 'content' => $module->getBlock($tree, $block_id, ModuleBlockInterface::CONTEXT_TREE_PAGE),
+ ]);
+
+ return response($html);
+ }
+}
diff --git a/app/Http/RequestHandlers/TreePageBlockEdit.php b/app/Http/RequestHandlers/TreePageBlockEdit.php
new file mode 100644
index 0000000000..72fa2d2e6e
--- /dev/null
+++ b/app/Http/RequestHandlers/TreePageBlockEdit.php
@@ -0,0 +1,78 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Http\ViewResponseTrait;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class TreePageBlockEdit implements RequestHandlerInterface
+{
+ use ViewResponseTrait;
+
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Show a form to edit block config options.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $user = $request->getAttribute('user');
+ $block_id = (int) $request->getQueryParams()['block_id'];
+ $block = $this->home_page_service->treeBlock($request, $user);
+ $title = $block->title() . ' — ' . I18N::translate('Preferences');
+
+ return $this->viewResponse('modules/edit-block-config', [
+ 'block' => $block,
+ 'block_id' => $block_id,
+ 'cancel_url' => route(TreePage::class, ['tree' => $tree->name()]),
+ 'title' => $title,
+ 'tree' => $tree,
+ ]);
+ }
+}
diff --git a/app/Http/RequestHandlers/TreePageBlockUpdate.php b/app/Http/RequestHandlers/TreePageBlockUpdate.php
new file mode 100644
index 0000000000..6a31b6c841
--- /dev/null
+++ b/app/Http/RequestHandlers/TreePageBlockUpdate.php
@@ -0,0 +1,70 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function redirect;
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class TreePageBlockUpdate implements RequestHandlerInterface
+{
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Update block config options.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $user = $request->getAttribute('user');
+ $block = $this->home_page_service->treeBlock($request, $user);
+ $block_id = (int) $request->getQueryParams()['block_id'];
+
+ $block->saveBlockConfiguration($request, $block_id);
+
+ return redirect(route(TreePage::class, ['tree' => $tree->name()]));
+ }
+}
diff --git a/app/Http/RequestHandlers/TreePageDefaultEdit.php b/app/Http/RequestHandlers/TreePageDefaultEdit.php
new file mode 100644
index 0000000000..2c28d1f69b
--- /dev/null
+++ b/app/Http/RequestHandlers/TreePageDefaultEdit.php
@@ -0,0 +1,83 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Http\ViewResponseTrait;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class TreePageDefaultEdit implements RequestHandlerInterface
+{
+ use ViewResponseTrait;
+
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Show a form to edit the default blocks for new trees.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $this->layout = 'layouts/administration';
+
+ $this->home_page_service->checkDefaultTreeBlocksExist();
+
+ $main_blocks = $this->home_page_service->treeBlocks(-1, ModuleBlockInterface::MAIN_BLOCKS);
+ $side_blocks = $this->home_page_service->treeBlocks(-1, ModuleBlockInterface::SIDE_BLOCKS);
+
+ $all_blocks = $this->home_page_service->availableTreeBlocks();
+ $title = I18N::translate('Set the default blocks for new family trees');
+ $url_cancel = route(ControlPanel::class);
+ $url_save = route(TreePageDefaultUpdate::class);
+
+ return $this->viewResponse('edit-blocks-page', [
+ 'all_blocks' => $all_blocks,
+ 'can_reset' => false,
+ 'main_blocks' => $main_blocks,
+ 'side_blocks' => $side_blocks,
+ 'title' => $title,
+ 'url_cancel' => $url_cancel,
+ 'url_save' => $url_save,
+ ]);
+ }
+}
diff --git a/app/Http/RequestHandlers/TreePageDefaultUpdate.php b/app/Http/RequestHandlers/TreePageDefaultUpdate.php
new file mode 100644
index 0000000000..ea3b9fb872
--- /dev/null
+++ b/app/Http/RequestHandlers/TreePageDefaultUpdate.php
@@ -0,0 +1,68 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Illuminate\Support\Collection;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function redirect;
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class TreePageDefaultUpdate implements RequestHandlerInterface
+{
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Save updated default blocks for new trees.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $params = (array) $request->getParsedBody();
+
+ $main_blocks = new Collection($params[ModuleBlockInterface::MAIN_BLOCKS] ?? []);
+ $side_blocks = new Collection($params[ModuleBlockInterface::SIDE_BLOCKS] ?? []);
+
+ $this->home_page_service->updateTreeBlocks(-1, $main_blocks, $side_blocks);
+
+ return redirect(route(ControlPanel::class));
+ }
+}
diff --git a/app/Http/RequestHandlers/TreePageEdit.php b/app/Http/RequestHandlers/TreePageEdit.php
new file mode 100644
index 0000000000..d0a7ce43e3
--- /dev/null
+++ b/app/Http/RequestHandlers/TreePageEdit.php
@@ -0,0 +1,85 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Http\ViewResponseTrait;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class TreePageEdit implements RequestHandlerInterface
+{
+ use ViewResponseTrait;
+
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Show a form to edit the blocks on a tree's page.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $main_blocks = $this->home_page_service->treeBlocks($tree->id(), ModuleBlockInterface::MAIN_BLOCKS);
+ $side_blocks = $this->home_page_service->treeBlocks($tree->id(), ModuleBlockInterface::SIDE_BLOCKS);
+
+ $all_blocks = $this->home_page_service->availableTreeBlocks();
+ $title = I18N::translate('Change the “Home page” blocks');
+ $url_cancel = route(TreePage::class, ['tree' => $tree->name()]);
+ $url_save = route(TreePageUpdate::class, ['tree' => $tree->name()]);
+
+ return $this->viewResponse('edit-blocks-page', [
+ 'all_blocks' => $all_blocks,
+ 'can_reset' => true,
+ 'main_blocks' => $main_blocks,
+ 'side_blocks' => $side_blocks,
+ 'title' => $title,
+ 'tree' => $tree,
+ 'url_cancel' => $url_cancel,
+ 'url_save' => $url_save,
+ ]);
+ }
+}
diff --git a/app/Http/RequestHandlers/TreePageUpdate.php b/app/Http/RequestHandlers/TreePageUpdate.php
new file mode 100644
index 0000000000..ba4b21c303
--- /dev/null
+++ b/app/Http/RequestHandlers/TreePageUpdate.php
@@ -0,0 +1,86 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Illuminate\Support\Collection;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function redirect;
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class TreePageUpdate implements RequestHandlerInterface
+{
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Save updated blocks on a tree's page.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $params = (array) $request->getParsedBody();
+
+ $defaults = (bool) ($params['defaults'] ?? false);
+
+ if ($defaults) {
+ $main_blocks = $this->home_page_service->treeBlocks(-1, ModuleBlockInterface::MAIN_BLOCKS)
+ ->map(static function (ModuleBlockInterface $block) {
+ return $block->name();
+ });
+ $side_blocks = $this->home_page_service->treeBlocks(-1, ModuleBlockInterface::SIDE_BLOCKS)
+ ->map(static function (ModuleBlockInterface $block) {
+ return $block->name();
+ });
+ } else {
+ $main_blocks = new Collection($params[ModuleBlockInterface::MAIN_BLOCKS] ?? []);
+ $side_blocks = new Collection($params[ModuleBlockInterface::SIDE_BLOCKS] ?? []);
+ }
+
+ $this->home_page_service->updateTreeBlocks($tree->id(), $main_blocks, $side_blocks);
+
+ return redirect(route(TreePage::class, ['tree' => $tree->name()]));
+ }
+}
diff --git a/app/Http/RequestHandlers/UserPage.php b/app/Http/RequestHandlers/UserPage.php
new file mode 100644
index 0000000000..0357bf53c2
--- /dev/null
+++ b/app/Http/RequestHandlers/UserPage.php
@@ -0,0 +1,96 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Http\ViewResponseTrait;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Illuminate\Database\Capsule\Manager as DB;
+use Illuminate\Database\Query\Builder;
+use Illuminate\Database\Query\Expression;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class UserPage implements RequestHandlerInterface
+{
+ use ViewResponseTrait;
+
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Show a users's page.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $user = $request->getAttribute('user');
+
+ $has_blocks = DB::table('block')
+ ->where('user_id', '=', $user->id())
+ ->exists();
+
+ if (!$has_blocks) {
+ $this->home_page_service->checkDefaultUserBlocksExist();
+
+ // Copy the defaults
+ (new Builder(DB::connection()))->from('block')->insertUsing(
+ ['user_id', 'location', 'block_order', 'module_name'],
+ static function (Builder $query) use ($user): void {
+ $query
+ ->select([new Expression($user->id()), 'location', 'block_order', 'module_name'])
+ ->from('block')
+ ->where('user_id', '=', -1);
+ }
+ );
+ }
+
+ return $this->viewResponse('user-page', [
+ 'main_blocks' => $this->home_page_service->userBlocks($user->id(), ModuleBlockInterface::MAIN_BLOCKS),
+ 'side_blocks' => $this->home_page_service->userBlocks($user->id(), ModuleBlockInterface::SIDE_BLOCKS),
+ 'title' => I18N::translate('My page'),
+ 'tree' => $tree,
+ ]);
+ }
+}
diff --git a/app/Http/RequestHandlers/UserPageBlock.php b/app/Http/RequestHandlers/UserPageBlock.php
new file mode 100644
index 0000000000..462c0137bf
--- /dev/null
+++ b/app/Http/RequestHandlers/UserPageBlock.php
@@ -0,0 +1,80 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Illuminate\Database\Capsule\Manager as DB;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function response;
+use function view;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class UserPageBlock implements RequestHandlerInterface
+{
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Load block asynchronously.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $user = $request->getAttribute('user');
+ $block_id = $request->getQueryParams()['block_id'];
+
+ $block_id = (int) DB::table('block')
+ ->where('block_id', '=', $block_id)
+ ->where('user_id', '=', $user->id())
+ ->value('block_id');
+
+ $module = $this->home_page_service->getBlockModule($tree, $block_id);
+
+ $html = view('layouts/ajax', [
+ 'content' => $module->getBlock($tree, $block_id, ModuleBlockInterface::CONTEXT_USER_PAGE),
+ ]);
+
+ return response($html);
+ }
+}
diff --git a/app/Http/RequestHandlers/UserPageBlockEdit.php b/app/Http/RequestHandlers/UserPageBlockEdit.php
new file mode 100644
index 0000000000..23337bedec
--- /dev/null
+++ b/app/Http/RequestHandlers/UserPageBlockEdit.php
@@ -0,0 +1,78 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Http\ViewResponseTrait;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class UserPageBlockEdit implements RequestHandlerInterface
+{
+ use ViewResponseTrait;
+
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Show a form to edit block config options.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $user = $request->getAttribute('user');
+ $block_id = (int) $request->getQueryParams()['block_id'];
+ $block = $this->home_page_service->userBlock($request, $user);
+ $title = $block->title() . ' — ' . I18N::translate('Preferences');
+
+ return $this->viewResponse('modules/edit-block-config', [
+ 'block' => $block,
+ 'block_id' => $block_id,
+ 'cancel_url' => route(UserPage::class, ['tree' => $tree->name()]),
+ 'title' => $title,
+ 'tree' => $tree,
+ ]);
+ }
+}
diff --git a/app/Http/RequestHandlers/UserPageBlockUpdate.php b/app/Http/RequestHandlers/UserPageBlockUpdate.php
new file mode 100644
index 0000000000..de38a309c9
--- /dev/null
+++ b/app/Http/RequestHandlers/UserPageBlockUpdate.php
@@ -0,0 +1,70 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function redirect;
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class UserPageBlockUpdate implements RequestHandlerInterface
+{
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Update block config options.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $user = $request->getAttribute('user');
+ $block = $this->home_page_service->userBlock($request, $user);
+ $block_id = (int) $request->getQueryParams()['block_id'];
+
+ $block->saveBlockConfiguration($request, $block_id);
+
+ return redirect(route(UserPage::class, ['tree' => $tree->name()]));
+ }
+}
diff --git a/app/Http/RequestHandlers/UserPageDefaultEdit.php b/app/Http/RequestHandlers/UserPageDefaultEdit.php
new file mode 100644
index 0000000000..c1e3602140
--- /dev/null
+++ b/app/Http/RequestHandlers/UserPageDefaultEdit.php
@@ -0,0 +1,82 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Http\ViewResponseTrait;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class UserPageDefaultEdit implements RequestHandlerInterface
+{
+ use ViewResponseTrait;
+
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Show a form to edit the default blocks for new uesrs.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $this->layout = 'layouts/administration';
+
+ $this->home_page_service->checkDefaultUserBlocksExist();
+
+ $main_blocks = $this->home_page_service->userBlocks(-1, ModuleBlockInterface::MAIN_BLOCKS);
+ $side_blocks = $this->home_page_service->userBlocks(-1, ModuleBlockInterface::SIDE_BLOCKS);
+ $all_blocks = $this->home_page_service->availableUserBlocks();
+ $title = I18N::translate('Set the default blocks for new users');
+ $url_cancel = route('admin-users');
+ $url_save = route(UserPageDefaultUpdate::class);
+
+ return $this->viewResponse('edit-blocks-page', [
+ 'all_blocks' => $all_blocks,
+ 'can_reset' => false,
+ 'main_blocks' => $main_blocks,
+ 'side_blocks' => $side_blocks,
+ 'title' => $title,
+ 'url_cancel' => $url_cancel,
+ 'url_save' => $url_save,
+ ]);
+ }
+}
diff --git a/app/Http/RequestHandlers/UserPageDefaultUpdate.php b/app/Http/RequestHandlers/UserPageDefaultUpdate.php
new file mode 100644
index 0000000000..37c3b449b7
--- /dev/null
+++ b/app/Http/RequestHandlers/UserPageDefaultUpdate.php
@@ -0,0 +1,68 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Illuminate\Support\Collection;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function redirect;
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class UserPageDefaultUpdate implements RequestHandlerInterface
+{
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Save the updated default blocks for new users.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $params = (array) $request->getParsedBody();
+
+ $main_blocks = new Collection($params[ModuleBlockInterface::MAIN_BLOCKS] ?? []);
+ $side_blocks = new Collection($params[ModuleBlockInterface::SIDE_BLOCKS] ?? []);
+
+ $this->home_page_service->updateUserBlocks(-1, $main_blocks, $side_blocks);
+
+ return redirect(route(ControlPanel::class));
+ }
+}
diff --git a/app/Http/RequestHandlers/UserPageEdit.php b/app/Http/RequestHandlers/UserPageEdit.php
new file mode 100644
index 0000000000..2fa8d4563e
--- /dev/null
+++ b/app/Http/RequestHandlers/UserPageEdit.php
@@ -0,0 +1,85 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Http\ViewResponseTrait;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class UserPageEdit implements RequestHandlerInterface
+{
+ use ViewResponseTrait;
+
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Show a form to edit the blocks on the user's page.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $user = $request->getAttribute('user');
+ $main_blocks = $this->home_page_service->userBlocks($user->id(), ModuleBlockInterface::MAIN_BLOCKS);
+ $side_blocks = $this->home_page_service->userBlocks($user->id(), ModuleBlockInterface::SIDE_BLOCKS);
+ $all_blocks = $this->home_page_service->availableUserBlocks();
+ $title = I18N::translate('Change the “My page” blocks');
+ $url_cancel = route(UserPage::class, ['tree' => $tree->name()]);
+ $url_save = route(UserPageUpdate::class, ['tree' => $tree->name()]);
+
+ return $this->viewResponse('edit-blocks-page', [
+ 'all_blocks' => $all_blocks,
+ 'can_reset' => true,
+ 'main_blocks' => $main_blocks,
+ 'side_blocks' => $side_blocks,
+ 'title' => $title,
+ 'tree' => $tree,
+ 'url_cancel' => $url_cancel,
+ 'url_save' => $url_save,
+ ]);
+ }
+}
diff --git a/app/Http/RequestHandlers/UserPageUpdate.php b/app/Http/RequestHandlers/UserPageUpdate.php
new file mode 100644
index 0000000000..e591801d8b
--- /dev/null
+++ b/app/Http/RequestHandlers/UserPageUpdate.php
@@ -0,0 +1,86 @@
+<?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\RequestHandlers;
+
+use Fisharebest\Webtrees\Module\ModuleBlockInterface;
+use Fisharebest\Webtrees\Services\HomePageService;
+use Fisharebest\Webtrees\Tree;
+use Illuminate\Support\Collection;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function redirect;
+use function route;
+
+/**
+ * Controller for the user/tree's home page.
+ */
+class UserPageUpdate implements RequestHandlerInterface
+{
+ /** @var HomePageService */
+ private $home_page_service;
+
+ /**
+ * HomePageController constructor.
+ *
+ * @param HomePageService $home_page_service
+ */
+ public function __construct(HomePageService $home_page_service)
+ {
+ $this->home_page_service = $home_page_service;
+ }
+
+ /**
+ * Save the updated blocks on a user's page.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $user = $request->getAttribute('user');
+ $params = (array) $request->getParsedBody();
+ $defaults = (bool) ($params['defaults'] ?? false);
+
+ if ($defaults) {
+ $main_blocks = $this->home_page_service->userBlocks(-1, ModuleBlockInterface::MAIN_BLOCKS)
+ ->map(static function (ModuleBlockInterface $block) {
+ return $block->name();
+ });
+ $side_blocks = $this->home_page_service->userBlocks(-1, ModuleBlockInterface::SIDE_BLOCKS)
+ ->map(static function (ModuleBlockInterface $block) {
+ return $block->name();
+ });
+ } else {
+ $main_blocks = new Collection($params[ModuleBlockInterface::MAIN_BLOCKS] ?? []);
+ $side_blocks = new Collection($params[ModuleBlockInterface::SIDE_BLOCKS] ?? []);
+ }
+
+ $this->home_page_service->updateUserBlocks($user->id(), $main_blocks, $side_blocks);
+
+ return redirect(route(UserPage::class, ['tree' => $tree->name()]));
+ }
+}