mirror of
https://github.com/standardebooks/web.git
synced 2025-07-07 15:20:32 -04:00
Enable strict exception type hint checking in PHPStan and add exception type hints
This commit is contained in:
parent
559e4a5e05
commit
c4c8e7353f
26 changed files with 300 additions and 82 deletions
|
@ -89,6 +89,7 @@ class Artist{
|
|||
* @throws Exceptions\InvalidArtistException
|
||||
*/
|
||||
public function Validate(): void{
|
||||
/** @throws void */
|
||||
$now = new DateTimeImmutable();
|
||||
$thisYear = intval($now->format('Y'));
|
||||
|
||||
|
@ -136,6 +137,9 @@ class Artist{
|
|||
return $result[0] ?? throw new Exceptions\ArtistNotFoundException();;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidArtistException
|
||||
*/
|
||||
public function Create(): void{
|
||||
$this->Validate();
|
||||
Db::Query('
|
||||
|
@ -149,7 +153,7 @@ class Artist{
|
|||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\ValidationException
|
||||
* @throws Exceptions\InvalidArtistException
|
||||
*/
|
||||
public static function GetOrCreate(Artist $artist): Artist{
|
||||
$result = Db::Query('
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
<?
|
||||
|
||||
use Exceptions\InvalidImageUploadException;
|
||||
use Exceptions\InvalidPageScanUrlException;
|
||||
use Exceptions\InvalidUrlException;
|
||||
use Safe\DateTimeImmutable;
|
||||
use Safe\Exceptions\ExecException;
|
||||
use Safe\Exceptions\FilesystemException;
|
||||
use Safe\Exceptions\PcreException;
|
||||
|
||||
use function Safe\copy;
|
||||
use function Safe\exec;
|
||||
use function Safe\getimagesize;
|
||||
|
@ -160,6 +168,9 @@ class Artwork{
|
|||
return $this->_Tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidUrlException
|
||||
*/
|
||||
public function GetMuseum(): ?Museum{
|
||||
if($this->_Museum === null){
|
||||
try{
|
||||
|
@ -252,6 +263,9 @@ class Artwork{
|
|||
return $this->_Dimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
protected function GetEbook(): ?Ebook{
|
||||
if($this->_Ebook === null){
|
||||
if($this->EbookUrl === null){
|
||||
|
@ -318,9 +332,10 @@ class Artwork{
|
|||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\ValidationException
|
||||
* @throws Exceptions\InvalidArtworkException
|
||||
*/
|
||||
protected function Validate(?string $imagePath = null, bool $isImageRequired = true): void{
|
||||
/** @throws void */
|
||||
$now = new DateTimeImmutable();
|
||||
$thisYear = intval($now->format('Y'));
|
||||
$error = new Exceptions\InvalidArtworkException();
|
||||
|
@ -509,6 +524,10 @@ class Artwork{
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidUrlException
|
||||
* @throws Exceptions\InvalidPageScanUrlException
|
||||
*/
|
||||
public static function NormalizePageScanUrl(string $url): string{
|
||||
$outputUrl = $url;
|
||||
|
||||
|
@ -621,6 +640,9 @@ class Artwork{
|
|||
return $outputUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidImageUploadException
|
||||
*/
|
||||
private function WriteImageAndThumbnails(string $imagePath): void{
|
||||
exec('exiftool -quiet -overwrite_original -all= ' . escapeshellarg($imagePath));
|
||||
copy($imagePath, $this->ImageFsPath);
|
||||
|
@ -645,6 +667,7 @@ class Artwork{
|
|||
|
||||
$this->Validate($imagePath, true);
|
||||
|
||||
/** @throws void */
|
||||
$this->Created = new DateTimeImmutable();
|
||||
|
||||
$tags = [];
|
||||
|
@ -700,7 +723,10 @@ class Artwork{
|
|||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\ValidationException
|
||||
* @throws Exceptions\InvalidArtworkException
|
||||
* @throws Exceptions\InvalidArtistException
|
||||
* @throws Exceptions\InvalidArtworkTagException
|
||||
* @throws Exceptions\InvalidImageUploadException
|
||||
*/
|
||||
public function Save(?string $imagePath = null): void{
|
||||
$this->_UrlName = null;
|
||||
|
@ -710,6 +736,7 @@ class Artwork{
|
|||
|
||||
// Manually set the updated timestamp, because if we only update the image and nothing else, the row's
|
||||
// updated timestamp won't change automatically.
|
||||
/** @throws void */
|
||||
$this->Updated = new DateTimeImmutable();
|
||||
$this->_ImageUrl = null;
|
||||
$this->_ThumbUrl = null;
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<?
|
||||
|
||||
use Exceptions\InvalidArtworkTagException;
|
||||
|
||||
use function Safe\preg_match;
|
||||
use function Safe\preg_replace;
|
||||
|
||||
|
@ -20,7 +23,7 @@ class ArtworkTag extends Tag{
|
|||
// *******
|
||||
|
||||
/**
|
||||
* @throws Exceptions\ValidationException
|
||||
* @throws Exceptions\InvalidArtworkTagException
|
||||
*/
|
||||
public function Validate(): void{
|
||||
$error = new Exceptions\InvalidArtworkTagException($this->Name);
|
||||
|
@ -46,6 +49,9 @@ class ArtworkTag extends Tag{
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArtworkTagException
|
||||
*/
|
||||
public function Create(): void{
|
||||
$this->Validate();
|
||||
|
||||
|
@ -57,7 +63,7 @@ class ArtworkTag extends Tag{
|
|||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\ValidationException
|
||||
* @throws Exceptions\InvalidArtworkTagException
|
||||
*/
|
||||
public static function GetOrCreate(ArtworkTag $artworkTag): ArtworkTag{
|
||||
$result = Db::Query('
|
||||
|
|
|
@ -39,6 +39,7 @@ class AtomFeed extends Feed{
|
|||
// Did we actually update the feed? If so, write to file and update the index
|
||||
if($this->HasChanged($this->Path)){
|
||||
// Files don't match, save the file
|
||||
/** @throws void */
|
||||
$this->Updated = new DateTimeImmutable();
|
||||
$this->Save();
|
||||
return true;
|
||||
|
|
|
@ -188,6 +188,7 @@ class DbConnection{
|
|||
switch($metadata[$i]['native_type'] ?? null){
|
||||
case 'DATETIME':
|
||||
case 'TIMESTAMP':
|
||||
/** @throws void */
|
||||
$object->{$metadata[$i]['name']} = new DateTimeImmutable($row[$i], new DateTimeZone('UTC'));
|
||||
break;
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?
|
||||
|
||||
use Safe\DateTimeImmutable;
|
||||
|
||||
use function Safe\file_get_contents;
|
||||
use function Safe\filesize;
|
||||
use function Safe\json_encode;
|
||||
|
@ -75,6 +77,11 @@ class Ebook{
|
|||
public ?string $TextSinglePageSizeUnit = null;
|
||||
public $TocEntries = null; // A list of non-Roman ToC entries ONLY IF the work has the 'se:is-a-collection' metadata element, null otherwise
|
||||
|
||||
/**
|
||||
* @throws Exceptions\EbookNotFoundException
|
||||
* @throws Exceptions\EbookParsingException
|
||||
* @throws Exceptions\InvalidGitCommitException
|
||||
*/
|
||||
public function __construct(?string $wwwFilesystemPath = null){
|
||||
if($wwwFilesystemPath === null){
|
||||
return;
|
||||
|
@ -88,7 +95,7 @@ class Ebook{
|
|||
try{
|
||||
$this->RepoFilesystemPath = preg_replace('/\.git$/ius', '', $this->RepoFilesystemPath);
|
||||
}
|
||||
catch(Exception){
|
||||
catch(\Exception){
|
||||
// We may get an exception from preg_replace if the passed repo wwwFilesystemPath contains invalid UTF-8 characters, whichis a common injection attack vector
|
||||
throw new Exceptions\EbookNotFoundException('Invalid repo filesystem path: ' . $this->RepoFilesystemPath);
|
||||
}
|
||||
|
@ -128,11 +135,16 @@ class Ebook{
|
|||
$bytes = @filesize($this->WwwFilesystemPath . '/text/single-page.xhtml');
|
||||
$sizes = 'BKMGTP';
|
||||
$factor = intval(floor((strlen((string)$bytes) - 1) / 3));
|
||||
$this->TextSinglePageSizeNumber = sprintf('%.1f', $bytes / pow(1024, $factor));
|
||||
try{
|
||||
$this->TextSinglePageSizeNumber = sprintf('%.1f', $bytes / pow(1024, $factor));
|
||||
}
|
||||
catch(\DivisionByZeroError){
|
||||
$this->TextSinglePageSizeNumber = '0';
|
||||
}
|
||||
$this->TextSinglePageSizeUnit = $sizes[$factor] ?? '';
|
||||
$this->TextSinglePageUrl = $this->Url . '/text/single-page';
|
||||
}
|
||||
catch(Exception){
|
||||
catch(\Exception){
|
||||
// Single page file doesn't exist, just pass
|
||||
}
|
||||
|
||||
|
@ -206,7 +218,13 @@ class Ebook{
|
|||
}
|
||||
|
||||
// Now do some heavy XML lifting!
|
||||
$xml = new SimpleXMLElement(str_replace('xmlns=', 'ns=', $rawMetadata));
|
||||
try{
|
||||
$xml = new SimpleXMLElement(str_replace('xmlns=', 'ns=', $rawMetadata));
|
||||
}
|
||||
catch(\Exception $ex){
|
||||
throw new Exceptions\EbookParsingException($ex->getMessage());
|
||||
}
|
||||
|
||||
$xml->registerXPathNamespace('dc', 'http://purl.org/dc/elements/1.1/');
|
||||
|
||||
$this->Title = $this->NullIfEmpty($xml->xpath('/package/metadata/dc:title'));
|
||||
|
@ -222,11 +240,13 @@ class Ebook{
|
|||
|
||||
$date = $xml->xpath('/package/metadata/dc:date') ?: [];
|
||||
if($date !== false && sizeof($date) > 0){
|
||||
/** @throws void */
|
||||
$this->Created = new DateTimeImmutable((string)$date[0]);
|
||||
}
|
||||
|
||||
$modifiedDate = $xml->xpath('/package/metadata/meta[@property="dcterms:modified"]') ?: [];
|
||||
if($modifiedDate !== false && sizeof($modifiedDate) > 0){
|
||||
/** @throws void */
|
||||
$this->Updated = new DateTimeImmutable((string)$modifiedDate[0]);
|
||||
}
|
||||
|
||||
|
@ -240,7 +260,12 @@ class Ebook{
|
|||
// Fill the ToC if necessary
|
||||
if($includeToc){
|
||||
$this->TocEntries = [];
|
||||
$tocDom = new SimpleXMLElement(str_replace('xmlns=', 'ns=', file_get_contents($wwwFilesystemPath . '/toc.xhtml')));
|
||||
try{
|
||||
$tocDom = new SimpleXMLElement(str_replace('xmlns=', 'ns=', file_get_contents($wwwFilesystemPath . '/toc.xhtml')));
|
||||
}
|
||||
catch(\Exception $ex){
|
||||
throw new Exceptions\EbookParsingException($ex->getMessage());
|
||||
}
|
||||
$tocDom->registerXPathNamespace('epub', 'http://www.idpf.org/2007/ops');
|
||||
foreach($tocDom->xpath('/html/body//nav[@epub:type="toc"]//a[not(contains(@epub:type, "z3998:roman")) and not(text() = "Titlepage" or text() = "Imprint" or text() = "Colophon" or text() = "Endnotes" or text() = "Uncopyright") and not(contains(@href, "halftitle"))]') ?: [] as $item){
|
||||
$this->TocEntries[] = (string)$item;
|
||||
|
|
5
lib/Exceptions/InvalidGitCommitException.php
Normal file
5
lib/Exceptions/InvalidGitCommitException.php
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?
|
||||
namespace Exceptions;
|
||||
|
||||
class InvalidGitCommitException extends AppException{
|
||||
}
|
|
@ -6,8 +6,16 @@ class GitCommit{
|
|||
public string $Message;
|
||||
public string $Hash;
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidGitCommitException
|
||||
*/
|
||||
public function __construct(string $unixTimestamp, string $hash, string $message){
|
||||
$this->Created = new DateTimeImmutable('@' . $unixTimestamp);
|
||||
try{
|
||||
$this->Created = new DateTimeImmutable('@' . $unixTimestamp);
|
||||
}
|
||||
catch(\Exception){
|
||||
throw new Exceptions\InvalidGitCommitException('Invalid timestamp for Git commit.');
|
||||
}
|
||||
$this->Message = $message;
|
||||
$this->Hash = $hash;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
<?
|
||||
|
||||
use Safe\Exceptions\ImageException;
|
||||
use Exceptions\InvalidImageUploadException;
|
||||
|
||||
use function Safe\exec;
|
||||
use function Safe\imagecopyresampled;
|
||||
use function Safe\imagecreatetruecolor;
|
||||
|
@ -69,19 +73,37 @@ class Image{
|
|||
return $handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidImageUploadException
|
||||
*/
|
||||
public function Resize(string $destImagePath, int $width, int $height): void{
|
||||
$imageDimensions = getimagesize($this->Path);
|
||||
try{
|
||||
$imageDimensions = getimagesize($this->Path);
|
||||
}
|
||||
catch(\Safe\Exceptions\ImageException $ex){
|
||||
throw new Exceptions\InvalidImageUploadException($ex->getMessage());
|
||||
}
|
||||
|
||||
$imageWidth = $imageDimensions[0];
|
||||
$imageHeight = $imageDimensions[1];
|
||||
|
||||
if($imageHeight > $imageWidth){
|
||||
$destinationHeight = $height;
|
||||
$destinationWidth = intval($destinationHeight * ($imageWidth / $imageHeight));
|
||||
try{
|
||||
$destinationWidth = intval($destinationHeight * ($imageWidth / $imageHeight));
|
||||
}
|
||||
catch(\DivisionByZeroError){
|
||||
$destinationWidth = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
$destinationWidth = $width;
|
||||
$destinationHeight = intval($destinationWidth * ($imageHeight / $imageWidth));
|
||||
try{
|
||||
$destinationHeight = intval($destinationWidth * ($imageHeight / $imageWidth));
|
||||
}
|
||||
catch(\DivisionByZeroError){
|
||||
$destinationHeight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$srcImageHandle = $this->GetImageHandle();
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
<?
|
||||
|
||||
use Exceptions\AppException;
|
||||
use Exceptions\ArtistNotFoundException;
|
||||
use Safe\DateTimeImmutable;
|
||||
use Safe\Exceptions\ExecException;
|
||||
use Safe\Exceptions\PcreException;
|
||||
use Safe\Exceptions\FilesystemException;
|
||||
use Safe\Exceptions\DatetimeException;
|
||||
use Safe\Exceptions\ArrayException;
|
||||
use Safe\Exceptions\MiscException;
|
||||
|
||||
use function Safe\apcu_fetch;
|
||||
use function Safe\exec;
|
||||
use function Safe\filemtime;
|
||||
|
@ -18,6 +28,7 @@ class Library{
|
|||
* @param array<string> $tags
|
||||
* @param EbookSort $sort
|
||||
* @return array<Ebook>
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
public static function FilterEbooks(string $query = null, array $tags = [], EbookSort $sort = null){
|
||||
$ebooks = Library::GetEbooks();
|
||||
|
@ -109,6 +120,7 @@ class Library{
|
|||
|
||||
/**
|
||||
* @return array<Ebook>
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
public static function GetEbooks(): array{
|
||||
// Get all ebooks, unsorted.
|
||||
|
@ -117,6 +129,7 @@ class Library{
|
|||
|
||||
/**
|
||||
* @return array<Ebook>
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
public static function GetEbooksByAuthor(string $wwwFilesystemPath): array{
|
||||
return self::GetFromApcu('author-' . $wwwFilesystemPath);
|
||||
|
@ -136,6 +149,7 @@ class Library{
|
|||
|
||||
/**
|
||||
* @return array<string, Collection>
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
public static function GetEbookCollections(): array{
|
||||
return self::GetFromApcu('collections');
|
||||
|
@ -143,6 +157,7 @@ class Library{
|
|||
|
||||
/**
|
||||
* @return array<Ebook>
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
public static function GetEbooksByCollection(string $collection): array{
|
||||
// Do we have the tag's ebooks cached?
|
||||
|
@ -151,6 +166,7 @@ class Library{
|
|||
|
||||
/**
|
||||
* @return array<Tag>
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
public static function GetTags(): array{
|
||||
return self::GetFromApcu('tags');
|
||||
|
@ -303,8 +319,10 @@ class Library{
|
|||
return ['artworks' => $artworks, 'artworksCount' => $artworksCount];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array<Artwork>
|
||||
* @return array<Artwork>
|
||||
* @throws Exceptions\ArtistNotFoundException
|
||||
*/
|
||||
public static function GetArtworksByArtist(?string $artistUrlName, ?string $status, ?int $submitterUserId): array{
|
||||
if($artistUrlName === null){
|
||||
|
@ -346,8 +364,10 @@ class Library{
|
|||
return $artworks;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
private static function GetFromApcu(string $variable): array{
|
||||
$results = [];
|
||||
|
@ -389,6 +409,7 @@ class Library{
|
|||
|
||||
/**
|
||||
* @return array<Ebook>
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
public static function Search(string $query): array{
|
||||
$ebooks = Library::GetEbooks();
|
||||
|
@ -432,6 +453,8 @@ class Library{
|
|||
|
||||
private static function FillBulkDownloadObject(string $dir, string $downloadType, string $urlRoot): stdClass{
|
||||
$obj = new stdClass();
|
||||
|
||||
/** @throws void */
|
||||
$now = new DateTimeImmutable();
|
||||
|
||||
// The count of ebooks in each file is stored as a filesystem attribute
|
||||
|
@ -479,6 +502,7 @@ class Library{
|
|||
$obj->ZipFiles[] = $zipFile;
|
||||
}
|
||||
|
||||
/** @throws void */
|
||||
$obj->Updated = new DateTimeImmutable('@' . filemtime($files[0]));
|
||||
$obj->UpdatedString = $obj->Updated->format('M j');
|
||||
// Add a period to the abbreviated month, but not if it's May (the only 3-letter month)
|
||||
|
@ -526,6 +550,7 @@ class Library{
|
|||
|
||||
/**
|
||||
* @return array<string, array<int|string, array<int|string, mixed>>>
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
public static function RebuildBulkDownloadsCache(): array{
|
||||
$collator = Collator::create('en_US'); // Used for sorting letters with diacritics like in author names
|
||||
|
@ -546,7 +571,12 @@ class Library{
|
|||
foreach($dirs as $dir){
|
||||
$obj = self::FillBulkDownloadObject($dir, 'months', '/months');
|
||||
|
||||
$date = new DateTimeImmutable($obj->Label . '-01');
|
||||
try{
|
||||
$date = new DateTimeImmutable($obj->Label . '-01');
|
||||
}
|
||||
catch(\Exception){
|
||||
throw new Exceptions\AppException('Couldn\'t parse date on bulk download object.');
|
||||
}
|
||||
$year = $date->format('Y');
|
||||
$month = $date->format('F');
|
||||
|
||||
|
@ -588,6 +618,7 @@ class Library{
|
|||
|
||||
/**
|
||||
* @return array<string, array<int|string, array<int|string, mixed>>>
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
public static function RebuildFeedsCache(?string $returnType = null, ?string $returnClass = null): ?array{
|
||||
$feedTypes = ['opds', 'atom', 'rss'];
|
||||
|
@ -634,6 +665,9 @@ class Library{
|
|||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
public static function GetEbook(?string $ebookWwwFilesystemPath): ?Ebook{
|
||||
if($ebookWwwFilesystemPath === null){
|
||||
return null;
|
||||
|
@ -649,6 +683,9 @@ class Library{
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\AppException
|
||||
*/
|
||||
public static function RebuildCache(): void{
|
||||
// We check a lockfile because this can be a long-running command.
|
||||
// We don't want to queue up a bunch of these in case someone is refreshing the index constantly.
|
||||
|
|
|
@ -33,6 +33,7 @@ class Log{
|
|||
return;
|
||||
}
|
||||
|
||||
/** @throws void */
|
||||
$now = new DateTimeImmutable();
|
||||
|
||||
fwrite($fp, $now->format('Y-m-d H:i:s') . "\t" . $this->RequestId . "\t" . $text . "\n");
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
<?
|
||||
|
||||
use Exceptions\InvalidUrlException;
|
||||
use Safe\Exceptions\PcreException;
|
||||
use Exceptions\InvalidMuseumUrlException;
|
||||
use Exceptions\InvalidPageScanUrlException;
|
||||
|
||||
use function Safe\parse_url;
|
||||
use function Safe\preg_match;
|
||||
use function Safe\preg_replace;
|
||||
|
@ -10,6 +16,11 @@ class Museum{
|
|||
public string $Name;
|
||||
public string $Domain;
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidUrlException
|
||||
* @throws Exceptions\InvalidMuseumUrlException
|
||||
* @throws Exceptions\InvalidPageScanUrlException
|
||||
*/
|
||||
public static function NormalizeUrl(string $url): string{
|
||||
$outputUrl = $url;
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<?
|
||||
|
||||
use Exceptions\InvalidNewsletterSubscription;
|
||||
use Exceptions\NewsletterSubscriptionExistsException;
|
||||
use Safe\DateTimeImmutable;
|
||||
use Safe\Exceptions\ErrorfuncException;
|
||||
|
||||
/**
|
||||
* @property User $User
|
||||
|
@ -33,6 +37,10 @@ class NewsletterSubscription{
|
|||
// METHODS
|
||||
// *******
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidNewsletterSubscription
|
||||
* @throws Exceptions\NewsletterSubscriptionExistsException
|
||||
*/
|
||||
public function Create(?string $expectedCaptcha = null, ?string $receivedCaptcha = null): void{
|
||||
$this->Validate($expectedCaptcha, $receivedCaptcha);
|
||||
|
||||
|
@ -42,10 +50,18 @@ class NewsletterSubscription{
|
|||
}
|
||||
catch(Exceptions\UserNotFoundException){
|
||||
// User doesn't exist, create the user
|
||||
$this->User->Create();
|
||||
|
||||
try{
|
||||
$this->User->Create();
|
||||
}
|
||||
catch(Exceptions\UserExistsException){
|
||||
// User exists, pass
|
||||
}
|
||||
}
|
||||
|
||||
$this->UserId = $this->User->UserId;
|
||||
|
||||
/** @throws void */
|
||||
$this->Created = new DateTimeImmutable();
|
||||
|
||||
try{
|
||||
|
@ -66,6 +82,9 @@ class NewsletterSubscription{
|
|||
$this->SendConfirmationEmail();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidNewsletterSubscription
|
||||
*/
|
||||
public function Save(): void{
|
||||
$this->Validate();
|
||||
|
||||
|
@ -107,6 +126,10 @@ class NewsletterSubscription{
|
|||
', [$this->UserId]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidNewsletterSubscription
|
||||
*/
|
||||
public function Validate(?string $expectedCaptcha = null, ?string $receivedCaptcha = null): void{
|
||||
$error = new Exceptions\InvalidNewsletterSubscription();
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ class OpdsFeed extends AtomFeed{
|
|||
if($this->HasChanged($this->Path)){
|
||||
// Files don't match, save the file and update the parent navigation feed with the last updated timestamp
|
||||
|
||||
/** @throws void */
|
||||
$this->Updated = new DateTimeImmutable();
|
||||
|
||||
if($this->Parent !== null){
|
||||
|
|
|
@ -21,6 +21,7 @@ class Patron{
|
|||
// *******
|
||||
|
||||
public function Create(): void{
|
||||
/** @throws void */
|
||||
$this->Created = new DateTimeImmutable();
|
||||
Db::Query('
|
||||
INSERT into Patrons (Created, UserId, IsAnonymous, AlternateName, IsSubscribedToEmails)
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<?
|
||||
|
||||
use Exceptions\UserExistsException;
|
||||
use Exceptions\PaymentExistsException;
|
||||
use Safe\DateTimeImmutable;
|
||||
|
||||
/**
|
||||
|
@ -23,6 +26,9 @@ class Payment{
|
|||
// METHODS
|
||||
// *******
|
||||
|
||||
/**
|
||||
* @throws Exceptions\PaymentExistsException
|
||||
*/
|
||||
public function Create(): void{
|
||||
if($this->UserId === null){
|
||||
// Check if we have to create a new user in the database
|
||||
|
@ -45,7 +51,13 @@ class Payment{
|
|||
}
|
||||
catch(Exceptions\UserNotFoundException){
|
||||
// User doesn't exist, create it now
|
||||
$this->User->Create();
|
||||
|
||||
try{
|
||||
$this->User->Create();
|
||||
}
|
||||
catch(Exceptions\UserExistsException){
|
||||
// User already exists, pass
|
||||
}
|
||||
}
|
||||
|
||||
$this->UserId = $this->User->UserId;
|
||||
|
|
|
@ -87,6 +87,7 @@ class Poll{
|
|||
// *******
|
||||
|
||||
public function IsActive(): bool{
|
||||
/** @throws void */
|
||||
$now = new DateTimeImmutable();
|
||||
if( ($this->Start !== null && $this->Start > $now) || ($this->End !== null && $this->End < $now)){
|
||||
return false;
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<?
|
||||
|
||||
use Exceptions\PollItemNotFoundException;
|
||||
|
||||
/**
|
||||
* @property int $VoteCount
|
||||
* @property Poll $Poll
|
||||
|
@ -37,7 +40,7 @@ class PollItem{
|
|||
// ***********
|
||||
|
||||
/**
|
||||
* @throws Exceptions\PollNotFoundException
|
||||
* @throws Exceptions\PollItemNotFoundException
|
||||
*/
|
||||
public static function Get(?int $pollItemId): PollItem{
|
||||
if($pollItemId === null ){
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
|
||||
use Exceptions\InvalidPollVoteException;
|
||||
use Safe\DateTimeImmutable;
|
||||
|
||||
/**
|
||||
|
@ -86,6 +88,9 @@ class PollVote{
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidPollVoteException
|
||||
*/
|
||||
public function Create(?string $email = null): void{
|
||||
if($email !== null){
|
||||
try{
|
||||
|
@ -103,13 +108,11 @@ class PollVote{
|
|||
}
|
||||
|
||||
$this->Validate();
|
||||
$this->Created = new DateTimeImmutable();
|
||||
Db::Query('
|
||||
INSERT into PollVotes (UserId, PollItemId, Created)
|
||||
INSERT into PollVotes (UserId, PollItemId)
|
||||
values (?,
|
||||
?,
|
||||
?)
|
||||
', [$this->UserId, $this->PollItemId, $this->Created]);
|
||||
', [$this->UserId, $this->PollItemId]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<?
|
||||
use Safe\DateTimeImmutable;
|
||||
use Safe\Exceptions\DatetimeException;
|
||||
use Safe\Exceptions\FilesystemException;
|
||||
use Safe\Exceptions\ExecException;
|
||||
|
||||
use function Safe\file_get_contents;
|
||||
use function Safe\filesize;
|
||||
use function Safe\preg_replace;
|
||||
|
@ -27,7 +31,9 @@ class RssFeed extends Feed{
|
|||
|
||||
protected function GetXmlString(): string{
|
||||
if($this->XmlString === null){
|
||||
$feed = Template::RssFeed(['url' => $this->Url, 'description' => $this->Description, 'title' => $this->Title, 'entries' => $this->Entries, 'updated' => (new DateTimeImmutable())->format('r')]);
|
||||
/** @throws void */
|
||||
$timestamp = (new DateTimeImmutable())->format('r');
|
||||
$feed = Template::RssFeed(['url' => $this->Url, 'description' => $this->Description, 'title' => $this->Title, 'entries' => $this->Entries, 'updated' => $timestamp]);
|
||||
|
||||
$this->XmlString = $this->CleanXmlString($feed);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<?
|
||||
use Exceptions\InvalidLoginException;
|
||||
use Exceptions\PasswordRequiredException;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Safe\DateTimeImmutable;
|
||||
use Safe\Exceptions\DatetimeException;
|
||||
|
||||
use function Safe\strtotime;
|
||||
|
||||
/**
|
||||
|
@ -35,6 +38,10 @@ class Session{
|
|||
// METHODS
|
||||
// *******
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidLoginException
|
||||
* @throws Exceptions\PasswordRequiredException
|
||||
*/
|
||||
public function Create(?string $email = null, ?string $password = null): void{
|
||||
try{
|
||||
$this->User = User::GetIfRegistered($email, $password);
|
||||
|
@ -54,6 +61,8 @@ class Session{
|
|||
else{
|
||||
$uuid = Uuid::uuid4();
|
||||
$this->SessionId = $uuid->toString();
|
||||
|
||||
/** @throws void */
|
||||
$this->Created = new DateTimeImmutable();
|
||||
Db::Query('
|
||||
INSERT into Sessions (UserId, SessionId, Created)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
|
||||
use Exceptions\UserExistsException;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Safe\DateTimeImmutable;
|
||||
|
||||
|
@ -77,9 +79,14 @@ class User{
|
|||
// METHODS
|
||||
// *******
|
||||
|
||||
/**
|
||||
* @throws UserExistsException
|
||||
*/
|
||||
public function Create(?string $password = null): void{
|
||||
$uuid = Uuid::uuid4();
|
||||
$this->Uuid = $uuid->toString();
|
||||
|
||||
/** @throws void */
|
||||
$this->Created = new DateTimeImmutable();
|
||||
|
||||
$this->PasswordHash = null;
|
||||
|
@ -145,6 +152,7 @@ class User{
|
|||
|
||||
/**
|
||||
* @throws Exceptions\UserNotFoundException
|
||||
* @throws Exceptions\PasswordRequiredException
|
||||
*/
|
||||
public static function GetIfRegistered(?string $identifier, ?string $password = null): User{
|
||||
// We consider a user "registered" if they have a row in the Benefits table.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue