PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 2.0.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v2.0.0
4.7.1 4.7.0 4.6.6 4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 4.5.1 4.5.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 4 years ago RequestService.php 3 years ago RequestServiceProvider.php 4 years ago
RequestService.php
409 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 * Constructor.
56 *
57 * @param string $token The rest api base path.
58 */
59 public function __construct( $token = '', $base_path = '/v1', $errors_service = null ) {
60 // error handing service.
61 $this->errors_service = $errors_service ? $errors_service : new ErrorsService();
62 // set the token.
63 $this->token = $token;
64 // set the base path and url.
65 $this->base_path = $base_path;
66 $this->base_url = $this->getBaseUrl();
67 }
68
69 /**
70 * Set the API token on the fly.
71 *
72 * @param string $token API token.
73 *
74 * @return $this
75 */
76 public function setToken( $token ) {
77 $this->token = $token;
78 return $this;
79 }
80
81 /**
82 * Get the base url.
83 */
84 public function getBaseUrl() {
85 return untrailingslashit( SURECART_API_URL ) . trailingslashit( $this->base_path );
86 }
87
88 /**
89 * Should we get a cached request?
90 *
91 * @return boolean
92 */
93 public function shouldFindCache( $cachable, $cache_key, $args = [] ) {
94 // only for fetch requests.
95 if ( isset( $args['method'] ) && 'GET' !== $args['method'] ) {
96 return false;
97 }
98
99 // if the args are set, then do what they say.
100 if ( isset( $args['query']['cached'] ) ) {
101 return (bool) $args['query']['cached'];
102 }
103
104 // don't cache edit context.
105 if ( isset( $args['query']['context'] ) && 'edit' === $args['query']['context'] ) {
106 return false;
107 }
108
109 return (bool) $cachable && $cache_key;
110 }
111
112 /**
113 * Respond to the request.
114 *
115 * @param array $response Reponse data.
116 * @param array $args Request arguments.
117 * @param string $endpoint The endpoint to request.
118 *
119 * @return array Response data.
120 */
121 public function respond( $response, $args, $endpoint ) {
122 if ( is_array( $response ) ) {
123 foreach ( $response as $item ) {
124 $item->cache_status = $this->cache_status;
125 }
126 }
127
128 if ( is_object( $response ) ) {
129 $response->cache_status = $this->cache_status;
130 }
131
132 return apply_filters( 'surecart/request/response', $response, $args, $endpoint );
133 }
134
135 /**
136 * Set the response cache status.
137 *
138 * @param object $response Response object.
139 * @param string $status The response status.
140 *
141 * @return void
142 */
143 public function setResponseCacheStatus( $response, $status ) {
144 if ( is_array( $response ) ) {
145 foreach ( $response as $item ) {
146 $item->cached = $status;
147 }
148 } elseif ( is_object( $response ) ) {
149 $response->cached = $status;
150 }
151
152 return $response;
153 }
154
155 /**
156 * Make the request
157 *
158 * @param string $endpoint Endpoint to request.
159 * @param array $args Arguments for request.
160 * @param boolean $cachable Should this request be cached.
161 * @param string $cache_key The cache key to use.
162 *
163 * @return mixed
164 */
165 public function makeRequest( $endpoint, $args = [], $cachable = false, $cache_key = '' ) {
166 // use the cache service for this request.
167 $cache = new RequestCacheService( $endpoint, $args, $cache_key );
168
169 // check if we should get a cached version of this.
170 if ( $this->shouldFindCache( $cachable, $cache_key, $args ) ) {
171 // get from cache.
172 $response_body = $cache->getTransientCache();
173 // we have a cached response.
174 if ( false !== $response_body ) {
175 $this->cache_status = 'transient';
176 return $this->respond( $response_body, $args, $endpoint );
177 }
178 }
179
180 // make the uncached request.
181 $response_body = $this->makeUncachedRequest( $endpoint, $args );
182
183 if ( is_wp_error( $response_body ) ) {
184 return $response_body;
185 }
186
187 // set in object cache.
188 $cache->setCache( $response_body, 'object' );
189 if ( (bool) $cachable && $cache_key ) {
190 $cache->setCache( $response_body, 'transient' );
191 }
192
193 // return response.
194 return $this->respond( $response_body, $args, $endpoint );
195 }
196
197 /**
198 * Make the uncached request.
199 *
200 * @param string $endpoint Endpoint to request.
201 * @param array $args Arguments for request.
202 *
203 * @return mixed
204 */
205 public function makeUncachedRequest( $endpoint, $args = [] ) {
206 // must have a token for the request.
207 if ( empty( $this->token ) ) {
208 return new \WP_Error( 'missing_token', __( 'Please connect your site to SureCart.', 'surecart' ) );
209 }
210
211 // make sure we send json.
212 if ( empty( $args['headers']['Content-Type'] ) ) {
213 $args['headers']['Content-Type'] = 'application/json';
214 }
215
216 // add auth.
217 if ( empty( $args['headers']['Authorization'] ) ) {
218 $args['headers']['Authorization'] = "Bearer $this->token";
219 }
220
221 // add version header.
222 $args['headers']['X-SURECART-WP-PLUGIN-VERSION'] = \SureCart::plugin()->version();
223
224 // add referer header.
225 if ( isset( $_SERVER['HTTP_REFERER'] ) ) {
226 $args['headers']['X-SURECART-REFERRER'] = esc_url_raw( $_SERVER['HTTP_REFERER'] );
227 }
228
229 // parse args.
230 $args = wp_parse_args(
231 $args,
232 [
233 'timeout' => 20,
234 'sslverify' => true,
235 ]
236 );
237
238 // filter args and endpoint.
239 $args = apply_filters( 'surecart/request/args', $args, $endpoint );
240 $endpoint = apply_filters( 'surecart/request/endpoint', $endpoint, $args );
241
242 // make url.
243 $url = trailingslashit( $this->base_url ) . untrailingslashit( $endpoint );
244
245 // add query args.
246 if ( ! empty( $args['query'] ) ) {
247 $url = add_query_arg( $this->parseArgs( $args['query'] ), $url );
248 $url = preg_replace( '/%5B[0-9]+%5D/', '%5B%5D', $url );
249 unset( $args['query'] );
250 }
251
252 // json encode body.
253 if ( ! empty( $args['body'] ) ) {
254 if ( 'application/json' === $args['headers']['Content-Type'] ) {
255 $args['body'] = wp_json_encode( $this->parseArgs( $args['body'] ) );
256 }
257 }
258
259 // make request.
260 $response = $this->remoteRequest( $url, $args );
261
262 // bail early if it's a wp_error.
263 if ( is_wp_error( $response ) ) {
264 return $response;
265 }
266
267 $response_code = wp_remote_retrieve_response_code( $response );
268 $response_body = wp_remote_retrieve_body( $response );
269 $admin_notice = (array) wp_remote_retrieve_header( $response, 'X-SURECART-WP-ADMIN-NOTICE' );
270
271 if ( $admin_notice ) {
272 // we don't care if this fails.
273 try {
274 \SureCart::notices()->showResponseNotice( $admin_notice );
275 } catch ( \Exception $e ) {
276 error_log( $e->getMessage() );
277 }
278 }
279
280 // Handle invalid token first.
281 if ( 401 === $response_code ) {
282 ApiToken::clear();
283 return new \WP_Error( 'invalid_token', __( 'Invalid API token.', 'surecart' ) );
284 }
285
286 // check for errors.
287 if ( ! in_array( $response_code, [ 200, 201 ], true ) ) {
288 $body = json_decode( $response_body, true );
289 if ( is_string( $body ) ) {
290 return new \WP_Error( 'error', $response_body );
291 }
292 return $this->errors_service->translate( $body, $response_code );
293 }
294
295 return json_decode( $response_body );
296 }
297
298 /**
299 * Make the remote request.
300 *
301 * @param string $url The url to request.
302 * @param array $args The args to pass to the request.
303 *
304 * @return mixed
305 */
306 public function remoteRequest( $url, $args = [] ) {
307 return wp_remote_request( esc_url_raw( $url ), $args );
308 }
309
310 /**
311 * Make a get request
312 *
313 * @param string $endpoint Endpoint for the request.
314 * @param array $args Request arguments.
315 *
316 * @return mixed
317 */
318 public function get( $endpoint, $args = [] ) {
319 $args['method'] = 'GET';
320 return $this->makeRequest( $endpoint, $args );
321 }
322
323 /**
324 * Make a post request
325 *
326 * @param string $endpoint Endpoint for the request.
327 * @param array $args Request arguments.
328 *
329 * @return mixed
330 */
331 public function post( $endpoint, $args = [] ) {
332 $args['method'] = 'POST';
333 return $this->makeRequest( $endpoint, $args );
334 }
335
336 /**
337 * Make a put request
338 *
339 * @param string $endpoint Endpoint for the request.
340 * @param array $args Request arguments.
341 *
342 * @return mixed
343 */
344 public function put( $endpoint, $args = [] ) {
345 $args['method'] = 'PUT';
346 return $this->makeRequest( $endpoint, $args );
347 }
348
349 /**
350 * Make a patch request
351 *
352 * @param string $endpoint Endpoint for the request.
353 * @param array $args Request arguments.
354 *
355 * @return mixed
356 */
357 public function patch( $endpoint, $args = [] ) {
358 $args['method'] = 'PATCH';
359 return $this->makeRequest( $endpoint, $args );
360 }
361
362 /**
363 * Make a delete request
364 *
365 * @param string $endpoint Endpoint for the request.
366 * @param array $args Request arguments.
367 *
368 * @return mixed
369 */
370 public function delete( $endpoint, $args = [] ) {
371 $args['method'] = 'DELETE';
372 return $this->makeRequest( $endpoint, $args );
373 }
374
375 /**
376 * Removes empty args
377 *
378 * @param array $args Array of arguments.
379 */
380 protected function parseArgs( $args = [] ) {
381 if ( ! is_array( $args ) ) {
382 return $args;
383 }
384 foreach ( $args as $key => $arg ) {
385 // unset null.
386 if ( null === $arg ) {
387 unset( $args[ $key ] );
388 }
389
390 // filter out wp params.
391 if ( in_array( $key, [ 'locale', 'rest_route' ], true ) ) {
392 unset( $args[ $key ] );
393 }
394
395 // convert bool to int to prevent getting unset.
396 if ( is_bool( $arg ) ) {
397 $args[ $key ] = $arg ? 1 : 0;
398 }
399
400 // url encode any strings.
401 if ( is_string( $arg ) ) {
402 $args[ $key ] = urlencode( $arg );
403 }
404 }
405
406 return $args;
407 }
408 }
409