PluginProbe
WPGet API – Connect to any external REST API / 2.25.4
WPGet API – Connect to any external REST API v2.25.4
1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.3 2.1.4 2.1.5 2.2.0 2.2.1 2.2.10 2.2.2 2.2.3 All 97 releases
wpgetapi / includes / class-wpgetapi-api.php

class-wpgetapi-api.php in WPGet API – Connect to any external REST API 2.25.4, at includes/class-wpgetapi-api.php

931 lines 33.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Exit if accessed directly
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 /**
9 * The main class
10 *
11 * @since 1.0.0
12 */
13 class WpGetApi_Api {
14
15 public $encryption = ''; // the encryption class
16
17 public $setup = ''; // store the setup data from the admin page
18 public $api = ''; // store the api's from the admin page
19
20 public $api_id = ''; // the api_id that we are wanting to get
21 public $endpoint_id = ''; // the endpoint_id that we are wanting to get
22 public $args = ''; // the args
23 public $keys = ''; // the keys we want to retrieve
24
25 public $base_url = ''; // base url of the API
26 public $method = 'GET'; // the endpoint method GET POST etc
27 public $cache_time = ''; // the time to cache
28 public $endpoint = ''; // the endpoint that we will get
29 public $query_parameters = ''; // the query parameters appended to url
30 public $header_parameters = ''; // the header parameters
31 public $body_parameters = ''; // the body parameters
32 public $body_json_encode = ''; // body_json_encode body
33 public $body_url_encode = ''; // urlencode body
34 public $body_base64_encode = ''; // base64 encode body
35 public $body_xml_format = ''; // xml format body
36 public $xml_root_node = 'root'; // root node for xml
37
38 public $response = ''; // the returned response
39
40 public $final_url = ''; // final URL
41 public $final_request_args = array(); // final request_args
42
43 public $results_format = 'json_string'; // results format
44
45 public $response_code = ''; // the response code from the call
46
47 public $timeout = 10; // the timeout
48 public $sslverify = 1; // ssl verify
49 public $debug = false;
50
51 public $pro_plugin = false;
52
53 public $oauth2 = false;
54
55 /**
56 * API response headers.
57 *
58 * @var array|string Response headers from the API.
59 */
60 public $response_header = '';
61
62 /**
63 * Main constructor
64 *
65 * @since 1.0.0
66 *
67 */
68 public function __construct( $api_id = '', $endpoint_id = '', $args = array(), $keys = array() ) {
69
70 $this->setup = get_option( 'wpgetapi_setup' );
71 $this->api = get_option( 'wpgetapi_' . $api_id );
72
73 $this->encryption = new WpGetApi_Encryption();
74 $this->api_id = sanitize_text_field( $api_id );
75 $this->endpoint_id = sanitize_text_field( $endpoint_id );
76 $this->keys = $keys;
77 $this->args = $args;
78
79 add_filter( 'wpgetapi_raw_error_data', array( $this, 'maybe_add_debug_info' ), 99, 2 );
80 add_filter( 'wpgetapi_raw_data', array( $this, 'maybe_add_debug_info' ), 99, 2 );
81 }
82
83
84 /**
85 * Init our api data
86 */
87 public function init() {
88
89 if ( ! function_exists( 'is_plugin_active' ) ) {
90 include_once ABSPATH . 'wp-admin/includes/plugin.php';
91 }
92
93 $this->pro_plugin = is_plugin_active( 'wpgetapi-extras/wpgetapi-extras.php' ) ? true : false;
94
95 // if we are doing importer plugin,
96 // we need to intercept and modify most of our methods values
97 if ( $this->api_id === 'wpgetapi_importer' ) {
98
99 $data = apply_filters( 'wpgetapi_api_importer_init', $this );
100
101 if ( $data ) {
102
103 foreach ( $data as $key => $value ) {
104 $this->{$key} = $value;
105 }
106
107 $this->query_parameters = ! empty( $this->query_parameters ) ? $this->do_parameters( $this->query_parameters ) : array();
108 $this->header_parameters = ! empty( $this->header_parameters ) ? $this->do_parameters( $this->header_parameters ) : array();
109 $this->body_parameters = ! empty( $this->body_parameters ) ? $this->do_parameters( $this->body_parameters ) : array();
110 return;
111
112 }
113 }
114
115 // do some checks
116 if ( empty( $this->setup ) || ! isset( $this->setup['apis'] ) || empty( $this->setup['apis'] ) ) {
117 return 'No API found.';
118 }
119
120 // do some checks
121 if ( ! $this->api || ! isset( $this->api['endpoints'] ) || empty( $this->api['endpoints'] ) ) {
122 return 'API not found.';
123 }
124
125 // loop through api's
126 // set base_url
127 foreach ( $this->setup['apis'] as $index => $api_item ) {
128 if ( $this->api_id == $api_item['id'] ) {
129 $this->base_url = isset( $api_item['base_url'] ) && ! empty( $api_item['base_url'] ) ? esc_url_raw( $api_item['base_url'] ) : '';
130 }
131 }
132
133 // loop through endpoints
134 foreach ( $this->api['endpoints'] as $index => $endpoint ) {
135
136 if ( $this->endpoint_id == $endpoint['id'] ) {
137
138 $this->method = isset( $endpoint['method'] ) && $endpoint['method'] != '' ? sanitize_text_field( $endpoint['method'] ) : 'GET';
139 $this->timeout = isset( $endpoint['timeout'] ) && ! empty( $endpoint['timeout'] ) ? absint( $endpoint['timeout'] ) : '';
140 $this->cache_time = isset( $endpoint['cache_time'] ) && ! empty( $endpoint['cache_time'] ) ? absint( $endpoint['cache_time'] ) : '';
141 $this->endpoint = isset( $endpoint['endpoint'] ) && ! empty( $endpoint['endpoint'] ) ? sanitize_text_field( $endpoint['endpoint'] ) : '';
142
143 $this->query_parameters = isset( $endpoint['query_parameters'] ) && ! empty( $endpoint['query_parameters'] ) ? $this->do_parameters( $endpoint['query_parameters'] ) : array();
144
145 $this->header_parameters = isset( $endpoint['header_parameters'] ) && ! empty( $endpoint['header_parameters'] ) ? $this->do_parameters( $endpoint['header_parameters'] ) : array();
146
147 $this->body_parameters = isset( $endpoint['body_parameters'] ) && ! empty( $endpoint['body_parameters'] ) ? $this->do_parameters( $endpoint['body_parameters'] ) : array();
148
149 // how to encode the body
150 $this->body_json_encode = isset( $endpoint['body_json_encode'] ) && $endpoint['body_json_encode'] == 'true' ? true : false;
151 $this->body_url_encode = isset( $endpoint['body_json_encode'] ) && $endpoint['body_json_encode'] == 'url' ? true : false;
152 $this->body_base64_encode = isset( $endpoint['body_json_encode'] ) && $endpoint['body_json_encode'] == 'base64' ? true : false;
153 $this->body_xml_format = isset( $endpoint['body_json_encode'] ) && $endpoint['body_json_encode'] == 'xml' ? true : false;
154
155 $this->xml_root_node = isset( $endpoint['xml_root'] ) && ! empty( $endpoint['xml_root'] ) ? $endpoint['xml_root'] : $this->xml_root_node;
156
157 $this->results_format = isset( $endpoint['results_format'] ) ? sanitize_text_field( $endpoint['results_format'] ) : $this->results_format;
158
159 if ( // set the format to php array data if html format is set
160 ( isset( $this->args['format'] ) && $this->args['format'] == 'html' && $this->results_format != 'xml_array' ) ||
161 // set the format to php array data if it is set in the args (coming from the importer)
162 ( isset( $this->args['results_format'] ) && $this->args['results_format'] == 'json_decoded' )
163 ) {
164 $this->results_format = 'json_decoded';
165 }
166
167 // set the format to JSON string if it is set in the args (coming from the wpdatatables integration)
168 if ( isset( $this->args['results_format'] ) && $this->args['results_format'] == 'json_string' ) {
169 $this->results_format = 'json_string';
170 }
171
172 // set the format to JSON string if it is set in the args (coming from the wpdatatables integration)
173 if ( isset( $this->args['results_format'] ) && $this->args['results_format'] == 'json_decoded' ) {
174 $this->results_format = 'json_decoded';
175 }
176 }
177 }
178
179 $this->timeout = isset( $this->api['timeout'] ) && ! empty( $this->api['timeout'] ) ? $this->api['timeout'] : $this->timeout;
180 $this->sslverify = isset( $this->api['sslverify'] ) ? absint( $this->api['sslverify'] ) : $this->sslverify;
181 }
182
183
184 /**
185 * The main function to output the data
186 *
187 * @param string $field Field to retrieve
188 */
189 public function endpoint_output() {
190
191 do_action( 'wpgetapi_before_do_the_call', $this );
192
193 return $this->do_the_call();
194 }
195
196
197 /**
198 * Send the request and return our data
199 */
200 public function do_the_call() {
201
202 $this->init();
203
204 // build the URL
205 $this->final_url = apply_filters( 'wpgetapi_final_url', $this->build_url(), $this );
206
207 // build the request args
208 $this->final_request_args = apply_filters( 'wpgetapi_final_request_args', $this->build_request_args(), $this );
209
210 /**
211 * Check if we should stop or not. Setting $on to true, will stop us calling the api.
212 * @param bool $on Whether on is set or not.
213 */
214
215 if ( apply_filters( 'wpgetapi_should_we_stop', false, $this ) ) {
216 return;
217 }
218
219 // POST request
220 if ( $this->method == 'POST' ) {
221 $this->response = $this->POST_request();
222 }
223
224 // PUT request
225 if ( $this->method == 'PUT' ) {
226 $this->response = $this->PUT_request();
227 }
228
229 // PATCH request
230 if ( $this->method == 'PATCH' ) {
231 $this->response = $this->PATCH_request();
232 }
233
234 // GET request
235 if ( $this->method == 'GET' ) {
236 $this->response = $this->GET_request();
237 }
238
239 // DELETE request
240 if ( $this->method == 'DELETE' ) {
241 $this->response = $this->DELETE_request();
242 }
243
244 // wp error
245 if ( is_wp_error( $this->response ) ) {
246 return apply_filters( 'wpgetapi_raw_error_data', wp_json_encode( $this->response ), $this );
247 }
248
249 // get and set response_code
250 $this->response_code = wp_remote_retrieve_response_code( $this->response );
251 wpgetapi_set_api_last_response_code( $this->api_id, $this->endpoint_id, $this->response_code );
252
253 // action to intercept call depending on response_code
254 $this->response = apply_filters( 'wpgetapi_before_retrieve_body', $this->response, $this->response_code, $this );
255
256 /**
257 * Retrieves and filters the response headers from the API request.
258 *
259 * This sets the `$this->response_header` property using the headers from the API response.
260 * Allows modification of the headers via the 'wpgetapi_response_headers' filter.
261 *
262 * @see https://developer.wordpress.org/reference/functions/wp_remote_retrieve_headers/
263 *
264 * @param array|Requests_Utility_CaseInsensitiveDictionary $headers The headers retrieved from the response.
265 * @param array|WP_Error $response The full response or WP_Error on failure.
266 * @param int $response_code The HTTP response code.
267 * @param object $this The WpGetApi_Api instance.
268 */
269 $this->response_header = apply_filters( 'wpgetapi_response_headers', wp_remote_retrieve_headers( $this->response ), $this->response, $this->response_code, $this );
270
271 // get body
272 // modified in version 1.6.1 to allow for OAuth 2.0 plugin returning body already
273 $data = isset( $this->response['body'] ) ? $this->response['body'] : $this->response;
274
275 // returning in JSON format
276 if ( $this->results_format == 'json_string' || $this->results_format == 'json_decoded' ) {
277 $data = $this->return_data( $data );
278 }
279
280 if ( $data === 'null' ) {
281 $data = 'Result is null. Check that all endpoint settings are correct.';
282 }
283
284 return apply_filters( 'wpgetapi_raw_data', $data, $this );
285 }
286
287
288 /**
289 * Build the request url with the ability to add args
290 */
291 public function build_url() {
292
293 // first make sure our endpoint starts with a slash
294 if ( substr( $this->endpoint, 0, 1 ) != '/' ) {
295 $this->endpoint = '/' . $this->endpoint;
296 }
297
298 // if we have item_key from api to posts plugin
299 // replace our keyword with the actual item_key value
300 if ( isset( $this->args['item_key'] ) && strpos( $this->endpoint, '(importer:item_key)' ) !== false ) {
301 $this->endpoint = str_replace( '(importer:item_key)', $this->args['item_key'], $this->endpoint );
302 }
303
304 $this->endpoint = apply_filters( 'wpgetapi_endpoint', $this->endpoint, $this );
305
306 $url = untrailingslashit( $this->base_url ) . $this->endpoint;
307
308 // if we have a URL pagination event from the import plugin
309 // we need to modify the URL here
310 if ( isset( $this->args['paginate_url'] ) ) {
311 $url = $this->args['paginate_url'];
312 }
313
314 // filter our params - added for use in Oauth 2.0 plugin
315 $params = apply_filters( 'wpgetapi_query_parameters', $this->query_parameters, $this );
316
317 // add empty array - was getting errors if it was just null or false
318 $params = empty( $params ) ? array( '' => '' ) : $params;
319 $params = array_map( 'rawurlencode', $params );
320
321 $result = add_query_arg( $params, $url );
322
323 return rawurldecode( $result );
324 }
325
326
327 /**
328 * build the header with the ability to add args
329 */
330 public function build_request_args() {
331
332 // add our header parameters to the headers
333 $headers = apply_filters(
334 'wpgetapi_header_parameters',
335 array(
336 'headers' => $this->header_parameters,
337 ),
338 $this
339 );
340
341 // if doing POST request, include body parameters
342 if ( $this->method == 'POST' || $this->method == 'PUT' || $this->method == 'DELETE' || $this->method == 'PATCH' ) {
343
344 // tokens are sent through here
345 $this->body_parameters = apply_filters( 'wpgetapi_body_parameters', $this->body_parameters, $this );
346
347 // do we json_encode the entire body
348 if ( $this->body_json_encode == true ) {
349 $this->body_parameters = wp_json_encode( $this->body_parameters );
350 }
351
352 // do we urlencode the entire body
353 if ( $this->body_parameters && $this->body_url_encode == true ) {
354
355 // checking if the parameters have a json string (raw)
356 if ( ( ! is_array( $this->body_parameters ) ) &&
357 ( substr( $this->body_parameters, 0, 1 ) === '{' || substr( $this->body_parameters, 0, 1 ) === '[' )
358 ) {
359 $this->body_parameters = json_decode( $this->body_parameters, true );
360 }
361
362 $this->body_parameters = http_build_query( $this->body_parameters, '', '&' );
363
364 }
365
366 // do we xml the entire body
367 if ( $this->body_parameters && $this->body_xml_format == true ) {
368
369 $root_node = $this->xml_root_node != '' ? '<' . $this->xml_root_node . '/>' : '';
370
371 $xml_element = apply_filters( 'wpgetapi_xml_element', '<?xml version="1.0" encoding="UTF-8"?>' . $root_node );
372
373 $xml = new SimpleXmlElement( $xml_element );
374
375 foreach ( $this->body_parameters as $key => $value ) {
376 $xml->addChild( $key, $value );
377 }
378
379 $this->body_parameters = $xml->asXML();
380
381 }
382
383 // do we base64 encode the entire body
384 if ( $this->body_parameters && $this->body_base64_encode == true ) {
385
386 $this->body_parameters = is_array( $this->body_parameters ) ? wp_json_encode( $this->body_parameters ) : $this->body_parameters;
387 $this->body_parameters = base64_encode( $this->body_parameters );
388
389 }
390
391 $this->body_parameters = apply_filters( 'wpgetapi_modify_formatted_body_parameters', $this->body_parameters, $this );
392
393 // add our body parameters
394 if ( $this->body_parameters && ! empty( $this->body_parameters ) ) {
395 $headers['body'] = $this->body_parameters;
396 }
397 }
398
399 // get our body parameters as they are formatted
400 // this won't change anything, it just allows us to get the parameters
401 $this->body_parameters = apply_filters( 'wpgetapi_final_body_parameters', $this->body_parameters, $this );
402
403 // add headers to our final request args
404 $this->final_request_args = wp_parse_args( $headers, $this->final_request_args );
405
406 // build the args that are sent to the request
407 $default_args = apply_filters(
408 'wpgetapi_default_request_args_parameters',
409 array(
410 'timeout' => ( absint( $this->timeout ) > 0 ? absint( $this->timeout ) : 10 ),
411 'sslverify' => $this->sslverify,
412 'redirection' => 5,
413 'blocking' => true,
414 'cookies' => array(),
415 'reject_unsafe_urls' => defined( 'WPGETAPI_REJECT_UNSAFE_URL' ) ? WPGETAPI_REJECT_UNSAFE_URL : false,
416 )
417 );
418
419 return wp_parse_args( $this->final_request_args, $default_args );
420 }
421
422
423
424
425 /**
426 * Do a GET request
427 */
428 public function GET_request() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Ignore not snake case format because it's used in the other premium plugins.
429
430 $response = '';
431 // so we can so something before the remote_get (caching)
432 $response = apply_filters( 'wpgetapi_before_get_request', $response, $this );
433
434 if ( empty( $response ) ) {
435 $response = wp_remote_get( $this->final_url, $this->final_request_args );
436 }
437
438 return $response;
439 }
440
441 /**
442 * Do a POST request
443 */
444 public function POST_request() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Ignore not snake case format because it's used in the other premium plugins.
445
446 $response = '';
447 // so we can so something before the remote_post (caching)
448 $response = apply_filters( 'wpgetapi_before_post_request', $response, $this );
449
450 //$this->final_request_args['method'] = 'POST';
451
452 if ( empty( $response ) ) {
453 $response = wp_remote_post( $this->final_url, $this->final_request_args );
454 }
455
456 return $response;
457 }
458
459 /**
460 * Do a PUT request
461 */
462 public function PUT_request() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Ignore not snake case format because it's used in the other premium plugins.
463 $this->final_request_args['method'] = 'PUT';
464 $response = wp_remote_request( $this->final_url, $this->final_request_args );
465 return $response;
466 }
467
468 /**
469 * Do a PATCH request
470 */
471 public function PATCH_request() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Ignore not snake case format because it's used in the premium plugins.
472 $this->final_request_args['method'] = 'PATCH';
473 $response = wp_remote_request( $this->final_url, $this->final_request_args );
474 return $response;
475 }
476
477 /**
478 * Do a DELETE request
479 */
480 public function DELETE_request() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Ignore not snake case format because it's used in the premium plugins.
481 $this->final_request_args['method'] = 'DELETE';
482 $response = wp_remote_request( $this->final_url, $this->final_request_args );
483 return $response;
484 }
485
486
487 /**
488 * return data
489 */
490 public function return_data( $data ) {
491
492 $data = apply_filters( 'wpgetapi_json_response_body_before_decode', $data, $this->keys );
493
494 // converts all data to arrays, removing objects
495 if ( is_string( $data ) ) {
496 $decode = json_decode( $data, true );
497 if ( json_last_error() ) {
498 return esc_html( $data );
499 } else {
500 $data = $decode;
501 }
502 }
503
504 $data = apply_filters( 'wpgetapi_json_response_body', $data, $this->keys );
505
506 if ( $this->results_format == 'json_string' ) {
507 return trim( wp_json_encode( $data, JSON_PRETTY_PRINT ), '"' );
508 }
509
510 if ( $this->results_format == 'json_decoded' ) {
511 return $data;
512 }
513 }
514
515 /**
516 * Sort out the parameters if they exist
517 */
518 public function do_parameters( $parameters ) {
519
520 $new_array = array();
521 $raw = '';
522 $parameters = $this->decrypt( $parameters );
523
524 if ( is_array( $parameters ) ) {
525 foreach ( $parameters as $key => $parameter ) {
526
527 if ( ! empty( $parameter['name'] ) && ( ! empty( $parameter['value'] ) || $parameter['value'] == 0 ) ) {
528
529 $parameter['value'] = stripslashes( $parameter['value'] );
530
531 // if we have wpgetapi_on, delete it so we don't send to api
532 if ( $parameter['name'] == 'wpgetapi_on' ) {
533 unset( $parameters[ $key ] );
534 continue;
535 }
536
537 // if we have item_key from api to posts plugin
538 // replace our keyword with the actual item_key value
539 if ( isset( $this->args['item_key'] ) && strpos( $parameter['value'], '(importer:item_key)' ) !== false ) {
540 $parameter['value'] = str_replace( '(importer:item_key)', $this->args['item_key'], $parameter['value'] );
541 }
542
543 $new_array[ sanitize_text_field( $parameter['name'] ) ] = $parameter['value'];
544
545 // if we are sending raw body
546 } elseif ( empty( $parameter['name'] ) && ! empty( $parameter['value'] ) ) {
547
548 $raw = stripslashes( $parameter['value'] );
549
550 }
551 }
552 }
553
554 // now look for array or json string and sort these out - for using such things in shortcode
555 if ( ! empty( $new_array ) ) {
556
557 foreach ( $new_array as $key => $value ) {
558
559 // checking if the parameters have a json string
560 if ( strpos( $value, '{"' ) !== false && strpos( $value, '}' ) !== false ) {
561
562 $tmp_val = $value;
563 $tmp_val = json_decode( $tmp_val, true );
564 $new_array[ $key ] = $tmp_val ? $tmp_val : $value;
565
566 } else {
567
568 // checking if the parameters have an array within the string
569 // if they do, create them as an actual array
570 if ( substr( $value, 0, 1 ) === '[' && substr( $value, -1 ) === ']' ) {
571 $value_arr = trim( $value );
572 $value_arr = $this->check_contains_array_value( $value_arr ); //If array value pass in body then convert to array from string
573 $new_array[ $key ] = $value_arr;
574 }
575 }
576
577 // set value as integer
578 if ( strpos( $value, 'integer(' ) !== false && substr( $value, -1 ) === ')' ) {
579
580 preg_match( '/\(([^\)]*)\)/', $value, $match );
581 $result = trim( $match[1] );
582
583 // checking if we have additional token within
584 // and we need to send this directly to PRO plugin from here
585 if ( strpos( $value, '(' ) !== false && strpos( $value, ':' ) !== false && $this->pro_plugin ) {
586 $result = $this->replace_tokens( $result );
587 } else {
588 $result = $result;
589 }
590
591 $new_array[ $key ] = absint( $result );
592
593 }
594
595 // set value as float
596 if ( strpos( $value, 'float(' ) !== false && substr( $value, -1 ) === ')' ) {
597
598 preg_match( '/\(([^\)]*)\)/', $value, $match );
599 $result = trim( $match[1] );
600 if ( substr( $result, 0, 1 ) === '"' && substr( $result, -1 ) === '"' ) {
601 $result = trim( $result, '""' );
602 }
603
604 // checking if we have additional token within
605 // and we need to send this directly to PRO plugin from here
606 if ( strpos( $value, '(' ) !== false && strpos( $value, ':' ) !== false && $this->pro_plugin ) {
607 $result = $this->replace_tokens( $result );
608 }
609
610 $new_array[ $key ] = (float) $result;
611
612 }
613
614 // set value as boolean
615 if ( strpos( $value, 'boolean(' ) !== false && substr( $value, -1 ) === ')' ) {
616 preg_match( '/\(([^\)]*)\)/', $value, $match );
617 $result = $match[1];
618
619 // checking if we have additional token within
620 // and we need to send this directly to PRO plugin from here
621 if ( strpos( $value, '(' ) !== false && strpos( $value, ':' ) !== false && $this->pro_plugin ) {
622 $result = $this->replace_tokens( $result );
623 } else {
624 $result = $result;
625 }
626
627 $result = filter_var( $result, FILTER_VALIDATE_BOOLEAN );
628
629 $new_array[ $key ] = $result;
630
631 }
632 }
633 }
634
635 return $raw ? $raw : $new_array;
636 }
637
638
639 /**
640 * Do a direct token replacement if PRO plugin installed and is required.
641 */
642 public function replace_tokens( $value ) {
643 $tokens = new WpGetApi_Extras_Tokens();
644 $action_args = isset( $this->args['action_args'] ) ? $this->args['action_args'] : null;
645 $value = ( substr( $value, -1 ) !== ')' ? $value . ')' : $value );
646 $result = $tokens->replace_tokens( $value, $action_args );
647 return $result;
648 }
649
650
651 /**
652 * decrypt our parameters from the DB
653 */
654 public function decrypt( $array_or_string ) {
655
656 if ( is_string( $array_or_string ) ) {
657 $array_or_string = $this->encryption->decrypt( $array_or_string );
658 } elseif ( is_array( $array_or_string ) ) {
659 foreach ( $array_or_string as $key => &$value ) {
660 if ( $key === 'name' ) {
661 continue;
662 }
663 if ( is_array( $value ) ) {
664 $value = $this->decrypt( $value );
665 } else {
666 $value = $this->encryption->decrypt( $value );
667
668 }
669 }
670 }
671 return $array_or_string;
672 }
673
674
675 /**
676 * check parameter value contains array value
677 * @param string $parameter_value // parameter value
678 */
679 public function check_contains_array_value( $parameter_value ) {
680 //check $parameter_value first character [ and last character is ]
681 if ( substr( $parameter_value, 0, 1 ) === '[' && substr( $parameter_value, -1 ) === ']' ) {
682 $parameter_value = str_replace( "'", '"', $parameter_value ); // replce single quote with the double quote convert into array
683 $parameter_value = json_decode( $parameter_value, true ); //If array value pass in body then convert to array
684 }
685 return $parameter_value;
686 }
687
688
689 /**
690 * debug
691 */
692 public function maybe_add_debug_info( $data, $wpgetapi ) {
693
694 if ( ( isset( $this->args['debug'] ) && ( $this->args['debug'] === true || $this->args['debug'] === 'true' ) ) ||
695 ( isset( $this->args['test_endpoint'] ) && ( $this->args['test_endpoint'] === true ) )
696 ) {
697
698 $this->debug = true;
699
700 // admin test endpoint button
701 $testing = isset( $this->args['test_endpoint'] ) && ( $this->args['test_endpoint'] === true ) ? true : false;
702
703 // get api status from response code
704 $status = array(
705 'title' => 'Error in API response.',
706 'desc' => 'Check all details within your endpoint. Something is misconfigured.',
707 'type' => '<span class="dashicons dashicons-dismiss"></span>',
708 );
709
710 $search = 'cURL error 28';
711 if ( isset( $data ) && ! is_array( $data ) && preg_match( "/{$search}/i", $data ) ) {
712 $status = array(
713 'title' => 'Error!',
714 'desc' => 'Timeout error. Try increasing the timeout value.',
715 'type' => '<span class="dashicons dashicons-dismiss"></span>',
716 );
717 }
718
719 $search = 'cURL error 60';
720 if ( isset( $data ) && ! is_array( $data ) && preg_match( "/{$search}/i", $data ) ) {
721 $status = array(
722 'title' => 'Error!',
723 'desc' => 'SSL verification has failed. See <a href="https://wordpress.stackexchange.com/a/167910/11827" target="_blank">here</a> for possible solution.',
724 'type' => '<span class="dashicons dashicons-dismiss"></span>',
725 );
726 }
727
728 if ( $this->response_code >= 200 && $this->response_code <= 299 ) {
729 $status = array(
730 'title' => 'Success!',
731 'desc' => 'Your API is returning a success message and is returning the data as shown in the Data Output section below. You can modify this by changing the Results Format option or see <a href="https://wpgetapi.com/docs/format-api-data-as-html/">here</a> for info on formatting this data.',
732 'type' => '<span class="dashicons dashicons-yes-alt"></span>',
733 );
734 }
735 if ( $this->response_code >= 400 && $this->response_code <= 499 ) {
736 $status = array(
737 'title' => 'Bad Request',
738 'desc' => 'This could indicate that the URL you are calling is incorrect or that some other data is missing or incorrect. Please check your Base URL and Endpoint are correct as well as the Request Method.',
739 'type' => '<span class="dashicons dashicons-dismiss"></span>',
740 );
741 }
742 if ( $this->response_code == 401 ) {
743 $status = array(
744 'title' => 'Unauthorised',
745 'desc' => 'You are successfully connecting to your API. But your API key, login or API credentials are incorrect. See <a href="https://wpgetapi.com/docs/authentication-authorization/">here</a> for info on correctly authorizing your API requests.',
746 'type' => '<span class="dashicons dashicons-warning"></span>',
747 );
748 }
749 if ( $this->response_code == 403 ) {
750 $status = array(
751 'title' => 'Forbidden',
752 'desc' => 'This could indicate that you may need to get your IP address whitelisted with your API provider or that you do not have access to this API.',
753 'type' => '<span class="dashicons dashicons-dismiss"></span>',
754 );
755 }
756 if ( $this->response_code == 405 ) {
757 $status = array(
758 'title' => 'Method Not Allowed',
759 'desc' => 'Try changing the Request Method within the endpoint settings.',
760 'type' => '<span class="dashicons dashicons-dismiss"></span>',
761 );
762 }
763 if ( $this->response_code == 415 ) {
764 $status = array(
765 'title' => 'Unsupported Media Type',
766 'desc' => 'Try adding "Content-type" to the Headers with the Value of "json/application" as shown <a href="https://wpgetapi.com/docs/troubleshooting/">here</a>.',
767 'type' => '<span class="dashicons dashicons-dismiss"></span>',
768 );
769 }
770 if ( $this->response_code >= 500 && $this->response_code <= 599 ) {
771 $status = array(
772 'title' => 'Internal Server Error',
773 'desc' => 'This indicates an issue with the API server. Contact your API provider.',
774 'type' => '<span class="dashicons dashicons-dismiss"></span>',
775 );
776 }
777
778 ob_start(); ?>
779
780 <div class="wpgetapi-debug <?php echo $testing ? 'testing' : ''; ?>">
781
782 <?php if ( $testing ) { ?>
783
784 <div class="debug-item status">
785 <div class="">
786 <h5><?php echo wp_kses( $status['type'], array( 'span' => array( 'class' => array() ) ) ); ?> <?php echo esc_html( $status['title'] ); ?></h5>
787 <span class="desc"><?php echo wp_kses( $status['desc'], array( 'a' => array() ) ); ?></span>
788 </div>
789 </div>
790 <div class="debug-item">
791 <h6><?php esc_html_e( 'Full URL', 'wpgetapi' ); ?></h6>
792 <p class="small"><?php esc_html_e( 'The full URL that is being called.', 'wpgetapi' ); ?></p>
793 <div class="debug-result"><?php echo esc_html( $this->final_url ); ?></div>
794 </div>
795
796 <div class="debug-item">
797 <h6><?php esc_html_e( 'Data Output', 'wpgetapi' ); ?></h6>
798 <p class="small">
799 <?php
800 esc_html_e( 'The output that has been returned from the API.', 'wpgetapi' );
801 echo ' ';
802 esc_html_e( 'This is what the shortcode or template tag will display and can be formatted however you like.', 'wpgetapi' );
803 ?>
804 </p>
805 <div class="debug-result"><?php wpgetapi_pp( $data ); ?></div>
806 </div>
807
808 <div class="debug-item">
809 <h6><?php esc_html_e( 'Final Request Arguments', 'wpgetapi' ); ?></h6>
810 <p class="small">
811 <?php
812 esc_html_e( 'The final request arguments sent in the API request.', 'wpgetapi' );
813 echo ' ';
814 esc_html_e( 'Includes headers and body arguments.', 'wpgetapi' );
815 ?>
816 </p>
817 <div class="debug-result"><?php wpgetapi_pp( $this->final_request_args ); ?></div>
818 </div>
819
820 <div class="debug-item">
821 <h6><?php esc_html_e( 'Response', 'wpgetapi' ); ?></h6>
822 <p class="small"><?php esc_html_e( 'The full response from the API request.', 'wpgetapi' ); ?></p>
823 <div class="debug-result"><?php $this->render_api_response( $this->response, $status['title'], $status['desc'] ); ?></div>
824 </div>
825
826 <?php } else { ?>
827
828 <h5><strong><?php esc_html_e( 'WPGetAPI, Debug Mode - Plugin Version', 'wpgetapi' ); ?> <?php echo esc_html( WP_Get_API()->version ); ?></strong></h5>
829 <p class="small">
830 <?php
831 esc_html_e( 'Below you will find debug info for the current API call.', 'wpgetapi' );
832 echo ' ';
833 esc_html_e( 'To turn this off, set debug to false in your shortcode or template tag.', 'wpgetapi' );
834 ?>
835 <br><?php esc_html_e( 'Connecting to API\'s can be tricky - if you require help, please see the', 'wpgetapi' ); ?> <a target="_blank" href="https://wpgetapi.com/docs/"><?php esc_html_e( 'Documentation', 'wpgetapi' ); ?></a>.</p>
836
837 <div class="debug-item">
838 <h6><?php esc_html_e( 'Full URL', 'wpgetapi' ); ?></h6>
839 <p class="small"><?php esc_html_e( 'The full URL that is being called.', 'wpgetapi' ); ?></p>
840 <div class="debug-result"><?php echo esc_html( $this->final_url ); ?></div>
841 </div>
842
843 <div class="debug-item">
844 <h6><?php esc_html_e( 'Data Output', 'wpgetapi' ); ?></h6>
845 <p class="small"><?php esc_html_e( 'The resulting output that has been returned from the API.', 'wpgetapi' ); ?></p>
846 <div class="debug-result"><?php wpgetapi_pp( $data ); ?></div>
847 </div>
848
849 <div class="debug-item">
850 <h6><?php esc_html_e( 'Query String', 'wpgetapi' ); ?></h6>
851 <p class="small"><?php esc_html_e( 'The query string parameters (if any) that you have set within the endpoint settings.', 'wpgetapi' ); ?></p>
852 <div class="debug-result"><?php wpgetapi_pp( $this->query_parameters ); ?></div>
853 </div>
854
855 <div class="debug-item">
856 <h6><?php esc_html_e( 'Headers', 'wpgetapi' ); ?></h6>
857 <p class="small"><?php esc_html_e( 'The header parameters (if any) that you have set within the endpoint settings.', 'wpgetapi' ); ?></p>
858 <div class="debug-result"><?php wpgetapi_pp( $this->header_parameters ); ?></div>
859 </div>
860
861 <div class="debug-item">
862 <h6><?php esc_html_e( 'Body', 'wpgetapi' ); ?></h6>
863 <p class="small"><?php esc_html_e( 'The body parameters (if any) that you have set within the endpoint settings.', 'wpgetapi' ); ?></p>
864 <div class="debug-result"><?php wpgetapi_pp( $this->body_parameters ); ?></div>
865 </div>
866
867 <div class="debug-item">
868 <h6><?php esc_html_e( 'Final Request Arguments', 'wpgetapi' ); ?></h6>
869 <p class="small">
870 <?php
871 esc_html_e( 'The final request arguments sent in the API request.', 'wpgetapi' );
872 echo ' ';
873 esc_html_e( 'Includes headers and body arguments.', 'wpgetapi' );
874 ?>
875 </p>
876 <div class="debug-result"><?php wpgetapi_pp( $this->final_request_args ); ?></div>
877 </div>
878
879 <div class="debug-item">
880 <h6><?php esc_html_e( 'Arguments', 'wpgetapi' ); ?></h6>
881 <p class="small"><?php esc_html_e( 'The arguments set within your shortcode or template tag.', 'wpgetapi' ); ?></p>
882 <div class="debug-result"><?php wpgetapi_pp( $this->args ); ?></div>
883 </div>
884
885 <div class="debug-item">
886 <h6><?php esc_html_e( 'Response', 'wpgetapi' ); ?></h6>
887 <p class="small"><?php esc_html_e( 'The full response from the API request.', 'wpgetapi' ); ?></p>
888 <div class="debug-result"><?php $this->render_api_response( $this->response, $status['title'], $status['desc'] ); ?></div>
889 </div>
890
891 <?php } ?>
892
893 </div>
894
895 <?php
896
897 return ob_get_clean();
898
899 } else {
900
901 return $data;
902
903 }
904 }
905
906 /**
907 * The full response from the API request.
908 *
909 * @param object $response Full response from the API request.
910 * @param string $status_title API request status title.
911 * @param string $display_error_content If response content invalid data then display this text.
912 */
913 private function render_api_response( $response, $status_title, $display_error_content ) {
914 /*
915 * If the API response status is 'Bad Request', check if the body contains HTML.
916 * This typically occurs when the API returns a 404 or other HTML error page.
917 * Detecting HTML prevents raw markup from breaking the site's debug output.
918 */
919 if ( 'Bad Request' === $status_title ) {
920 $body = wp_remote_retrieve_body( $response );
921 if ( preg_match( '/<\s*!DOCTYPE\s+html/i', $body ) || preg_match( '/<html[^>]*>/i', $body ) ) {
922 echo esc_html( $display_error_content );
923 } else {
924 wpgetapi_pp( $response );
925 }
926 } else {
927 wpgetapi_pp( $response );
928 }
929 }
930 }
931