Settings (the key never leaves the server). Cached for 10 minutes per provider and key * (transient `zadex_int_lists__`); `refresh=1` (the editor's Refresh tool) bypasses the cache. * Errors: 404 unknown provider, 400 not configured / provider error (message safe to show to editors). */ final class ListsController { public const NS = 'zadex/v1'; public const CACHE_TTL = 600; public function routes(): void { register_rest_route(self::NS, '/forms/integrations/(?P[a-z0-9_-]+)/lists', [ 'methods' => 'GET', 'callback' => [$this, 'lists'], 'permission_callback' => static fn(): bool => current_user_can('edit_posts'), ]); } /** @return WP_REST_Response|WP_Error */ public function lists(WP_REST_Request $request) { $id = is_string($request['provider'] ?? null) ? sanitize_key($request['provider']) : ''; $provider = Integrations::provider($id); if ($provider === null) { return new WP_Error('zadex_unknown_provider', __('Unknown integration.', 'zadex'), ['status' => 404]); } if (!$provider->configured()) { /* translators: %s: integration name, e.g. "Mailchimp". */ return new WP_Error('zadex_integration_not_configured', sprintf(__('Add your %s API key in Zadex > Settings > Integrations.', 'zadex'), $provider->label()), ['status' => 400]); } $key = 'zadex_int_lists_' . $id . '_' . substr(md5((string) wp_json_encode(array_map([Credentials::class, 'get'], array_keys(Credentials::fields())))), 0, 10); $refresh = !empty($request['refresh']); $cached = $refresh ? false : get_transient($key); if (is_array($cached)) { return new WP_REST_Response(['options' => $cached, 'cached' => true], 200); } $lists = $provider->lists(); if ($lists instanceof WP_Error) { Log::error($id, 'Lists: ' . $lists->get_error_message()); return new WP_Error('zadex_integration_error', $provider->label() . ': ' . $lists->get_error_message(), ['status' => 400]); } set_transient($key, $lists, self::CACHE_TTL); return new WP_REST_Response(['options' => $lists, 'cached' => false], 200); } }