[a-z_]+)'; private const SCAN_STEP_ROUTE = '/scan/step'; private const CRON_SCHEDULES_FILTER = 'cron_schedules'; public function __construct( private readonly RestRoutes $routes, private readonly JobsEndpoint $endpoint, private readonly JobRunner $runner, private readonly JobScheduler $scheduler, private readonly JobStateStore $store ) { } public function register(): void { $add_recurrences = $this->scheduler->add_recurrences( ... ); add_action( 'rest_api_init', $this->add_routes( ... ) ); add_filter( self::CRON_SCHEDULES_FILTER, $add_recurrences ); foreach ( JobId::cases() as $job ) { $run_job = fn() => $this->runner->run( $job ); add_action( $job->hook_name(), $run_job ); } } public function add_routes(): void { $list_jobs = $this->endpoint->list_jobs( ... ); $run_jobs = $this->endpoint->run_jobs( ... ); $change_job = $this->endpoint->change_job( ... ); $this->routes->add( self::JOBS_ROUTE, 'GET', $list_jobs ); $this->routes->add( self::RUN_ROUTE, 'POST', $run_jobs ); $this->routes->add( self::JOB_ROUTE, 'POST', $change_job ); $this->routes->add( self::SCAN_STEP_ROUTE, 'POST', $this->step_scan( ... ) ); } /** @return list> */ public function step_scan(): array { $this->runner->step( JobId::Check ); return $this->endpoint->list_jobs(); } public function activate(): void { foreach ( JobId::cases() as $job ) { $this->scheduler->reschedule( $job, $this->store->load( $job ) ); } } public function deactivate(): void { foreach ( JobId::cases() as $job ) { wp_clear_scheduled_hook( $job->hook_name() ); } } }