diff --git a/src/Core/Actions/ScheduleServiceProvider.php b/src/Core/Actions/ScheduleServiceProvider.php new file mode 100644 index 0000000..54c5c69 --- /dev/null +++ b/src/Core/Actions/ScheduleServiceProvider.php @@ -0,0 +1,73 @@ +app->runningInConsole()) { + return; + } + + // Guard against table not existing (pre-migration) + if (! Schema::hasTable('scheduled_actions')) { + return; + } + + $this->app->booted(function () { + $schedule = $this->app->make(Schedule::class); + + $actions = ScheduledAction::enabled()->get(); + + foreach ($actions as $action) { + $class = $action->action_class; + + if (! class_exists($class)) { + continue; + } + + $event = $schedule->call(function () use ($class, $action) { + $class::run(); + $action->markRun(); + })->name($class); + + // Apply frequency + $method = $action->frequencyMethod(); + $args = $action->frequencyArgs(); + $event->{$method}(...$args); + + // Apply options + if ($action->without_overlapping) { + $event->withoutOverlapping(); + } + + if ($action->timezone) { + $event->timezone($action->timezone); + } + } + }); + } +} diff --git a/src/Core/Front/Cli/Boot.php b/src/Core/Front/Cli/Boot.php index c40ff74..5e76367 100644 --- a/src/Core/Front/Cli/Boot.php +++ b/src/Core/Front/Cli/Boot.php @@ -35,6 +35,8 @@ class Boot extends ServiceProvider return; } + $this->app->register(\Core\Actions\ScheduleServiceProvider::class); + $this->fireConsoleBooting(); } diff --git a/tests/Feature/ScheduleServiceProviderTest.php b/tests/Feature/ScheduleServiceProviderTest.php new file mode 100644 index 0000000..4cef2eb --- /dev/null +++ b/tests/Feature/ScheduleServiceProviderTest.php @@ -0,0 +1,76 @@ +loadMigrationsFrom(__DIR__.'/../../database/migrations'); + } + + protected function defineEnvironment($app): void + { + $app['config']->set('database.default', 'testing'); + $app['config']->set('database.connections.testing', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + ]); + } + + protected function getPackageProviders($app): array + { + return [ + ScheduleServiceProvider::class, + ]; + } + + public function test_provider_registers_enabled_actions_with_scheduler(): void + { + ScheduledAction::create([ + 'action_class' => 'Core\\Tests\\Fixtures\\Mod\\Scheduled\\Actions\\EveryMinuteAction', + 'frequency' => 'everyMinute', + 'is_enabled' => true, + ]); + + ScheduledAction::create([ + 'action_class' => 'Core\\Tests\\Fixtures\\Mod\\Scheduled\\Actions\\DailyAction', + 'frequency' => 'dailyAt:09:00', + 'timezone' => 'Europe/London', + 'is_enabled' => false, + ]); + + // Re-boot the provider to pick up the new rows + $provider = new ScheduleServiceProvider($this->app); + $provider->boot(); + + $schedule = $this->app->make(Schedule::class); + $events = $schedule->events(); + + // Should have at least the enabled action + $this->assertNotEmpty($events); + } + + public function test_provider_skips_when_table_does_not_exist(): void + { + // Drop the table + Schema::dropIfExists('scheduled_actions'); + + // Should not throw + $provider = new ScheduleServiceProvider($this->app); + $provider->boot(); + + $this->assertTrue(true); + } +}