PluginProbe
Parse.ly / 3.8.4
Parse.ly v3.8.4
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
← All changes | src/Endpoints/class-base-api-proxy.php +26 -147 3.16.23.8.4 View file →
@@ -17,11 +17,8 @@
17 17 use WP_REST_Request;
18 18 use WP_REST_Server;
19 19
20 20 use function Parsely\Utils\convert_endpoint_to_filter_key;
21 -use function Parsely\Utils\get_date_format;
22 -use function Parsely\Utils\get_formatted_duration;
23 -use function Parsely\Utils\parsely_is_https_supported;
24 21
25 22 /**
26 23 * Configures a REST API endpoint for use.
27 24 */
@@ -40,15 +37,8 @@
40 37 */
41 38 private $api;
42 39
43 40 /**
44 - * The itm_source value to be used for some of the returned URLs.
45 - *
46 - * @var string|null
47 - */
48 - protected $itm_source = null;
49 -
50 - /**
51 41 * Registers the endpoint's WP REST route.
52 42 */
53 43 abstract public function run(): void;
54 44
@@ -63,22 +53,20 @@
63 53 /**
64 54 * Cached "proxy" to the Parse.ly API endpoint.
65 55 *
66 56 * @param WP_REST_Request $request The request object.
57 + *
67 58 * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure.
68 59 */
69 60 abstract public function get_items( WP_REST_Request $request );
70 61
71 62 /**
72 - * Returns whether the endpoint is available for access by the current
73 - * user.
63 + * Determines if there are enough permissions to call the endpoint.
74 64 *
75 - * @since 3.14.0 Renamed from `permission_callback()`.
76 - *
77 65 * @return bool
78 66 */
79 - public function is_available_to_current_user(): bool {
80 - return $this->api->is_available_to_current_user();
67 + public function permission_callback(): bool {
68 + return $this->api->is_user_allowed_to_make_api_call();
81 69 }
82 70
83 71 /**
84 72 * Constructor.
@@ -93,12 +81,11 @@
93 81
94 82 /**
95 83 * Registers the endpoint's WP REST route.
96 84 *
97 - * @param string $endpoint The endpoint's route (e.g. /stats/posts).
98 - * @param array<string> $methods The HTTP methods to use for the endpoint.
85 + * @param string $endpoint The endpoint's route (e.g. /stats/posts).
99 86 */
100 - protected function register_endpoint( string $endpoint, array $methods = array( WP_REST_Server::READABLE ) ): void {
87 + protected function register_endpoint( string $endpoint ): void {
101 88 if ( ! apply_filters( 'wp_parsely_enable_' . convert_endpoint_to_filter_key( $endpoint ) . '_api_proxy', true ) ) {
102 89 return;
103 90 }
104 91
@@ -117,13 +104,13 @@
117 104 );
118 105
119 106 $rest_route_args = array(
120 107 array(
121 - 'methods' => $methods,
108 + 'methods' => WP_REST_Server::READABLE,
122 109 'callback' => array( $this, 'get_items' ),
123 - 'permission_callback' => array( $this, 'is_available_to_current_user' ),
110 + 'permission_callback' => array( $this, 'permission_callback' ),
124 111 'args' => $get_items_args,
125 - 'show_in_index' => $this->is_available_to_current_user(),
112 + 'show_in_index' => $this->permission_callback(),
126 113 ),
127 114 );
128 115
129 116 register_rest_route( 'wp-parsely/v1', $endpoint, $rest_route_args );
@@ -132,51 +119,16 @@
132 119 /**
133 120 * Cached "proxy" to the endpoint.
134 121 *
135 122 * @param WP_REST_Request $request The request object.
136 - * @param bool $require_api_secret Specifies if the API Secret is required.
137 - * @param string|null $param_item The param element to use to get the items.
123 + * @param bool $require_api_secret Specifies if the API Secret is
124 + * required.
125 + * @param string $param_item The param element to use to
126 + * get the items.
127 + *
138 128 * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure.
139 129 */
140 130 protected function get_data( WP_REST_Request $request, bool $require_api_secret = true, string $param_item = null ) {
141 - // Validate Site ID and secret.
142 - $validation = $this->validate_apikey_and_secret( $require_api_secret );
143 - if ( is_wp_error( $validation ) ) {
144 - return $validation;
145 - }
146 -
147 - if ( null !== $param_item ) {
148 - $params = $request->get_param( $param_item );
149 - } else {
150 - $params = $request->get_params();
151 - }
152 -
153 - if ( is_array( $params ) && isset( $params['itm_source'] ) ) {
154 - $this->itm_source = $params['itm_source'];
155 - }
156 -
157 - // A proxy with caching behavior is used here.
158 - $response = $this->api->get_items( $params ); // @phpstan-ignore-line.
159 -
160 - if ( is_wp_error( $response ) ) {
161 - return $response;
162 - }
163 -
164 - return (object) array(
165 - 'data' => $this->generate_data( $response ), // @phpstan-ignore-line.
166 - );
167 - }
168 -
169 - /**
170 - * Validates that the Site ID and secret are set.
171 - * If the API secret is not required, it will not be validated.
172 - *
173 - * @since 3.13.0
174 - *
175 - * @param bool $require_api_secret Specifies if the API Secret is required.
176 - * @return WP_Error|bool
177 - */
178 - protected function validate_apikey_and_secret( bool $require_api_secret = true ) {
179 131 if ( false === $this->parsely->site_id_is_set() ) {
180 132 return new WP_Error(
181 133 'parsely_site_id_not_set',
182 134 __( 'A Parse.ly Site ID must be set in site options to use this endpoint', 'wp-parsely' ),
@@ -183,9 +135,9 @@
183 135 array( 'status' => 403 )
184 136 );
185 137 }
186 138
187 - if ( $require_api_secret && false === $this->parsely->api_secret_is_set() ) {
139 + if ( true === $require_api_secret && false === $this->parsely->api_secret_is_set() ) {
188 140 return new WP_Error(
189 141 'parsely_api_secret_not_set',
190 142 __( 'A Parse.ly API Secret must be set in site options to use this endpoint', 'wp-parsely' ),
191 143 array( 'status' => 403 )
@@ -191,95 +143,22 @@
191 143 array( 'status' => 403 )
192 144 );
193 145 }
194 146
195 - return true;
196 - }
197 -
198 - /**
199 - * Extracts the post data from the passed object.
200 - *
201 - * Should only be used with endpoints that return post data.
202 - *
203 - * @since 3.10.0
204 - *
205 - * @param stdClass $item The object to extract the data from.
206 - * @return array<string, mixed> The extracted data.
207 - */
208 - protected function extract_post_data( stdClass $item ): array {
209 - $data = array();
210 -
211 - if ( isset( $item->author ) ) {
212 - $data['author'] = $item->author;
147 + if ( null !== $param_item ) {
148 + $params = $request->get_param( $param_item );
149 + } else {
150 + $params = $request->get_params();
213 151 }
214 152
215 - if ( isset( $item->metrics->views ) ) {
216 - $data['views'] = number_format_i18n( $item->metrics->views );
217 - }
153 + // A proxy with caching behavior is used here.
154 + $response = $this->api->get_items( $params ); // @phpstan-ignore-line.
218 155
219 - if ( isset( $item->metrics->visitors ) ) {
220 - $data['visitors'] = number_format_i18n( $item->metrics->visitors );
156 + if ( is_wp_error( $response ) ) {
157 + return $response;
221 158 }
222 159
223 - // The avg_engaged metric can be in different locations depending on the
224 - // endpoint and passed sort/url parameters.
225 - $avg_engaged = $item->metrics->avg_engaged ?? $item->avg_engaged ?? null;
226 - if ( null !== $avg_engaged ) {
227 - $data['avgEngaged'] = get_formatted_duration( (float) $avg_engaged );
228 - }
229 -
230 - if ( isset( $item->pub_date ) ) {
231 - $data['date'] = wp_date( get_date_format(), strtotime( $item->pub_date ) );
232 - }
233 -
234 - if ( isset( $item->title ) ) {
235 - $data['title'] = $item->title;
236 - }
237 -
238 - if ( isset( $item->url ) ) {
239 - $site_id = $this->parsely->get_site_id();
240 - // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.url_to_postid_url_to_postid
241 - $post_id = url_to_postid( $item->url ); // 0 if the post cannot be found.
242 -
243 - $post_url = Parsely::get_url_with_itm_source( $item->url, null );
244 - if ( parsely_is_https_supported() ) {
245 - $post_url = str_replace( 'http://', 'https://', $post_url );
246 - }
247 -
248 - $data['rawUrl'] = $post_url;
249 - $data['dashUrl'] = Parsely::get_dash_url( $site_id, $post_url );
250 - $data['id'] = Parsely::get_url_with_itm_source( $post_url, null ); // Unique.
251 - $data['postId'] = $post_id; // Might not be unique.
252 - $data['url'] = Parsely::get_url_with_itm_source( $post_url, $this->itm_source );
253 -
254 - // Set thumbnail URL, falling back to the Parse.ly thumbnail if needed.
255 - $thumbnail_url = get_the_post_thumbnail_url( $post_id, 'thumbnail' );
256 - if ( false !== $thumbnail_url ) {
257 - $data['thumbnailUrl'] = $thumbnail_url;
258 - } elseif ( isset( $item->thumb_url_medium ) ) {
259 - $data['thumbnailUrl'] = $item->thumb_url_medium;
260 - }
261 - }
262 -
263 - return $data;
264 - }
265 -
266 - /**
267 - * Generates the post data from the passed response.
268 - *
269 - * Should only be used with endpoints that return post data.
270 - *
271 - * @since 3.10.0
272 - *
273 - * @param array<stdClass> $response The response received by the proxy.
274 - * @return array<stdClass> The generated data.
275 - */
276 - protected function generate_post_data( array $response ): array {
277 - $data = array();
278 -
279 - foreach ( $response as $item ) {
280 - $data [] = (object) $this->extract_post_data( $item );
281 - }
282 -
283 - return $data;
160 + return (object) array(
161 + 'data' => $this->generate_data( $response ), // @phpstan-ignore-line.
162 + );
284 163 }
285 164 }