get_row($wpdb->prepare( "SELECT cache_value FROM {$wpdb->prefix}qbws_cache WHERE cache_key = %s AND expires_at > NOW()", $key )); if (!$row) return null; return json_decode($row->cache_value, true); } public static function set(string $key, $value, int $ttlSeconds = null): void { global $wpdb; $ttl = $ttlSeconds ?? (int) QBWS_Config::get('cache_ttl_seconds'); $wpdb->query($wpdb->prepare( "INSERT INTO {$wpdb->prefix}qbws_cache (cache_key, cache_value, expires_at) VALUES (%s, %s, DATE_ADD(NOW(), INTERVAL %d SECOND)) ON DUPLICATE KEY UPDATE cache_value = VALUES(cache_value), expires_at = VALUES(expires_at)", $key, wp_json_encode($value), $ttl )); } public static function forget(string $key): void { global $wpdb; $wpdb->delete($wpdb->prefix . 'qbws_cache', ['cache_key' => $key]); } /** * Fetch all active QB Items, cache-aware. $forceRefresh bypasses TTL * (used by the "Sync Now" admin button and by CDC-triggered runs). */ public static function getItems(QBWS_Api_Client $api, bool $forceRefresh = false): array { $cacheKey = 'qb_items_active'; if (!$forceRefresh) { $cached = self::get($cacheKey); if ($cached !== null) return $cached; } $items = []; $pageSize = (int) QBWS_Config::get('page_size'); $start = 1; do { $sql = "SELECT * FROM Item WHERE Active = true STARTPOSITION {$start} MAXRESULTS {$pageSize}"; $chunk = $api->query($sql)['Item'] ?? []; foreach ($chunk as $item) { $items[$item['Id']] = $item; } $start += $pageSize; } while (count($chunk) === $pageSize); self::set($cacheKey, $items); return $items; } /** Same pattern as getItems() but for the Customer entity. */ public static function getCustomers(QBWS_Api_Client $api, bool $forceRefresh = false): array { $cacheKey = 'qb_customers_active'; if (!$forceRefresh) { $cached = self::get($cacheKey); if ($cached !== null) return $cached; } $customers = []; $pageSize = (int) QBWS_Config::get('page_size'); $start = 1; do { $sql = "SELECT * FROM Customer WHERE Active = true STARTPOSITION {$start} MAXRESULTS {$pageSize}"; $chunk = $api->query($sql)['Customer'] ?? []; foreach ($chunk as $customer) { $customers[$customer['Id']] = $customer; } $start += $pageSize; } while (count($chunk) === $pageSize); self::set($cacheKey, $customers); return $customers; } }