Use a NOW constant instead of new DateTimeImmutable objects, and tweak how some donation drive dates work

This commit is contained in:
Alex Cabal 2024-10-15 22:21:12 -05:00
parent 376dacd833
commit eec79712fc
27 changed files with 108 additions and 143 deletions

View file

@ -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();

View file

@ -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

View file

@ -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;
}

View file

@ -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');

View file

@ -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('/^(.+?)(?<!May) /', '\1. ', $obj->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');
}

View file

@ -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);
}
}

View file

@ -57,8 +57,7 @@ class NewsletterSubscription{
$this->UserId = $this->User->UserId;
/** @throws void */
$this->Created = new DateTimeImmutable();
$this->Created = NOW;
try{
Db::Query('

View file

@ -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);

View file

@ -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(?,

View file

@ -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;
}

View file

@ -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);

View file

@ -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 (?,

View file

@ -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){

View file

@ -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.

View file

@ -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);

View file

@ -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

View file

@ -9,8 +9,6 @@ if($artwork === null){
}
$isEditForm = $isEditForm ?? false;
$now = new DateTimeImmutable('now', new DateTimeZone('America/Juneau')); // Latest continental US time zone
?>
<fieldset>
<legend>Artist details</legend>

View file

@ -1,5 +1,4 @@
<? if($GLOBALS['User'] === null){
// The Kindle browsers renders <aside> as an undismissable popup. Serve a <div> to Kindle instead. See https://github.com/standardebooks/web/issues/204
$element = 'aside';
@ -7,10 +6,8 @@
$element = 'div';
}
?>
<<?= $element ?> class="donation">
<p>We rely on your support to help us keep producing beautiful, free, and unrestricted editions of literature for the digital age.</p>
<p>Will you <a href="/donate">support our efforts with a donation</a>?</p>
</<?= $element ?>>
<<?= $element ?> class="donation">
<p>We rely on your support to help us keep producing beautiful, free, and unrestricted editions of literature for the digital age.</p>
<p>Will you <a href="/donate">support our efforts with a donation</a>?</p>
</<?= $element ?>>
<? } ?>

View file

@ -1,12 +1,6 @@
<?
use Safe\DateTimeImmutable;
$start = new DateTimeImmutable(DONATION_DRIVE_COUNTER_START);
$end = new DateTimeImmutable(DONATION_DRIVE_COUNTER_END);
$now = new DateTimeImmutable();
// Hide the alert if the user has closed it
if(!DONATION_DRIVE_COUNTER_ON || ($autoHide ?? $_COOKIE['hide-donation-alert'] ?? false) || $now > $end){
// Hide the alert if the user has closed it.
if(!DONATION_DRIVE_COUNTER_ON || ($autoHide ?? $_COOKIE['hide-donation-alert'] ?? false) || NOW > DONATION_DRIVE_COUNTER_END){
return;
}
@ -14,12 +8,12 @@ $autoHide = $autoHide ?? true;
$showDonateButton = $showDonateButton ?? true;
$current = 0;
if($now < $start || $now > $end){
if(NOW < DONATION_DRIVE_COUNTER_START || NOW > DONATION_DRIVE_COUNTER_END){
return;
}
$deadline = $end->format('F j');
$timeLeft = $now->diff($end);
$deadline = DONATION_DRIVE_COUNTER_END->format('F j');
$timeLeft = NOW->diff(DONATION_DRIVE_COUNTER_END);
$timeString = '';
if($timeLeft->d < 1 && $timeLeft->h < 20){
$timeString = 'Just hours';
@ -44,14 +38,13 @@ else{
}
$digits = str_split(str_pad($current, 3, "0", STR_PAD_LEFT))
?>
<aside class="donation counter closable">
<? if($autoHide){ ?>
<form action="/settings" method="post">
<input type="hidden" name="hide-donation-alert" value="1" />
<button class="close" title="Close this box">Close this box</button>
</form>
<form action="/settings" method="post">
<input type="hidden" name="hide-donation-alert" value="true" />
<button class="close" title="Close this box">Close this box</button>
</form>
<? } ?>
<header>
<p><?= $timeString ?> left to help us win $1,000</p>
@ -64,5 +57,9 @@ $digits = str_split(str_pad($current, 3, "0", STR_PAD_LEFT))
<p><strong>Each one-time donation of any amount to Standard Ebooks through <?= $deadline ?> gives us one entry in this $1,000 giveaway.</strong> The more donations we receive through <?= $deadline ?>, the more chances we have to win!</p>
<p><strong>This is a great time to <a href="/donate#patrons-circle">join our Patrons Circle</a> with a one-time donation of $100.</strong> Not only will your donation support us directly, but itll give us one more entry in this big giveaway.</p>
<p>Will you show your support for free, beautiful digital literature?</p>
<? if($showDonateButton){ ?><p class="donate-button"><a class="button" href="/donate">Make a one-time donation!</a></p><? } ?>
<? if($showDonateButton){ ?>
<p class="donate-button">
<a class="button" href="/donate">Make a one-time donation!</a>
</p>
<? } ?>
</aside>

View file

@ -1,11 +1,6 @@
<?
use Safe\DateTimeImmutable;
$start = new DateTimeImmutable(DONATION_DRIVE_START);
$end = new DateTimeImmutable(DONATION_DRIVE_END);
$now = new DateTimeImmutable();
$totalCurrent = 0;
$baseTarget = 25;
$baseTarget = 50;
$stretchCurrent = 0;
$stretchTarget = 20;
@ -17,9 +12,9 @@ if(
||
$GLOBALS['User'] !== null // If a user is logged in
||
$start > $now // If the drive hasn't started yet
DONATION_DRIVE_START > NOW // If the drive hasn't started yet
||
$now > $end // If the drive has ended
NOW > DONATION_DRIVE_END // If the drive has ended
){
return;
}
@ -49,11 +44,11 @@ $totalCurrent = Db::QueryInt('
where Created >= ?
)
) x
', [$start, $start, $start]);
', [DONATION_DRIVE_START, DONATION_DRIVE_START, DONATION_DRIVE_START]);
$totalTarget = $baseTarget;
$deadline = $end->format('F j');
$timeLeft = $now->diff($end);
$deadline = DONATION_DRIVE_END->format('F j');
$timeLeft = NOW->diff(DONATION_DRIVE_END);
$timeString = '';
if($timeLeft->days < 1 && $timeLeft->h < 20){
$timeString = 'Just hours';
@ -83,27 +78,26 @@ if($stretchTarget > 0 && $totalCurrent >= $baseTarget){
$stretchCurrent = $totalCurrent - $baseTarget;
$totalTarget = $baseTarget + $stretchTarget;
}
?>
<aside class="donation closable">
<? if($autoHide){ ?>
<form action="/settings" method="post">
<input type="hidden" name="hide-donation-alert" value="1" />
<button class="close" title="Close this box">Close this box</button>
</form>
<form action="/settings" method="post">
<input type="hidden" name="hide-donation-alert" value="true" />
<button class="close" title="Close this box">Close this box</button>
</form>
<? } ?>
<? if(!$stretchOn){ ?>
<header>
<? if($timeLeft->days > 5){ ?>
<p>Help us reach <?= number_format($baseTarget) ?> new patrons by <?= $deadline ?></p>
<? }else{ ?>
<p><?= $timeString ?> left to help us reach <?= number_format($baseTarget) ?> new patrons!</p>
<? } ?>
</header>
<header>
<? if($timeLeft->days > 5){ ?>
<p>Help us reach <?= number_format($baseTarget) ?> new patrons by <?= $deadline ?></p>
<? }else{ ?>
<p><?= $timeString ?> left to help us reach <?= number_format($baseTarget) ?> new patrons!</p>
<? } ?>
</header>
<? }else{ ?>
<header>
<p>Help us meet our stretch goal of<br/> <?= number_format($totalTarget) ?> new patrons by <?= $deadline ?></p>
</header>
<header>
<p>Help us meet our stretch goal of<br/> <?= number_format($totalTarget) ?> new patrons by <?= $deadline ?></p>
</header>
<? } ?>
<div class="progress">
<div aria-hidden="true">
@ -115,14 +109,20 @@ if($stretchTarget > 0 && $totalCurrent >= $baseTarget){
<p class="target"><?= number_format($totalTarget) ?></p>
</div>
<progress max="<?= $baseTarget ?>" value="<?= $totalCurrent - $stretchCurrent ?>"></progress>
<? if($stretchOn){ ?><progress class="stretch" max="<?= $stretchTarget ?>" value="<?= $stretchCurrent ?>"></progress><? } ?>
<? if($stretchOn){ ?>
<progress class="stretch" max="<?= $stretchTarget ?>" value="<?= $stretchCurrent ?>"></progress>
<? } ?>
</div>
<? if($stretchOn){ ?>
<p>When we started this drive, we set a goal of <?= number_format($baseTarget) ?> Patrons Circle members by <?= $deadline ?>. Thanks to the incredible generosity of literature lovers like you, we hit that goal!</p>
<p>Since theres still some time left in our drive, we thought wed challenge our readers to help us reach our stretch goal of <?= number_format($totalTarget) ?> patrons, so that we can continue on a rock-solid financial footing. Will you help us with a donation, and support free and unrestricted digital literature?</p>
<p>When we started this drive, we set a goal of <?= number_format($baseTarget) ?> Patrons Circle members by <?= $deadline ?>. Thanks to the incredible generosity of literature lovers like you, we hit that goal!</p>
<p>Since theres still some time left in our drive, we thought wed challenge our readers to help us reach our stretch goal of <?= number_format($totalTarget) ?> patrons, so that we can continue on a rock-solid financial footing. Will you help us with a donation, and support free and unrestricted digital literature?</p>
<? }else{ ?>
<p>It takes a huge amount of resources and highly-skilled work to create and distribute each of our free ebooks, and we need your support to keep it up. Thats why we want to welcome <?= number_format($baseTarget) ?> new patrons by <?= $deadline ?>. Its our patrons who keep us on the stable financial footing we need to continue producing and giving away beautiful ebooks.</p>
<p>Will you become a patron, and support free and unrestricted digital literature?</p>
<p>It takes a huge amount of resources and highly-skilled work to create and distribute each of our free ebooks, and we need your support to keep it up. Thats why we want to welcome <?= number_format($baseTarget) ?> new patrons by <?= $deadline ?>. Its our patrons who keep us on the stable financial footing we need to continue producing and giving away beautiful ebooks.</p>
<p>Will you become a patron, and support free and unrestricted digital literature?</p>
<? } ?>
<? if($showDonateButton){ ?>
<p class="donate-button">
<a class="button" href="/donate#patrons-circle">Join the patrons circle</a>
</p>
<? } ?>
<? if($showDonateButton){ ?><p class="donate-button"><a class="button" href="/donate#patrons-circle">Join the patrons circle</a></p><? } ?>
</aside>

View file

@ -40,7 +40,7 @@ catch(Exceptions\CollectionNotFoundException){
<?= Template::DonationCounter() ?>
<?= Template::DonationProgress() ?>
<? if(!DONATION_DRIVE_ON && !DONATION_DRIVE_COUNTER_ON && DONATION_HOLIDAY_ALERT_ON){ ?>
<?= Template::DonationAlert() ?>
<?= Template::DonationAlert() ?>
<? } ?>
<p class="ebooks-toolbar">
<a class="button" href="/collections/<?= Formatter::EscapeHtml($collection) ?>/downloads">Download collection</a>

View file

@ -170,7 +170,7 @@ catch(Exceptions\EbookNotFoundException){
<?= Template::DonationCounter() ?>
<?= Template::DonationProgress() ?>
<? if(!DONATION_DRIVE_ON && !DONATION_DRIVE_COUNTER_ON && DONATION_ALERT_ON){ ?>
<?= Template::DonationAlert() ?>
<?= Template::DonationAlert() ?>
<? } ?>
<? if($ebook->LongDescription === null){ ?>
<p><i>Theres no description for this ebook yet.</i></p>

View file

@ -110,7 +110,7 @@ catch(Exceptions\AppException $ex){
<?= Template::DonationCounter() ?>
<?= Template::DonationProgress() ?>
<? if(!DONATION_DRIVE_ON && !DONATION_DRIVE_COUNTER_ON && DONATION_HOLIDAY_ALERT_ON){ ?>
<?= Template::DonationAlert() ?>
<?= Template::DonationAlert() ?>
<? } ?>
<?= Template::SearchForm(['query' => $query, 'tags' => $tags, 'sort' => $sort, 'view' => $view, 'perPage' => $perPage]) ?>
<? if(sizeof($ebooks) == 0){ ?>

View file

@ -25,7 +25,7 @@ print("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<?xml-stylesheet href=\"" . S
<title>Search Results</title>
<subtitle>Results for <?= Formatter::EscapeXml($query) ?>”.</subtitle>
<icon><?= SITE_URL ?>/images/logo.png</icon>
<updated><?= (new DateTimeImmutable())->Format('Y-m-d\TH:i:s\Z') ?></updated>
<updated><?= NOW->format('Y-m-d\TH:i:s\Z') ?></updated>
<author>
<name>Standard Ebooks</name>
<uri><?= SITE_URL ?></uri>

View file

@ -26,7 +26,7 @@ print("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<?xml-stylesheet href=\"". SI
<title>Search Results</title>
<subtitle>Results for <?= Formatter::EscapeXml($query) ?>”.</subtitle>
<icon><?= SITE_URL ?>/images/logo.png</icon>
<updated><?= (new DateTimeImmutable())->Format('Y-m-d\TH:i:s\Z') ?></updated>
<updated><?= NOW->format('Y-m-d\TH:i:s\Z') ?></updated>
<author>
<name>Standard Ebooks</name>
<uri><?= SITE_URL ?></uri>

View file

@ -24,7 +24,7 @@ print("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<?xml-stylesheet href=\"" . S
<description>Results for <?= Formatter::EscapeXml($query) ?>”.</description>
<language>en-US</language>
<copyright>https://creativecommons.org/publicdomain/zero/1.0/</copyright>
<lastBuildDate><?= (new DateTimeImmutable())->format('r') ?></lastBuildDate>
<lastBuildDate><?= NOW->format('r') ?></lastBuildDate>
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
<atom:link href="<?= SITE_URL ?>/feeds/rss/all?query=<?= urlencode($query) ?>" rel="self" type="application/rss+xml"/>
<atom:link href="<?= SITE_URL ?>/ebooks/opensearch" rel="search" type="application/opensearchdescription+xml" />

View file

@ -7,7 +7,7 @@ $canVote = true; // Allow non-logged-in users to see the 'vote' button
try{
$poll = Poll::GetByUrlName(HttpInput::Str(GET, 'pollurlname'));
if(!$poll->IsActive() && $poll->End !== null && $poll->End < new DateTimeImmutable()){
if(!$poll->IsActive() && $poll->End !== null && $poll->End < NOW){
// If the poll ended, redirect to the results
header('Location: ' . $poll->Url . '/votes');
exit();
@ -47,7 +47,7 @@ catch(Exceptions\AppException){
<a href="<?= $poll->Url ?>/votes" class="button">View results</a>
</p>
<? }else{ ?>
<? if($poll->Start !== null && $poll->Start > new DateTimeImmutable()){ ?>
<? if($poll->Start !== null && $poll->Start > NOW){ ?>
<p class="center-notice">This poll opens on <?= $poll->Start->format('F j, Y g:i a') ?>.</p>
<? }else{ ?>
<p class="center-notice">This poll closed on <?= $poll->End->format('F j, Y g:i a') ?>.</p>