id = self::requiredString($definition, 'id'); $this->name = self::requiredString($definition, 'name'); $this->description = (string)($definition['description'] ?? ''); $this->module = self::requiredString($definition, 'module'); $this->handler = self::requiredString($definition, 'handler'); $this->schedule = cron_schedule::normalize($definition['schedule'] ?? []); $this->enabled = (bool)($definition['enabled'] ?? true); $this->timeout_seconds = max(30, (int)($definition['timeout_seconds'] ?? 600)); $this->estimated_duration_ms = max(0, (int)($definition['estimated_duration_ms'] ?? 0)); $this->priority = (int)($definition['priority'] ?? 100); $legacy_name = trim((string)($definition['legacy_name'] ?? '')); $this->legacy_name = $legacy_name !== '' ? $legacy_name : null; if (!preg_match('/^[a-z0-9][a-z0-9_.-]{1,190}$/', $this->id)) { throw new InvalidArgumentException('Invalid cron task id: ' . $this->id); } if (!preg_match('/^[a-z0-9][a-z0-9_-]{1,63}$/', $this->module)) { throw new InvalidArgumentException('Invalid cron task module: ' . $this->module); } } public function asArray(?array $state = null, ?int $estimatedDurationMs = null): array { $schedule = is_array($state['schedule'] ?? null) && ($state['schedule'] ?? []) !== [] ? $state['schedule'] : $this->schedule; $enabled = array_key_exists('enabled', $state ?? []) ? (bool)$state['enabled'] : $this->enabled; return [ 'id' => $this->id, 'name' => $this->name, 'description' => $this->description, 'module' => $this->module, 'handler' => $this->handler, 'schedule' => $schedule, 'default_schedule' => $this->schedule, 'enabled' => $enabled, 'default_enabled' => $this->enabled, 'timeout_seconds' => $this->timeout_seconds, 'estimated_duration_ms' => $estimatedDurationMs ?? $this->estimated_duration_ms, 'priority' => $this->priority, 'legacy_name' => $this->legacy_name, 'last_run_at' => $state['last_run_at'] ?? null, 'next_run_at' => $state['next_run_at'] ?? null, 'locked_until' => $state['locked_until'] ?? null, 'lock_owner' => $state['lock_owner'] ?? null, 'current_run_id' => $state['current_run_id'] ?? null, 'last_status' => $state['last_status'] ?? null, 'last_error' => $state['last_error'] ?? null, ]; } private static function requiredString(array $definition, string $key): string { $value = trim((string)($definition[$key] ?? '')); if ($value === '') { throw new InvalidArgumentException('Missing cron task definition field: ' . $key); } return $value; } }