PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 2.13.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v2.13.0
4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / Request / RequestService.php
surecart / app / src / Request Last commit date
RequestCacheService.php 2 years ago RequestService.php 3 years ago RequestServiceProvider.php 3 years ago
RequestService.php
422 lines
1 <?php
2
3 namespace SureCart\Request;
4
5 use SureCart\Models\ApiToken;
6 use SureCart\Support\Errors\ErrorsService;
7
8 /**
9 * Provide api request functionality.
10 */
11 class RequestService {
12 /**
13 * Has this been cached yet for the request?
14 *
15 * @var boolean
16 */
17 protected static $cached = false;
18
19 /**
20 * Undocumented variable
21 *
22 * @var string
23 */
24 protected $token = '';
25
26 /**
27 * Request URL
28 *
29 * @var string
30 */
31 protected $base_url = '';
32
33 /**
34 * The base path for the request.
35 *
36 * @var string
37 */
38 protected $base_path;
39
40 /**
41 * Errors service container
42 *
43 * @var \SureCart\Support\Errors\ErrorsService;
44 */
45 protected $errors_service;
46
47 /**
48 * What type of cached request is this.
49 *
50 * @var string|null
51 */
52 protected $cache_status = 'none';
53
54 /**
55 * Is this request authorized?
56 *
57 * @var boolean
58 */
59 protected $authorized = true;
60
61 /**
62 * Constructor.
63 *
64 * @param string $token The rest api base path.
65 */
66 public function __construct( $token = '', $base_path = '/v1', $errors_service = null, $authorized = true ) {
67 // error handing service.
68 $this->errors_service = $errors_service ? $errors_service : new ErrorsService();
69 // set the token.
70 $this->token = $token;
71 // set the base path and url.
72 $this->base_path = $base_path;
73 $this->base_url = $this->getBaseUrl();
74 $this->authorized = $authorized;
75 }
76
77 /**
78 * Set the API token on the fly.
79 *
80 * @param string $token API token.
81 *
82 * @return $this
83 */
84 public function setToken( $token ) {
85 $this->token = $token;
86 return $this;
87 }
88
89 /**
90 * Get the base url.
91 */
92 public function getBaseUrl() {
93 return untrailingslashit( SURECART_API_URL ) . trailingslashit( $this->base_path );
94 }
95
96 /**
97 * Should we get a cached request?
98 *
99 * @return boolean
100 */
101 public function shouldFindCache( $cachable, $cache_key, $args = [] ) {
102 // only for fetch requests.
103 if ( isset( $args['method'] ) && 'GET' !== $args['method'] ) {
104 return false;
105 }
106
107 // if the args are set, then do what they say.
108 if ( isset( $args['query']['cached'] ) ) {
109 return (bool) $args['query']['cached'];
110 }
111
112 // don't cache edit context.
113 if ( isset( $args['query']['context'] ) && 'edit' === $args['query']['context'] ) {
114 return false;
115 }
116
117 return (bool) $cachable && $cache_key;
118 }
119
120 /**
121 * Respond to the request.
122 *
123 * @param array $response Reponse data.
124 * @param array $args Request arguments.
125 * @param string $endpoint The endpoint to request.
126 *
127 * @return array Response data.
128 */
129 public function respond( $response, $args, $endpoint ) {
130 if ( is_array( $response ) ) {
131 foreach ( $response as $item ) {
132 $item->cache_status = $this->cache_status;
133 }
134 }
135
136 if ( is_object( $response ) ) {
137 $response->cache_status = $this->cache_status;
138 }
139
140 return apply_filters( 'surecart/request/response', $response, $args, $endpoint );
141 }
142
143 /**
144 * Set the response cache status.
145 *
146 * @param object $response Response object.
147 * @param string $status The response status.
148 *
149 * @return void
150 */
151 public function setResponseCacheStatus( $response, $status ) {
152 if ( is_array( $response ) ) {
153 foreach ( $response as $item ) {
154 $item->cached = $status;
155 }
156 } elseif ( is_object( $response ) ) {
157 $response->cached = $status;
158 }
159
160 return $response;
161 }
162
163 /**
164 * Make the request
165 *
166 * @param string $endpoint Endpoint to request.
167 * @param array $args Arguments for request.
168 * @param boolean $cachable Should this request be cached.
169 * @param string $cache_key The cache key to use.
170 *
171 * @return mixed
172 */
173 public function makeRequest( $endpoint, $args = [], $cachable = false, $cache_key = '' ) {
174 // use the cache service for this request.
175 $cache = new RequestCacheService( $endpoint, $args, $cache_key );
176
177 // check if we should get a cached version of this.
178 if ( $this->shouldFindCache( $cachable, $cache_key, $args ) ) {
179 // get from cache.
180 $response_body = $cache->getTransientCache();
181 // we have a cached response.
182 if ( false !== $response_body ) {
183 $this->cache_status = 'transient';
184 return $this->respond( $response_body, $args, $endpoint );
185 }
186 }
187
188 // make the uncached request.
189 $response_body = $this->makeUncachedRequest( $endpoint, $args );
190
191 if ( is_wp_error( $response_body ) ) {
192 return $response_body;
193 }
194
195 // set in object cache.
196 $cache->setCache( $response_body, 'object' );
197 if ( (bool) $cachable && $cache_key ) {
198 $cache->setCache( $response_body, 'transient' );
199 }
200
201 // return response.
202 return $this->respond( $response_body, $args, $endpoint );
203 }
204
205 /**
206 * Make the uncached request.
207 *
208 * @param string $endpoint Endpoint to request.
209 * @param array $args Arguments for request.
210 *
211 * @return mixed
212 */
213 public function makeUncachedRequest( $endpoint, $args = [] ) {
214 // must have a token for the request.
215 if ( $this->authorized && empty( $this->token ) ) {
216 return new \WP_Error( 'missing_token', __( 'Please connect your site to SureCart.', 'surecart' ) );
217 }
218
219 // make sure we send json.
220 if ( empty( $args['headers']['Content-Type'] ) ) {
221 $args['headers']['Content-Type'] = 'application/json';
222 }
223
224 // add auth.
225 if ( $this->authorized && ! empty( $this->token ) && empty( $args['headers']['Authorization'] ) ) {
226 $args['headers']['Authorization'] = "Bearer $this->token";
227 }
228
229 // add version header.
230 $args['headers']['X-SURECART-WP-PLUGIN-VERSION'] = \SureCart::plugin()->version();
231
232 // add referer header.
233 if ( isset( $_SERVER['HTTP_REFERER'] ) ) {
234 $args['headers']['X-SURECART-REFERRER'] = esc_url_raw( $_SERVER['HTTP_REFERER'] );
235 }
236
237 // parse args.
238 $args = wp_parse_args(
239 $args,
240 [
241 'timeout' => 20,
242 'sslverify' => true,
243 ]
244 );
245
246 // filter args and endpoint.
247 $args = apply_filters( 'surecart/request/args', $args, $endpoint );
248 $endpoint = apply_filters( 'surecart/request/endpoint', $endpoint, $args );
249
250 // make url.
251 $url = trailingslashit( $this->base_url ) . untrailingslashit( $endpoint );
252
253 // add query args.
254 if ( ! empty( $args['query'] ) ) {
255 $url = add_query_arg( $this->parseArgs( $args['query'] ), $url );
256 $url = preg_replace( '/%5B[0-9]+%5D/', '%5B%5D', $url );
257 unset( $args['query'] );
258 }
259
260 // json encode body.
261 if ( ! empty( $args['body'] ) ) {
262 if ( 'application/json' === $args['headers']['Content-Type'] ) {
263 $args['body'] = wp_json_encode( $this->parseArgs( $args['body'] ) );
264 }
265 }
266
267 // make request.
268 $response = $this->remoteRequest( $url, $args );
269
270 // bail early if it's a wp_error.
271 if ( is_wp_error( $response ) ) {
272 return $response;
273 }
274
275 $response_code = wp_remote_retrieve_response_code( $response );
276 $response_body = wp_remote_retrieve_body( $response );
277 $admin_notice = (array) wp_remote_retrieve_header( $response, 'X-SURECART-WP-ADMIN-NOTICE' );
278
279 if ( ! $this->authorized ) {
280 $api_token = (string) wp_remote_retrieve_header( $response, 'X-SURECART-API-TOKEN' );
281 ApiToken::save( $api_token );
282 }
283
284 if ( $admin_notice ) {
285 // we don't care if this fails.
286 try {
287 \SureCart::notices()->showResponseNotice( $admin_notice );
288 } catch ( \Exception $e ) {
289 error_log( $e->getMessage() );
290 }
291 }
292
293 // Handle invalid token first.
294 if ( $this->authorized && 401 === $response_code ) {
295 ApiToken::clear();
296 return new \WP_Error( 'invalid_token', __( 'Invalid API token.', 'surecart' ) );
297 }
298
299 // check for errors.
300 if ( ! in_array( $response_code, [ 200, 201 ], true ) ) {
301 $body = json_decode( $response_body, true );
302 if ( is_string( $body ) ) {
303 return new \WP_Error( 'error', $response_body );
304 }
305 return $this->errors_service->translate( $body, $response_code );
306 }
307
308 return json_decode( $response_body );
309 }
310
311 /**
312 * Make the remote request.
313 *
314 * @param string $url The url to request.
315 * @param array $args The args to pass to the request.
316 *
317 * @return mixed
318 */
319 public function remoteRequest( $url, $args = [] ) {
320 return wp_remote_request( esc_url_raw( $url ), $args );
321 }
322
323 /**
324 * Make a get request
325 *
326 * @param string $endpoint Endpoint for the request.
327 * @param array $args Request arguments.
328 *
329 * @return mixed
330 */
331 public function get( $endpoint, $args = [] ) {
332 $args['method'] = 'GET';
333 return $this->makeRequest( $endpoint, $args );
334 }
335
336 /**
337 * Make a post request
338 *
339 * @param string $endpoint Endpoint for the request.
340 * @param array $args Request arguments.
341 *
342 * @return mixed
343 */
344 public function post( $endpoint, $args = [] ) {
345 $args['method'] = 'POST';
346 return $this->makeRequest( $endpoint, $args );
347 }
348
349 /**
350 * Make a put request
351 *
352 * @param string $endpoint Endpoint for the request.
353 * @param array $args Request arguments.
354 *
355 * @return mixed
356 */
357 public function put( $endpoint, $args = [] ) {
358 $args['method'] = 'PUT';
359 return $this->makeRequest( $endpoint, $args );
360 }
361
362 /**
363 * Make a patch request
364 *
365 * @param string $endpoint Endpoint for the request.
366 * @param array $args Request arguments.
367 *
368 * @return mixed
369 */
370 public function patch( $endpoint, $args = [] ) {
371 $args['method'] = 'PATCH';
372 return $this->makeRequest( $endpoint, $args );
373 }
374
375 /**
376 * Make a delete request
377 *
378 * @param string $endpoint Endpoint for the request.
379 * @param array $args Request arguments.
380 *
381 * @return mixed
382 */
383 public function delete( $endpoint, $args = [] ) {
384 $args['method'] = 'DELETE';
385 return $this->makeRequest( $endpoint, $args );
386 }
387
388 /**
389 * Removes empty args
390 *
391 * @param array $args Array of arguments.
392 */
393 protected function parseArgs( $args = [] ) {
394 if ( ! is_array( $args ) ) {
395 return $args;
396 }
397 foreach ( $args as $key => $arg ) {
398 // unset null.
399 if ( null === $arg ) {
400 unset( $args[ $key ] );
401 }
402
403 // filter out wp params.
404 if ( in_array( $key, [ 'locale', 'rest_route' ], true ) ) {
405 unset( $args[ $key ] );
406 }
407
408 // convert bool to int to prevent getting unset.
409 if ( is_bool( $arg ) ) {
410 $args[ $key ] = $arg ? 1 : 0;
411 }
412
413 // url encode any strings.
414 if ( is_string( $arg ) ) {
415 $args[ $key ] = urlencode( $arg );
416 }
417 }
418
419 return $args;
420 }
421 }
422