PluginProbe
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript / trunk
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript vtrunk
4.1.15 4.1.14 4.1.13 4.1.12 4.1.11 4.1.10 4.0.30 4.0.29 4.0.28 4.0.27 4.0.26 4.0.24 4.0.25 4.0.23 4.0.22 4.0.21 4.0.19 4.0.18 4.0.17 4.0.16 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 All 169 releases
searchpro / inc / cache / class-berqCloudflareAPIHandler.php

class-berqCloudflareAPIHandler.php in BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript trunk, at inc/cache/class-berqCloudflareAPIHandler.php

228 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH'))
3 exit;
4
5 class BerqCloudflareAPIHandler
6 {
7 private $api_url = 'https://api.cloudflare.com/client/v4/';
8 private $api_email;
9 private $api_key;
10 private $zone_id;
11
12 public function __construct($api_email, $api_key, $zone_id)
13 {
14 $this->api_email = $api_email;
15 $this->api_key = $api_key;
16 $this->zone_id = $zone_id;
17 }
18
19 public function verify_credentials()
20 {
21 $endpoint = "zones/{$this->zone_id}";
22 $response = $this->make_request($endpoint, 'GET');
23
24 return isset($response['success']) && $response['success'];
25 }
26
27 public function add_rule()
28 {
29 $rules_rep = $this->get_cache_ruleset();
30 $rules = !empty($rules_rep['result']['rules']) ? $rules_rep['result']['rules'] : false;
31 $rule_found = false;
32
33 if (!empty($rules)) {
34 foreach ($rules as $rule) {
35 // Cloudflare stores description and enabled on the rule object,
36 // not inside action_parameters.
37 if (isset($rule['description']) && $rule['description'] === 'BerqWP cache rules') {
38 $rule_found = true;
39 break;
40 }
41 }
42 }
43
44 if (!$rule_found) {
45 $this->update_cache_rules();
46 }
47 }
48
49 public function get_cache_ruleset()
50 {
51 $endpoint = "zones/{$this->zone_id}/rulesets/phases/http_request_cache_settings/entrypoint";
52 return $this->make_request($endpoint, 'GET');
53 }
54
55 public function delete_rule_by_description($description) {
56 // Step 1: Get the ruleset from Cloudflare
57 $response = $this->get_cache_ruleset();
58
59 // Handle API errors
60 if (!isset($response['success']) || !$response['success']) {
61 return [
62 'success' => false,
63 'message' => 'Failed to fetch ruleset: ' . ($response['errors'][0]['message'] ?? 'Unknown error'),
64 ];
65 }
66
67 // Extract the ruleset and its rules
68 $ruleset = $response['result'] ?? [];
69 $rules = $ruleset['rules'] ?? [];
70
71 // Step 2: Find and remove the rule by description
72 $updatedRules = [];
73 $found = false;
74
75 foreach ($rules as $rule) {
76 if (isset($rule['description']) && $rule['description'] === $description) {
77 $found = true;
78 } else {
79 $updatedRules[] = $rule; // Keep rules that don't match
80 }
81 }
82
83 if (!$found) {
84 return [
85 'success' => false,
86 'message' => "No rule found with description: {$description}",
87 ];
88 }
89
90 // Step 3: Send only the rules array back to Cloudflare.
91 // Sending read-only fields (id, version, kind, phase) is non-idiomatic and fragile.
92 $update_endpoint = "zones/{$this->zone_id}/rulesets/{$ruleset['id']}";
93 $update_response = $this->make_request($update_endpoint, 'PUT', ['rules' => $updatedRules]);
94
95 // Step 5: Return result
96 if (isset($update_response['success']) && $update_response['success']) {
97 return [
98 'success' => true,
99 'message' => 'Rule deleted successfully.',
100 ];
101 } else {
102 return [
103 'success' => false,
104 'message' => 'Failed to update ruleset: ' .
105 implode(' ', array_column($update_response['errors'] ?? [], 'message')),
106 ];
107 }
108 }
109
110 public function purge_all_cache() {
111 $endpoint = "zones/{$this->zone_id}/purge_cache";
112 $response = $this->make_request($endpoint, 'POST', [
113 'purge_everything' => true
114 ]);
115
116 if (is_array($response) && isset($response['success']) && $response['success']) {
117 return [
118 'success' => true,
119 'message' => 'All cache purged successfully.',
120 ];
121 }
122
123 $errors = is_array($response) && isset($response['errors'])
124 ? implode(' ', array_column($response['errors'], 'message'))
125 : 'Unknown error';
126
127 return [
128 'success' => false,
129 'message' => 'Failed to purge cache: ' . $errors,
130 ];
131 }
132
133 // Method to flush a specific URL from cache
134 public function flush_url($url) {
135 $endpoint = "zones/{$this->zone_id}/purge_cache";
136 $response = $this->make_request($endpoint, 'POST', [
137 'files' => [$url]
138 ]);
139
140 if (is_array($response) && isset($response['success']) && $response['success']) {
141 return [
142 'success' => true,
143 'message' => "Cache for {$url} purged successfully."
144 ];
145 }
146
147 $errors = is_array($response) && isset($response['errors'])
148 ? implode(' ', array_column($response['errors'], 'message'))
149 : 'Unknown error';
150
151 return [
152 'success' => false,
153 'message' => 'Failed to purge URL: ' . $errors,
154 ];
155 }
156
157 public function update_cache_rules()
158 {
159 $endpoint = "zones/{$this->zone_id}/rulesets/phases/http_request_cache_settings/entrypoint";
160
161 // GET existing rules so we don't wipe other CF cache rules in the zone.
162 $existing = $this->get_cache_ruleset();
163 $existing_rules = !empty($existing['result']['rules']) ? $existing['result']['rules'] : [];
164
165 // Remove any old BerqWP rule, keep everything else.
166 $merged = [];
167 foreach ($existing_rules as $rule) {
168 if (!isset($rule['description']) || $rule['description'] !== 'BerqWP cache rules') {
169 $merged[] = $rule;
170 }
171 }
172
173 // Append the canonical BerqWP cache rule.
174 $merged[] = [
175 'expression' => 'not (http.request.method ne "GET" or http.cookie contains "wordpress_logged_in_" or http.request.uri.path contains "/wp-admin" or http.request.uri.path contains ".xml" or http.request.uri.path contains ".txt" or http.request.uri.path contains ".gz" or http.request.uri.path contains "sitemap" or http.request.uri.query ne "")',
176 'action' => 'set_cache_settings',
177 'action_parameters' => [
178 'cache' => true,
179 ],
180 'description' => 'BerqWP cache rules',
181 ];
182
183 $response = $this->make_request($endpoint, 'PUT', ['rules' => $merged]);
184
185 if (is_array($response) && isset($response['success']) && $response['success']) {
186 return [
187 'success' => true,
188 'message' => 'Cache rules updated successfully'
189 ];
190 }
191
192 return [
193 'success' => false,
194 'message' => is_array($response) && isset($response['errors']) ? json_encode($response['errors']) : 'Unknown error occurred'
195 ];
196 }
197
198 private function make_request($endpoint, $method = 'GET', $data = null)
199 {
200 $url = $this->api_url . $endpoint;
201
202 $args = [
203 'method' => $method,
204 'headers' => [
205 'Content-Type' => 'application/json',
206 'X-Auth-Email' => $this->api_email,
207 'X-Auth-Key' => $this->api_key
208 ],
209 'timeout' => 30
210 ];
211
212 if ($data !== null) {
213 $args['body'] = json_encode($data);
214 }
215
216 $response = wp_remote_request($url, $args);
217
218 if (is_wp_error($response)) {
219 return [
220 'success' => false,
221 'errors' => [['message' => $response->get_error_message()]]
222 ];
223 }
224
225 $body = wp_remote_retrieve_body($response);
226 return json_decode($body, true);
227 }
228 }