From 0afb2c0046b55c123eafb4ab9ee77efa68d12463 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sat, 06 Jun 2026 17:15:31 +0000
Subject: [PATCH] =Starting the Favourites.js setup, converting previous Northeh stuff to new Registrar, fixing up Square.php integration to match
---
inc/rest/RateLimits.php | 98 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 98 insertions(+), 0 deletions(-)
diff --git a/inc/rest/RateLimits.php b/inc/rest/RateLimits.php
index e69de29..41d75b8 100644
--- a/inc/rest/RateLimits.php
+++ b/inc/rest/RateLimits.php
@@ -0,0 +1,98 @@
+<?php
+namespace JVBase\rest;
+
+use WP_REST_Request;
+
+if (!defined('ABSPATH')) {
+ exit;
+}
+
+/**
+ * Handles rate limiting for REST requests
+ */
+class RateLimits
+{
+ protected string $cacheGroup = 'jvb_rate_limits';
+
+ protected array $defaults = [
+ 'GET' => ['count' => 1000, 'window' => 3600],
+ 'POST' => ['count' => 100, 'window' => 3600],
+ 'PUT' => ['count' => 100, 'window' => 3600],
+ 'PATCH' => ['count' => 100, 'window' => 3600],
+ 'DELETE' => ['count' => 50, 'window' => 3600],
+ ];
+
+ /**
+ * Check if request is within rate limits
+ *
+ * @param WP_REST_Request $request
+ * @param int|null $limit Optional custom limit (overrides defaults)
+ * @param int|null $window Optional custom window in seconds (overrides defaults)
+ * @return bool True if within limits, false if exceeded
+ */
+ public function checkLimit(WP_REST_Request $request, ?int $limit = null, ?int $window = null): bool
+ {
+ $method = $request->get_method();
+ $default = $this->defaults[$method] ?? $this->defaults['GET'];
+
+ $limit = $limit ?? $default['count'];
+ $window = $window ?? $default['window'];
+
+ $key = $this->getCacheKey($request, $window);
+ $current = (int) wp_cache_get($key, $this->cacheGroup);
+
+ if ($current >= $limit) {
+ return false;
+ }
+
+ // Increment or initialize
+ if ($current === 0) {
+ wp_cache_set($key, 1, $this->cacheGroup, $window);
+ } else {
+ wp_cache_incr($key, 1, $this->cacheGroup);
+ }
+
+ return true;
+ }
+
+ /**
+ * Get remaining requests for current window
+ */
+ public function getRemaining(WP_REST_Request $request, ?int $limit = null, ?int $window = null): int
+ {
+ $method = $request->get_method();
+ $default = $this->defaults[$method] ?? $this->defaults['GET'];
+
+ $limit = $limit ?? $default['count'];
+ $window = $window ?? $default['window'];
+
+ $key = $this->getCacheKey($request, $window);
+ $current = (int) wp_cache_get($key, $this->cacheGroup);
+
+ return max(0, $limit - $current);
+ }
+
+ /**
+ * Reset rate limit for a request pattern
+ */
+ public function reset(WP_REST_Request $request, ?int $window = null): void
+ {
+ $method = $request->get_method();
+ $default = $this->defaults[$method] ?? $this->defaults['GET'];
+ $window = $window ?? $default['window'];
+
+ $key = $this->getCacheKey($request, $window);
+ wp_cache_delete($key, $this->cacheGroup);
+ }
+
+ protected function getCacheKey(WP_REST_Request $request, int $window): string
+ {
+ $ip = $request->get_header('X-Forwarded-For') ?: ($_SERVER['REMOTE_ADDR'] ?? 'unknown');
+ $userId = get_current_user_id();
+ $method = $request->get_method();
+ $route = $request->get_route();
+
+ // Include window in key so different windows don't collide
+ return "rate:{$ip}:{$userId}:{$method}:{$route}:{$window}";
+ }
+}
--
Gitblit v1.10.0