From f449c024eaae4ea83236978ba2e7fbb28d935b6c Mon Sep 17 00:00:00 2001 From: Mike Colagrosso Date: Tue, 17 Dec 2024 21:06:01 -0700 Subject: [PATCH] Add /edit endpoint to update placeholders --- config/apache/rewrites/ebooks.conf | 6 ++ lib/Ebook.php | 84 ++++++++++++++++++- www/ebook-placeholders/edit.php | 64 +++++++++++++++ www/ebook-placeholders/get.php | 18 ++++ www/ebook-placeholders/post.php | 128 +++++++++++++---------------- www/ebooks/edit.php | 35 ++++++++ www/ebooks/post.php | 35 ++++++++ 7 files changed, 297 insertions(+), 73 deletions(-) create mode 100644 www/ebook-placeholders/edit.php create mode 100644 www/ebooks/edit.php create mode 100644 www/ebooks/post.php diff --git a/config/apache/rewrites/ebooks.conf b/config/apache/rewrites/ebooks.conf index de4d34bd..7b1632b1 100644 --- a/config/apache/rewrites/ebooks.conf +++ b/config/apache/rewrites/ebooks.conf @@ -19,6 +19,12 @@ RewriteRule ^/collections/([^\./]+?)$ /collections/get.php?collection=$1 [QSA] RewriteRule ^/collections/([^/]+?)/downloads$ /bulk-downloads/get.php?collection=$1 RewriteRule ^/collections/([^/]+?)/feeds$ /feeds/get.php?collection=$1 +# Edit rewrites +RewriteRule ^/ebooks/(.+?)/edit$ /ebooks/edit.php?url-path=$1 [L] + +RewriteCond expr "tolower(%{REQUEST_METHOD}) =~ /^post$/" +RewriteRule ^/ebooks/([^\.]+?)$ /ebooks/post.php?url-path=$1 [L] + # List of specific URL rewrites RewriteRule ^/contribute/accepted-ebooks/? /contribute/collections-policy [R=301,L] RewriteRule ^/ebooks/aristotle/the-nicomachean-ethics(/?$|/.+?$) /ebooks/aristotle/nicomachean-ethics$1 [R=301,L] diff --git a/lib/Ebook.php b/lib/Ebook.php index 308139c0..10fa7283 100644 --- a/lib/Ebook.php +++ b/lib/Ebook.php @@ -21,6 +21,7 @@ use function Safe\shell_exec; * @property array $Contributors * @property ?array $TocEntries A list of non-Roman ToC entries *only if* the work has the `se:is-a-collection` metadata element; `null` otherwise. * @property string $Url + * @property string $EditUrl * @property bool $HasDownloads * @property string $UrlSafeIdentifier * @property string $HeroImageUrl @@ -99,6 +100,7 @@ class Ebook{ /** @var ?array $_TocEntries */ protected ?array $_TocEntries = null; protected string $_Url; + protected string $_EditUrl; protected bool $_HasDownloads; protected string $_UrlSafeIdentifier; protected string $_HeroImageUrl; @@ -365,6 +367,14 @@ class Ebook{ return $this->_Url; } + protected function GetEditUrl(): string{ + if(!isset($this->_EditUrl)){ + $this->_EditUrl = $this->Url . '/edit'; + } + + return $this->_EditUrl; + } + protected function GetHasDownloads(): bool{ if(!isset($this->_HasDownloads)){ $this->_HasDownloads = $this->EpubUrl || $this->AdvancedEpubUrl || $this->KepubUrl || $this->Azw3Url; @@ -1059,7 +1069,7 @@ class Ebook{ * * @throws Exceptions\InvalidEbookIdentifierException */ - public function FillIdentifierFromTitleAndContributors(): void{ + protected function FillIdentifierFromTitleAndContributors(): void{ if(!isset($this->Authors) || sizeof($this->Authors) == 0){ throw new Exceptions\InvalidEbookIdentifierException('Authors required'); } @@ -1092,6 +1102,78 @@ class Ebook{ } } + /** + * Populates `EbookPlaceholder` and other fields from `Template::EbookPlaceholderForm()`. + * + * @throws Exceptions\InvalidEbookIdentifierException + */ + public function FillFromEbookPlaceholderForm(): void{ + $title = HttpInput::Str(POST, 'ebook-title'); + if(isset($title)){ + $this->Title = $title; + } + + $authors = []; + $authorFields = ['author-name-1', 'author-name-2', 'author-name-3']; + foreach($authorFields as $authorField){ + $authorName = HttpInput::Str(POST, $authorField); + if(!isset($authorName)){ + continue; + } + $author = new Contributor(); + $author->Name = $authorName; + $author->UrlName = Formatter::MakeUrlSafe($author->Name); + $author->MarcRole = Enums\MarcRole::Author; + $authors[] = $author; + } + $this->Authors = $authors; + + $translators = []; + $translatorFields = ['translator-name-1', 'translator-name-2']; + foreach($translatorFields as $translatorField){ + $translatorName = HttpInput::Str(POST, $translatorField); + if(!isset($translatorName)){ + continue; + } + $translator = new Contributor(); + $translator->Name = $translatorName; + $translator->UrlName = Formatter::MakeUrlSafe($translator->Name); + $translator->MarcRole = Enums\MarcRole::Translator; + $translators[] = $translator; + } + $this->Translators = $translators; + + $collectionMemberships = []; + $collectionNameFields = ['collection-name-1', 'collection-name-2', 'collection-name-3']; + foreach($collectionNameFields as $collectionNameField){ + $collectionName = HttpInput::Str(POST, $collectionNameField); + if(!isset($collectionName)){ + continue; + } + $collectionSequenceNumber = HttpInput::Int(POST, 'sequence-number-' . $collectionNameField); + $collection = Collection::FromName($collectionName); + $collection->Type = Enums\CollectionType::tryFrom(HttpInput::Str(POST, 'type-' . $collectionNameField) ?? ''); + + $cm = new CollectionMembership(); + $cm->Collection = $collection; + $cm->SequenceNumber = $collectionSequenceNumber; + $collectionMemberships[] = $cm; + } + $this->CollectionMemberships = $collectionMemberships; + + $ebookPlaceholder = new EbookPlaceholder(); + $ebookPlaceholder->FillFromHttpPost(); + $this->EbookPlaceholder = $ebookPlaceholder; + + // These properties must be set before calling `Ebook::Create()` to prevent the getters from triggering DB queries or accessing `Ebook::$EbookId` before it is set. + $this->Contributors = []; + $this->Illustrators = []; + $this->LocSubjects = []; + $this->Tags = []; + $this->TocEntries = []; + + $this->FillIdentifierFromTitleAndContributors(); + } // ******* // METHODS diff --git a/www/ebook-placeholders/edit.php b/www/ebook-placeholders/edit.php new file mode 100644 index 00000000..d46ab12e --- /dev/null +++ b/www/ebook-placeholders/edit.php @@ -0,0 +1,64 @@ +Benefits->CanEditEbookPlaceholders){ + throw new Exceptions\InvalidPermissionsException(); + } + + if($ebook === null){ + $ebook = Ebook::GetByIdentifier($identifier); + } + + if(!$ebook->IsPlaceholder() || $ebook->EbookPlaceholder === null){ + throw new Exceptions\EbookNotFoundException(); + } + + if($exception){ + http_response_code(Enums\HttpCode::UnprocessableContent->value); + session_unset(); + } +} +catch(Exceptions\EbookNotFoundException){ + Template::Emit404(); +} +catch(Exceptions\LoginRequiredException){ + Template::RedirectToLogin(); +} +catch(Exceptions\InvalidPermissionsException){ + Template::Emit403(); +} +?> + 'Edit Ebook Placeholder for ' . $ebook->Title, + 'css' => ['/css/ebook-placeholder.css'], + 'highlight' => '', + 'description' => 'Edit the ebook placeholder for ' . $ebook->Title + ] +) ?> +
+
+

Edit Ebook Placeholder

+ + $exception]) ?> + +
+ + $ebook]) ?> +
+
+
+ diff --git a/www/ebook-placeholders/get.php b/www/ebook-placeholders/get.php index b76702c4..aeeaacd1 100644 --- a/www/ebook-placeholders/get.php +++ b/www/ebook-placeholders/get.php @@ -1,15 +1,24 @@ EbookPlaceholder === null){ throw new Exceptions\EbookNotFoundException(); } + + if($isSaved){ + session_unset(); + } } catch(Exceptions\EbookNotFoundException){ Template::Emit404(); @@ -53,6 +62,10 @@ catch(Exceptions\EbookNotFoundException){ + +

Ebook Placeholder saved!

+ +