Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 44 additions & 30 deletions resources/fieldsets/event.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fields:
monthly: Monthly
every: Every
multi_day: Multi-Day
width: 33
width: 50
display: Recurrence
default: none
-
Expand All @@ -22,14 +22,7 @@ fields:
default: UTC
type: dictionary
display: Timezone
-
handle: all_day
field:
type: toggle
width: 33
display: 'All Day?'
unless:
recurrence: 'equals multi_day'
width: 50
-
handle: specific_days
field:
Expand Down Expand Up @@ -75,6 +68,13 @@ fields:
multi_day: 'equals true'
recurrence: 'equals multi_day'
format: Y-m-d
-
handle: end_date_spacer
field:
type: spacer
width: 33
if:
recurrence: 'equals none'
-
handle: end_date
field:
Expand All @@ -91,11 +91,44 @@ fields:
if:
recurrence: 'contains_any daily, weekly, monthly, every'
format: Y-m-d
-
handle: exclude_dates
field:
type: grid
fullscreen: false
display: 'Exclude Days'
add_row: 'Add Day'
if_any:
recurrence: 'contains_any monthly, daily, weekly, every'
fields:
-
handle: date
field:
type: date
allow_blank: false
allow_time: false
require_time: false
input_format: YYYY/M/D/YYYY
display: Date
format: Y-m-d
-
handle: times_sections
field:
type: section
display: Times
-
handle: all_day
field:
type: toggle
width: 33
display: 'All Day?'
unless:
recurrence: 'equals multi_day'
-
handle: start_time
field:
type: time
width: 25
width: 33
display: 'Start Time'
instructions: 'Input in [24-hour format](https://en.wikipedia.org/wiki/24-hour_clock)'
unless_any:
Expand All @@ -106,7 +139,7 @@ fields:
handle: end_time
field:
type: time
width: 25
width: 33
display: 'End Time'
instructions: 'Input in [24-hour format](https://en.wikipedia.org/wiki/24-hour_clock)'
unless_any:
Expand Down Expand Up @@ -170,22 +203,3 @@ fields:
field: 'events::event.all_day'
config:
width: 25
-
handle: exclude_dates
field:
type: grid
display: 'Exclude Days'
add_row: 'Add Day'
if_any:
recurrence: 'contains_any monthly, daily, weekly, every'
fields:
-
handle: date
field:
type: date
allow_blank: false
allow_time: false
require_time: false
input_format: YYYY/M/D/YYYY
display: Date
format: Y-m-d
2 changes: 1 addition & 1 deletion src/Events.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ private function isMultiDay(Entry $occurrence): bool
private function occurrences(callable $generator): EntryCollection
{
return $this->entries
->filter(fn (Entry $occurrence) => $this->hasStartDate($occurrence))
->filter(fn (Entry $event) => $this->hasStartDate($event))
// take each event and generate the occurrences
->flatMap(callback: $generator)
->reject(fn (Entry $occurrence) => collect($occurrence->exclude_dates)
Expand Down
3 changes: 3 additions & 0 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@
use Statamic\Entries\Entry;
use Statamic\Facades\Collection;
use Statamic\Fields\Field;
use Statamic\Fields\Fields;
use Statamic\Fields\Value;
use Statamic\Fieldtypes\Dictionary;
use Statamic\Providers\AddonServiceProvider;
use Statamic\Statamic;

class ServiceProvider extends AddonServiceProvider
{
public function bootAddon()
{
// Fields::default('events_timezone', fn () => Statamic::displayTimezone());
collect(Events::setting('collections', [['collection' => 'events']]))
->each(fn (array $collection) => Collection::computed(
$collection['collection'],
Expand Down
11 changes: 11 additions & 0 deletions src/Tags/Events.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Carbon\CarbonInterface;
use Carbon\CarbonPeriod;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Collection;
use Statamic\Contracts\Query\Builder;
Expand Down Expand Up @@ -47,6 +48,16 @@ public function calendar(): Collection
return $this->output($this->makeEmptyDates(from: $from, to: $to)->merge($occurrences)->values());
}

public function daysOfWeek(): Collection
{
return collect(CarbonPeriod::dates(now()->startOfWeek(), now()->endOfWeek()))
->map(fn (Carbon $date) => [
'short' => $date->format('D')[0],
'medium' => $date->format('D'),
'long' => $date->format('l'),
]);
}

public function downloadLink(): string
{
return route(
Expand Down
7 changes: 6 additions & 1 deletion src/Types/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ public function isRecurring(): bool

public function occurrencesBetween(string|CarbonInterface $from, string|CarbonInterface $to): Collection
{
return $this->collect($this->rule()->getOccurrencesBetween(begin: $from, end: $to));
$tz = $this->timezone['name'];

return $this->collect($this->rule()->getOccurrencesBetween(
begin: $from->shiftTimezone($tz),
end: $to->shiftTimezone($tz)
));
}

public function occursOnDate(string|CarbonInterface $date): bool
Expand Down
2 changes: 1 addition & 1 deletion src/Types/SingleDayEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ protected function rule(): RRuleInterface
{
return new RRule([
'count' => 1,
'dtstart' => $this->start()->setTimeFromTimeString($this->endTime()),
'dtstart' => $this->end(),
'freq' => RRule::DAILY,
]);
}
Expand Down
36 changes: 36 additions & 0 deletions tests/EventsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace TransformStudios\Events\Tests;

use Carbon\CarbonImmutable;
use Illuminate\Support\Carbon;
use Statamic\Extensions\Pagination\LengthAwarePaginator;
use Statamic\Facades\Entry;
Expand Down Expand Up @@ -386,3 +387,38 @@

expect($occurrences)->toBeEmpty();
});

test('app and event in same timezone ', function () {
$date = CarbonImmutable::createFromDate(2026, 2, 28);
Entry::make()
->collection('events')
->data([
'start_date' => $date->toDateString(),
'start_time' => '05:00',
'end_time' => '23:00',
])->save();

$events1 = Events::fromCollection('events')->between($date->startOfMonth(), $date->endOfMonth());
$events2 = Events::fromCollection('events')->between($date->startOfMonth(), $date->endOfMonth()->endOfWeek());

expect($events1)->toHaveCount(1);
expect($events2)->toHaveCount(1);
});

test('app and event in different timezone', function () {
$date = CarbonImmutable::createFromDate(2026, 2, 28);
Entry::make()
->collection('events')
->data([
'start_date' => $date->toDateString(),
'timezone' => 'America/Los_Angeles',
'start_time' => '05:00',
'end_time' => '23:00',
])->save();

$events1 = Events::fromCollection('events')->between($date->startOfMonth(), $date->endOfMonth());
$events2 = Events::fromCollection('events')->between($date->startOfMonth(), $date->endOfMonth()->endOfWeek());

expect($events1)->toHaveCount(1);
expect($events2)->toHaveCount(1);
});
Loading
Loading