From 032032b920a68130cc5d9f41aa80749aa709308e Mon Sep 17 00:00:00 2001 From: Mike Colagrosso Date: Fri, 26 Apr 2024 23:52:28 -0600 Subject: [PATCH] Additional Ebook validation --- lib/Constants.php | 2 + lib/Ebook.php | 137 +++++++++++++++++- .../EbookDescriptionRequiredException.php | 6 + .../EbookIdentifierRequiredException.php | 1 + .../EbookIndexableTextRequiredException.php | 6 + .../EbookLongDescriptionRequiredException.php | 6 + .../EbookTitleRequiredException.php | 1 + .../InvalidEbookAdvancedEpubUrlException.php | 5 + .../InvalidEbookAzw3UrlException.php | 5 + .../InvalidEbookCreatedDatetimeException.php | 13 ++ .../InvalidEbookDistCoverUrlException.php | 5 + .../InvalidEbookEpubUrlException.php | 5 + .../InvalidEbookGitHubUrlException.php | 5 + .../InvalidEbookKepubUrlException.php | 5 + .../InvalidEbookKindleCoverUrlException.php | 5 + .../InvalidEbookReadingEaseException.php | 5 + ...nvalidEbookRepoFilesystemPathException.php | 12 ++ ...dEbookTextSinglePageByteCountException.php | 5 + .../InvalidEbookUpdatedDatetimeException.php | 13 ++ .../InvalidEbookWikipediaUrlException.php | 5 + .../InvalidEbookWordCountException.php | 5 + ...InvalidEbookWwwFilesystemPathException.php | 12 ++ 22 files changed, 262 insertions(+), 2 deletions(-) create mode 100644 lib/Exceptions/EbookDescriptionRequiredException.php create mode 100644 lib/Exceptions/EbookIndexableTextRequiredException.php create mode 100644 lib/Exceptions/EbookLongDescriptionRequiredException.php create mode 100644 lib/Exceptions/InvalidEbookAdvancedEpubUrlException.php create mode 100644 lib/Exceptions/InvalidEbookAzw3UrlException.php create mode 100644 lib/Exceptions/InvalidEbookCreatedDatetimeException.php create mode 100644 lib/Exceptions/InvalidEbookDistCoverUrlException.php create mode 100644 lib/Exceptions/InvalidEbookEpubUrlException.php create mode 100644 lib/Exceptions/InvalidEbookGitHubUrlException.php create mode 100644 lib/Exceptions/InvalidEbookKepubUrlException.php create mode 100644 lib/Exceptions/InvalidEbookKindleCoverUrlException.php create mode 100644 lib/Exceptions/InvalidEbookReadingEaseException.php create mode 100644 lib/Exceptions/InvalidEbookRepoFilesystemPathException.php create mode 100644 lib/Exceptions/InvalidEbookTextSinglePageByteCountException.php create mode 100644 lib/Exceptions/InvalidEbookUpdatedDatetimeException.php create mode 100644 lib/Exceptions/InvalidEbookWikipediaUrlException.php create mode 100644 lib/Exceptions/InvalidEbookWordCountException.php create mode 100644 lib/Exceptions/InvalidEbookWwwFilesystemPathException.php diff --git a/lib/Constants.php b/lib/Constants.php index fb246cd9..9d531c86 100644 --- a/lib/Constants.php +++ b/lib/Constants.php @@ -32,7 +32,9 @@ const DATABASE_DEFAULT_HOST = 'localhost'; const EBOOKS_PER_PAGE = 12; const EBOOKS_MAX_STRING_LENGTH = 250; +const EBOOKS_MAX_LONG_STRING_LENGTH = 500; const EBOOK_SINGLE_PAGE_SIZE_WARNING = 3 *1024 * 1024; // 3145728 +const EBOOK_EARLIEST_CREATION_DATE = new DateTimeImmutable('2014-01-01'); const ARTWORK_THUMBNAIL_HEIGHT = 350; const ARTWORK_THUMBNAIL_WIDTH = 350; diff --git a/lib/Ebook.php b/lib/Ebook.php index 0170e7d2..af533117 100644 --- a/lib/Ebook.php +++ b/lib/Ebook.php @@ -581,16 +581,87 @@ class Ebook{ // ******* public function Validate(): void{ + $now = new DateTimeImmutable(); $error = new Exceptions\ValidationException(); if($this->Identifier == ''){ $error->Add(new Exceptions\EbookIdentifierRequiredException()); } - if(strlen($this->Identifier) > EBOOKS_MAX_STRING_LENGTH){ + if(strlen($this->Identifier) > EBOOKS_MAX_LONG_STRING_LENGTH){ $error->Add(new Exceptions\StringTooLongException('Ebook Identifier')); } + if(!is_readable($this->WwwFilesystemPath)){ + $error->Add(new Exceptions\InvalidEbookWwwFilesystemPathException($this->WwwFilesystemPath)); + } + + if(strlen($this->WwwFilesystemPath) > EBOOKS_MAX_LONG_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook WwwFilesystemPath')); + } + + if(!is_readable($this->RepoFilesystemPath)){ + $error->Add(new Exceptions\InvalidEbookRepoFilesystemPathException($this->RepoFilesystemPath)); + } + + if(strlen($this->RepoFilesystemPath) > EBOOKS_MAX_LONG_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook RepoFilesystemPath')); + } + + if($this->KindleCoverUrl !== null && !preg_match('|/*_EBOK_portrait.jpg|ius', $this->KindleCoverUrl)){ + $error->Add(new Exceptions\InvalidEbookKindleCoverUrlException('Invalid Ebook KindleCoverUrl: ' . $this->KindleCoverUrl)); + + } + + if($this->KindleCoverUrl !== null && strlen($this->KindleCoverUrl) > EBOOKS_MAX_LONG_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook KindleCoverUrl')); + } + + if($this->EpubUrl !== null && !preg_match('|/*.epub|ius', $this->EpubUrl)){ + $error->Add(new Exceptions\InvalidEbookEpubUrlException('Invalid Ebook EpubUrl: ' . $this->EpubUrl)); + + } + + if($this->EpubUrl !== null && strlen($this->EpubUrl) > EBOOKS_MAX_LONG_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook EpubUrl')); + } + + if($this->AdvancedEpubUrl !== null && !preg_match('|/*_advanced.epub|ius', $this->AdvancedEpubUrl)){ + $error->Add(new Exceptions\InvalidEbookAdvancedEpubUrlException('Invalid Ebook AdvancedEpubUrl: ' . $this->AdvancedEpubUrl)); + + } + + if($this->AdvancedEpubUrl !== null && strlen($this->AdvancedEpubUrl) > EBOOKS_MAX_LONG_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook AdvancedEpubUrl')); + } + + if($this->KepubUrl !== null && !preg_match('|/*.kepub.epub|ius', $this->KepubUrl)){ + $error->Add(new Exceptions\InvalidEbookKepubUrlException('Invalid Ebook KepubUrl: ' . $this->KepubUrl)); + + } + + if($this->KepubUrl !== null && strlen($this->KepubUrl) > EBOOKS_MAX_LONG_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook KepubUrl')); + } + + if($this->Azw3Url !== null && !preg_match('|/*.azw3|ius', $this->Azw3Url)){ + $error->Add(new Exceptions\InvalidEbookAzw3UrlException('Invalid Ebook Azw3Url: ' . $this->Azw3Url)); + + } + + if($this->Azw3Url !== null && strlen($this->Azw3Url) > EBOOKS_MAX_LONG_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook Azw3Url')); + } + + if($this->DistCoverUrl !== null && !preg_match('|/*cover.jpg|ius', $this->DistCoverUrl)){ + $error->Add(new Exceptions\InvalidEbookDistCoverUrlException('Invalid Ebook DistCoverUrl: ' . $this->DistCoverUrl)); + + } + + if($this->DistCoverUrl !== null && strlen($this->DistCoverUrl) > EBOOKS_MAX_LONG_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook DistCoverUrl')); + } + if($this->Title === null || $this->Title == ''){ $error->Add(new Exceptions\EbookTitleRequiredException()); } @@ -599,7 +670,69 @@ class Ebook{ $error->Add(new Exceptions\StringTooLongException('Ebook Title')); } - // TODO: Add more validation. + if($this->FullTitle !== null && strlen($this->FullTitle) > EBOOKS_MAX_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook FullTitle')); + } + + if($this->AlternateTitle !== null && strlen($this->AlternateTitle) > EBOOKS_MAX_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook AlternateTitle')); + } + + if($this->Description === null || $this->Description == ''){ + $error->Add(new Exceptions\EbookDescriptionRequiredException()); + } + + if($this->LongDescription === null || $this->LongDescription == ''){ + $error->Add(new Exceptions\EbookLongDescriptionRequiredException()); + } + + if($this->Language !== null && strlen($this->Language) > 10){ + $error->Add(new Exceptions\StringTooLongException('Ebook Language: ' . $this->Language)); + } + + if($this->WordCount <= 0){ + $error->Add(new Exceptions\InvalidEbookWordCountException('Invalid Ebook WordCount: ' . $this->WordCount)); + } + + // In theory, Flesch reading ease can be negative, but in practice it's positive. + if($this->ReadingEase <= 0){ + $error->Add(new Exceptions\InvalidEbookReadingEaseException('Invalid Ebook ReadingEase: ' . $this->ReadingEase)); + } + + if($this->GitHubUrl !== null && !preg_match('|https://github.com/standardebooks/\w+|ius', $this->GitHubUrl)){ + $error->Add(new Exceptions\InvalidEbookGitHubUrlException('Invalid Ebook GitHubUrl: ' . $this->GitHubUrl)); + + } + + if($this->GitHubUrl !== null && strlen($this->GitHubUrl) > EBOOKS_MAX_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook GitHubUrl')); + } + + if($this->WikipediaUrl !== null && !preg_match('|https://.*wiki.*|ius', $this->WikipediaUrl)){ + $error->Add(new Exceptions\InvalidEbookWikipediaUrlException('Invalid Ebook WikipediaUrl: ' . $this->WikipediaUrl)); + + } + + if($this->WikipediaUrl !== null && strlen($this->WikipediaUrl) > EBOOKS_MAX_STRING_LENGTH){ + $error->Add(new Exceptions\StringTooLongException('Ebook WikipediaUrl')); + } + + if($this->Created > $now || $this->Created < EBOOK_EARLIEST_CREATION_DATE){ + $error->Add(new Exceptions\InvalidEbookCreatedDatetimeException($this->Created)); + } + + if($this->Updated > $now || $this->Updated < EBOOK_EARLIEST_CREATION_DATE){ + $error->Add(new Exceptions\InvalidEbookUpdatedDatetimeException($this->Updated)); + + } + + if($this->TextSinglePageByteCount === null || $this->TextSinglePageByteCount <= 0){ + $error->Add(new Exceptions\InvalidEbookTextSinglePageByteCountException('Invalid Ebook TextSinglePageByteCount: ' . $this->TextSinglePageByteCount)); + } + + if($this->IndexableText === null || $this->IndexableText == ''){ + $error->Add(new Exceptions\EbookIndexableTextRequiredException()); + } if($error->HasExceptions){ throw $error; diff --git a/lib/Exceptions/EbookDescriptionRequiredException.php b/lib/Exceptions/EbookDescriptionRequiredException.php new file mode 100644 index 00000000..c2fc7ac0 --- /dev/null +++ b/lib/Exceptions/EbookDescriptionRequiredException.php @@ -0,0 +1,6 @@ +message = 'Invalid EbookCreated datetime. ' . $createdDatetime->format('Y-m-d') . ' is not between ' . EBOOK_EARLIEST_CREATION_DATE->format('Y-m-d') . ' and ' . $now->format('Y-m-d') . '.'; + } +} diff --git a/lib/Exceptions/InvalidEbookDistCoverUrlException.php b/lib/Exceptions/InvalidEbookDistCoverUrlException.php new file mode 100644 index 00000000..40390231 --- /dev/null +++ b/lib/Exceptions/InvalidEbookDistCoverUrlException.php @@ -0,0 +1,5 @@ +message = 'Invalid RepoFilesystemPath. Not readable: ' . $path; + } +} diff --git a/lib/Exceptions/InvalidEbookTextSinglePageByteCountException.php b/lib/Exceptions/InvalidEbookTextSinglePageByteCountException.php new file mode 100644 index 00000000..fd9d0b77 --- /dev/null +++ b/lib/Exceptions/InvalidEbookTextSinglePageByteCountException.php @@ -0,0 +1,5 @@ +message = 'Invalid EbookUpdated datetime. ' . $updatedDatetime->format('Y-m-d') . ' is not between ' . EBOOK_EARLIEST_CREATION_DATE->format('Y-m-d') . ' and ' . $now->format('Y-m-d') . '.'; + } +} diff --git a/lib/Exceptions/InvalidEbookWikipediaUrlException.php b/lib/Exceptions/InvalidEbookWikipediaUrlException.php new file mode 100644 index 00000000..74621e51 --- /dev/null +++ b/lib/Exceptions/InvalidEbookWikipediaUrlException.php @@ -0,0 +1,5 @@ +message = 'Invalid WwwFilesystemPath. Not readable: ' . $path; + } +}