feat: add two- and four-weekly series and drop the weekday picker

This commit is contained in:
fromme committed 2026-09-14 08:25:05 +02:00
1 parent 8b88384d68
commit faef4d70a8
10 files changed
+166 -103

No files matched your search

+10 -32
View File
@@ -41,15 +41,6 @@ class BookingSeries
#[ORM\Column(enumType: RecurrenceRule::class)]
private RecurrenceRule $rule;
/**
* ISO weekdays (1 = Monday) the series falls on. Empty for a DAILY rule, which means
* every calendar day.
*
* @var list<int>
*/
#[ORM\Column]
private array $weekdays = [];
#[ORM\Column(type: 'date_immutable')]
private \DateTimeImmutable $startDate;
@@ -69,9 +60,6 @@ class BookingSeries
#[ORM\OneToMany(targetEntity: Booking::class, mappedBy: 'series')]
private Collection $bookings;
/**
* @param list<int> $weekdays
*/
public function __construct(
User $user,
Resource $resource,
@@ -79,7 +67,6 @@ class BookingSeries
\DateTimeImmutable $startDate,
\DateTimeImmutable $endDate,
TimeRange $time,
array $weekdays = [],
) {
$this->user = $user;
$this->resource = $resource;
@@ -88,7 +75,6 @@ class BookingSeries
$this->endDate = $endDate->setTime(0, 0);
$this->startMinute = $time->startMinute;
$this->endMinute = $time->endMinute;
$this->weekdays = RecurrenceRule::WEEKLY === $rule ? array_values(array_unique($weekdays)) : [];
$this->createdAt = new \DateTimeImmutable();
$this->bookings = new ArrayCollection();
}
@@ -96,17 +82,18 @@ class BookingSeries
/**
* Every day this series falls on, in order.
*
* A rule is only a step size, so this is a stride from the start date. For any rule whose
* interval is a multiple of a week that means every occurrence lands on the same weekday as
* the start -- the series never has to be told which weekday it runs on.
*
* @return list<\DateTimeImmutable>
*/
public function occurrences(): array
{
$dates = [];
$step = \sprintf('+%d days', $this->rule->intervalDays());
for ($day = $this->startDate; $day <= $this->endDate; $day = $day->modify('+1 day')) {
if (RecurrenceRule::WEEKLY === $this->rule && !\in_array((int) $day->format('N'), $this->weekdays, true)) {
continue;
}
for ($day = $this->startDate; $day <= $this->endDate; $day = $day->modify($step)) {
$dates[] = $day;
}
@@ -133,14 +120,6 @@ class BookingSeries
return $this->rule;
}
/**
* @return list<int>
*/
public function getWeekdays(): array
{
return $this->weekdays;
}
public function getStartDate(): \DateTimeImmutable
{
return $this->startDate;
@@ -178,12 +157,11 @@ class BookingSeries
{
$description = $this->rule->label();
if (RecurrenceRule::WEEKLY === $this->rule && [] !== $this->weekdays) {
// Naming the weekday only says something for a rule that actually holds it fixed; for a
// daily series it would just repeat the start date back at the reader.
if ($this->rule->keepsWeekday()) {
$names = ['', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'];
// Sort the numbers, not the names -- alphabetical would read "Di, Do, Fr, Mi, Mo".
$weekdays = $this->weekdays;
sort($weekdays);
$description .= ' ('.implode(', ', array_map(static fn (int $day): string => $names[$day], $weekdays)).')';
$description .= ' ('.$names[(int) $this->startDate->format('N')].')';
}
return $description.', '.$this->getTimeRange();