← All changes
|
Inc/Framework/Inc/Base/Integrations/Integration.php
+55
-15
3.1.8
→
3.1.14
View file →
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | 3 | * @package FirePlugins Framework |
| 4 | - * @version 1.1.146 | |
| 4 | + * @version 1.2.6 | |
| 5 | 5 | * |
| 6 | 6 | * @author FirePlugins <[email protected]> |
| 7 | 7 | * @link https://www.fireplugins.com |
| 8 | 8 | * @copyright Copyright © 2026 FirePlugins All Rights Reserved |
| @@ -88,8 +88,32 @@ | ||
| 88 | 88 | return $this->last_error ?: false; |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | /** |
| 92 | + * Last-resort error message for a failed request whose body carried no | |
| 93 | + * recognisable API error. Without it a 4xx/5xx would be silently reported | |
| 94 | + * as an empty result (eg "this account has no lists"). | |
| 95 | + * | |
| 96 | + * @return string | |
| 97 | + */ | |
| 98 | + protected function getHttpStatusError() | |
| 99 | + { | |
| 100 | + if (!is_array($this->last_response) || !isset($this->last_response['response']['code'])) | |
| 101 | + { | |
| 102 | + return ''; | |
| 103 | + } | |
| 104 | + | |
| 105 | + $status = (int) $this->last_response['response']['code']; | |
| 106 | + | |
| 107 | + if ($status >= 200 && $status <= 299) | |
| 108 | + { | |
| 109 | + return ''; | |
| 110 | + } | |
| 111 | + | |
| 112 | + return sprintf('The request failed with HTTP status %d.', $status); | |
| 113 | + } | |
| 114 | + | |
| 115 | + /** | |
| 92 | 116 | * Get an array containing the HTTP headers and the body of the API response. |
| 93 | 117 | * @return array Assoc array with keys 'headers' and 'body' |
| 94 | 118 | */ |
| 95 | 119 | public function getLastResponse() |
| @@ -170,15 +194,10 @@ | ||
| 170 | 194 | * @throws \Exception |
| 171 | 195 | */ |
| 172 | 196 | protected function makeRequest($http_verb, $method, $args = []) |
| 173 | 197 | { |
| 174 | - $url = $this->endpoint; | |
| 198 | + $url = $this->buildRequestUrl($method); | |
| 175 | 199 | |
| 176 | - if (!empty($method) && !is_null($method) && strpos($url, '?') === false) | |
| 177 | - { | |
| 178 | - $url .= '/' . $method; | |
| 179 | - } | |
| 180 | - | |
| 181 | 200 | $this->last_error = ''; |
| 182 | 201 | $this->request_successful = false; |
| 183 | 202 | $this->last_response = []; |
| 184 | 203 | $this->last_request = [ |
| @@ -204,9 +223,9 @@ | ||
| 204 | 223 | |
| 205 | 224 | $body = ''; |
| 206 | 225 | |
| 207 | 226 | // Send request to API Endpoint |
| 208 | - $response = wp_remote_request($url, $this->last_request); | |
| 227 | + $response = wp_safe_remote_request($url, $this->last_request); | |
| 209 | 228 | |
| 210 | 229 | if (!is_wp_error($response)) |
| 211 | 230 | { |
| 212 | 231 | $response['body'] = $this->convertResponse($response); |
| @@ -235,15 +254,10 @@ | ||
| 235 | 254 | * @return array|false |
| 236 | 255 | */ |
| 237 | 256 | protected function curlRequest($http_verb, $method, $args = []) |
| 238 | 257 | { |
| 239 | - $url = $this->endpoint; | |
| 258 | + $url = $this->buildRequestUrl($method); | |
| 240 | 259 | |
| 241 | - if (!empty($method) && !is_null($method) && strpos($url, '?') === false) | |
| 242 | - { | |
| 243 | - $url .= '/' . $method; | |
| 244 | - } | |
| 245 | - | |
| 246 | 260 | $this->last_error = ''; |
| 247 | 261 | $this->request_successful = false; |
| 248 | 262 | $this->last_response = []; |
| 249 | 263 | $this->last_request = [ |
| @@ -280,8 +294,9 @@ | ||
| 280 | 294 | |
| 281 | 295 | curl_setopt($curl, CURLOPT_URL, $url); |
| 282 | 296 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); |
| 283 | 297 | curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout); |
| 298 | + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5); | |
| 284 | 299 | curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); |
| 285 | 300 | |
| 286 | 301 | if ($http_verb === 'post') |
| 287 | 302 | { |
| @@ -292,9 +307,11 @@ | ||
| 292 | 307 | $raw_body = curl_exec($curl); |
| 293 | 308 | $curl_err = curl_error($curl); |
| 294 | 309 | $status = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE); |
| 295 | 310 | |
| 296 | - curl_close($curl); | |
| 311 | + // The handle is released when $curl goes out of scope. curl_close() has been a no-op | |
| 312 | + // since PHP 8.0 and is deprecated in 8.5. | |
| 313 | + unset($curl); | |
| 297 | 314 | |
| 298 | 315 | if ($raw_body === false) |
| 299 | 316 | { |
| 300 | 317 | $this->last_error = $curl_err; |
| @@ -314,8 +331,31 @@ | ||
| 314 | 331 | $this->last_response = $response; |
| 315 | 332 | $this->determineSuccess(); |
| 316 | 333 | |
| 317 | 334 | return $this->last_response['body']; |
| 335 | + } | |
| 336 | + | |
| 337 | + /** | |
| 338 | + * Join the endpoint and the API method into the request URL. | |
| 339 | + * | |
| 340 | + * Callers pass the method without leading or trailing slashes: some APIs | |
| 341 | + * (eg Brevo) return 404 for `/contacts/lists/`. An endpoint that already | |
| 342 | + * carries a query string is used as-is. | |
| 343 | + * | |
| 344 | + * @param string $method | |
| 345 | + * | |
| 346 | + * @return string | |
| 347 | + */ | |
| 348 | + protected function buildRequestUrl($method) | |
| 349 | + { | |
| 350 | + $url = (string) $this->endpoint; | |
| 351 | + | |
| 352 | + if (empty($method) || strpos($url, '?') !== false) | |
| 353 | + { | |
| 354 | + return $url; | |
| 355 | + } | |
| 356 | + | |
| 357 | + return $url . '/' . $method; | |
| 318 | 358 | } |
| 319 | 359 | |
| 320 | 360 | /** |
| 321 | 361 | * Encode the data and attach it to the request |