PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 1.9.2
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v1.9.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 3 years ago RequestService.php 3 years ago RequestServiceProvider.php 3 years ago
RequestService.php
412 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 error_log( print_r( $response_body, 1 ) );
289 error_log( print_r( $url, 1 ) );
290 error_log( print_r( $args, 1 ) );
291 $body = json_decode( $response_body, true );
292 if ( is_string( $body ) ) {
293 return new \WP_Error( 'error', $response_body );
294 }
295 return $this->errors_service->translate( $body, $response_code );
296 }
297
298 return json_decode( $response_body );
299 }
300
301 /**
302 * Make the remote request.
303 *
304 * @param string $url The url to request.
305 * @param array $args The args to pass to the request.
306 *
307 * @return mixed
308 */
309 public function remoteRequest( $url, $args = [] ) {
310 return wp_remote_request( esc_url_raw( $url ), $args );
311 }
312
313 /**
314 * Make a get request
315 *
316 * @param string $endpoint Endpoint for the request.
317 * @param array $args Request arguments.
318 *
319 * @return mixed
320 */
321 public function get( $endpoint, $args = [] ) {
322 $args['method'] = 'GET';
323 return $this->makeRequest( $endpoint, $args );
324 }
325
326 /**
327 * Make a post request
328 *
329 * @param string $endpoint Endpoint for the request.
330 * @param array $args Request arguments.
331 *
332 * @return mixed
333 */
334 public function post( $endpoint, $args = [] ) {
335 $args['method'] = 'POST';
336 return $this->makeRequest( $endpoint, $args );
337 }
338
339 /**
340 * Make a put request
341 *
342 * @param string $endpoint Endpoint for the request.
343 * @param array $args Request arguments.
344 *
345 * @return mixed
346 */
347 public function put( $endpoint, $args = [] ) {
348 $args['method'] = 'PUT';
349 return $this->makeRequest( $endpoint, $args );
350 }
351
352 /**
353 * Make a patch request
354 *
355 * @param string $endpoint Endpoint for the request.
356 * @param array $args Request arguments.
357 *
358 * @return mixed
359 */
360 public function patch( $endpoint, $args = [] ) {
361 $args['method'] = 'PATCH';
362 return $this->makeRequest( $endpoint, $args );
363 }
364
365 /**
366 * Make a delete request
367 *
368 * @param string $endpoint Endpoint for the request.
369 * @param array $args Request arguments.
370 *
371 * @return mixed
372 */
373 public function delete( $endpoint, $args = [] ) {
374 $args['method'] = 'DELETE';
375 return $this->makeRequest( $endpoint, $args );
376 }
377
378 /**
379 * Removes empty args
380 *
381 * @param array $args Array of arguments.
382 */
383 protected function parseArgs( $args = [] ) {
384 if ( ! is_array( $args ) ) {
385 return $args;
386 }
387 foreach ( $args as $key => $arg ) {
388 // unset null.
389 if ( null === $arg ) {
390 unset( $args[ $key ] );
391 }
392
393 // filter out wp params.
394 if ( in_array( $key, [ 'locale', 'rest_route' ], true ) ) {
395 unset( $args[ $key ] );
396 }
397
398 // convert bool to int to prevent getting unset.
399 if ( is_bool( $arg ) ) {
400 $args[ $key ] = $arg ? 1 : 0;
401 }
402
403 // url encode any strings.
404 if ( is_string( $arg ) ) {
405 $args[ $key ] = urlencode( $arg );
406 }
407 }
408
409 return $args;
410 }
411 }
412