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 new file mode 100644 index 0000000..6334348 --- /dev/null +++ b/resources/blueprints/settings.yaml @@ -0,0 +1,43 @@ +tabs: + main: + display: Main + sections: + - + fields: + - + handle: collections + field: + type: grid + display: Collections + sortable: false + add_row: 'Add Collection' + full_width_setting: true + 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 + default: + - + collection: events + location_field: location + - + handle: timezone + field: + mode: select + max_items: 1 + type: timezones + display: Timezone + full_width_setting: true + default: 'UTC' diff --git a/src/Events.php b/src/Events.php index 1779351..d05c350 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')->settings()->get($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..886b4de 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', [['collection' => 'events']])) + ->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,19 @@ private function publishConfig(): self return $this; } + + private function timezone(Entry $entry, $value): string|Value + { + $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( diff --git a/src/UpdateScripts/ConvertConfigToSettings.php b/src/UpdateScripts/ConvertConfigToSettings.php new file mode 100644 index 0000000..75137b9 --- /dev/null +++ b/src/UpdateScripts/ConvertConfigToSettings.php @@ -0,0 +1,84 @@ +isUpdatingTo('6.0'); + } + + public function update() + { + $this->addon = AddonFacade::get('transformstudios/events'); + + 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) { + if (is_string($collection)) { + return [ + 'id' => Str::random(8), + 'collection' => $collection, + ]; + } + + $collectionSetting = [ + 'id' => Str::random(8), + 'collection' => $handle, + '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'))) + ->values() + ->all(); + + $timezone = $config->timezone; + + return $this->addon + ->settings() + ->set(Arr::removeNullValues(compact('collections', 'timezone'))); + } +}