From 1f96aa858cdec849807d707c4fc2f5766b32b6b7 Mon Sep 17 00:00:00 2001 From: edalzell Date: Sun, 31 Aug 2025 14:04:55 -0700 Subject: [PATCH 01/11] wip --- resources/blueprints/settings.yaml | 36 +++++++++++++++++++++ src/Events.php | 21 +++++++++++-- src/Http/Controllers/IcsController.php | 2 +- src/ServiceProvider.php | 43 +++++++++++++++++--------- src/Tags/Events.php | 6 ++-- 5 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 resources/blueprints/settings.yaml diff --git a/resources/blueprints/settings.yaml b/resources/blueprints/settings.yaml new file mode 100644 index 0000000..58494b2 --- /dev/null +++ b/resources/blueprints/settings.yaml @@ -0,0 +1,36 @@ +tabs: + main: + display: Main + sections: + - + fields: + - + handle: collections + field: + type: grid + display: Collections + sortable: false + add_row: 'Add Collection' + fields: + - + handle: collection + field: + type: collections + display: Collection + width: 50 + mode: select + max_items: 1 + - + handle: location_field + field: + type: text + display: 'Location Field' + width: 50 + default: location + - + handle: timezone + field: + mode: select + max_items: 1 + type: timezones + display: Timezone diff --git a/src/Events.php b/src/Events.php index 1779351..d61b4b4 100644 --- a/src/Events.php +++ b/src/Events.php @@ -4,10 +4,12 @@ use Carbon\CarbonInterface; use Exception; +use Illuminate\Support\Collection; use Illuminate\Support\Traits\Conditionable; use Statamic\Entries\Entry; use Statamic\Entries\EntryCollection; use Statamic\Extensions\Pagination\LengthAwarePaginator; +use Statamic\Facades\Addon; use Statamic\Facades\Cascade; use Statamic\Facades\Entry as EntryFacade; use Statamic\Facades\Site; @@ -45,18 +47,31 @@ class Events public static function fromCollection(string $handle): self { - return tap(new static())->collection($handle); + return tap(new static)->collection($handle); } public static function fromEntry(string $id): self { - return tap(new static())->event($id); + return tap(new static)->event($id); } - private function __construct() + public static function collectionHandles(): Collection { + return collect(static::setting('collections', ['events']))->keys(); } + public static function setting(string $key, $default = null): mixed + { + return Addon::get('transformstudios/events')->setting($key, $default); + } + + public static function timezone(): string + { + return static::setting('timezone', config('app.timezone')); + } + + private function __construct() {} + public function collapseMultiDays(): self { $this->collapseMultiDays = true; diff --git a/src/Http/Controllers/IcsController.php b/src/Http/Controllers/IcsController.php index 19e7230..bb36994 100644 --- a/src/Http/Controllers/IcsController.php +++ b/src/Http/Controllers/IcsController.php @@ -25,7 +25,7 @@ class IcsController extends Controller public function __invoke(Request $request) { - $handle = $request->get('collection', config('events.collection', 'events')); + $handle = $request->get('collection', 'events'); $date = $request->has('date') ? CarbonImmutable::parse($request->get('date')) : null; $eventId = $request->get('event'); $entry = null; diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index edd5c95..f38a410 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -5,16 +5,18 @@ use Composer\InstalledVersions; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Artisan; +use Statamic\Entries\Entry; use Statamic\Facades\Collection; use Statamic\Facades\Site; use Statamic\Fields\Field; +use Statamic\Fields\Value; use Statamic\Providers\AddonServiceProvider; use Statamic\Statamic; use TransformStudios\Events\Fieldtypes\Timezones; use TransformStudios\Events\Modifiers\InMonth; use TransformStudios\Events\Modifiers\IsEndOfWeek; use TransformStudios\Events\Modifiers\IsStartOfWeek; -use TransformStudios\Events\Tags\Events; +use TransformStudios\Events\Tags\Events as EventsTag; class ServiceProvider extends AddonServiceProvider { @@ -33,7 +35,7 @@ class ServiceProvider extends AddonServiceProvider ]; protected $tags = [ - Events::class, + EventsTag::class, ]; public function bootAddon() @@ -72,23 +74,18 @@ private function bootCarbon(): self private function bootFields(): self { - Collection::computed(config('events.collection', 'events'), 'timezone', function ($entry, $value) { - $value ??= config('events.timezone', config('app.timezone')); - - if ($entry->blueprint()->fields()->get('timezone')?->fieldtype() instanceof Timezones) { - return $value; - } - - return (new Field('timezone', ['type' => 'timezones', 'max_items' => 1])) - ->setValue($value) - ->setParent($entry) - ->augment() - ->value(); - }); + collect(Events::setting('collections')) + ->each(fn (array $collection) => $this + ->defineComputedTimezoneField($collection['collection'])); return $this; } + private function defineComputedTimezoneField(string $handle): void + { + Collection::computed($handle, 'timezone', $this->timezone(...)); + } + private function publishConfig(): self { Statamic::afterInstalled(function ($command) { @@ -97,4 +94,20 @@ private function publishConfig(): self return $this; } + + private function timezone(Entry $entry, $value): string|Value + { + ray('hi'); + $value ??= Events::timezone(); + + if ($entry->blueprint()->fields()->get('timezone')?->fieldtype() instanceof Timezones) { + return $value; + } + + return (new Field('timezone', ['type' => 'timezones', 'max_items' => 1])) + ->setValue($value) + ->setParent($entry) + ->augment() + ->value(); + } } diff --git a/src/Tags/Events.php b/src/Tags/Events.php index 5fdf720..ec42d76 100755 --- a/src/Tags/Events.php +++ b/src/Tags/Events.php @@ -51,7 +51,7 @@ public function downloadLink(): string return route( 'statamic.events.ics.show', Arr::removeNullValues([ - 'collection' => $this->params->get('collection', config('events.collection', 'events')), + 'collection' => $this->params->get('collection', 'events'), 'date' => $this->params->has('date') ? Carbon::parse($this->params->get('date'))->toDateString() : null, 'event' => $this->params->get('event'), ]) @@ -129,7 +129,7 @@ private function generator(): Generator { $generator = $this->params->has('event') ? Generator::fromEntry($this->params->get('event')) : - Generator::fromCollection($this->params->get('collection', config('events.collection', 'events'))); + Generator::fromCollection($this->params->get('collection', 'events')); return $generator ->site($this->params->get('site')) @@ -140,7 +140,7 @@ private function generator(): Generator )->when( value: $this->parseFilters(), callback: fn (Generator $generator, array $filters) => $generator->filters(filters: $filters) - )-> when( + )->when( value: $this->params->int('offset'), callback: fn (Generator $generator, int $offset) => $generator->offset(offset: $offset) )->when( From da81cac4c521eb8d0de018365ae8960eb8c4b623 Mon Sep 17 00:00:00 2001 From: edalzell Date: Sun, 31 Aug 2025 14:18:56 -0700 Subject: [PATCH 02/11] until the PR is merged --- src/Events.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Events.php b/src/Events.php index d61b4b4..d05c350 100644 --- a/src/Events.php +++ b/src/Events.php @@ -62,7 +62,7 @@ public static function collectionHandles(): Collection public static function setting(string $key, $default = null): mixed { - return Addon::get('transformstudios/events')->setting($key, $default); + return Addon::get('transformstudios/events')->settings()->get($key, $default); } public static function timezone(): string From 0612e25c96c5743b66ca824b609adf29001cc2f3 Mon Sep 17 00:00:00 2001 From: edalzell Date: Sun, 31 Aug 2025 20:13:42 -0700 Subject: [PATCH 03/11] need a default --- src/ServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index f38a410..e5c8650 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -74,7 +74,7 @@ private function bootCarbon(): self private function bootFields(): self { - collect(Events::setting('collections')) + collect(Events::setting('collections', [['collection' => 'events']])) ->each(fn (array $collection) => $this ->defineComputedTimezoneField($collection['collection'])); From fc565490851b5f8304a3ff530372807eb0dc3b30 Mon Sep 17 00:00:00 2001 From: edalzell Date: Wed, 22 Oct 2025 15:25:26 -0700 Subject: [PATCH 04/11] wip --- .github/workflows/test.yml | 2 +- src/UpdateScripts/ConvertConfigToSettings.php | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/UpdateScripts/ConvertConfigToSettings.php diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b7c9652..43658fb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ jobs: stability: [prefer-lowest, prefer-stable] os: [ubuntu-latest] dependency-version: [prefer-stable] - name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} - ubuntu-latest + name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 diff --git a/src/UpdateScripts/ConvertConfigToSettings.php b/src/UpdateScripts/ConvertConfigToSettings.php new file mode 100644 index 0000000..077afb7 --- /dev/null +++ b/src/UpdateScripts/ConvertConfigToSettings.php @@ -0,0 +1,52 @@ +isUpdatingTo('6.0'); + } + + public function update() + { + + $config = Fluent::make(config('events')); + + if ($config->isEmpty()) { + return; + } + + $collections = collect([$config->collection => null]) + ->merge($config->collections) + ->map(function (array|string $collection, $handle) { + if (is_string($collection)) { + return [ + 'id' => Str::random(8), + 'collection' => $collection, + ]; + } + + $locationField = Arr::get($collection, 'location_field', 'location'); + + $collectionSetting = [ + 'id' => Str::random(8), + 'collection' => $handle, + 'location_field' => $locationField == 'location' ? null : $locationField, + ]; + + return Arr::removeNullValues($collectionSetting); + })->reject(fn (array $collection) => $collection['collection'] == 'events' && is_null(Arr::get($collection, 'location_field'))) + ->all(); + + $timezone = $config->timezone ?: config('app.timezone', 'UTC'); + + return Arr::removeNullValues(compact('collections', 'timezone')); + } +} From 3327af06c0b27a6e29a82259d9ee9ced4956bad9 Mon Sep 17 00:00:00 2001 From: edalzell Date: Thu, 23 Oct 2025 15:20:57 -0700 Subject: [PATCH 05/11] wip --- composer.json | 2 +- resources/blueprints/config.yaml | 18 ------------------ resources/blueprints/settings.yaml | 2 ++ src/ServiceProvider.php | 1 - 4 files changed, 3 insertions(+), 20 deletions(-) delete mode 100644 resources/blueprints/config.yaml diff --git a/composer.json b/composer.json index ae20d1c..0d1f108 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "rlanvin/php-rrule": "^2.3.1", "spatie/calendar-links": "^1.0", "spatie/icalendar-generator": "^2.3.3", - "statamic/cms": "6.0.0-alpha.4" + "statamic/cms": "^6.0.0-alpha.14" }, "require-dev": { "orchestra/testbench": "^9.2 || ^10.0", diff --git a/resources/blueprints/config.yaml b/resources/blueprints/config.yaml deleted file mode 100644 index 28d7083..0000000 --- a/resources/blueprints/config.yaml +++ /dev/null @@ -1,18 +0,0 @@ -timezone: - display: Default Timezone - type: timezones - max_items: 1 - mode: typeahead - default: UTC -collection: - max_items: 1 - mode: select - type: collections - display: 'Events Collection' - icon: collections - localizable: false - listable: hidden - instructions_position: above - visibility: visible - replicator_preview: true - hide_display: false diff --git a/resources/blueprints/settings.yaml b/resources/blueprints/settings.yaml index 58494b2..59e6a1b 100644 --- a/resources/blueprints/settings.yaml +++ b/resources/blueprints/settings.yaml @@ -11,6 +11,7 @@ tabs: display: Collections sortable: false add_row: 'Add Collection' + full_width_setting: true fields: - handle: collection @@ -34,3 +35,4 @@ tabs: max_items: 1 type: timezones display: Timezone + full_width_setting: true diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index e5c8650..886b4de 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -97,7 +97,6 @@ private function publishConfig(): self private function timezone(Entry $entry, $value): string|Value { - ray('hi'); $value ??= Events::timezone(); if ($entry->blueprint()->fields()->get('timezone')?->fieldtype() instanceof Timezones) { From 13a3d2d0ca044751def41afbec5c583aec1609c8 Mon Sep 17 00:00:00 2001 From: edalzell Date: Fri, 24 Oct 2025 11:18:07 -0700 Subject: [PATCH 06/11] remove duplicate `UTC` tz --- resources/timezones.json | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/resources/timezones.json b/resources/timezones.json index cb99581..866605c 100644 --- a/resources/timezones.json +++ b/resources/timezones.json @@ -1979,16 +1979,6 @@ "abbreviation": "UST", "name": "Ulaanbaatar Standard Time" }, - { - "timezone": "America/Danmarkshavn", - "abbreviation": "UTC", - "name": "UTC" - }, - { - "timezone": "Etc/GMT", - "abbreviation": "UTC", - "name": "UTC" - }, { "timezone": "UTC", "abbreviation": "UTC", From 247cfdab651ab30da19e7ec398fa03e5187a4d65 Mon Sep 17 00:00:00 2001 From: edalzell Date: Fri, 24 Oct 2025 11:18:46 -0700 Subject: [PATCH 07/11] actual save the new settings --- resources/blueprints/settings.yaml | 5 +++++ src/UpdateScripts/ConvertConfigToSettings.php | 13 +++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/resources/blueprints/settings.yaml b/resources/blueprints/settings.yaml index 59e6a1b..6334348 100644 --- a/resources/blueprints/settings.yaml +++ b/resources/blueprints/settings.yaml @@ -28,6 +28,10 @@ tabs: display: 'Location Field' width: 50 default: location + default: + - + collection: events + location_field: location - handle: timezone field: @@ -36,3 +40,4 @@ tabs: type: timezones display: Timezone full_width_setting: true + default: 'UTC' diff --git a/src/UpdateScripts/ConvertConfigToSettings.php b/src/UpdateScripts/ConvertConfigToSettings.php index 077afb7..c5e30db 100644 --- a/src/UpdateScripts/ConvertConfigToSettings.php +++ b/src/UpdateScripts/ConvertConfigToSettings.php @@ -4,6 +4,7 @@ use Illuminate\Support\Fluent; use Illuminate\Support\Str; +use Statamic\Facades\Addon; use Statamic\Support\Arr; use Statamic\UpdateScripts\UpdateScript; @@ -16,7 +17,6 @@ public function shouldUpdate($newVersion, $oldVersion) public function update() { - $config = Fluent::make(config('events')); if ($config->isEmpty()) { @@ -33,20 +33,21 @@ public function update() ]; } - $locationField = Arr::get($collection, 'location_field', 'location'); - $collectionSetting = [ 'id' => Str::random(8), 'collection' => $handle, - 'location_field' => $locationField == 'location' ? null : $locationField, + 'location_field' => Arr::get($collection, 'location_field', 'location'), ]; return Arr::removeNullValues($collectionSetting); })->reject(fn (array $collection) => $collection['collection'] == 'events' && is_null(Arr::get($collection, 'location_field'))) ->all(); - $timezone = $config->timezone ?: config('app.timezone', 'UTC'); + $timezone = $config->timezone; - return Arr::removeNullValues(compact('collections', 'timezone')); + Addon::get('transformstudios/events') + ->settings() + ->set(Arr::removeNullValues(compact('collections', 'timezone'))) + ->save(); } } From a24f56008d5d162da71c75176bfad97edd342f03 Mon Sep 17 00:00:00 2001 From: edalzell Date: Fri, 24 Oct 2025 11:47:38 -0700 Subject: [PATCH 08/11] make new settings, remove old config --- src/UpdateScripts/ConvertConfigToSettings.php | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/UpdateScripts/ConvertConfigToSettings.php b/src/UpdateScripts/ConvertConfigToSettings.php index c5e30db..a2e461a 100644 --- a/src/UpdateScripts/ConvertConfigToSettings.php +++ b/src/UpdateScripts/ConvertConfigToSettings.php @@ -4,12 +4,16 @@ use Illuminate\Support\Fluent; use Illuminate\Support\Str; -use Statamic\Facades\Addon; +use Statamic\Addons\Addon; +use Statamic\Addons\Settings; +use Statamic\Facades\Addon as AddonFacade; use Statamic\Support\Arr; use Statamic\UpdateScripts\UpdateScript; class ConvertConfigToSettings extends UpdateScript { + private Addon $addon; + public function shouldUpdate($newVersion, $oldVersion) { return $this->isUpdatingTo('6.0'); @@ -17,12 +21,39 @@ public function shouldUpdate($newVersion, $oldVersion) public function update() { - $config = Fluent::make(config('events')); + $this->addon = AddonFacade::get('transformstudios/events'); - if ($config->isEmpty()) { + if (is_null($settings = $this->settingsFromConfig())) { return; } + if (! $settings->save()) { + $this->console()->error('Failed to save events settings. Please check your logs for details.'); + + return; + } + + $this->console()->info('Converted events config to settings.'); + + $this->removeConfig(); + } + + private function removeConfig(): void + { + if ($this->files->exists($configPath = config_path('events.php'))) { + $this->files->delete($configPath); + $this->console()->info('Removed old events config file.'); + } + } + + private function settingsFromConfig(): ?Settings + { + $config = Fluent::make($this->addon->config()); + + if ($config->isEmpty()) { + return null; + } + $collections = collect([$config->collection => null]) ->merge($config->collections) ->map(function (array|string $collection, $handle) { @@ -45,9 +76,8 @@ public function update() $timezone = $config->timezone; - Addon::get('transformstudios/events') + return $this->addon ->settings() - ->set(Arr::removeNullValues(compact('collections', 'timezone'))) - ->save(); + ->set(Arr::removeNullValues(compact('collections', 'timezone'))); } } From 45fcb8f9fc0d150fb2460b17e55e75d971221180 Mon Sep 17 00:00:00 2001 From: edalzell Date: Fri, 24 Oct 2025 11:57:26 -0700 Subject: [PATCH 09/11] remove keys --- src/UpdateScripts/ConvertConfigToSettings.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/UpdateScripts/ConvertConfigToSettings.php b/src/UpdateScripts/ConvertConfigToSettings.php index a2e461a..75137b9 100644 --- a/src/UpdateScripts/ConvertConfigToSettings.php +++ b/src/UpdateScripts/ConvertConfigToSettings.php @@ -72,6 +72,7 @@ private function settingsFromConfig(): ?Settings return Arr::removeNullValues($collectionSetting); })->reject(fn (array $collection) => $collection['collection'] == 'events' && is_null(Arr::get($collection, 'location_field'))) + ->values() ->all(); $timezone = $config->timezone; From 8660c00197932fc55cc92591ee31748afc83eaff Mon Sep 17 00:00:00 2001 From: edalzell Date: Fri, 24 Oct 2025 12:01:53 -0700 Subject: [PATCH 10/11] revert, out of scope --- resources/timezones.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/resources/timezones.json b/resources/timezones.json index 866605c..cb99581 100644 --- a/resources/timezones.json +++ b/resources/timezones.json @@ -1979,6 +1979,16 @@ "abbreviation": "UST", "name": "Ulaanbaatar Standard Time" }, + { + "timezone": "America/Danmarkshavn", + "abbreviation": "UTC", + "name": "UTC" + }, + { + "timezone": "Etc/GMT", + "abbreviation": "UTC", + "name": "UTC" + }, { "timezone": "UTC", "abbreviation": "UTC", From 1ae38199ea25cab304be0c2def9cc25fff6669a1 Mon Sep 17 00:00:00 2001 From: edalzell Date: Fri, 24 Oct 2025 12:03:03 -0700 Subject: [PATCH 11/11] revert, out of scope --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 43658fb..b7c9652 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ jobs: stability: [prefer-lowest, prefer-stable] os: [ubuntu-latest] dependency-version: [prefer-stable] - name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ubuntu-latest + name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} - ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3