log(self::$current, self::PREFIX . wp_json_encode(['outcome' => $outcome, 'attempt' => $attempt])); } /** @return list> */ public static function recent(string $destinationId, int $limit = 25): array { if (!class_exists(\ActionScheduler::class)) return []; $limit = max(1, min(100, $limit)); $store = \ActionScheduler::store(); // AS cannot index nested argument fields. Bound the candidate page. $ids = $store->query_actions(['hook' => PushJob::HOOK, 'group' => ActionSchedulerQueue::GROUP, 'per_page' => 100, 'orderby' => 'date', 'order' => 'DESC']); $rows = []; foreach ($ids as $id) { $action = $store->fetch_action($id); $args = $action->get_args(); $job = PushJob::fromArgs(is_array($args[0] ?? null) ? $args[0] : []); if ($job === null || $job->destinationId !== $destinationId) continue; $outcome = null; $at = null; foreach (\ActionScheduler::logger()->get_logs($id) as $entry) { $message = $entry->get_message(); if (!str_starts_with($message, self::PREFIX)) continue; $decoded = json_decode(substr($message, strlen(self::PREFIX)), true); if (is_array($decoded) && in_array($decoded['outcome'] ?? null, ['accepted', 'retry_scheduled', 'needs_attention', 'skipped'], true)) { $outcome = $decoded['outcome']; $at = $entry->get_date()->format('Y-m-d H:i:s'); } } $status = $store->get_status($id); $rows[] = ['id' => (int) $id, 'lead' => $job->leadId, 'submission' => $job->submissionId, 'attempt' => $job->attempt, 'at' => $at, 'status' => $status, 'outcome' => $outcome ?? ($status === 'pending' ? 'queued' : ($status === 'in-progress' ? 'running' : 'unknown'))]; if (count($rows) >= $limit) break; } return $rows; } }