diff --git a/lib/Artist.php b/lib/Artist.php index e177fd2f..fd072c72 100644 --- a/lib/Artist.php +++ b/lib/Artist.php @@ -87,9 +87,7 @@ class Artist{ * @throws Exceptions\InvalidArtistException */ public function Validate(): void{ - /** @throws void */ - $now = new DateTimeImmutable(); - $thisYear = intval($now->format('Y')); + $thisYear = intval(NOW->format('Y')); $error = new Exceptions\InvalidArtistException(); diff --git a/lib/Artwork.php b/lib/Artwork.php index dc159742..cc563983 100644 --- a/lib/Artwork.php +++ b/lib/Artwork.php @@ -330,9 +330,7 @@ class Artwork{ * @throws Exceptions\InvalidArtworkException */ protected function Validate(?string $imagePath = null, bool $isImageRequired = true): void{ - /** @throws void */ - $now = new DateTimeImmutable(); - $thisYear = intval($now->format('Y')); + $thisYear = intval(NOW->format('Y')); $error = new Exceptions\InvalidArtworkException(); if($this->Artist === null){ @@ -664,8 +662,7 @@ class Artwork{ $this->Validate($imagePath, true); - /** @throws void */ - $this->Created = new DateTimeImmutable(); + $this->Created = NOW; $tags = []; foreach($this->Tags as $artworkTag){ @@ -731,10 +728,8 @@ class Artwork{ if($imagePath !== null){ $this->MimeType = ImageMimeType::FromFile($imagePath); - // 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(); + // Manually set the updated timestamp, because if we only update the image and nothing else, the row's updated timestamp won't change automatically. + $this->Updated = NOW; $this->_ImageUrl = null; $this->_ThumbUrl = null; $this->_Thumb2xUrl = null; @@ -751,12 +746,12 @@ class Artwork{ $newDeathYear = $this->Artist->DeathYear; $this->Artist = Artist::GetOrCreate($this->Artist); - // Save the artist death year in case we changed it + // Save the artist death year in case we changed it. if($newDeathYear != $this->Artist->DeathYear){ Db::Query('UPDATE Artists set DeathYear = ? where ArtistId = ?', [$newDeathYear , $this->Artist->ArtistId]); } - // Save the artwork + // Save the artwork. Db::Query(' UPDATE Artworks set @@ -787,9 +782,8 @@ class Artwork{ $this->ArtworkId] ); - // Delete artists who are no longer to attached to an artwork - // Don't delete from the ArtistAlternateNames table to prevent accidentally - // deleting those manually-added entries. + // Delete artists who are no longer to attached to an artwork. + // Don't delete from the ArtistAlternateNames table to prevent accidentally deleting those manually-added entries. Db::Query(' DELETE from Artists @@ -797,7 +791,7 @@ class Artwork{ (select distinct ArtistId from Artworks) '); - // Update tags for this artwork + // Update tags for this artwork. Db::Query(' DELETE from ArtworkTags where diff --git a/lib/AtomFeed.php b/lib/AtomFeed.php index 5e338081..1762f44f 100644 --- a/lib/AtomFeed.php +++ b/lib/AtomFeed.php @@ -39,8 +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->Updated = NOW; $this->Save(); return true; } diff --git a/lib/Constants.php b/lib/Constants.php index 1ee8a286..494de623 100644 --- a/lib/Constants.php +++ b/lib/Constants.php @@ -1,15 +1,14 @@ -// Auto-included by Composer in composer.json to satisfy PHPStan +// Auto-included by Composer in composer.json to satisfy PHPStan. use Safe\DateTimeImmutable; use function Safe\define; -$now = new DateTimeImmutable(); -$nowPd = new DateTimeImmutable('now', new DateTimeZone('America/Juneau')); // Latest continental US time zone +const NOW = new DateTimeImmutable(); const SITE_STATUS_LIVE = 'live'; const SITE_STATUS_DEV = 'dev'; -define('SITE_STATUS', get_cfg_var('app.site_status') ?: SITE_STATUS_DEV); // Set in the PHP INI configuration for both CLI and FPM. Have to use define() and not const so we can use a function. +define('SITE_STATUS', get_cfg_var('app.site_status') ?: SITE_STATUS_DEV); // Set in the PHP INI configuration for both CLI and FPM. Have to use `define()` and not `const` so we can use a function. // No trailing slash on any of the below constants. if(SITE_STATUS == SITE_STATUS_LIVE){ @@ -44,7 +43,7 @@ const ARTWORK_IMAGE_MINIMUM_HEIGHT = 300; const CAPTCHA_IMAGE_HEIGHT = 72; const CAPTCHA_IMAGE_WIDTH = 230; -// These are defined for convenience, so that getting HTTP input isn't so wordy +// These are defined for convenience, so that getting HTTP input isn't so wordy. const GET = Enums\HttpVariableSource::Get; const POST = Enums\HttpVariableSource::Post; const SESSION = Enums\HttpVariableSource::Session; @@ -72,18 +71,18 @@ const ZOHO_WEBHOOK_LOG_FILE_PATH = '/var/log/local/webhooks-zoho.log'; // Must b const DONATIONS_LOG_FILE_PATH = '/var/log/local/donations.log'; // Must be writable by `www-data` Unix user. const ARTWORK_UPLOADS_LOG_FILE_PATH = '/var/log/local/artwork-uploads.log'; // Must be writable by `www-data` Unix user. -define('PD_YEAR', intval($nowPd->format('Y')) - 96); +define('PD_YEAR', intval((new DateTimeImmutable('now', new DateTimeZone('America/Juneau')))->format('Y')) - 96); // Latest continental US time zone. define('PD_STRING', 'January 1, ' . (PD_YEAR + 1)); -define('DONATION_HOLIDAY_ALERT_ON', $now > new DateTimeImmutable('November 15, ' . $now->format('Y')) || $now < new DateTimeImmutable('January 7, ' . $now->add(new DateInterval('P1Y'))->format('Y'))); +define('DONATION_HOLIDAY_ALERT_ON', NOW > new DateTimeImmutable('November 15, ' . NOW->format('Y')) || NOW < new DateTimeImmutable('January 7, ' . NOW->add(new DateInterval('P1Y'))->format('Y'))); define('DONATION_ALERT_ON', DONATION_HOLIDAY_ALERT_ON || rand(1, 4) == 2); // Controls the progress bar donation dialog const DONATION_DRIVE_ON = true; -const DONATION_DRIVE_START = 'May 20, 2024 00:00:00 America/New_York'; -const DONATION_DRIVE_END = 'June 3, 2024 23:59:00 America/New_York'; +const DONATION_DRIVE_START = new DateTimeImmutable('May 20, 2024 00:00:00 America/New_York'); +const DONATION_DRIVE_END = new DateTimeImmutable('June 3, 2024 23:59:00 America/New_York'); // Controls the countdown donation dialog const DONATION_DRIVE_COUNTER_ON = false; -const DONATION_DRIVE_COUNTER_START = 'May 2, 2022 00:00:00 America/New_York'; -const DONATION_DRIVE_COUNTER_END = 'May 8, 2022 23:59:00 America/New_York'; +const DONATION_DRIVE_COUNTER_START = new DateTimeImmutable('May 2, 2022 00:00:00 America/New_York'); +const DONATION_DRIVE_COUNTER_END = new DateTimeImmutable('May 8, 2022 23:59:00 America/New_York'); diff --git a/lib/Library.php b/lib/Library.php index 0c826ad5..281ffb3f 100644 --- a/lib/Library.php +++ b/lib/Library.php @@ -446,9 +446,6 @@ 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 $obj->EbookCount = exec('attr -g se-ebook-count ' . escapeshellarg($dir)) ?: null; if($obj->EbookCount == null){ @@ -499,7 +496,7 @@ class Library{ $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) $obj->UpdatedString = preg_replace('/^(.+?)(?UpdatedString); - if($obj->Updated->format('Y') != $now->format('Y')){ + if($obj->Updated->format('Y') != NOW->format('Y')){ $obj->UpdatedString = $obj->Updated->format('M j, Y'); } diff --git a/lib/Log.php b/lib/Log.php index 201dcda4..4c805597 100644 --- a/lib/Log.php +++ b/lib/Log.php @@ -33,10 +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"); + fwrite($fp, NOW->format('Y-m-d H:i:s') . "\t" . $this->RequestId . "\t" . $text . "\n"); fclose($fp); } } diff --git a/lib/NewsletterSubscription.php b/lib/NewsletterSubscription.php index 534d59a3..fe2dd10c 100644 --- a/lib/NewsletterSubscription.php +++ b/lib/NewsletterSubscription.php @@ -57,8 +57,7 @@ class NewsletterSubscription{ $this->UserId = $this->User->UserId; - /** @throws void */ - $this->Created = new DateTimeImmutable(); + $this->Created = NOW; try{ Db::Query(' diff --git a/lib/OpdsFeed.php b/lib/OpdsFeed.php index 7a22cafe..169ca83c 100644 --- a/lib/OpdsFeed.php +++ b/lib/OpdsFeed.php @@ -50,8 +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(); + $this->Updated = NOW; if($this->Parent !== null){ $this->Parent->SaveUpdated($this->Id, $this->Updated); diff --git a/lib/Patron.php b/lib/Patron.php index 35e6308b..381224b1 100644 --- a/lib/Patron.php +++ b/lib/Patron.php @@ -21,8 +21,7 @@ class Patron{ // ******* public function Create(): void{ - /** @throws void */ - $this->Created = new DateTimeImmutable(); + $this->Created = NOW; Db::Query(' INSERT into Patrons (Created, UserId, IsAnonymous, AlternateName, IsSubscribedToEmails) values(?, diff --git a/lib/Poll.php b/lib/Poll.php index 5b0688f6..061aff5d 100644 --- a/lib/Poll.php +++ b/lib/Poll.php @@ -88,8 +88,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)){ + if( ($this->Start !== null && $this->Start > NOW) || ($this->End !== null && $this->End < NOW)){ return false; } diff --git a/lib/RssFeed.php b/lib/RssFeed.php index fa4179d7..716b26c0 100644 --- a/lib/RssFeed.php +++ b/lib/RssFeed.php @@ -24,8 +24,7 @@ class RssFeed extends Feed{ protected function GetXmlString(): string{ if($this->XmlString === null){ - /** @throws void */ - $timestamp = (new DateTimeImmutable())->format('r'); + $timestamp = NOW->format('r'); $feed = Template::RssFeed(['url' => $this->Url, 'description' => $this->Description, 'title' => $this->Title, 'entries' => $this->Entries, 'updated' => $timestamp]); $this->XmlString = $this->CleanXmlString($feed); diff --git a/lib/Session.php b/lib/Session.php index 4ad00afc..853115b1 100644 --- a/lib/Session.php +++ b/lib/Session.php @@ -60,8 +60,7 @@ class Session{ $uuid = Uuid::uuid4(); $this->SessionId = $uuid->toString(); - /** @throws void */ - $this->Created = new DateTimeImmutable(); + $this->Created = NOW; Db::Query(' INSERT into Sessions (UserId, SessionId, Created) values (?, diff --git a/lib/User.php b/lib/User.php index 1ae71ad5..553806c6 100644 --- a/lib/User.php +++ b/lib/User.php @@ -85,8 +85,7 @@ class User{ $uuid = Uuid::uuid4(); $this->Uuid = $uuid->toString(); - /** @throws void */ - $this->Created = new DateTimeImmutable(); + $this->Created = NOW; $this->PasswordHash = null; if($password !== null){ diff --git a/scripts/generate-feeds b/scripts/generate-feeds index 69977a65..c7a583b0 100755 --- a/scripts/generate-feeds +++ b/scripts/generate-feeds @@ -114,15 +114,13 @@ usort($allEbooks, 'SortByUpdatedDesc'); usort($newestEbooks, function($a, $b){ return $b->Created <=> $a->Created; }); $newestEbooks = array_slice($newestEbooks, 0, $ebooksPerNewestEbooksFeed); -$now = new DateTimeImmutable(); - // Create OPDS feeds. $opdsRootEntries = [ new OpdsNavigationEntry( 'Newest Standard Ebooks', 'The ' . number_format($ebooksPerNewestEbooksFeed) . ' latest Standard Ebooks, most-recently-released first.', '/feeds/opds/new-releases', - $now, + NOW, 'http://opds-spec.org/sort/new', 'acquisition' ), @@ -130,51 +128,51 @@ $opdsRootEntries = [ 'Standard Ebooks by Subject', 'Browse Standard Ebooks by subject.', '/feeds/opds/subjects', - $now, + NOW, 'subsection', 'navigation'), new OpdsNavigationEntry( 'Standard Ebooks by Collection', 'Browse Standard Ebooks by collection.', '/feeds/opds/collections', - $now, + NOW, 'subsection', 'navigation'), new OpdsNavigationEntry( 'Standard Ebooks by Author', 'Browse Standard Ebooks by author.', '/feeds/opds/authors', - $now, + NOW, 'subsection', 'navigation'), new OpdsNavigationEntry( 'All Standard Ebooks', 'All Standard Ebooks, most-recently-updated first. This is a Complete Acquisition Feed as defined in OPDS 1.2 §2.5.', '/feeds/opds/all', - $now, + NOW, 'http://opds-spec.org/crawlable', 'acquisition') ]; $opdsRoot = new OpdsNavigationFeed('Standard Ebooks', 'The Standard Ebooks catalog.', '/feeds/opds', $webRoot . '/feeds/opds/index.xml', $opdsRootEntries, null); -SaveFeed($opdsRoot, $force, null, null, $now); +SaveFeed($opdsRoot, $force, null, null, NOW); // Create the Subjects feeds. -CreateOpdsCollectionFeed('subject', '/feeds/opds/subjects', 'Standard Ebooks in the “%s” subject, most-recently-released first.', $subjects, $ebooksBySubject, $now, $webRoot, $opdsRoot, $force); +CreateOpdsCollectionFeed('subject', '/feeds/opds/subjects', 'Standard Ebooks in the “%s” subject, most-recently-released first.', $subjects, $ebooksBySubject, NOW, $webRoot, $opdsRoot, $force); // Create the Collections feeds. -CreateOpdsCollectionFeed('collection', '/feeds/opds/collections', 'Standard Ebooks in the “%s” collection, most-recently-released first.', $collections, $ebooksByCollection, $now, $webRoot, $opdsRoot, $force); +CreateOpdsCollectionFeed('collection', '/feeds/opds/collections', 'Standard Ebooks in the “%s” collection, most-recently-released first.', $collections, $ebooksByCollection, NOW, $webRoot, $opdsRoot, $force); // Create the Author feeds. -CreateOpdsCollectionFeed('author', '/feeds/opds/authors', 'Standard Ebooks by %s, most-recently-released first.', $authors, $ebooksByAuthor, $now, $webRoot, $opdsRoot, $force); +CreateOpdsCollectionFeed('author', '/feeds/opds/authors', 'Standard Ebooks by %s, most-recently-released first.', $authors, $ebooksByAuthor, NOW, $webRoot, $opdsRoot, $force); // Create the All feed. $allFeed = new OpdsAcquisitionFeed('All Standard Ebooks', 'All Standard Ebooks, most-recently-updated first. This is a Complete Acquisition Feed as defined in OPDS 1.2 §2.5.', '/feeds/opds/all', $webRoot . '/feeds/opds/all.xml', $allEbooks, $opdsRoot, true); -SaveFeed($allFeed, $force, null, null, $now); +SaveFeed($allFeed, $force, null, null, NOW); // Create the Newest feed. $newestFeed = new OpdsAcquisitionFeed('Newest Standard Ebooks', 'The ' . number_format($ebooksPerNewestEbooksFeed) . ' latest Standard Ebooks, most-recently-released first.', '/feeds/opds/new-releases', $webRoot . '/feeds/opds/new-releases.xml', $newestEbooks, $opdsRoot); -SaveFeed($newestFeed, $force, null, null, $now); +SaveFeed($newestFeed, $force, null, null, NOW); @@ -190,11 +188,11 @@ SaveFeed($newestRssFeed, $force, null, null); // Create the Atom All feed. $allAtomFeed = new AtomFeed('Standard Ebooks - All Ebooks', 'All Standard Ebooks, most-recently-released first.', '/feeds/atom/all', $webRoot . '/feeds/atom/all.xml', $allEbooks); -SaveFeed($allAtomFeed, $force, null, null, $now); +SaveFeed($allAtomFeed, $force, null, null, NOW); // Create the Atom Newest feed. $newestAtomFeed = new AtomFeed('Standard Ebooks - Newest Ebooks', 'The ' . number_format($ebooksPerNewestEbooksFeed) . ' latest Standard Ebooks, most-recently-released first.', '/feeds/atom/new-releases', $webRoot . '/feeds/atom/new-releases.xml', $newestEbooks); -SaveFeed($newestAtomFeed, $force, null, null, $now); +SaveFeed($newestAtomFeed, $force, null, null, NOW); // Generate each individual subject feed. foreach($ebooksBySubject as $subject => $ebooks){ @@ -207,7 +205,7 @@ foreach($ebooksBySubject as $subject => $ebooks){ SaveFeed($subjectRssFeed, $force, $subjects[$subject]['name'], $subjects[$subject]['sortedname']); $subjectAtomFeed = new AtomFeed($title, $subtitle, '/feeds/atom/subjects/' . Formatter::MakeUrlSafe($subject), $webRoot . '/feeds/atom/subjects/' . Formatter::MakeUrlSafe($subject) . '.xml', $ebooks); - SaveFeed($subjectAtomFeed, $force, $subjects[$subject]['name'], $subjects[$subject]['sortedname'], $now); + SaveFeed($subjectAtomFeed, $force, $subjects[$subject]['name'], $subjects[$subject]['sortedname'], NOW); } // Generate each individual collection feed. @@ -223,7 +221,7 @@ foreach($ebooksByCollection as $collection => $ebooks){ SaveFeed($collectionRssFeed, $force, $collections[$collection]['name'], $collections[$collection]['sortedname']); $collectionAtomFeed = new AtomFeed($title, $subtitle, '/feeds/atom/collections/' . Formatter::MakeUrlSafe($collection), $webRoot . '/feeds/atom/collections/' . Formatter::MakeUrlSafe($collection) . '.xml', $ebooks); - SaveFeed($collectionAtomFeed, $force, $collections[$collection]['name'], $collections[$collection]['sortedname'], $now); + SaveFeed($collectionAtomFeed, $force, $collections[$collection]['name'], $collections[$collection]['sortedname'], NOW); } // Generate each individual author feed. @@ -237,7 +235,7 @@ foreach($ebooksByAuthor as $collection => $ebooks){ SaveFeed($collectionRssFeed, $force, $authors[$collection]['name'], $authors[$collection]['sortedname']); $collectionAtomFeed = new AtomFeed($title, $subtitle, '/feeds/atom/authors/' . $authors[$collection]['id'], $webRoot . '/feeds/atom/authors/' . $authors[$collection]['id'] . '.xml', $ebooks); - SaveFeed($collectionAtomFeed, $force, $authors[$collection]['name'], $authors[$collection]['sortedname'], $now); + SaveFeed($collectionAtomFeed, $force, $authors[$collection]['name'], $authors[$collection]['sortedname'], NOW); } // Set ownership and permissions. diff --git a/scripts/ingest-fa-payments b/scripts/ingest-fa-payments index c3bf5c9f..2452c9b2 100755 --- a/scripts/ingest-fa-payments +++ b/scripts/ingest-fa-payments @@ -46,8 +46,7 @@ $lastSeenTransactionId = null; $firstTransactionId = null; $transactionFilePath = '/tmp/last-fa-donation'; $transactionIds = []; -$now = new DateTimeImmutable(); -$today = $now->format('n/j/Y'); +$today = NOW->format('n/j/Y'); $faItemsPerPage = 20; // How many items are on a full page of FA results? // General plan: Read /tmp/last-fa-donation to see what the last transaction ID was that we processed. @@ -94,7 +93,7 @@ try{ } if($lastSeenTransactionId === null){ - $log->Write('No last transaction ID, checking everything from ' . $now->format('Y-m-d')); + $log->Write('No last transaction ID, checking everything from ' . NOW->format('Y-m-d')); } else{ $log->Write('Checking from last transaction ID ' . $lastSeenTransactionId); diff --git a/scripts/update-patrons-circle b/scripts/update-patrons-circle index 0cee2a24..55f619f0 100755 --- a/scripts/update-patrons-circle +++ b/scripts/update-patrons-circle @@ -11,7 +11,6 @@ use function Safe\shell_exec; // Get a list of payments that are within 1 year / 45 days of today, and deactivate Patrons Circle members who aren't in that list. // We give a 15 day grace period to Patrons Circle members because sometimes FA can be delayed in charging. -$now = new DateTimeImmutable(); $lastYear = new DateTimeImmutable('-1 year'); $expiredPatrons = Db::Query(' @@ -29,7 +28,7 @@ $expiredPatrons = Db::Query(' (IsRecurring = false and Amount >= 100 and Created > ? - interval 1 year) ) ) -', [$now, $now], Patron::class); +', [NOW, NOW], Patron::class); if(sizeof($expiredPatrons) > 0){ $ebooksThisYear = 0; @@ -54,7 +53,7 @@ if(sizeof($expiredPatrons) > 0){ UPDATE Patrons set Ended = ? where UserId = ? - ', [$now, $patron->UserId]); + ', [NOW, $patron->UserId]); Db::Query(' UPDATE Benefits diff --git a/templates/ArtworkForm.php b/templates/ArtworkForm.php index d1a34f62..deb6a227 100644 --- a/templates/ArtworkForm.php +++ b/templates/ArtworkForm.php @@ -9,8 +9,6 @@ if($artwork === null){ } $isEditForm = $isEditForm ?? false; - -$now = new DateTimeImmutable('now', new DateTimeZone('America/Juneau')); // Latest continental US time zone ?>