summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Roach <greg@subaqua.co.uk>2021-01-15 11:27:36 +0000
committerGreg Roach <greg@subaqua.co.uk>2021-01-15 12:42:56 +0000
commitddb44b4cf356ab8fd0c5d21becf3fce4c4e46244 (patch)
treea827a0a327afb5702c455010ca6297e536130a59
parent9dce578d99445e6098ac1e8cf1f38367a902bfcd (diff)
downloadwebtrees-ddb44b4cf356ab8fd0c5d21becf3fce4c4e46244.tar.gz
webtrees-ddb44b4cf356ab8fd0c5d21becf3fce4c4e46244.tar.bz2
webtrees-ddb44b4cf356ab8fd0c5d21becf3fce4c4e46244.zip
Refactor controller into request handlers
-rw-r--r--app/Http/Controllers/EditMediaController.php415
-rw-r--r--app/Http/RequestHandlers/AddMediaFileAction.php102
-rw-r--r--app/Http/RequestHandlers/AddMediaFileModal.php91
-rw-r--r--app/Http/RequestHandlers/CreateMediaObjectFromFile.php79
-rw-r--r--app/Http/RequestHandlers/EditMediaFileAction.php168
-rw-r--r--app/Http/RequestHandlers/EditMediaFileModal.php102
-rw-r--r--app/Http/RequestHandlers/LinkMediaToFamilyModal.php58
-rw-r--r--app/Http/RequestHandlers/LinkMediaToIndividualModal.php58
-rw-r--r--app/Http/RequestHandlers/LinkMediaToRecordAction.php63
-rw-r--r--app/Http/RequestHandlers/LinkMediaToSourceModal.php58
-rw-r--r--app/Http/RequestHandlers/ManageMediaData.php2
-rw-r--r--app/Http/Routes/WebRoutes.php45
-rw-r--r--phpstan-baseline.neon18
-rw-r--r--resources/views/media-page-menu.phtml14
-rw-r--r--resources/views/media-page.phtml6
-rw-r--r--resources/views/modals/add-media-file.phtml12
-rw-r--r--resources/views/modals/create-media-from-file.phtml5
-rw-r--r--resources/views/modals/edit-media-file.phtml13
-rw-r--r--resources/views/modals/link-media-to-family.phtml10
-rw-r--r--resources/views/modals/link-media-to-individual.phtml10
-rw-r--r--resources/views/modals/link-media-to-source.phtml10
21 files changed, 879 insertions, 460 deletions
diff --git a/app/Http/Controllers/EditMediaController.php b/app/Http/Controllers/EditMediaController.php
deleted file mode 100644
index dd27338240..0000000000
--- a/app/Http/Controllers/EditMediaController.php
+++ /dev/null
@@ -1,415 +0,0 @@
-<?php
-
-/**
- * webtrees: online genealogy
- * Copyright (C) 2020 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;
-
-use Exception;
-use Fig\Http\Message\StatusCodeInterface;
-use Fisharebest\Webtrees\Auth;
-use Fisharebest\Webtrees\FlashMessages;
-use Fisharebest\Webtrees\Html;
-use Fisharebest\Webtrees\Http\RequestHandlers\TreePage;
-use Fisharebest\Webtrees\I18N;
-use Fisharebest\Webtrees\MediaFile;
-use Fisharebest\Webtrees\Registry;
-use Fisharebest\Webtrees\Services\MediaFileService;
-use Fisharebest\Webtrees\Services\PendingChangesService;
-use Fisharebest\Webtrees\Tree;
-use League\Flysystem\FileExistsException;
-use League\Flysystem\FileNotFoundException;
-use League\Flysystem\Util;
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-
-use function assert;
-use function is_string;
-
-/**
- * Controller for edit forms and responses.
- */
-class EditMediaController extends AbstractBaseController
-{
- /** @var MediaFileService */
- private $media_file_service;
-
- /** @var PendingChangesService */
- private $pending_changes_service;
-
- /**
- * EditMediaController constructor.
- *
- * @param MediaFileService $media_file_service
- * @param PendingChangesService $pending_changes_service
- */
- public function __construct(MediaFileService $media_file_service, PendingChangesService $pending_changes_service)
- {
- $this->media_file_service = $media_file_service;
- $this->pending_changes_service = $pending_changes_service;
- }
-
- /**
- * Add a media file to an existing media object.
- *
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function addMediaFile(ServerRequestInterface $request): ResponseInterface
- {
- $tree = $request->getAttribute('tree');
- assert($tree instanceof Tree);
-
- $data_filesystem = Registry::filesystem()->data();
-
- $xref = $request->getQueryParams()['xref'];
- $media = Registry::mediaFactory()->make($xref, $tree);
-
- try {
- $media = Auth::checkMediaAccess($media);
- } catch (Exception $ex) {
- return response(view('modals/error', [
- 'title' => I18N::translate('Add a media file'),
- 'error' => $ex->getMessage(),
- ]));
- }
-
- return response(view('modals/add-media-file', [
- 'max_upload_size' => $this->media_file_service->maxUploadFilesize(),
- 'media' => $media,
- 'media_types' => $this->media_file_service->mediaTypes(),
- 'tree' => $tree,
- 'unused_files' => $this->media_file_service->unusedFiles($tree, $data_filesystem),
- ]));
- }
-
- /**
- * Add a media file to an existing media object.
- *
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function addMediaFileAction(ServerRequestInterface $request): ResponseInterface
- {
- $tree = $request->getAttribute('tree');
- assert($tree instanceof Tree);
-
- $xref = $request->getQueryParams()['xref'];
- $media = Registry::mediaFactory()->make($xref, $tree);
-
- $params = (array) $request->getParsedBody();
-
- $title = $params['title'];
- $type = $params['type'];
-
- if ($media === null || $media->isPendingDeletion() || !$media->canEdit()) {
- return redirect(route(TreePage::class, ['tree' => $tree->name()]));
- }
-
- $file = $this->media_file_service->uploadFile($request);
-
- if ($file === '') {
- FlashMessages::addMessage(I18N::translate('There was an error uploading your file.'));
-
- return redirect($media->url());
- }
-
- $gedcom = $this->media_file_service->createMediaFileGedcom($file, $type, $title, '');
-
- $media->createFact($gedcom, true);
-
- // Accept the changes, to keep the filesystem in sync with the GEDCOM data.
- $this->pending_changes_service->acceptRecord($media);
-
- return redirect($media->url());
- }
-
- /**
- * Edit an existing media file.
- *
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function editMediaFile(ServerRequestInterface $request): ResponseInterface
- {
- $tree = $request->getAttribute('tree');
- assert($tree instanceof Tree);
-
- $data_filesystem = Registry::filesystem()->data();
-
- $params = $request->getQueryParams();
- $xref = $params['xref'];
- $fact_id = $params['fact_id'];
- $media = Registry::mediaFactory()->make($xref, $tree);
-
- try {
- $media = Auth::checkMediaAccess($media);
- } catch (Exception $ex) {
- return response(view('modals/error', [
- 'title' => I18N::translate('Edit a media file'),
- 'error' => $ex->getMessage(),
- ]), StatusCodeInterface::STATUS_FORBIDDEN);
- }
-
- foreach ($media->mediaFiles() as $media_file) {
- if ($media_file->factId() === $fact_id) {
- return response(view('modals/edit-media-file', [
- 'media_file' => $media_file,
- 'max_upload_size' => $this->media_file_service->maxUploadFilesize(),
- 'media' => $media,
- 'media_types' => $this->media_file_service->mediaTypes(),
- 'unused_files' => $this->media_file_service->unusedFiles($tree, $data_filesystem),
- 'tree' => $tree,
- ]));
- }
- }
-
- return response('', StatusCodeInterface::STATUS_NOT_FOUND);
- }
-
- /**
- * Save an edited media file.
- *
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function editMediaFileAction(ServerRequestInterface $request): ResponseInterface
- {
- $tree = $request->getAttribute('tree');
- assert($tree instanceof Tree);
-
- $data_filesystem = Registry::filesystem()->data();
-
- $xref = $request->getQueryParams()['xref'];
- $fact_id = $request->getQueryParams()['fact_id'];
-
- $params = (array) $request->getParsedBody();
-
- $folder = $params['folder'];
- $new_file = $params['new_file'];
- $remote = $params['remote'];
- $title = $params['title'];
- $type = $params['type'];
- $media = Registry::mediaFactory()->make($xref, $tree);
-
- // Tidy non-printing characters
- $type = trim(preg_replace('/\s+/', ' ', $type));
- $title = trim(preg_replace('/\s+/', ' ', $title));
-
- // Media object oes not exist? Media object is read-only?
- if ($media === null || $media->isPendingDeletion() || !$media->canEdit()) {
- return redirect(route(TreePage::class, ['tree' => $tree->name()]));
- }
-
- // Find the fact to edit
- $media_file = $media->mediaFiles()
- ->first(static function (MediaFile $media_file) use ($fact_id): bool {
- return $media_file->factId() === $fact_id;
- });
-
- // Media file does not exist?
- if ($media_file === null) {
- return redirect(route(TreePage::class, ['tree' => $tree->name()]));
- }
-
- // We can edit the file as either a URL or a folder/file
- if ($remote !== '') {
- $file = $remote;
- } else {
- $new_file = str_replace('\\', '/', $new_file);
- $folder = str_replace('\\', '/', $folder);
- $folder = trim($folder, '/');
-
- if ($folder === '') {
- $file = $new_file;
- } else {
- $file = $folder . '/' . $new_file;
- }
- }
-
- // Invalid filename? Do not change it.
- if ($new_file === '') {
- $file = $media_file->filename();
- }
-
- $filesystem = $media->tree()->mediaFilesystem($data_filesystem);
- $old = $media_file->filename();
- $new = $file;
-
- // Update the filesystem, if we can.
- if ($old !== $new && !$media_file->isExternal()) {
- try {
- $new = Util::normalizePath($new);
- $filesystem->rename($old, $new);
- FlashMessages::addMessage(I18N::translate('The media file %1$s has been renamed to %2$s.', Html::filename($media_file->filename()), Html::filename($file)), 'info');
- } catch (FileNotFoundException $ex) {
- // The "old" file may not exist. For example, if the file was renamed on disk,
- // and we are now renaming the GEDCOM data to match.
- } catch (FileExistsException $ex) {
- // Don't overwrite existing file
- FlashMessages::addMessage(I18N::translate('The media file %1$s could not be renamed to %2$s.', Html::filename($media_file->filename()), Html::filename($file)), 'info');
- $file = $old;
- }
- }
-
- $gedcom = $this->media_file_service->createMediaFileGedcom($file, $type, $title, '');
-
- $media->updateFact($fact_id, $gedcom, true);
-
- // Accept the changes, to keep the filesystem in sync with the GEDCOM data.
- if ($old !== $new && !$media_file->isExternal()) {
- $this->pending_changes_service->acceptRecord($media);
- }
-
- return redirect($media->url());
- }
-
- /**
- * Show a form to create a new media object.
- *
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function createMediaObject(ServerRequestInterface $request): ResponseInterface
- {
- $tree = $request->getAttribute('tree');
- assert($tree instanceof Tree);
-
- $data_filesystem = Registry::filesystem()->data();
-
- return response(view('modals/create-media-object', [
- 'max_upload_size' => $this->media_file_service->maxUploadFilesize(),
- 'media_types' => $this->media_file_service->mediaTypes(),
- 'unused_files' => $this->media_file_service->unusedFiles($tree, $data_filesystem),
- ]));
- }
-
- /**
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function createMediaObjectFromFileAction(ServerRequestInterface $request): ResponseInterface
- {
- $tree = $request->getAttribute('tree');
- assert($tree instanceof Tree);
-
- $params = (array) $request->getParsedBody();
- $file = $params['file'];
- $type = $params['type'];
- $title = $params['title'];
- $note = $params['note'];
-
- $gedcom = "0 @@ OBJE\n" . $this->media_file_service->createMediaFileGedcom($file, $type, $title, $note);
-
- $media_object = $tree->createRecord($gedcom);
-
- // Accept the new record. Rejecting it would leave the filesystem out-of-sync with the genealogy
- $this->pending_changes_service->acceptRecord($media_object);
-
- return redirect($media_object->url());
- }
-
- /**
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function linkMediaToIndividual(ServerRequestInterface $request): ResponseInterface
- {
- $tree = $request->getAttribute('tree');
- assert($tree instanceof Tree);
-
- $xref = $request->getQueryParams()['xref'];
- $media = Registry::mediaFactory()->make($xref, $tree);
-
- return response(view('modals/link-media-to-individual', [
- 'media' => $media,
- 'tree' => $tree,
- ]));
- }
-
- /**
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function linkMediaToFamily(ServerRequestInterface $request): ResponseInterface
- {
- $tree = $request->getAttribute('tree');
- assert($tree instanceof Tree);
-
- $xref = $request->getQueryParams()['xref'];
-
- $media = Registry::mediaFactory()->make($xref, $tree);
-
- return response(view('modals/link-media-to-family', [
- 'media' => $media,
- 'tree' => $tree,
- ]));
- }
-
- /**
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function linkMediaToSource(ServerRequestInterface $request): ResponseInterface
- {
- $tree = $request->getAttribute('tree');
- assert($tree instanceof Tree);
-
- $xref = $request->getQueryParams()['xref'];
-
- $media = Registry::mediaFactory()->make($xref, $tree);
-
- return response(view('modals/link-media-to-source', [
- 'media' => $media,
- 'tree' => $tree,
- ]));
- }
-
- /**
- * @param ServerRequestInterface $request
- *
- * @return ResponseInterface
- */
- public function linkMediaToRecordAction(ServerRequestInterface $request): ResponseInterface
- {
- $tree = $request->getAttribute('tree');
- assert($tree instanceof Tree);
-
- $xref = $request->getAttribute('xref');
- assert(is_string($xref));
-
- $params = (array) $request->getParsedBody();
-
- $link = $params['link'];
-
- $media = Registry::mediaFactory()->make($xref, $tree);
- $record = Registry::gedcomRecordFactory()->make($link, $tree);
-
- $record->createFact('1 OBJE @' . $xref . '@', true);
-
- return redirect($media->url());
- }
-}
diff --git a/app/Http/RequestHandlers/AddMediaFileAction.php b/app/Http/RequestHandlers/AddMediaFileAction.php
new file mode 100644
index 0000000000..5415f8e875
--- /dev/null
+++ b/app/Http/RequestHandlers/AddMediaFileAction.php
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 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\FlashMessages;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Services\MediaFileService;
+use Fisharebest\Webtrees\Services\PendingChangesService;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function is_string;
+use function redirect;
+use function route;
+
+/**
+ * Add a new media file to a media object.
+ */
+class AddMediaFileAction implements RequestHandlerInterface
+{
+ /** @var MediaFileService */
+ private $media_file_service;
+
+ /** @var PendingChangesService */
+ private $pending_changes_service;
+
+ /**
+ * AddMediaFileAction constructor.
+ *
+ * @param MediaFileService $media_file_service
+ * @param PendingChangesService $pending_changes_service
+ */
+ public function __construct(MediaFileService $media_file_service, PendingChangesService $pending_changes_service)
+ {
+ $this->media_file_service = $media_file_service;
+ $this->pending_changes_service = $pending_changes_service;
+ }
+
+ /**
+ * Add a media file to an existing media object.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $xref = $request->getAttribute('xref');
+ assert(is_string($xref));
+
+ $media = Registry::mediaFactory()->make($xref, $tree);
+
+ $params = (array) $request->getParsedBody();
+ $title = $params['title'] ?? '';
+ $type = $params['type'] ?? '';
+
+ if ($media === null || $media->isPendingDeletion() || !$media->canEdit()) {
+ return redirect(route(TreePage::class, ['tree' => $tree->name()]));
+ }
+
+ $file = $this->media_file_service->uploadFile($request);
+
+ if ($file === '') {
+ FlashMessages::addMessage(I18N::translate('There was an error uploading your file.'));
+
+ return redirect($media->url());
+ }
+
+ $gedcom = $this->media_file_service->createMediaFileGedcom($file, $type, $title, '');
+
+ $media->createFact($gedcom, true);
+
+ // Accept the changes, to keep the filesystem in sync with the GEDCOM data.
+ $this->pending_changes_service->acceptRecord($media);
+
+ return redirect($media->url());
+ }
+}
diff --git a/app/Http/RequestHandlers/AddMediaFileModal.php b/app/Http/RequestHandlers/AddMediaFileModal.php
new file mode 100644
index 0000000000..c1f27bad5d
--- /dev/null
+++ b/app/Http/RequestHandlers/AddMediaFileModal.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 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 Exception;
+use Fisharebest\Webtrees\Auth;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Services\MediaFileService;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function is_string;
+use function response;
+use function view;
+
+/**
+ * dd a new media file to a media object.
+ */
+class AddMediaFileModal implements RequestHandlerInterface
+{
+ /** @var MediaFileService */
+ private $media_file_service;
+
+ /**
+ * AddMediaFileModal constructor.
+ *
+ * @param MediaFileService $media_file_service
+ */
+ public function __construct(MediaFileService $media_file_service)
+ {
+ $this->media_file_service = $media_file_service;
+ }
+
+ /**
+ * Add a media file to an existing media object.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $xref = $request->getAttribute('xref');
+ assert(is_string($xref));
+
+ $data_filesystem = Registry::filesystem()->data();
+
+ $media = Registry::mediaFactory()->make($xref, $tree);
+
+ try {
+ $media = Auth::checkMediaAccess($media);
+ } catch (Exception $ex) {
+ return response(view('modals/error', [
+ 'title' => I18N::translate('Add a media file'),
+ 'error' => $ex->getMessage(),
+ ]));
+ }
+
+ return response(view('modals/add-media-file', [
+ 'max_upload_size' => $this->media_file_service->maxUploadFilesize(),
+ 'media' => $media,
+ 'media_types' => $this->media_file_service->mediaTypes(),
+ 'tree' => $tree,
+ 'unused_files' => $this->media_file_service->unusedFiles($tree, $data_filesystem),
+ ]));
+ }
+}
diff --git a/app/Http/RequestHandlers/CreateMediaObjectFromFile.php b/app/Http/RequestHandlers/CreateMediaObjectFromFile.php
new file mode 100644
index 0000000000..46481a3a89
--- /dev/null
+++ b/app/Http/RequestHandlers/CreateMediaObjectFromFile.php
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 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\MediaFileService;
+use Fisharebest\Webtrees\Services\PendingChangesService;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+
+/**
+ * Create a new media object.
+ */
+class CreateMediaObjectFromFile implements RequestHandlerInterface
+{
+ /** @var MediaFileService */
+ private $media_file_service;
+
+ /** @var PendingChangesService */
+ private $pending_changes_service;
+
+ /**
+ * CreateMediaObjectFromFileAction constructor.
+ *
+ * @param MediaFileService $media_file_service
+ * @param PendingChangesService $pending_changes_service
+ */
+ public function __construct(MediaFileService $media_file_service, PendingChangesService $pending_changes_service)
+ {
+ $this->media_file_service = $media_file_service;
+ $this->pending_changes_service = $pending_changes_service;
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $params = (array) $request->getParsedBody();
+ $file = $params['file'] ?? '';
+ $type = $params['type'] ?? '';
+ $title = $params['title'] ?? '';
+ $note = $params['note'] ?? '';
+
+ $gedcom = "0 @@ OBJE\n" . $this->media_file_service->createMediaFileGedcom($file, $type, $title, $note);
+
+ $media_object = $tree->createRecord($gedcom);
+
+ // Accept the new record. Rejecting it would leave the filesystem out-of-sync with the genealogy
+ $this->pending_changes_service->acceptRecord($media_object);
+
+ return redirect($media_object->url());
+ }
+}
diff --git a/app/Http/RequestHandlers/EditMediaFileAction.php b/app/Http/RequestHandlers/EditMediaFileAction.php
new file mode 100644
index 0000000000..d2ff66476e
--- /dev/null
+++ b/app/Http/RequestHandlers/EditMediaFileAction.php
@@ -0,0 +1,168 @@
+<?php
+
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 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 Exception;
+use Fisharebest\Webtrees\FlashMessages;
+use Fisharebest\Webtrees\Html;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\MediaFile;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Services\MediaFileService;
+use Fisharebest\Webtrees\Services\PendingChangesService;
+use Fisharebest\Webtrees\Tree;
+use League\Flysystem\FileExistsException;
+use League\Flysystem\FileNotFoundException;
+use League\Flysystem\Util;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function is_string;
+use function preg_replace;
+use function redirect;
+use function route;
+use function str_replace;
+use function trim;
+
+/**
+ * Edit a media file.
+ */
+class EditMediaFileAction implements RequestHandlerInterface
+{
+ /** @var MediaFileService */
+ private $media_file_service;
+
+ /** @var PendingChangesService */
+ private $pending_changes_service;
+
+ /**
+ * EditMediaFileAction constructor.
+ *
+ * @param MediaFileService $media_file_service
+ * @param PendingChangesService $pending_changes_service
+ */
+ public function __construct(MediaFileService $media_file_service, PendingChangesService $pending_changes_service)
+ {
+ $this->media_file_service = $media_file_service;
+ $this->pending_changes_service = $pending_changes_service;
+ }
+
+ /**
+ * Save an edited media file.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $xref = $request->getAttribute('xref');
+ assert(is_string($xref));
+
+ $fact_id = $request->getAttribute('fact_id');
+ assert(is_string($fact_id));
+
+ $data_filesystem = Registry::filesystem()->data();
+
+ $params = (array) $request->getParsedBody();
+ $folder = $params['folder'] ?? '';
+ $new_file = $params['new_file'] ?? '';
+ $remote = $params['remote'] ?? '';
+ $title = $params['title'] ?? '';
+ $type = $params['type'] ?? '';
+ $media = Registry::mediaFactory()->make($xref, $tree);
+
+ // Tidy non-printing characters
+ $type = trim(preg_replace('/\s+/', ' ', $type));
+ $title = trim(preg_replace('/\s+/', ' ', $title));
+
+ // Media object oes not exist? Media object is read-only?
+ if ($media === null || $media->isPendingDeletion() || !$media->canEdit()) {
+ return redirect(route(TreePage::class, ['tree' => $tree->name()]));
+ }
+
+ // Find the fact to edit
+ $media_file = $media->mediaFiles()
+ ->first(static function (MediaFile $media_file) use ($fact_id): bool {
+ return $media_file->factId() === $fact_id;
+ });
+
+ // Media file does not exist?
+ if ($media_file === null) {
+ return redirect(route(TreePage::class, ['tree' => $tree->name()]));
+ }
+
+ // We can edit the file as either a URL or a folder/file
+ if ($remote !== '') {
+ $file = $remote;
+ } else {
+ $new_file = str_replace('\\', '/', $new_file);
+ $folder = str_replace('\\', '/', $folder);
+ $folder = trim($folder, '/');
+
+ if ($folder === '') {
+ $file = $new_file;
+ } else {
+ $file = $folder . '/' . $new_file;
+ }
+ }
+
+ // Invalid filename? Do not change it.
+ if ($new_file === '') {
+ $file = $media_file->filename();
+ }
+
+ $filesystem = $media->tree()->mediaFilesystem($data_filesystem);
+ $old = $media_file->filename();
+ $new = $file;
+
+ // Update the filesystem, if we can.
+ if ($old !== $new && !$media_file->isExternal()) {
+ try {
+ $new = Util::normalizePath($new);
+ $filesystem->rename($old, $new);
+ FlashMessages::addMessage(I18N::translate('The media file %1$s has been renamed to %2$s.', Html::filename($media_file->filename()), Html::filename($file)), 'info');
+ } catch (FileNotFoundException $ex) {
+ // The "old" file may not exist. For example, if the file was renamed on disk,
+ // and we are now renaming the GEDCOM data to match.
+ } catch (FileExistsException $ex) {
+ // Don't overwrite existing file
+ FlashMessages::addMessage(I18N::translate('The media file %1$s could not be renamed to %2$s.', Html::filename($media_file->filename()), Html::filename($file)), 'info');
+ $file = $old;
+ }
+ }
+
+ $gedcom = $this->media_file_service->createMediaFileGedcom($file, $type, $title, '');
+
+ $media->updateFact($fact_id, $gedcom, true);
+
+ // Accept the changes, to keep the filesystem in sync with the GEDCOM data.
+ if ($old !== $new && !$media_file->isExternal()) {
+ $this->pending_changes_service->acceptRecord($media);
+ }
+
+ return redirect($media->url());
+ }
+}
diff --git a/app/Http/RequestHandlers/EditMediaFileModal.php b/app/Http/RequestHandlers/EditMediaFileModal.php
new file mode 100644
index 0000000000..5691438dbb
--- /dev/null
+++ b/app/Http/RequestHandlers/EditMediaFileModal.php
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 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 Exception;
+use Fig\Http\Message\StatusCodeInterface;
+use Fisharebest\Webtrees\Auth;
+use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Services\MediaFileService;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function is_string;
+use function response;
+use function view;
+
+/**
+ * Edit a media file.
+ */
+class EditMediaFileModal implements RequestHandlerInterface
+{
+ /** @var MediaFileService */
+ private $media_file_service;
+
+ /**
+ * EditMediaFileModal constructor.
+ *
+ * @param MediaFileService $media_file_service
+ */
+ public function __construct(MediaFileService $media_file_service)
+ {
+ $this->media_file_service = $media_file_service;
+ }
+
+ /**
+ * Edit an existing media file.
+ *
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $xref = $request->getAttribute('xref');
+ assert(is_string($xref));
+
+ $fact_id = $request->getAttribute('fact_id');
+ assert(is_string($fact_id));
+
+ $data_filesystem = Registry::filesystem()->data();
+
+ $media = Registry::mediaFactory()->make($xref, $tree);
+
+ try {
+ $media = Auth::checkMediaAccess($media);
+ } catch (Exception $ex) {
+ return response(view('modals/error', [
+ 'title' => I18N::translate('Edit a media file'),
+ 'error' => $ex->getMessage(),
+ ]), StatusCodeInterface::STATUS_FORBIDDEN);
+ }
+
+ foreach ($media->mediaFiles() as $media_file) {
+ if ($media_file->factId() === $fact_id) {
+ return response(view('modals/edit-media-file', [
+ 'media_file' => $media_file,
+ 'max_upload_size' => $this->media_file_service->maxUploadFilesize(),
+ 'media' => $media,
+ 'media_types' => $this->media_file_service->mediaTypes(),
+ 'unused_files' => $this->media_file_service->unusedFiles($tree, $data_filesystem),
+ 'tree' => $tree,
+ ]));
+ }
+ }
+
+ return response('', StatusCodeInterface::STATUS_NOT_FOUND);
+ }
+}
diff --git a/app/Http/RequestHandlers/LinkMediaToFamilyModal.php b/app/Http/RequestHandlers/LinkMediaToFamilyModal.php
new file mode 100644
index 0000000000..dcd1c012b9
--- /dev/null
+++ b/app/Http/RequestHandlers/LinkMediaToFamilyModal.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 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\Auth;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function is_string;
+
+/**
+ * Link a media object to a record.
+ */
+class LinkMediaToFamilyModal implements RequestHandlerInterface
+{
+ /**
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $xref = $request->getAttribute('xref');
+ assert(is_string($xref));
+
+ $media = Registry::mediaFactory()->make($xref, $tree);
+ $media = Auth::checkMediaAccess($media);
+
+ return response(view('modals/link-media-to-family', [
+ 'media' => $media,
+ 'tree' => $tree,
+ ]));
+ }
+}
diff --git a/app/Http/RequestHandlers/LinkMediaToIndividualModal.php b/app/Http/RequestHandlers/LinkMediaToIndividualModal.php
new file mode 100644
index 0000000000..a8978f9ba4
--- /dev/null
+++ b/app/Http/RequestHandlers/LinkMediaToIndividualModal.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 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\Auth;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function is_string;
+
+/**
+ * Link a media object to a record.
+ */
+class LinkMediaToIndividualModal implements RequestHandlerInterface
+{
+ /**
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $xref = $request->getAttribute('xref');
+ assert(is_string($xref));
+
+ $media = Registry::mediaFactory()->make($xref, $tree);
+ $media = Auth::checkMediaAccess($media);
+
+ return response(view('modals/link-media-to-individual', [
+ 'media' => $media,
+ 'tree' => $tree,
+ ]));
+ }
+}
diff --git a/app/Http/RequestHandlers/LinkMediaToRecordAction.php b/app/Http/RequestHandlers/LinkMediaToRecordAction.php
new file mode 100644
index 0000000000..86289806c0
--- /dev/null
+++ b/app/Http/RequestHandlers/LinkMediaToRecordAction.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 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\Auth;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function is_string;
+
+/**
+ * Link a media object to a record.
+ */
+class LinkMediaToRecordAction implements RequestHandlerInterface
+{
+ /**
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $xref = $request->getAttribute('xref');
+ assert(is_string($xref));
+
+ $params = (array) $request->getParsedBody();
+ $link = $params['link'] ?? '';
+
+ $media = Registry::mediaFactory()->make($xref, $tree);
+ $media = Auth::checkMediaAccess($media);
+
+ $record = Registry::gedcomRecordFactory()->make($link, $tree);
+ $record = Auth::checkRecordAccess($record, true);
+
+ $record->createFact('1 OBJE @' . $xref . '@', true);
+
+ return redirect($media->url());
+ }
+}
diff --git a/app/Http/RequestHandlers/LinkMediaToSourceModal.php b/app/Http/RequestHandlers/LinkMediaToSourceModal.php
new file mode 100644
index 0000000000..9d9a0821b1
--- /dev/null
+++ b/app/Http/RequestHandlers/LinkMediaToSourceModal.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 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\Auth;
+use Fisharebest\Webtrees\Registry;
+use Fisharebest\Webtrees\Tree;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+use function assert;
+use function is_string;
+
+/**
+ * Link a media object to a record.
+ */
+class LinkMediaToSourceModal implements RequestHandlerInterface
+{
+ /**
+ * @param ServerRequestInterface $request
+ *
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $tree = $request->getAttribute('tree');
+ assert($tree instanceof Tree);
+
+ $xref = $request->getAttribute('xref');
+ assert(is_string($xref));
+
+ $media = Registry::mediaFactory()->make($xref, $tree);
+ $media = Auth::checkMediaAccess($media);
+
+ return response(view('modals/link-media-to-source', [
+ 'media' => $media,
+ 'tree' => $tree,
+ ]));
+ }
+}
diff --git a/app/Http/RequestHandlers/ManageMediaData.php b/app/Http/RequestHandlers/ManageMediaData.php
index 1c9f62a162..265af721fd 100644
--- a/app/Http/RequestHandlers/ManageMediaData.php
+++ b/app/Http/RequestHandlers/ManageMediaData.php
@@ -224,7 +224,7 @@ class ManageMediaData implements RequestHandlerInterface
if (str_starts_with($row[0], $media_directory)) {
$tmp = substr($row[0], strlen($media_directory));
$create_form .=
- '<p><a href="#" data-toggle="modal" data-backdrop="static" data-target="#modal-create-media-from-file" data-file="' . e($tmp) . '" data-url="' . e(route('create-media-from-file', ['tree' => $media_tree])) . '" onclick="document.getElementById(\'modal-create-media-from-file-form\').action=this.dataset.url; document.getElementById(\'file\').value=this.dataset.file;">' . I18N::translate('Create') . '</a> — ' . e($media_tree) . '<p>';
+ '<p><a href="#" data-toggle="modal" data-backdrop="static" data-target="#modal-create-media-from-file" data-file="' . e($tmp) . '" data-url="' . e(route(CreateMediaObjectFromFile::class, ['tree' => $media_tree])) . '" onclick="document.getElementById(\'modal-create-media-from-file-form\').action=this.dataset.url; document.getElementById(\'file\').value=this.dataset.file;">' . I18N::translate('Create') . '</a> — ' . e($media_tree) . '<p>';
}
}
diff --git a/app/Http/Routes/WebRoutes.php b/app/Http/Routes/WebRoutes.php
index 3433579884..17d2ac5b65 100644
--- a/app/Http/Routes/WebRoutes.php
+++ b/app/Http/Routes/WebRoutes.php
@@ -33,6 +33,8 @@ use Fisharebest\Webtrees\Http\RequestHandlers\AddChildToFamilyAction;
use Fisharebest\Webtrees\Http\RequestHandlers\AddChildToFamilyPage;
use Fisharebest\Webtrees\Http\RequestHandlers\AddChildToIndividualAction;
use Fisharebest\Webtrees\Http\RequestHandlers\AddChildToIndividualPage;
+use Fisharebest\Webtrees\Http\RequestHandlers\AddMediaFileAction;
+use Fisharebest\Webtrees\Http\RequestHandlers\AddMediaFileModal;
use Fisharebest\Webtrees\Http\RequestHandlers\AddName;
use Fisharebest\Webtrees\Http\RequestHandlers\AddNewFact;
use Fisharebest\Webtrees\Http\RequestHandlers\AddParentToIndividualAction;
@@ -64,6 +66,7 @@ use Fisharebest\Webtrees\Http\RequestHandlers\ContactPage;
use Fisharebest\Webtrees\Http\RequestHandlers\ControlPanel;
use Fisharebest\Webtrees\Http\RequestHandlers\CopyFact;
use Fisharebest\Webtrees\Http\RequestHandlers\CreateMediaObjectAction;
+use Fisharebest\Webtrees\Http\RequestHandlers\CreateMediaObjectFromFile;
use Fisharebest\Webtrees\Http\RequestHandlers\CreateMediaObjectModal;
use Fisharebest\Webtrees\Http\RequestHandlers\CreateNoteAction;
use Fisharebest\Webtrees\Http\RequestHandlers\CreateNoteModal;
@@ -89,6 +92,8 @@ use Fisharebest\Webtrees\Http\RequestHandlers\DeleteTreeAction;
use Fisharebest\Webtrees\Http\RequestHandlers\DeleteUser;
use Fisharebest\Webtrees\Http\RequestHandlers\EditFactAction;
use Fisharebest\Webtrees\Http\RequestHandlers\EditFactPage;
+use Fisharebest\Webtrees\Http\RequestHandlers\EditMediaFileAction;
+use Fisharebest\Webtrees\Http\RequestHandlers\EditMediaFileModal;
use Fisharebest\Webtrees\Http\RequestHandlers\EditName;
use Fisharebest\Webtrees\Http\RequestHandlers\EditNoteAction;
use Fisharebest\Webtrees\Http\RequestHandlers\EditNotePage;
@@ -114,6 +119,10 @@ use Fisharebest\Webtrees\Http\RequestHandlers\ImportGedcomPage;
use Fisharebest\Webtrees\Http\RequestHandlers\IndividualPage;
use Fisharebest\Webtrees\Http\RequestHandlers\LinkChildToFamilyAction;
use Fisharebest\Webtrees\Http\RequestHandlers\LinkChildToFamilyPage;
+use Fisharebest\Webtrees\Http\RequestHandlers\LinkMediaToFamilyModal;
+use Fisharebest\Webtrees\Http\RequestHandlers\LinkMediaToIndividualModal;
+use Fisharebest\Webtrees\Http\RequestHandlers\LinkMediaToRecordAction;
+use Fisharebest\Webtrees\Http\RequestHandlers\LinkMediaToSourceModal;
use Fisharebest\Webtrees\Http\RequestHandlers\LinkSpouseToIndividualAction;
use Fisharebest\Webtrees\Http\RequestHandlers\LinkSpouseToIndividualPage;
use Fisharebest\Webtrees\Http\RequestHandlers\LoginAction;
@@ -301,11 +310,11 @@ class WebRoutes
$router->post(SiteLogsDelete::class, '/logs-delete');
$router->get(SiteLogsDownload::class, '/logs-download');
$router->post(Masquerade::class, '/masquerade/{user_id}');
- $router->get(ManageMediaPage::class, '/media', ManageMediaPage::class);
- $router->post(ManageMediaAction::class, '/media', ManageMediaAction::class);
- $router->get(ManageMediaData::class, '/media-data', ManageMediaData::class);
- $router->get(UploadMediaPage::class, '/media-upload', UploadMediaPage::class);
- $router->post(UploadMediaAction::class, '/media-upload', UploadMediaAction::class);
+ $router->get(ManageMediaPage::class, '/media');
+ $router->post(ManageMediaAction::class, '/media');
+ $router->get(ManageMediaData::class, '/media-data');
+ $router->get(UploadMediaPage::class, '/media-upload');
+ $router->post(UploadMediaAction::class, '/media-upload');
$router->get(AdminMediaFileDownload::class, '/media-file');
$router->get(AdminMediaFileThumbnail::class, '/media-thumbnail');
$router->get(CreateTreePage::class, '/trees/create');
@@ -327,8 +336,8 @@ class WebRoutes
$router->get('locations-export', '/locations-export', 'Admin\LocationController::exportLocations');
$router->get('locations-import', '/locations-import', 'Admin\LocationController::importLocations');
$router->post('locations-import-action', '/locations-import', 'Admin\LocationController::importLocationsAction');
- $router->get(MapProviderPage::class, '/map-provider', MapProviderPage::class);
- $router->post(MapProviderAction::class, '/map-provider', MapProviderAction::class);
+ $router->get(MapProviderPage::class, '/map-provider');
+ $router->post(MapProviderAction::class, '/map-provider');
$router->post(ModuleDeleteSettings::class, '/module-delete-settings');
$router->get(ModulesAllPage::class, '/modules');
$router->post(ModulesAllAction::class, '/modules');
@@ -473,8 +482,8 @@ class WebRoutes
$router->post(AddChildToFamilyAction::class, '/add-child-to-family');
$router->get(AddNewFact::class, '/add-fact/{xref}/{fact}');
$router->post(SelectNewFact::class, '/add-fact/{xref}');
- $router->get('add-media-file', '/add-media-file', 'EditMediaController::addMediaFile');
- $router->post('add-media-file-update', '/add-media-file', 'EditMediaController::addMediaFileAction');
+ $router->get(AddMediaFileModal::class, '/add-media-file/{xref}');
+ $router->post(AddMediaFileAction::class, '/add-media-file/{xref}');
$router->get(AddName::class, '/add-name');
$router->get(AddSpouseToFamilyPage::class, '/add-spouse-to-family');
$router->post(AddSpouseToFamilyAction::class, '/add-spouse-to-family');
@@ -482,7 +491,7 @@ class WebRoutes
$router->post(ChangeFamilyMembersAction::class, '/change-family-members');
$router->get(CreateMediaObjectModal::class, '/create-media-object');
$router->post(CreateMediaObjectAction::class, '/create-media-object');
- $router->post('create-media-from-file', '/create-media-from-file', 'EditMediaController::createMediaObjectFromFileAction');
+ $router->post(CreateMediaObjectFromFile::class, '/create-media-from-file');
$router->post(CopyFact::class, '/copy/{xref}/{fact_id}');
$router->get(CreateNoteModal::class, '/create-note-object');
$router->post(CreateNoteAction::class, '/create-note-object');
@@ -496,18 +505,18 @@ class WebRoutes
$router->post(DeleteFact::class, '/delete/{xref}/{fact_id}');
$router->get(EditFactPage::class, '/edit-fact/{xref}/{fact_id}');
$router->post(EditFactAction::class, '/update-fact/{xref}{/fact_id}');
- $router->get('edit-media-file', '/edit-media-file', 'EditMediaController::editMediaFile');
- $router->post('edit-media-file-update', '/edit-media-file', 'EditMediaController::editMediaFileAction');
- $router->get(EditNotePage::class, '/edit-note-object/{xref}', EditNotePage::class);
- $router->post(EditNoteAction::class, '/edit-note-object/{xref}', EditNoteAction::class);
+ $router->get(EditMediaFileModal::class, '/edit-media-file/{xref}/{fact_id}');
+ $router->post(EditMediaFileAction::class, '/edit-media-file/{xref}/{fact_id}');
+ $router->get(EditNotePage::class, '/edit-note-object/{xref}');
+ $router->post(EditNoteAction::class, '/edit-note-object/{xref}');
$router->get(EditRawFactPage::class, '/edit-raw/{xref}/{fact_id}');
$router->post(EditRawFactAction::class, '/edit-raw/{xref}/{fact_id}');
$router->get(EditRawRecordPage::class, '/edit-raw/{xref}');
$router->post(EditRawRecordAction::class, '/edit-raw/{xref}');
- $router->get('link-media-to-individual', '/link-media-to-individual', 'EditMediaController::linkMediaToIndividual');
- $router->get('link-media-to-family', '/link-media-to-family', 'EditMediaController::linkMediaToFamily');
- $router->get('link-media-to-source', '/link-media-to-source', 'EditMediaController::linkMediaToSource');
- $router->post('link-media-to-record', '/link-media-to-record/{xref}', 'EditMediaController::linkMediaToRecordAction');
+ $router->get(LinkMediaToFamilyModal::class, '/link-media-to-family/{xref}');
+ $router->get(LinkMediaToIndividualModal::class, '/link-media-to-individual/{xref}');
+ $router->get(LinkMediaToSourceModal::class, '/link-media-to-source/{xref}');
+ $router->post(LinkMediaToRecordAction::class, '/link-media-to-record/{xref}');
$router->post(PasteFact::class, '/paste-fact/{xref}');
$router->get(ReorderChildrenPage::class, '/reorder-children/{xref}');
$router->post(ReorderChildrenAction::class, '/reorder-children/{xref}');
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 2e00a9e55e..8291bd8305 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -380,16 +380,6 @@ parameters:
path: app/Http/Controllers/Admin/UsersController.php
-
- message: "#^Cannot call method createFact\\(\\) on Fisharebest\\\\Webtrees\\\\GedcomRecord\\|null\\.$#"
- count: 1
- path: app/Http/Controllers/EditMediaController.php
-
- -
- message: "#^Cannot call method url\\(\\) on Fisharebest\\\\Webtrees\\\\Media\\|null\\.$#"
- count: 1
- path: app/Http/Controllers/EditMediaController.php
-
- -
message: "#^Parameter \\#1 \\$path of method Psr\\\\Http\\\\Message\\\\UriInterface\\:\\:withPath\\(\\) expects string, string\\|false given\\.$#"
count: 1
path: app/Http/Middleware/BaseUrl.php
@@ -952,12 +942,12 @@ parameters:
-
message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#"
count: 1
- path: modules_v4/example.disable/module.php
+ path: modules_v4/example-footer.disable/module.php
-
message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#"
count: 1
- path: modules_v4/example-theme.disable/module.php
+ path: modules_v4/example-middleware.disable/module.php
-
message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#"
@@ -967,12 +957,12 @@ parameters:
-
message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#"
count: 1
- path: modules_v4/example-middleware.disable/module.php
+ path: modules_v4/example-theme.disable/module.php
-
message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#"
count: 1
- path: modules_v4/example-footer.disable/module.php
+ path: modules_v4/example.disable/module.php
-
message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#"
diff --git a/resources/views/media-page-menu.phtml b/resources/views/media-page-menu.phtml
index 0b8024c982..9b22675667 100644
--- a/resources/views/media-page-menu.phtml
+++ b/resources/views/media-page-menu.phtml
@@ -3,7 +3,15 @@
use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Http\RequestHandlers\DeleteRecord;
use Fisharebest\Webtrees\Http\RequestHandlers\EditRawRecordPage;
+use Fisharebest\Webtrees\Http\RequestHandlers\LinkMediaToFamilyModal;
+use Fisharebest\Webtrees\Http\RequestHandlers\LinkMediaToIndividualModal;
+use Fisharebest\Webtrees\Http\RequestHandlers\LinkMediaToSourceModal;
use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Media;
+
+/**
+ * @var Media $record
+ */
?>
@@ -14,17 +22,17 @@ use Fisharebest\Webtrees\I18N;
</button>
<div class="dropdown-menu dropdown-menu-right wt-page-menu-items" aria-labelledby="page-menu">
- <a class="dropdown-item" href="#" data-href="<?= e(route('link-media-to-individual', ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal" data-backdrop="static">
+ <a class="dropdown-item" href="#" data-href="<?= e(route(LinkMediaToIndividualModal::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal" data-backdrop="static">
<?= view('icons/link') ?>
<?= I18N::translate('Link this media object to an individual') ?>
</a>
- <a class="dropdown-item" href="#" data-href="<?= e(route('link-media-to-family', ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal" data-backdrop="static">
+ <a class="dropdown-item" href="#" data-href="<?= e(route(LinkMediaToFamilyModal::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal" data-backdrop="static">
<?= view('icons/link') ?>
<?= I18N::translate('Link this media object to a family') ?>
</a>
- <a class="dropdown-item" href="#" data-href="<?= e(route('link-media-to-source', ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal" data-backdrop="static">
+ <a class="dropdown-item" href="#" data-href="<?= e(route(LinkMediaToSourceModal::class, ['tree' => $record->tree()->name(), 'xref' => $record->xref()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal" data-backdrop="static">
<?= view('icons/link') ?>
<?= I18N::translate('Link this media object to a source') ?>
</a>
diff --git a/resources/views/media-page.phtml b/resources/views/media-page.phtml
index e03a93ae59..1631959149 100644
--- a/resources/views/media-page.phtml
+++ b/resources/views/media-page.phtml
@@ -4,8 +4,10 @@ use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Functions\FunctionsPrint;
use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\GedcomTag;
+use Fisharebest\Webtrees\Http\RequestHandlers\AddMediaFileModal;
use Fisharebest\Webtrees\Http\RequestHandlers\AddNewFact;
use Fisharebest\Webtrees\Http\RequestHandlers\DeleteFact;
+use Fisharebest\Webtrees\Http\RequestHandlers\EditMediaFileModal;
use Fisharebest\Webtrees\Http\RequestHandlers\PendingChangesAcceptRecord;
use Fisharebest\Webtrees\Http\RequestHandlers\PendingChangesRejectRecord;
use Fisharebest\Webtrees\I18N;
@@ -92,7 +94,7 @@ use Illuminate\Support\Collection;
<?= I18N::translate('Media file') ?>
<?php if ($media->canEdit()) : ?>
<div class="editfacts nowrap">
- <a class="btn btn-link" href="#" data-toggle="modal" data-backdrop="static" data-target="#wt-ajax-modal" data-href="<?= route('edit-media-file', ['tree' => $media->tree()->name(), 'xref' => $media->xref(), 'fact_id' => $media_file->factId()]) ?>" title="<?= I18N::translate('Edit') ?>">
+ <a class="btn btn-link" href="#" data-toggle="modal" data-backdrop="static" data-target="#wt-ajax-modal" data-href="<?= route(EditMediaFileModal::class, ['tree' => $media->tree()->name(), 'xref' => $media->xref(), 'fact_id' => $media_file->factId()]) ?>" title="<?= I18N::translate('Edit') ?>">
<?= view('icons/edit') ?>
<span class="sr-only">
<?= I18N::translate('Edit') ?>
@@ -195,7 +197,7 @@ use Illuminate\Support\Collection;
<?= I18N::translate('Media file') ?>
</th>
<td>
- <a href="#" data-href="<?= e(route('add-media-file', ['tree' => $media->tree()->name(), 'xref' => $media->xref()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal" data-backdrop="static">
+ <a href="#" data-href="<?= e(route(AddMediaFileModal::class, ['tree' => $media->tree()->name(), 'xref' => $media->xref()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal" data-backdrop="static">
<?= I18N::translate('Add a media file') ?>
</a>
</td>
diff --git a/resources/views/modals/add-media-file.phtml b/resources/views/modals/add-media-file.phtml
index fdf5f47ac4..1ceb43c9a5 100644
--- a/resources/views/modals/add-media-file.phtml
+++ b/resources/views/modals/add-media-file.phtml
@@ -1,10 +1,20 @@
<?php
+use Fisharebest\Webtrees\Http\RequestHandlers\AddMediaFileAction;
use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Media;
+use Fisharebest\Webtrees\Tree;
+
+/**
+ * @var string $max_upload_size
+ * @var Media $media
+ * @var Tree $tree
+ * @var array<string,string> $unused_files
+ */
?>
-<form method="post" action="<?= e(route('add-media-file', ['xref' => $media->xref(), 'tree' => $media->tree()->name()])) ?>" enctype="multipart/form-data">
+<form method="post" action="<?= e(route(AddMediaFileAction::class, ['xref' => $media->xref(), 'tree' => $media->tree()->name()])) ?>" enctype="multipart/form-data">
<?= csrf_field() ?>
<?= view('modals/header', ['title' => I18N::translate('Add a media file')]) ?>
diff --git a/resources/views/modals/create-media-from-file.phtml b/resources/views/modals/create-media-from-file.phtml
index 6afa89bd05..6ac3b43313 100644
--- a/resources/views/modals/create-media-from-file.phtml
+++ b/resources/views/modals/create-media-from-file.phtml
@@ -3,10 +3,11 @@
use Fisharebest\Webtrees\GedcomTag;
?>
-<?php use Fisharebest\Webtrees\I18N; ?>
+<?php use Fisharebest\Webtrees\Http\RequestHandlers\CreateMediaObjectFromFile;
+use Fisharebest\Webtrees\I18N; ?>
<div class="modal" id="modal-create-media-from-file">
- <form method="post" action="<?= e(route('create-media-from-file')) ?>" id="modal-create-media-from-file-form">
+ <form method="post" action="<?= e(route(CreateMediaObjectFromFile::class)) ?>" id="modal-create-media-from-file-form">
<?= csrf_field() ?>
<input type="hidden" name="action" value="create-media-object-from-file">
<input type="hidden" name="tree" id="tree" value="">
diff --git a/resources/views/modals/edit-media-file.phtml b/resources/views/modals/edit-media-file.phtml
index 100fbbb795..fb3347c4f3 100644
--- a/resources/views/modals/edit-media-file.phtml
+++ b/resources/views/modals/edit-media-file.phtml
@@ -1,10 +1,21 @@
<?php
+use Fisharebest\Webtrees\Http\RequestHandlers\EditMediaFileAction;
use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Media;
+use Fisharebest\Webtrees\MediaFile;
+use Fisharebest\Webtrees\Tree;
+
+/**
+ * @var string $max_upload_size
+ * @var Media $media
+ * @var MediaFile $media_file
+ * @var Tree $tree
+ */
?>
-<form method="post" action="<?= e(route('edit-media-file', ['xref' => $media->xref(), 'tree' => $media->tree()->name(), 'fact_id' => $media_file->factId()])) ?>" enctype="multipart/form-data">
+<form method="post" action="<?= e(route(EditMediaFileAction::class, ['xref' => $media->xref(), 'tree' => $media->tree()->name(), 'fact_id' => $media_file->factId()])) ?>" enctype="multipart/form-data">
<?= csrf_field() ?>
<?= view('modals/header', ['title' => I18N::translate('Edit a media file')]) ?>
diff --git a/resources/views/modals/link-media-to-family.phtml b/resources/views/modals/link-media-to-family.phtml
index 0d2d2fc498..5959b6401e 100644
--- a/resources/views/modals/link-media-to-family.phtml
+++ b/resources/views/modals/link-media-to-family.phtml
@@ -1,10 +1,18 @@
<?php
+use Fisharebest\Webtrees\Http\RequestHandlers\LinkMediaToRecordAction;
use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Media;
+use Fisharebest\Webtrees\Tree;
+
+/**
+ * @var Media $media
+ * @var Tree $tree
+ */
?>
-<form method="post" action="<?= e(route('link-media-to-record', ['tree' => $tree->name(), 'xref' => $media->xref()])) ?>" id="wt-modal-form">
+<form method="post" action="<?= e(route(LinkMediaToRecordAction::class, ['tree' => $tree->name(), 'xref' => $media->xref()])) ?>" id="wt-modal-form">
<?= csrf_field() ?>
<?= view('modals/header', ['title' => I18N::translate('Link this media object to a family')]) ?>
diff --git a/resources/views/modals/link-media-to-individual.phtml b/resources/views/modals/link-media-to-individual.phtml
index b092c96cdf..dc9fcca5f5 100644
--- a/resources/views/modals/link-media-to-individual.phtml
+++ b/resources/views/modals/link-media-to-individual.phtml
@@ -1,10 +1,18 @@
<?php
+use Fisharebest\Webtrees\Http\RequestHandlers\LinkMediaToRecordAction;
use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Media;
+use Fisharebest\Webtrees\Tree;
+
+/**
+ * @var Media $media
+ * @var Tree $tree
+ */
?>
-<form method="post" action="<?= e(route('link-media-to-record', ['tree' => $tree->name(), 'xref' => $media->xref()])) ?>" id="wt-modal-form">
+<form method="post" action="<?= e(route(LinkMediaToRecordAction::class, ['tree' => $tree->name(), 'xref' => $media->xref()])) ?>" id="wt-modal-form">
<?= csrf_field() ?>
<?= view('modals/header', ['title' => I18N::translate('Link this media object to an individual')]) ?>
diff --git a/resources/views/modals/link-media-to-source.phtml b/resources/views/modals/link-media-to-source.phtml
index acac353113..1cfa0fe95d 100644
--- a/resources/views/modals/link-media-to-source.phtml
+++ b/resources/views/modals/link-media-to-source.phtml
@@ -1,10 +1,18 @@
<?php
+use Fisharebest\Webtrees\Http\RequestHandlers\LinkMediaToRecordAction;
use Fisharebest\Webtrees\I18N;
+use Fisharebest\Webtrees\Media;
+use Fisharebest\Webtrees\Tree;
+
+/**
+ * @var Media $media
+ * @var Tree $tree
+ */
?>
-<form method="post" action="<?= e(route('link-media-to-record', ['tree' => $tree->name(), 'xref' => $media->xref()])) ?>" id="wt-modal-form">
+<form method="post" action="<?= e(route(LinkMediaToRecordAction::class, ['tree' => $tree->name(), 'xref' => $media->xref()])) ?>" id="wt-modal-form">
<?= csrf_field() ?>
<?= view('modals/header', ['title' => I18N::translate('Link this media object to a source')]) ?>