WIP on option / PJson integration
This commit is contained in:
@@ -2,24 +2,46 @@
|
||||
|
||||
namespace MyPrayerJournal\Domain;
|
||||
|
||||
use JsonSerializable;
|
||||
use BitBadger\InspiredByFSharp\Option;
|
||||
use Square\Pjson\{Json, JsonSerialize};
|
||||
|
||||
/**
|
||||
* A record of an action taken on a request
|
||||
*/
|
||||
class History implements JsonSerializable
|
||||
class History
|
||||
{
|
||||
use JsonSerialize;
|
||||
|
||||
/** @var string The date/time this entry was made */
|
||||
#[Json]
|
||||
public string $asOf = '';
|
||||
|
||||
/** @var RequestAction The action taken for this history entry */
|
||||
#[Json]
|
||||
public RequestAction $action;
|
||||
|
||||
/** @var string|null The text for this history entry (optional) */
|
||||
#[Json('text', omit_empty: true)]
|
||||
private ?string $dbText {
|
||||
get => $this->text->unwrap();
|
||||
set { $this->text = Option::of($value); }
|
||||
}
|
||||
|
||||
/** @var Option<string> The text for this history entry */
|
||||
public Option $text {
|
||||
get => $this->text ?? Option::None();
|
||||
set { $this->text = $value; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $asOf The date/time this entry was made
|
||||
* @param RequestAction $action The action taken for this history entry
|
||||
* @param string|null $text The text for this history entry (optional)
|
||||
*/
|
||||
public function __construct(public string $asOf, public RequestAction $action, public ?string $text = null) { }
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
public function __construct(string $asOf, RequestAction $action, ?string $text = null)
|
||||
{
|
||||
$values = ['asOf' => $this->asOf, 'action' => $this->action->value];
|
||||
if (isset($this->text)) $values['text'] = $this->text;
|
||||
return $values;
|
||||
$this->asOf = $asOf;
|
||||
$this->action = $action;
|
||||
$this->dbText = $text;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,17 +4,20 @@ namespace MyPrayerJournal\Domain;
|
||||
|
||||
use BitBadger\InspiredByFSharp\Option;
|
||||
use BitBadger\PDODocument\DocumentException;
|
||||
use Square\Pjson\{Json, JsonSerialize};
|
||||
|
||||
/**
|
||||
* A note entered on a prayer request
|
||||
*/
|
||||
class Note
|
||||
{
|
||||
use JsonSerialize;
|
||||
|
||||
/**
|
||||
* @param string $asOf The date/time this note was recorded
|
||||
* @param string $text The text of the note
|
||||
*/
|
||||
public function __construct(public string $asOf, public string $text) { }
|
||||
public function __construct(#[Json] public string $asOf, #[Json] public string $text) { }
|
||||
|
||||
/**
|
||||
* Retrieve notes for a given request
|
||||
|
||||
@@ -2,19 +2,46 @@
|
||||
|
||||
namespace MyPrayerJournal\Domain;
|
||||
|
||||
use BitBadger\InspiredByFSharp\Option;
|
||||
use DateInterval;
|
||||
use JsonSerializable;
|
||||
use Square\Pjson\{Json, JsonSerialize};
|
||||
|
||||
/**
|
||||
* The recurrence for a prayer request
|
||||
*/
|
||||
class Recurrence implements JsonSerializable
|
||||
class Recurrence
|
||||
{
|
||||
use JsonSerialize;
|
||||
|
||||
/** @var RecurrencePeriod The recurrence period */
|
||||
#[Json]
|
||||
public RecurrencePeriod $period {
|
||||
get => $this->period ?? RecurrencePeriod::Immediate;
|
||||
set { $this->period = $value; }
|
||||
}
|
||||
|
||||
/** @var int|null How many of the periods will pass before the request is visible again */
|
||||
#[Json('interval', omit_empty: true)]
|
||||
private ?int $dbInterval {
|
||||
get => $this->interval->unwrap();
|
||||
set { $this->interval = Option::of($value); }
|
||||
}
|
||||
|
||||
/** @var Option<int> How many of the periods will pass before the request is visible again */
|
||||
public Option $interval {
|
||||
get => $this->interval ?? Option::None();
|
||||
set { $this->interval = $value; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RecurrencePeriod $period The recurrence period
|
||||
* @param int|null $interval How many of the periods will pass before the request is visible again
|
||||
*/
|
||||
public function __construct(public RecurrencePeriod $period, public ?int $interval = null) { }
|
||||
public function __construct(RecurrencePeriod $period, ?int $interval = null)
|
||||
{
|
||||
$this->period = $period;
|
||||
$this->dbInterval = $interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the date/time interval for this recurrence
|
||||
@@ -25,17 +52,10 @@ class Recurrence implements JsonSerializable
|
||||
{
|
||||
$period = match ($this->period) {
|
||||
RecurrencePeriod::Immediate => 'T0S',
|
||||
RecurrencePeriod::Hours => "T{$this->interval}H",
|
||||
RecurrencePeriod::Days => "{$this->interval}D",
|
||||
RecurrencePeriod::Weeks => ($this->interval * 7) . 'D'
|
||||
RecurrencePeriod::Hours => "T{$this->interval->value}H",
|
||||
RecurrencePeriod::Days => "{$this->interval->value}D",
|
||||
RecurrencePeriod::Weeks => ($this->interval->value * 7) . 'D'
|
||||
};
|
||||
return new DateInterval("P$period");
|
||||
}
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
$values = ['period' => $this->period->value];
|
||||
if (isset($this->interval)) $values['interval'] = $this->interval;
|
||||
return $values;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,71 +7,82 @@ use BitBadger\PDODocument\{Custom, DocumentException, DocumentList, Find};
|
||||
use BitBadger\PDODocument\Mapper\DocumentMapper;
|
||||
use DateTimeImmutable;
|
||||
use Exception;
|
||||
use JsonSerializable;
|
||||
use MyPrayerJournal\Table;
|
||||
use Square\Pjson\{Json, JsonSerialize};
|
||||
|
||||
/**
|
||||
* A prayer request
|
||||
*/
|
||||
class Request implements JsonSerializable
|
||||
class Request
|
||||
{
|
||||
/**
|
||||
* @param string $id The ID for the request
|
||||
* @param string $enteredOn The date/time this request was originally entered
|
||||
* @param string $userId The ID of the user to whom this request belongs
|
||||
* @param string|null $snoozedUntil The date/time the snooze expires for this request (null = not snoozed)
|
||||
* @param string|null $showAfter The date/time the current recurrence period is over (null = immediate)
|
||||
* @param Recurrence $recurrence The recurrence for this request
|
||||
* @param History[] $history The history of this request
|
||||
* @param Note[] $notes Notes regarding this request
|
||||
* @throws Exception If the ID generation fails
|
||||
*/
|
||||
public function __construct(public string $id = '', public string $enteredOn = '', public string $userId = '',
|
||||
public ?string $snoozedUntil = null, public ?string $showAfter = null,
|
||||
public Recurrence $recurrence = new Recurrence(RecurrencePeriod::Immediate),
|
||||
public array $history = [], public array $notes = []) { }
|
||||
use JsonSerialize;
|
||||
|
||||
/**
|
||||
* Get the current text for this request
|
||||
*
|
||||
* @return string The most recent text for the request
|
||||
*/
|
||||
public function currentText(): string
|
||||
{
|
||||
foreach ($this->history as $hist) if (isset($hist->text)) return $hist->text;
|
||||
return '';
|
||||
/** @var string The ID for the request */
|
||||
#[Json]
|
||||
public string $id = '';
|
||||
|
||||
/** @var string The date/time this request was originally entered */
|
||||
#[Json]
|
||||
public string $enteredOn = '';
|
||||
|
||||
/** @var string The ID of the user to whom this request belongs */
|
||||
#[Json]
|
||||
public string $userId = '';
|
||||
|
||||
/** @var string|null The date/time the snooze expires for this request (null = not snoozed) */
|
||||
#[Json('snoozedUntil', omit_empty: true)]
|
||||
private ?string $dbSnoozedUntil {
|
||||
get => $this->snoozedUntil->unwrap();
|
||||
set { $this->snoozedUntil = Option::of($value); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the date/time this request was last marked as prayed
|
||||
*
|
||||
* @return string|null The date/time this request was last marked as prayed
|
||||
*/
|
||||
public function lastPrayed(): ?string
|
||||
{
|
||||
foreach ($this->history as $hist) if ($hist->action == RequestAction::Prayed) return $hist->asOf;
|
||||
return null;
|
||||
/** @var Option<string> The date/time the snooze expires for this request (None = not snoozed) */
|
||||
public Option $snoozedUntil {
|
||||
get => $this->snoozedUntil ?? Option::None();
|
||||
set { $this->snoozedUntil = $value; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Has this request been answered?
|
||||
*
|
||||
* @return bool True if the request is answered, false if not
|
||||
*/
|
||||
public function isAnswered(): bool
|
||||
{
|
||||
return $this->history[0]->action === RequestAction::Answered;
|
||||
/** @var string|null The date/time the current recurrence period is over (null = immediate) */
|
||||
#[Json(omit_empty: true)]
|
||||
public ?string $showAfter = null;
|
||||
|
||||
/** @var Recurrence The recurrence for this request */
|
||||
#[Json]
|
||||
public Recurrence $recurrence {
|
||||
get => $this->recurrence ?? new Recurrence(RecurrencePeriod::Immediate);
|
||||
set => $this->recurrence = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this request currently snoozed?
|
||||
*
|
||||
* @return bool True if the request is snoozed, false if not
|
||||
* @throws Exception If the snoozed until date/time is not valid
|
||||
*/
|
||||
public function isSnoozed(): bool
|
||||
{
|
||||
return isset($this->snoozedUntil) && new DateTimeImmutable($this->snoozedUntil) > new DateTimeImmutable('now');
|
||||
/** @var History[] The history of this request */
|
||||
#[Json(type: History::class)]
|
||||
public array $history = [];
|
||||
|
||||
/** @param Note[] $notes Notes regarding this request */
|
||||
#[Json(type: Note::class)]
|
||||
public array $notes = [];
|
||||
|
||||
/** The current text for this request */
|
||||
public string $currentText {
|
||||
get => Option::of(array_find($this->history, fn(History $it) => $it->text->isSome))
|
||||
->map(fn(History $it) => $it->text->value)
|
||||
->getOrDefault('');
|
||||
}
|
||||
|
||||
/** @var Option<string> The date/time this request was last marked as prayed */
|
||||
public Option $lastPrayed {
|
||||
get => Option::of(array_find($this->history, fn(History $it) => $it->action === RequestAction::Prayed))
|
||||
->map(fn(History $it) => $it->asOf);
|
||||
}
|
||||
|
||||
/** Has this request been answered? */
|
||||
public bool $isAnswered {
|
||||
get => $this->history[0]->action === RequestAction::Answered;
|
||||
}
|
||||
|
||||
/** Is this request currently snoozed? */
|
||||
public bool $isSnoozed {
|
||||
get => $this->snoozedUntil->isSome
|
||||
&& new DateTimeImmutable($this->snoozedUntil->value) > new DateTimeImmutable('now');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,28 +91,12 @@ class Request implements JsonSerializable
|
||||
* @return bool True if the request is pending, false if not
|
||||
* @throws Exception If the snoozed or show-after date/times are not valid
|
||||
*/
|
||||
public function isPending(): bool
|
||||
{
|
||||
return !$this->isSnoozed()
|
||||
public bool $isPending {
|
||||
get => !$this->isSnoozed
|
||||
&& isset($this->showAfter)
|
||||
&& new DateTimeImmutable($this->showAfter) > new DateTimeImmutable('now');
|
||||
}
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
$values = [
|
||||
'id' => $this->id,
|
||||
'enteredOn' => $this->enteredOn,
|
||||
'userId' => $this->userId,
|
||||
'recurrence' => $this->recurrence,
|
||||
'history' => $this->history,
|
||||
'notes' => $this->notes
|
||||
];
|
||||
if (isset($this->snoozedUntil)) $values['snoozedUntil'] = $this->snoozedUntil;
|
||||
if (isset($this->showAfter)) $values['showAfter'] = $this->showAfter;
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a request by its ID
|
||||
*
|
||||
@@ -112,7 +107,7 @@ class Request implements JsonSerializable
|
||||
public static function byId(string $id): Option
|
||||
{
|
||||
return Find::byId(Table::REQUEST, $id, self::class)
|
||||
->map(fn(Request $it) => $it->userId === $_SESSION['user_id'] ? Option::Some($it) : Option::None());
|
||||
->map(fn(Request $it) => $it->userId === $_SESSION['user_id'] ? $it : null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user