From 23b5c8ef31d23f77b0c81775e0352cb8ebba49ba Mon Sep 17 00:00:00 2001 From: Alex Cabal Date: Sat, 14 Dec 2024 11:32:02 -0600 Subject: [PATCH] Allow admin to view collection metadata --- config/sql/se/Benefits.sql | 1 + lib/Benefits.php | 1 + lib/Collection.php | 35 +++++++++++++++++++++++++-- lib/Ebook.php | 8 +++---- www/collections/get.php | 48 +++++++++++++++++--------------------- www/css/core.css | 19 +++++++++++++++ www/css/user.css | 19 --------------- www/users/get.php | 6 ++--- 8 files changed, 82 insertions(+), 55 deletions(-) diff --git a/config/sql/se/Benefits.sql b/config/sql/se/Benefits.sql index e11a7e62..7606efb2 100644 --- a/config/sql/se/Benefits.sql +++ b/config/sql/se/Benefits.sql @@ -7,6 +7,7 @@ CREATE TABLE IF NOT EXISTS `Benefits` ( `CanReviewArtwork` tinyint(1) unsigned NOT NULL DEFAULT 0, `CanReviewOwnArtwork` tinyint(1) unsigned NOT NULL DEFAULT 0, `CanEditUsers` tinyint(1) unsigned NOT NULL DEFAULT 0, + `CanEditCollections` tinyint(1) unsigned NOT NULL DEFAULT 0, `CanCreateEbookPlaceholders` tinyint(1) unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`UserId`), KEY `idxBenefits` (`CanAccessFeeds`,`CanVote`,`CanBulkDownload`) diff --git a/lib/Benefits.php b/lib/Benefits.php index 9de908fd..20d25c14 100644 --- a/lib/Benefits.php +++ b/lib/Benefits.php @@ -15,6 +15,7 @@ class Benefits{ public bool $CanReviewArtwork = false; public bool $CanReviewOwnArtwork = false; public bool $CanEditUsers = false; + public bool $CanEditCollections = false; public bool $CanCreateEbookPlaceholders = false; protected bool $_HasBenefits; diff --git a/lib/Collection.php b/lib/Collection.php index 7f5d1c47..66e74a11 100644 --- a/lib/Collection.php +++ b/lib/Collection.php @@ -3,6 +3,7 @@ use function Safe\preg_replace; /** * @property string $Url + * @property array $Ebooks */ class Collection{ use Traits\Accessor; @@ -13,7 +14,9 @@ class Collection{ public ?Enums\CollectionType $Type = null; public bool $ArePlaceholdersComplete; /** Has a producer verified that every possible item in this `Collection` been added to our database? */ - protected ?string $_Url = null; + protected string $_Url; + /** @var array $_Ebooks */ + protected array $_Ebooks; // ******* @@ -21,13 +24,24 @@ class Collection{ // ******* protected function GetUrl(): string{ - if($this->_Url === null){ + if(!isset($this->_Url)){ $this->_Url = '/collections/' . $this->UrlName; } return $this->_Url; } + /** + * @return array + */ + protected function GetEbooks(): array{ + if(!isset($this->_Ebooks)){ + $this->_Ebooks = Ebook::GetAllByCollection($this->CollectionId); + } + + return $this->_Ebooks; + } + // *********** // ORM METHODS @@ -57,6 +71,23 @@ class Collection{ return $result[0] ?? throw new Exceptions\CollectionNotFoundException();; } + /** + * @throws Exceptions\CollectionNotFoundException + */ + public static function GetByUrlName(?string $urlName): Collection{ + if($urlName === null){ + throw new Exceptions\CollectionNotFoundException(); + } + + $result = Db::Query(' + SELECT * + from Collections + where UrlName = ? + ', [$urlName], Collection::class); + + return $result[0] ?? throw new Exceptions\CollectionNotFoundException();; + } + /** * @return array */ diff --git a/lib/Ebook.php b/lib/Ebook.php index 8ac4c3da..6f3649cb 100644 --- a/lib/Ebook.php +++ b/lib/Ebook.php @@ -2020,17 +2020,17 @@ class Ebook{ * Queries for books in a collection. * * Puts ebooks without a `SequenceNumber` at the end of the list, which is more common in a collection with both published and placeholder ebooks. + * * @return array */ - public static function GetAllByCollection(string $collection): array{ + public static function GetAllByCollection(int $collectionId): array{ $ebooks = Db::Query(' SELECT e.* from Ebooks e inner join CollectionEbooks ce using (EbookId) - inner join Collections c using (CollectionId) - where c.UrlName = ? + where ce.CollectionId = ? order by ce.SequenceNumber is null, ce.SequenceNumber, e.EbookCreated desc - ', [$collection], Ebook::class); + ', [$collectionId], Ebook::class); return $ebooks; } diff --git a/www/collections/get.php b/www/collections/get.php index 45fa014d..d47d2a84 100644 --- a/www/collections/get.php +++ b/www/collections/get.php @@ -2,34 +2,15 @@ use function Safe\preg_replace; try{ - $collection = HttpInput::Str(GET, 'collection') ?? ''; - $collectionObject = null; - $collectionName = ''; - $collectionType = ''; - - $ebooks = Ebook::GetAllByCollection($collection); - // Get the *actual* name of the collection, in case there are accent marks (like `Arsène Lupin`). - if(sizeof($ebooks) > 0){ - foreach($ebooks[0]->CollectionMemberships as $cm){ - $c = $cm->Collection; - if($collection == Formatter::MakeUrlSafe($c->Name)){ - $collectionObject = $c; - } - } - } - - if($collectionObject === null){ - throw new Exceptions\CollectionNotFoundException(); - } - - $collectionName = preg_replace('/^The /ius', '', $collectionObject->Name); - $collectionType = $collectionObject->Type->value ?? 'collection'; + $collection = Collection::GetByUrlName(HttpInput::Str(GET, 'collection')); + $collectionName = preg_replace('/^The /ius', '', $collection->Name); + $collectionType = $collection->Type->value ?? 'collection'; $pageTitle = 'Browse free ebooks in the ' . Formatter::EscapeHtml($collectionName) . ' ' . $collectionType; $pageDescription = 'A list of free ebooks in the ' . Formatter::EscapeHtml($collectionName) . ' ' . $collectionType; $pageHeader = 'Free Ebooks in the ' . Formatter::EscapeHtml($collectionName) . ' ' . ucfirst($collectionType); - $feedUrl = '/collections/' . $collection; + $feedUrl = '/collections/' . $collection->UrlName; $feedTitle = 'Standard Ebooks - Ebooks in the ' . Formatter::EscapeHtml($collectionName) . ' ' . $collectionType; } catch(Exceptions\CollectionNotFoundException){ @@ -44,13 +25,26 @@ catch(Exceptions\CollectionNotFoundException){

- Download collection - Collection feeds + Download collection + Collection feeds

- + + Ebooks) == 0){ ?>

No ebooks matched your filters. You can try different filters, or browse all of our ebooks.

- $ebooks, 'view' => Enums\ViewType::Grid, 'collection' => $collectionObject]) ?> + $collection->Ebooks, 'view' => Enums\ViewType::Grid, 'collection' => $collection]) ?> + + + Benefits->CanEditCollections){ ?> +

Metadata

+ + + + + + + +
Collection ID:CollectionId ?>

We also have bulk ebook downloads and a list of collections available, as well as ebook catalog feeds for use directly in your ereader app or RSS reader.

diff --git a/www/css/core.css b/www/css/core.css index 5d533958..d177d0b7 100644 --- a/www/css/core.css +++ b/www/css/core.css @@ -3254,6 +3254,25 @@ ol.ebooks-list > li.ribbon.not-pd a::after{ content: "not p.d. yet"; } +h2 + table.admin-table{ + margin-top: .5rem; +} + +table.admin-table td{ + padding: .5rem; + vertical-align: top; +} + +table.admin-table td:first-child{ + font-weight: bold; + text-align: right; + white-space: nowrap; +} + +table.admin-table td + td{ + width: 100%; +} + @media (hover: none) and (pointer: coarse){ /* target ipads and smartphones without a mouse */ /* For iPad, unset the height so it matches the other elements */ select[multiple]{ diff --git a/www/css/user.css b/www/css/user.css index cb425460..2b882f70 100644 --- a/www/css/user.css +++ b/www/css/user.css @@ -7,25 +7,6 @@ label:has(input[name="password-action"]) + label{ margin-top: .5rem; } -h2 + table{ - margin-top: .5rem; -} - -table td{ - padding: .5rem; - vertical-align: top; -} - -table td:first-child{ - font-weight: bold; - text-align: right; - white-space: nowrap; -} - -table td + td{ - width: 100%; -} - form{ display: flex; flex-direction: column; diff --git a/www/users/get.php b/www/users/get.php index 9f5883aa..eea72da4 100644 --- a/www/users/get.php +++ b/www/users/get.php @@ -52,7 +52,7 @@ catch(Exceptions\SeeOtherException $ex){ Edit user

Basics

- +
@@ -74,7 +74,7 @@ catch(Exceptions\SeeOtherException $ex){
Email:

Patron info

- +
@@ -134,7 +134,7 @@ catch(Exceptions\SeeOtherException $ex){

Registration info

-
Is Patron:
+
Is registered: