PluginProbe
Parse.ly / 3.6.2
Parse.ly v3.6.2
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.6.2, at src/RemoteAPI/class-base-proxy.php

125 lines 3.0 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 Parse.ly API endpoint.
48 *
49 * @since 3.6.2
50 *
51 * @return string
52 */
53 public function get_endpoint(): string {
54 return static::ENDPOINT;
55 }
56
57 /**
58 * Gets the URL for a particular Parse.ly API endpoint.
59 *
60 * @since 3.2.0
61 *
62 * @throws RuntimeException If the endpoint constant is not defined.
63 * @throws RuntimeException If the query filter constant is not defined.
64 *
65 * @param array<string, mixed> $query The query arguments to send to the remote API.
66 * @return string
67 */
68 public function get_api_url( array $query ): string {
69 if ( static::ENDPOINT === '' ) {
70 throw new RuntimeException( 'ENDPOINT constant must be defined in child class.' );
71 }
72 if ( static::QUERY_FILTER === '' ) {
73 throw new RuntimeException( 'QUERY_FILTER constant must be defined in child class.' );
74 }
75
76 $query['apikey'] = $this->parsely->get_api_key();
77 if ( $this->parsely->api_secret_is_set() ) {
78 $query['secret'] = $this->parsely->get_api_secret();
79 }
80 $query = array_filter( $query );
81
82 // Sort by key so the query args are in alphabetical order.
83 ksort( $query );
84
85 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound -- Hook names are defined in child classes.
86 $query = apply_filters( static::QUERY_FILTER, $query );
87 return add_query_arg( $query, static::ENDPOINT );
88 }
89
90 /**
91 * Implements the fetcher for the proxy interface.
92 *
93 * @since 3.2.0
94 *
95 * @param array<string, mixed> $query The query arguments to send to the remote API.
96 * @return WP_Error|array<string, mixed>
97 */
98 public function get_items( array $query ) {
99 $full_api_url = $this->get_api_url( $query );
100
101 $result = wp_safe_remote_get( $full_api_url, array() );
102
103 if ( is_wp_error( $result ) ) {
104 return $result;
105 }
106
107 $body = wp_remote_retrieve_body( $result );
108 $decoded = json_decode( $body );
109
110 if ( ! is_object( $decoded ) ) {
111 return new WP_Error( 400, __( 'Unable to decode upstream API response', 'wp-parsely' ) );
112 }
113
114 if ( ! property_exists( $decoded, 'data' ) ) {
115 return new WP_Error( $decoded->code ?? 400, $decoded->message ?? __( 'Unable to read data from upstream API', 'wp-parsely' ) );
116 }
117
118 if ( ! is_array( $decoded->data ) ) {
119 return new WP_Error( 400, __( 'Unable to parse data from upstream API', 'wp-parsely' ) );
120 }
121
122 return $decoded->data;
123 }
124 }
125