PluginProbe
Parse.ly / 3.5.0
Parse.ly v3.5.0
3.24.1 3.24.0 3.23.7 3.23.6 3.23.5 3.23.4 3.23.3 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.17.0 3.18.0 3.18.1 3.19.0 3.19.1 3.19.2 3.19.3 3.2.0 3.2.1 3.20.0 3.20.1 3.20.2 3.20.3 All 105 releases
wp-parsely / src / RemoteAPI / class-base-proxy.php

class-base-proxy.php in Parse.ly 3.5.0, at src/RemoteAPI/class-base-proxy.php

114 lines 2.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Remote API: Base Proxy class for all Parse.ly API endpoints
4 *
5 * @package Parsely
6 * @since 3.2.0
7 */
8
9 declare(strict_types=1);
10
11 namespace Parsely\RemoteAPI;
12
13 use Parsely\Parsely;
14 use RuntimeException;
15 use WP_Error;
16
17 /**
18 * Base Proxy for all Parse.ly API endpoints.
19 *
20 * Child classes must add a protected `ENDPOINT` constant, and a protected
21 * QUERY_FILTER constant.
22 *
23 * @since 3.2.0
24 */
25 abstract class Base_Proxy implements Proxy {
26 protected const ENDPOINT = '';
27 protected const QUERY_FILTER = '';
28
29 /**
30 * Parsely Instance.
31 *
32 * @var Parsely
33 */
34 private $parsely;
35
36 /**
37 * Constructor.
38 *
39 * @param Parsely $parsely Parsely instance.
40 * @since 3.2.0
41 */
42 public function __construct( Parsely $parsely ) {
43 $this->parsely = $parsely;
44 }
45
46 /**
47 * Gets the URL for a particular Parse.ly API endpoint.
48 *
49 * @since 3.2.0
50 *
51 * @throws RuntimeException If the endpoint constant is not defined.
52 * @throws RuntimeException If the query filter constant is not defined.
53 *
54 * @param array<string, mixed> $query The query arguments to send to the remote API.
55 * @return string
56 */
57 public function get_api_url( array $query ): string {
58 if ( static::ENDPOINT === '' ) {
59 throw new RuntimeException( 'ENDPOINT constant must be defined in child class.' );
60 }
61 if ( static::QUERY_FILTER === '' ) {
62 throw new RuntimeException( 'QUERY_FILTER constant must be defined in child class.' );
63 }
64
65 $query['apikey'] = $this->parsely->get_api_key();
66 if ( $this->parsely->api_secret_is_set() ) {
67 $query['secret'] = $this->parsely->get_api_secret();
68 }
69 $query = array_filter( $query );
70
71 // Sort by key so the query args are in alphabetical order.
72 ksort( $query );
73
74 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound -- Hook names are defined in child classes.
75 $query = apply_filters( static::QUERY_FILTER, $query );
76 return add_query_arg( $query, static::ENDPOINT );
77 }
78
79 /**
80 * Implements the fetcher for the proxy interface.
81 *
82 * @since 3.2.0
83 *
84 * @param array<string, mixed> $query The query arguments to send to the remote API.
85 * @return WP_Error|array<string, mixed>
86 */
87 public function get_items( array $query ) {
88 $full_api_url = $this->get_api_url( $query );
89
90 $result = wp_safe_remote_get( $full_api_url, array() );
91
92 if ( is_wp_error( $result ) ) {
93 return $result;
94 }
95
96 $body = wp_remote_retrieve_body( $result );
97 $decoded = json_decode( $body );
98
99 if ( ! is_object( $decoded ) ) {
100 return new WP_Error( 400, __( 'Unable to decode upstream API response', 'wp-parsely' ) );
101 }
102
103 if ( ! property_exists( $decoded, 'data' ) ) {
104 return new WP_Error( $decoded->code ?? 400, $decoded->message ?? __( 'Unable to read data from upstream API', 'wp-parsely' ) );
105 }
106
107 if ( ! is_array( $decoded->data ) ) {
108 return new WP_Error( 400, __( 'Unable to parse data from upstream API', 'wp-parsely' ) );
109 }
110
111 return $decoded->data;
112 }
113 }
114