0 ? (string) $userId : 'ip_' . md5($_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'); $transientKey = 'wclp_rate_' . $action . '_' . $key; $data = get_transient($transientKey); if ($data === false) { // First request, start counting set_transient($transientKey, ['count' => 1, 'start' => time()], $window); return true; } $count = (int) ($data['count'] ?? 0); $start = (int) ($data['start'] ?? time()); // Check if window has expired if (time() - $start >= $window) { // Reset counter set_transient($transientKey, ['count' => 1, 'start' => time()], $window); return true; } // Check if limit exceeded if ($count >= $limit) { return false; } // Increment counter set_transient($transientKey, ['count' => $count + 1, 'start' => $start], $window); return true; } /** * Get remaining time until rate limit resets * * @param string $action Action identifier * @param int $window Time window in seconds (must match the one used in checkUserRateLimit) * @return int Seconds until rate limit resets, or 0 if not rate limited */ protected function getRateLimitRetryAfter(string $action, int $window): int { $userId = get_current_user_id(); $key = $userId > 0 ? (string) $userId : 'ip_' . md5($_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'); $transientKey = 'wclp_rate_' . $action . '_' . $key; $data = get_transient($transientKey); if ($data === false) { return 0; } $start = (int) ($data['start'] ?? time()); return max(0, $window - (time() - $start)); } }