$ttl) { if (!\wp_next_scheduled('extendify_notifications_refresh', [$locale])) { \wp_schedule_single_event(time(), 'extendify_notifications_refresh', [$locale]); if (\is_admin()) { \spawn_cron(); } } } return $cached['data'] ?? []; } /** * Fetch notifications from the API and persist them. * Called synchronously on cold start and via wp-cron when the cache is stale. * * @param string $locale - Locale to fetch (cron may run in a different site locale). * @return array|null */ public static function refresh($locale) { if (!PartnerData::$id) { return []; } $optionKey = 'extendify_notifications_' . $locale; $url = \add_query_arg( ['partner' => PartnerData::$id, 'wp_language' => $locale], Constants::AI_HOST . '/api/notifications' ); $response = \wp_remote_get($url, ['headers' => ['Accept' => 'application/json']]); $result = \is_wp_error($response) ? null : json_decode(\wp_remote_retrieve_body($response), true); if (!is_array($result) || !is_array($result['notifications'] ?? null)) { $cached = \get_option($optionKey); \update_option( $optionKey, [ 'data' => is_array($cached) ? ($cached['data'] ?? []) : [], 'fetchedAt' => time(), 'failed' => true, ], false ); return null; } $notifications = $result['notifications']; \update_option( $optionKey, ['data' => $notifications, 'fetchedAt' => time()], false ); return $notifications; } }