diff --git a/src/app/lib/Data.php b/src/app/lib/Data.php index 17fa15f..cbf6a33 100644 --- a/src/app/lib/Data.php +++ b/src/app/lib/Data.php @@ -9,7 +9,7 @@ use MyPrayerJournal\Domain\{ History, JournalRequest, Note, Request, RequestActi class Data { /** The prayer request table */ - const REQ_TABLE = 'prayer_request'; + const REQ_TABLE = 'mpj.request'; /** * Ensure the table and index exist @@ -94,11 +94,11 @@ class Data */ private static function getJournalByAnswered(string $userId, string $op): array { - $sql = Query::selectFromTable(self::REQ_TABLE) - . ' WHERE ' . Query::whereDataContains('$1') . ' AND ' . Query::whereJsonPathMatches('$2'); + $sql = sprintf('%s WHERE %s AND %s', Query::selectFromTable(self::REQ_TABLE), Query::whereDataContains('$1'), + Query::whereJsonPathMatches('$2')); $params = [ Query::jsonbDocParam([ 'userId' => $userId ]), - sprintf("$.history[*].action ? (@ $op \"%s\")", RequestAction::Answered->name) + sprintf("$.history[0].status ? (@ $op \"%s\")", RequestAction::Answered->name) ]; return self::mapToJournalRequest( Document::customList($sql, $params, Request::class, Document::mapFromJson(...)), true); diff --git a/src/app/lib/DistanceFormat.php b/src/app/lib/DistanceFormat.php index 9173cb1..69b2c1c 100644 --- a/src/app/lib/DistanceFormat.php +++ b/src/app/lib/DistanceFormat.php @@ -32,19 +32,19 @@ enum DistanceFormat public static function format(DistanceFormat $it, bool $singular = false): string { return match ($it) { - self::LessThanXMinutes => $singular ? 'less than a minute' : 'less than %i minutes', - self::XMinutes => $singular ? 'a minute' : '%i minutes', - self::AboutXHours => $singular ? 'about an hour' : 'about %i hours', - self::XHours => $singular ? 'an hour' : '%i hours', - self::XDays => $singular ? 'a day' : '%i days', - self::AboutXWeeks => $singular ? 'about a week' : 'about %i weeks', - self::XWeeks => $singular ? 'a week' : '%i weeks', - self::AboutXMonths => $singular ? 'about a month' : 'about %i months', - self::XMonths => $singular ? 'a month' : '%i months', - self::AboutXYears => $singular ? 'about a year' : 'about %i years', - self::XYears => $singular ? 'a year' : '%i years', - self::OverXYears => $singular ? 'over a year' : 'over %i years', - self::AlmostXYears => $singular ? 'almost a year' : 'almost %i years', + self::LessThanXMinutes => $singular ? 'less than a minute' : 'less than %d minutes', + self::XMinutes => $singular ? 'a minute' : '%d minutes', + self::AboutXHours => $singular ? 'about an hour' : 'about %d hours', + self::XHours => $singular ? 'an hour' : '%d hours', + self::XDays => $singular ? 'a day' : '%d days', + self::AboutXWeeks => $singular ? 'about a week' : 'about %d weeks', + self::XWeeks => $singular ? 'a week' : '%d weeks', + self::AboutXMonths => $singular ? 'about a month' : 'about %d months', + self::XMonths => $singular ? 'a month' : '%d months', + self::AboutXYears => $singular ? 'about a year' : 'about %d years', + self::XYears => $singular ? 'a year' : '%d years', + self::OverXYears => $singular ? 'over a year' : 'over %d years', + self::AlmostXYears => $singular ? 'almost a year' : 'almost %d years', }; } } diff --git a/src/app/lib/domain/AsOf.php b/src/app/lib/domain/AsOf.php index 51668bd..7a96861 100644 --- a/src/app/lib/domain/AsOf.php +++ b/src/app/lib/domain/AsOf.php @@ -5,7 +5,7 @@ namespace MyPrayerJournal\Domain; use DateTimeImmutable; -trait AsOf +class AsOf { /** The "as of" date/time */ public DateTimeImmutable $asOf; diff --git a/src/app/lib/domain/History.php b/src/app/lib/domain/History.php index 2ac3990..3e5ceee 100644 --- a/src/app/lib/domain/History.php +++ b/src/app/lib/domain/History.php @@ -8,33 +8,31 @@ use DateTimeImmutable, DateTimeZone; /** * A record of action taken on a prayer request, including updates to its text */ -class History +class History extends AsOf { - use AsOf; - /** The action taken that generated this history entry */ - public RequestAction $action = RequestAction::Created; + public RequestAction $status = RequestAction::Created; /** The text of the update, if applicable */ public ?string $text = null; public function __construct() { - $this->asOf = new DateTimeImmutable('1/1/1970', new DateTimeZone('Etc/UTC')); + $this->asOf = unix_epoch(); } public function isCreated(): bool { - return $this->action == RequestAction::Created; + return $this->status == RequestAction::Created; } public function isPrayed(): bool { - return $this->action == RequestAction::Prayed; + return $this->status == RequestAction::Prayed; } public function isAnswered(): bool { - return $this->action == RequestAction::Answered; + return $this->status == RequestAction::Answered; } } diff --git a/src/app/lib/domain/JournalRequest.php b/src/app/lib/domain/JournalRequest.php index cc95efb..c758be3 100644 --- a/src/app/lib/domain/JournalRequest.php +++ b/src/app/lib/domain/JournalRequest.php @@ -8,10 +8,8 @@ use DateTimeImmutable, DateTimeZone; /** * A prayer request, along with calculated fields, for use in displaying journal lists */ -class JournalRequest +class JournalRequest extends AsOf { - use AsOf; - /** The ID of the prayer request */ public string $id = ''; @@ -22,7 +20,7 @@ class JournalRequest public string $text = ''; /** The date/time this request was last marked as prayed */ - public DateTimeImmutable $lastPrayed; + public ?DateTimeImmutable $lastPrayed = null; /** The last action taken on this request */ public RequestAction $lastAction = RequestAction::Created; @@ -60,8 +58,8 @@ class JournalRequest public function __construct(?Request $req = null, bool $full = false) { if (is_null($req)) { - $this->asOf = new DateTimeImmutable('1/1/1970', new DateTimeZone('Etc/UTC')); - $this->lastPrayed = new DateTimeImmutable('1/1/1970', new DateTimeZone('Etc/UTC')); + $this->asOf = unix_epoch(); + $this->lastPrayed = null; } else { $this->id = $req->id; $this->userId = $req->userId; @@ -71,9 +69,11 @@ class JournalRequest $this->recurrence = $req->recurrence; usort($req->history, AsOf::newestToOldest(...)); - $this->asOf = $req->history[0]->asOf; - $this->lastPrayed = array_values( - array_filter($req->history, fn (History $it) => $it->isPrayed()))[0]?->asOf; + $this->asOf = $req->history[array_key_first($req->history)]->asOf; + $lastText = array_filter($req->history, fn (History $it) => !is_null($it->text)); + $this->text = $lastText[array_key_first($lastText)]->text; + $lastPrayed = array_filter($req->history, fn (History $it) => $it->isPrayed()); + if ($lastPrayed) $this->lastPrayed = $lastPrayed[array_key_first($lastPrayed)]->asOf; if ($full) { usort($req->notes, AsOf::newestToOldest(...)); diff --git a/src/app/lib/domain/Note.php b/src/app/lib/domain/Note.php index fbbbf4c..db19518 100644 --- a/src/app/lib/domain/Note.php +++ b/src/app/lib/domain/Note.php @@ -8,15 +8,13 @@ use DateTimeImmutable, DateTimeZone; /** * A note entered on a prayer request */ -class Note +class Note extends AsOf { - use AsOf; - /** The note */ public string $notes = ''; public function __construct() { - $this->asOf = new DateTimeImmutable('1/1/1970', new DateTimeZone('Etc/UTC')); + $this->asOf = unix_epoch(); } } diff --git a/src/app/lib/domain/Request.php b/src/app/lib/domain/Request.php index ac6652c..9159ce6 100644 --- a/src/app/lib/domain/Request.php +++ b/src/app/lib/domain/Request.php @@ -46,7 +46,7 @@ class Request public function __construct() { - $this->id = new Cuid2(); - $this->enteredOn = new DateTimeImmutable('1/1/1970', new DateTimeZone('Etc/UTC')); + $this->id = (new Cuid2())->toString(); + $this->enteredOn = unix_epoch(); } } diff --git a/src/app/lib/domain/RequestAction.php b/src/app/lib/domain/RequestAction.php index 8222c0e..c5d2186 100644 --- a/src/app/lib/domain/RequestAction.php +++ b/src/app/lib/domain/RequestAction.php @@ -8,19 +8,19 @@ use JsonSerializable; /** * An action that was taken on a request */ -enum RequestAction implements JsonSerializable +enum RequestAction: string implements JsonSerializable { /** The request was entered */ - case Created; + case Created = 'Created'; /** Prayer was recorded for the request */ - case Prayed; + case Prayed = 'Prayed'; /** The request was updated */ - case Updated; + case Updated = 'Updated'; /** The request was marked as answered */ - case Answered; + case Answered = 'Answered'; /** * Serialize this enum using its name diff --git a/src/app/lib/start.php b/src/app/lib/start.php index 40dabab..79f68d7 100644 --- a/src/app/lib/start.php +++ b/src/app/lib/start.php @@ -55,7 +55,7 @@ function require_user(bool $fail = false) if ($fail) { http_response_code(403); } else { - header("Location: /user/log-on?{${Constants::RETURN_URL}}={$_SERVER[Constants::REQUEST_URI]}"); + header(sprintf('Location: /user/log-on?%s=%s', Constants::RETURN_URL, $_SERVER[Constants::REQUEST_URI])); } exit; } @@ -83,7 +83,7 @@ function page_link(string $url, array $classNames = [], bool $checkActive = fals array_push($classNames, 'is-active-route'); } if (!empty($classNames)) { - echo ' class="' . implode(' ', $classNames) . '"'; + echo sprintf(' class="%s"', implode(' ', $classNames)); } echo ' hx-target="#top" hx-swap="innerHTML" hx-push-url="true"'; } @@ -96,3 +96,13 @@ function end_request() Configuration::closeConn(); echo ''; } + +/** + * Create a new instance of the Unix epoch + * + * @return DateTimeImmutable An immutable date/time as of the Unix epoch + */ +function unix_epoch(): DateTimeImmutable +{ + return new DateTimeImmutable('1/1/1970', new DateTimeZone('Etc/UTC')); +} diff --git a/src/app/public/components/journal-items.php b/src/app/public/components/journal-items.php index 2b55165..f81bef1 100644 --- a/src/app/public/components/journal-items.php +++ b/src/app/public/components/journal-items.php @@ -40,11 +40,9 @@ end_request(); */ function format_activity(string $activity, DateTimeImmutable $asOf) { - echo sprintf('last %s %s', [ - $activity, + echo sprintf('last %s %s', $activity, $asOf->setTimezone($_REQUEST[Constants::TIME_ZONE])->format('l, F jS, Y/g:ia T'), - Dates::formatDistance(Dates::now(), $asOf) - ]); + Dates::formatDistance(Dates::now(), $asOf)); } /** diff --git a/src/app/public/journal.php b/src/app/public/journal.php index e27312f..5ecffcf 100644 --- a/src/app/public/journal.php +++ b/src/app/public/journal.php @@ -11,11 +11,10 @@ $_REQUEST[Constants::PAGE_TITLE] = "{$session->user[Constants::CLAIM_GIVEN_NAME] template('layout/page_header'); ?>
-

’s Prayer Journal

+

Loading your prayer journal…

-