53 lines
1.6 KiB
PHP
53 lines
1.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Enum;
|
|
|
|
/**
|
|
* How often a series repeats.
|
|
*
|
|
* Every rule is a whole number of days, which is what lets BookingSeries::occurrences() be a
|
|
* plain stride from the start date. Every stride that is a multiple of 7 therefore keeps the
|
|
* weekday fixed by construction -- that is why a series needs no weekday field at all.
|
|
*
|
|
* There is deliberately no calendar-monthly rule: "the 31st of each month" has no counterpart in
|
|
* five months of the year, and it would not hold the weekday. FOUR_WEEKLY is the nearest thing
|
|
* that behaves, at the cost of drifting against the calendar -- 13 occurrences a year, not 12,
|
|
* which is why it is not labelled "Monatlich".
|
|
*/
|
|
enum RecurrenceRule: string
|
|
{
|
|
case DAILY = 'daily';
|
|
case WEEKLY = 'weekly';
|
|
case TWO_WEEKLY = 'two_weekly';
|
|
case FOUR_WEEKLY = 'four_weekly';
|
|
|
|
public function label(): string
|
|
{
|
|
return match ($this) {
|
|
self::DAILY => 'Täglich',
|
|
self::WEEKLY => 'Wöchentlich',
|
|
self::TWO_WEEKLY => 'Alle zwei Wochen',
|
|
self::FOUR_WEEKLY => 'Alle vier Wochen',
|
|
};
|
|
}
|
|
|
|
/** Days between two occurrences. */
|
|
public function intervalDays(): int
|
|
{
|
|
return match ($this) {
|
|
self::DAILY => 1,
|
|
self::WEEKLY => 7,
|
|
self::TWO_WEEKLY => 14,
|
|
self::FOUR_WEEKLY => 28,
|
|
};
|
|
}
|
|
|
|
/** Whether the rule lands on the same weekday every time, i.e. whether naming it adds anything. */
|
|
public function keepsWeekday(): bool
|
|
{
|
|
return 0 === $this->intervalDays() % 7;
|
|
}
|
|
}
|