PluginProbe
WooCommerce Square / 2.0.7
WooCommerce Square v2.0.7
5.5.0 5.4.3 5.4.2 5.4.1 5.4.0 trunk 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 All 132 releases
woocommerce-square / includes / API.php

API.php in WooCommerce Square 2.0.7, at includes/API.php

886 lines 24.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WooCommerce Square
4 *
5 * This source file is subject to the GNU General Public License v3.0
6 * that is bundled with this package in the file license.txt.
7 * It is also available through the world-wide-web at this URL:
8 * http://www.gnu.org/licenses/gpl-3.0.html
9 * If you did not receive a copy of the license and are unable to
10 * obtain it through the world-wide-web, please send an email
11 * to license@woocommerce.com so we can send you a copy immediately.
12 *
13 * DISCLAIMER
14 *
15 * Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
16 * versions in the future. If you wish to customize WooCommerce Square for your
17 * needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
18 *
19 * @author WooCommerce
20 * @copyright Copyright: (c) 2019, Automattic, Inc.
21 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
22 */
23
24 namespace WooCommerce\Square;
25
26 use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
27 use SquareConnect;
28 use WooCommerce\Square\API\Requests;
29 use WooCommerce\Square\API\Responses;
30
31 defined( 'ABSPATH' ) or exit;
32
33 /**
34 * WooCommerce Square API class
35 *
36 * @since 2.0.0
37 */
38 class API extends Framework\SV_WC_API_Base {
39
40
41 /** catalog request type */
42 const REQUEST_TYPE_CATALOG = 'catalog';
43
44 /** inventory request type */
45 const REQUEST_TYPE_INVENTORY = 'inventory';
46
47
48 /** @var SquareConnect\ApiClient Square API client instance */
49 protected $client;
50
51
52 /**
53 * Constructs the main Square API wrapper class.
54 *
55 * @since 2.0.0
56 *
57 * @param string $access_token Square API access token
58 * @param bool $is_sandbox If sandbox access is desired
59 */
60 public function __construct( $access_token, $is_sandbox = null ) {
61 $api_config = SquareConnect\Configuration::getDefaultConfiguration();
62 $api_config->setAccessToken( $access_token );
63
64 // Set sandbox URL if enabled.
65 if ( $is_sandbox ) {
66 $api_config->setHost( 'https://connect.squareupsandbox.com' );
67 }
68
69 $this->client = new SquareConnect\ApiClient( $api_config );
70 }
71
72
73 /** Catalog API Methods *******************************************************************************************/
74
75
76 /**
77 * Batch-deletes an array of catalog objects.
78 *
79 * @since 2.0.0
80 *
81 * @param string[] $object_ids array of square catalog object IDs
82 * @return Responses\Catalog
83 * @throws Framework\SV_WC_API_Exception
84 */
85 public function batch_delete_catalog_objects( array $object_ids ) {
86
87 $request = $this->get_catalog_request();
88 $request->set_batch_delete_catalog_objects_data( $object_ids );
89
90 return $this->perform_request( $request );
91 }
92
93
94 /**
95 * Batch-retrieves an array of catalog objects.
96 *
97 * @since 2.0.0
98 *
99 * @param string[] $object_ids array of square catalog object IDs
100 * @param bool $include_related_objects whether or not to include related objects in the response
101 * @return Responses\Catalog
102 * @throws Framework\SV_WC_API_Exception
103 */
104 public function batch_retrieve_catalog_objects( array $object_ids, $include_related_objects = false ) {
105
106 $request = $this->get_catalog_request();
107 $request->set_batch_retrieve_catalog_objects_data( $object_ids, (bool) $include_related_objects );
108
109 return $this->perform_request( $request );
110 }
111
112
113 /**
114 * Batch-upserts an array of catalog objects.
115 *
116 * @since 2.0.0
117 *
118 * @param string $idempotency_key a UUID for this request
119 * @param array $batches an array of batches to upsert
120 * @return Responses\Catalog
121 * @throws Framework\SV_WC_API_Exception
122 */
123 public function batch_upsert_catalog_objects( $idempotency_key, array $batches ) {
124
125 $request = $this->get_catalog_request();
126 $request->set_batch_upsert_catalog_objects_data( $idempotency_key, $batches );
127
128 return $this->perform_request( $request );
129 }
130
131
132 /**
133 * Returns info about the Catalog API, including helpful info like request size limits.
134 *
135 * @since 2.0.0
136 * @return Responses\Catalog
137 * @throws Framework\SV_WC_API_Exception
138 */
139 public function catalog_info() {
140
141 $request = $this->get_catalog_request();
142 $request->set_catalog_info_data();
143
144 return $this->perform_request( $request );
145 }
146
147
148 /**
149 * Deletes an object from the Square catalog.
150 *
151 * @since 2.0.0
152 *
153 * @param string $object_id Square catalog object ID
154 * @return Responses\Catalog
155 * @throws Framework\SV_WC_API_Exception
156 */
157 public function delete_catalog_object( $object_id ) {
158
159 $request = $this->get_catalog_request();
160 $request->set_delete_catalog_object_data( $object_id );
161
162 return $this->perform_request( $request );
163 }
164
165
166 /**
167 * Returns a list of Square catalog items.
168 *
169 * @since 2.0.0
170 *
171 * @param string $cursor the cursor to list from
172 * @param string[] $types the item types to filter by
173 * @return Responses\Catalog
174 * @throws Framework\SV_WC_API_Exception
175 */
176 public function list_catalog( $cursor = '', $types = [] ) {
177
178 $request = $this->get_catalog_request();
179 $request->set_list_catalog_data( $cursor, $types );
180
181 return $this->perform_request( $request );
182 }
183
184
185 /**
186 * Retrieves a single catalog object.
187 *
188 * @since 2.0.0
189 *
190 * @param string $object_id the Square catalog object ID
191 * @param bool $include_related_objects whether or not to include related objects (such as categories)
192 * @return Responses\Catalog
193 * @throws Framework\SV_WC_API_Exception
194 */
195 public function retrieve_catalog_object( $object_id, $include_related_objects = false ) {
196
197 $request = $this->get_catalog_request();
198 $request->set_retrieve_catalog_object_data( $object_id, $include_related_objects );
199
200 return $this->perform_request( $request );
201 }
202
203
204 /**
205 * Searches the catalog for objects.
206 *
207 * @since 2.0.0
208 *
209 * @param array $args see Catalog::set_search_catalog_objects_data() for list of args
210 * @return Responses\Catalog
211 * @throws Framework\SV_WC_API_Exception
212 */
213 public function search_catalog_objects( $args = [] ) {
214
215 $request = $this->get_catalog_request();
216 $request->set_search_catalog_objects_data( $args );
217
218 return $this->perform_request( $request );
219 }
220
221
222 /**
223 * Updates the modifier lists that apply to given items.
224 *
225 * @since 2.0.0
226 *
227 * @param string[] $item_ids array of Square catalog item IDs
228 * @param string[] $modifier_lists_to_enable (optional) modifier list IDs to enable
229 * @param string[] $modifier_lists_to_disable (optional) modifier list IDs to disable
230 * @return Responses\Catalog
231 * @throws Framework\SV_WC_API_Exception
232 */
233 public function update_item_modifier_lists( array $item_ids, array $modifier_lists_to_enable = [], array $modifier_lists_to_disable = [] ) {
234
235 $request = $this->get_catalog_request();
236 $request->set_update_item_modifier_lists_data( $item_ids, $modifier_lists_to_enable, $modifier_lists_to_disable );
237
238 return $this->perform_request( $request );
239 }
240
241
242 /**
243 * Updates an item's applied taxes.
244 *
245 * @since 2.0.0
246 *
247 * @param string[] $item_ids array of Square catalog item IDs
248 * @param string[] $taxes_to_enable (optional) tax IDs to enable
249 * @param string[] $taxes_to_disable (optional) tax IDs to disable
250 * @return Responses\Catalog
251 * @throws Framework\SV_WC_API_Exception
252 */
253 public function update_item_taxes( array $item_ids, array $taxes_to_enable = [], array $taxes_to_disable = [] ) {
254
255 $request = $this->get_catalog_request();
256 $request->set_update_item_taxes_data( $item_ids, $taxes_to_enable, $taxes_to_disable );
257
258 return $this->perform_request( $request );
259 }
260
261
262 /**
263 * Upserts an object into the catalog.
264 *
265 * @since 2.0.0
266 *
267 * @param string $idempotency_key UUID for this request
268 * @param SquareConnect\Model\CatalogObject $object the object to upsert
269 * @return Responses\Catalog
270 * @throws Framework\SV_WC_API_Exception
271 */
272 public function upsert_catalog_object( $idempotency_key, $object ) {
273
274 $request = $this->get_catalog_request();
275 $request->set_upsert_catalog_object_data( $idempotency_key, $object );
276
277 return $this->perform_request( $request );
278 }
279
280
281 /**
282 * Creates an image in Square.
283 *
284 * Note that this method uses a custom request, since the Square SDK does not yet provide a method for image creation.
285 *
286 * @since 2.0.0
287 *
288 * @param $image_path
289 * @param string $square_item_id
290 * @param string $caption optional image caption
291 * @return string
292 * @throws Framework\SV_WC_API_Exception
293 */
294 public function create_image( $image_path, $square_item_id = '', $caption = '' ) {
295
296 if ( ! is_readable( $image_path ) ) {
297 throw new Framework\SV_WC_API_Exception( 'Image file is not readable' );
298 }
299
300 $image = file_get_contents( $image_path );
301
302 $headers = [
303 'accept' => 'application/json',
304 'content-type' => 'multipart/form-data; boundary="boundary"',
305 'Square-Version' => '2019-05-08',
306 'Authorization' => 'Bearer ' . wc_square()->get_settings_handler()->get_access_token(),
307 ];
308
309 $body = '--boundary' . "\r\n";
310 $body .= 'Content-Disposition: form-data; name="request"' . "\r\n";
311 $body .= 'Content-Type: application/json' . "\r\n\r\n";
312
313 $request = [
314 'idempotency_key' => wc_square()->get_idempotency_key(),
315 'image' => [
316 'type' => 'IMAGE',
317 'id' => '#TEMP_ID',
318 'image_data' => [
319 'caption' => esc_attr( $caption ),
320 ],
321 ],
322 ];
323
324 if ( $square_item_id ) {
325 $request['object_id'] = $square_item_id;
326 }
327
328 $body .= json_encode( $request );
329
330 $body .= "\r\n";
331
332 $body .= '--boundary' . "\r\n";
333 $body .= 'Content-Disposition: form-data; name="image"; filename="' . esc_attr( basename( $image_path ) ) . '"' . "\r\n";
334 $body .= 'Content-Type: image/jpeg' . "\r\n\r\n";
335 $body .= $image . "\r\n";
336 $body .= '--boundary--';
337
338 $response = wp_remote_post( 'https://connect.squareup.com/v2/catalog/images', [
339 'headers' => $headers,
340 'body' => $body,
341 ] );
342
343 if ( is_wp_error( $response ) ) {
344 throw new Framework\SV_WC_API_Exception( $response->get_error_message() );
345 }
346
347 $body = wp_remote_retrieve_body( $response );
348 $body = json_decode( $body, true );
349
350 if ( ! is_array( $body ) ) {
351 throw new Framework\SV_WC_API_Exception( 'Response was malformed' );
352 }
353
354 if ( ! empty( $body['errors'] ) || empty( $body['image']['id'] ) ) {
355
356 if ( ! empty( $body['errors'][0]['detail'] ) ) {
357 $message = $body['errors'][0]['detail'];
358 } else {
359 $message = 'Unknown error';
360 }
361
362 throw new Framework\SV_WC_API_Exception( $message );
363 }
364
365 return $body['image']['id'];
366 }
367
368
369 /** Inventory API Methods *****************************************************************************************/
370
371
372 /**
373 * Adds a count of inventory as "in-stock" to the given Square item variation ID as a result of a refund.
374 *
375 * @since 2.0.0
376 *
377 * @param string $square_id Square object ID
378 * @param int $amount amount of inventory to add
379 * @return Responses\Inventory
380 * @throws Framework\SV_WC_API_Exception
381 */
382 public function add_inventory_from_refund( $square_id, $amount ) {
383
384 return $this->add_inventory( $square_id, $amount, 'NONE' );
385 }
386
387
388 /**
389 * Adds a count of inventory as "in-stock" to the given Square item variation ID.
390 *
391 * @since 2.0.0
392 *
393 * @param string $square_id Square object ID
394 * @param int $amount amount of inventory to add
395 * @param string $from_state the API state the inventory is coming from
396 * @return Responses\Inventory
397 * @throws Framework\SV_WC_API_Exception
398 */
399 public function add_inventory( $square_id, $amount, $from_state = 'NONE' ) {
400
401 return $this->adjust_inventory( $square_id, $amount, $from_state, 'IN_STOCK' );
402 }
403
404
405 /**
406 * Removes a count of inventory as "in-stock" to the given Square item variation ID.
407 *
408 * @since 2.0.0
409 *
410 * @param string $square_id Square object ID
411 * @param int $amount amount of inventory to remove
412 * @return Responses\Inventory
413 * @throws Framework\SV_WC_API_Exception
414 */
415 public function remove_inventory( $square_id, $amount ) {
416
417 return $this->adjust_inventory( $square_id, $amount, 'IN_STOCK', 'SOLD' );
418 }
419
420
421 /**
422 * Performs an inventory adjustment.
423 *
424 * @since 2.0.0
425 *
426 * @param string $square_id Square object ID
427 * @param int $amount amount of inventory to add
428 * @param string $from_state the API state the inventory is coming from
429 * @param string $to_state the API state the inventory is changing to
430 * @return Responses\Inventory
431 * @throws Framework\SV_WC_API_Exception
432 */
433 protected function adjust_inventory( $square_id, $amount, $from_state, $to_state ) {
434
435 $date = new \DateTime();
436
437 $change = new SquareConnect\Model\InventoryChange();
438 $change->setType( 'ADJUSTMENT' );
439 $change->setAdjustment( new SquareConnect\Model\InventoryAdjustment( [
440 'catalog_object_id' => $square_id,
441 'location_id' => $this->get_plugin()->get_settings_handler()->get_location_id(),
442 'quantity' => (string) absint( $amount ),
443 'from_state' => $from_state,
444 'to_state' => $to_state,
445 'occurred_at' => $date->format( DATE_ATOM ),
446 ] ) );
447
448 return $this->batch_change_inventory( uniqid( '', false ), [
449 $change,
450 ] );
451 }
452
453
454 /**
455 * Performs a Batch Change Inventory request.
456 *
457 * @since 2.0.0
458 *
459 * @param string $idempotency_key UUID for this request
460 * @param SquareConnect\Model\InventoryChange[] $changes array of Inventory Changes
461 * @param bool $ignore_unchanged_counts whether the current physical count should be ignored if the quantity is unchanged since the last physical count
462 * @return Responses\Inventory
463 * @throws Framework\SV_WC_API_Exception
464 */
465 public function batch_change_inventory( $idempotency_key, $changes, $ignore_unchanged_counts = true ) {
466
467 $request = $this->get_inventory_request();
468 $request->set_batch_change_inventory_data( $idempotency_key, $changes, $ignore_unchanged_counts );
469
470 return $this->perform_request( $request );
471 }
472
473
474 /**
475 * Performs a Batch Retrieve Inventory Changes request.
476 *
477 * @since 2.0.0
478 *
479 * @param array $args see Requests\Inventory::set_batch_retrieve_inventory_changes_data() for accepted arguments
480 *
481 * @return Responses\Inventory
482 * @throws Framework\SV_WC_API_Exception
483 */
484 public function batch_retrieve_inventory_changes( array $args = [] ) {
485
486 $request = $this->get_inventory_request();
487 $request->set_batch_retrieve_inventory_changes_data( $args );
488
489 return $this->perform_request( $request );
490 }
491
492
493 /**
494 * Performs a Batch Retrieve Inventory Counts request.
495 *
496 * @since 2.0.0
497 *
498 * @param array $args see Requests\Inventory::set_batch_retrieve_inventory_counts_data() for accepted arguments
499 *
500 * @return Responses\Inventory
501 * @throws Framework\SV_WC_API_Exception
502 */
503 public function batch_retrieve_inventory_counts( array $args = [] ) {
504
505 $request = $this->get_inventory_request();
506 $request->set_batch_retrieve_inventory_counts_data( $args );
507
508 return $this->perform_request( $request );
509 }
510
511
512 /**
513 * Performs a Retrieve Inventory Adjustment request.
514 *
515 * @since 2.0.0
516 *
517 * @param string $adjustment_id the InventoryAdjustment ID to retrieve
518 *
519 * @return Responses\Inventory
520 * @throws Framework\SV_WC_API_Exception
521 */
522 public function retrieve_inventory_adjustment( $adjustment_id ) {
523
524 $request = $this->get_inventory_request();
525 $request->set_retrieve_inventory_adjustment_data( $adjustment_id );
526
527 return $this->perform_request( $request );
528 }
529
530
531 /**
532 * Performs a Retrieve Inventory Changes request.
533 *
534 * @since 2.0.0
535 *
536 * @param string $catalog_object_id the CatalogObject ID to retrieve
537 *
538 * @return Responses\Inventory
539 * @throws Framework\SV_WC_API_Exception
540 */
541 public function retrieve_inventory_changes( $catalog_object_id ) {
542
543 $request = $this->get_inventory_request();
544 $request->set_retrieve_inventory_changes_data( $catalog_object_id );
545
546 return $this->perform_request( $request );
547 }
548
549
550 /**
551 * Performs a Retrieve Inventory Count request.
552 *
553 * @since 2.0.0
554 *
555 * @param string $catalog_object_id the CatalogObject ID to retrieve
556 * @return Responses\Inventory
557 * @throws Framework\SV_WC_API_Exception
558 */
559 public function retrieve_inventory_count( $catalog_object_id ) {
560
561 $request = $this->get_inventory_request();
562 $request->set_retrieve_inventory_count_data( $catalog_object_id, [ $this->get_plugin()->get_settings_handler()->get_location_id() ] );
563
564 return $this->perform_request( $request );
565 }
566
567
568 /**
569 * Performs a Retrieve Inventory Physical Count request.
570 *
571 * @since 2.0.0
572 *
573 * @param string $physical_count_id the InventoryPhysicalCount ID to retrieve
574 *
575 * @return Responses\Inventory
576 * @throws Framework\SV_WC_API_Exception
577 */
578 public function retrieve_inventory_physical_count( $physical_count_id ) {
579
580 $request = $this->get_inventory_request();
581 $request->set_retrieve_inventory_physical_count_data( $physical_count_id );
582
583 return $this->perform_request( $request );
584 }
585
586
587 /** Locations methods *********************************************************************************************/
588
589
590 /**
591 * Gets the available locations.
592 *
593 * @since 2.0.0
594 *
595 * @return SquareConnect\Model\Location[]
596 * @throws Framework\SV_WC_API_Exception
597 */
598 public function get_locations() {
599
600 $request = new API\Requests\Locations( $this->client );
601
602 $request->set_list_locations_data();
603
604 $this->set_response_handler( API\Responses\Locations::class );
605
606 /* @type API\Responses\Locations $response */
607 $response = $this->perform_request( $request );
608
609 return $response->get_locations();
610 }
611
612
613 /** Customer methods **********************************************************************************************/
614
615
616 /**
617 * Gets all customers.
618 *
619 * @since 2.0.0
620 *
621 * @param string $cursor pagination cursor
622 * @return API\Response
623 * @throws Framework\SV_WC_API_Exception
624 */
625 public function get_customers( $cursor = '' ) {
626
627 $request = new API\Requests\Customers( $this->client );
628
629 $request->set_get_customers_data( $cursor );
630
631 $this->set_response_handler( API\Response::class );
632
633 return $this->perform_request( $request );
634 }
635
636
637 /** Request Helper Methods ****************************************************************************************/
638
639
640 /**
641 * Gets a new Catalog API request.
642 *
643 * @since 2.0.0
644 *
645 * @return Requests\Catalog
646 * @throws Framework\SV_WC_API_Exception
647 */
648 protected function get_catalog_request() {
649
650 return $this->get_new_request( self::REQUEST_TYPE_CATALOG );
651 }
652
653
654 /**
655 * Gets a new Inventory API request.
656 *
657 * @since 2.0.0
658 *
659 * @return Requests\Inventory
660 * @throws Framework\SV_WC_API_Exception
661 */
662 protected function get_inventory_request() {
663
664 return $this->get_new_request( self::REQUEST_TYPE_INVENTORY );
665 }
666
667
668 /**
669 * Gets a new request object.
670 *
671 * @since 2.0.0
672 *
673 * @param string $type desired request type
674 * @return Requests\Catalog|Requests\Inventory
675 * @throws Framework\SV_WC_API_Exception
676 */
677 protected function get_new_request( $type = '' ) {
678
679 switch ( $type ) {
680
681 case self::REQUEST_TYPE_CATALOG:
682 $request = new Requests\Catalog( $this->client );
683 $response_handler = Responses\Catalog::class;
684 break;
685
686 case self::REQUEST_TYPE_INVENTORY:
687 $request = new Requests\Inventory( $this->client );
688 $response_handler = Responses\Inventory::class;
689 break;
690
691 default:
692 throw new Framework\SV_WC_API_Exception( 'Invalid request type.' );
693 }
694
695 $this->set_response_handler( $response_handler );
696
697 return $request;
698 }
699
700
701 /**
702 * Performs an API request.
703 *
704 * @see Framework\SV_WC_API_Base::perform_request()
705 *
706 * @since 2.0.0
707 *
708 * @param API\Request $request request object
709 * @return Framework\SV_WC_API_Response
710 * @throws Framework\SV_WC_API_Exception
711 */
712 protected function perform_request( $request ) {
713
714 // ensure API is in its default state
715 $this->reset_response();
716
717 // save the request object
718 $this->request = $request;
719
720 $start_time = microtime( true );
721
722 try {
723
724 // set the request URI to the Square SDK method for better logging
725 $this->request_uri = $this->get_request()->get_square_api_method();
726 $this->request_method = '';
727
728 // add any query args to the logged request URI for easier debugging
729 foreach ( $this->get_request()->get_square_api_args() as $arg ) {
730
731 if ( is_string( $arg ) ) {
732 $this->request_uri .= "/{$arg}";
733 }
734 }
735
736 // perform the request
737 $response = $this->do_square_request( $this->get_request()->get_square_api(), $this->get_request()->get_square_api_method(), $this->get_request()->get_square_api_args() );
738
739 // calculate request duration
740 $this->request_duration = round( microtime( true ) - $start_time, 5 );
741
742 // parse & validate response
743 $response = $this->handle_response( $response );
744
745 } catch ( Framework\SV_WC_API_Exception $e ) {
746
747 // alert other actors that a request has been made
748 $this->broadcast_request();
749
750 throw $e;
751 }
752
753 return $response;
754 }
755
756
757 /**
758 * Handles and parses the response.
759 *
760 * @since 2.0.0
761 *
762 * @param array|\WP_Error $response response data
763 * @throws Framework\SV_WC_API_Exception
764 * @return Framework\SV_WC_API_Response|object request class instance that implements SV_WC_API_Request
765 */
766 protected function handle_response( $response ) {
767
768 // allow child classes to validate response prior to parsing
769 $this->do_pre_parse_response_validation();
770
771 // parse the response body and tie it to the request
772 $this->response = $this->get_parsed_response( $this->raw_response_body );
773
774 // allow child classes to validate response after parsing -- this is useful
775 // for checking error codes/messages included in a parsed response
776 $this->do_post_parse_response_validation();
777
778 // fire do_action() so other actors can act on request/response data,
779 // primarily used for logging
780 $this->broadcast_request();
781
782 return $this->response;
783 }
784
785
786 /**
787 * Validates the response data after it's been parsed.
788 *
789 * @since 2.0.0
790 *
791 * @return bool
792 * @throws Framework\SV_WC_API_Exception
793 */
794 protected function do_post_parse_response_validation() {
795
796 if ( ! $this->get_response()->has_errors() ) {
797 return true;
798 }
799
800 $errors = [];
801
802 foreach ( $this->get_response()->get_errors() as $error ) {
803 if ( empty( $error->code ) ) {
804 continue;
805 }
806
807 $errors[] = trim( "[{$error->code}] {$error->detail}" );
808
809 // Last attempt to refresh access token.
810 if ( 'ACCESS_TOKEN_EXPIRED' == $error->code ) {
811 $this->get_plugin()->log( 'Access Token Expired, attempting a refresh.' );
812 $this->get_plugin()->get_connection_handler()->refresh_connection();
813
814 $failure_value = get_option( 'wc_' . $this->get_plugin()->get_id() . '_refresh_failed', 'yes' );
815
816 if ( empty( $failure_value ) ) {
817 // Successfully refreshed on the last attempt
818 $this->get_plugin()->log( 'Connection successfully refreshed.' );
819 return true;
820 }
821 }
822
823 // if the error indicates that access token is bad, disconnect the plugin to prevent further attempts
824 if ( in_array( $error->code, [ 'ACCESS_TOKEN_EXPIRED', 'ACCESS_TOKEN_REVOKED' ], true ) ) {
825 $this->get_plugin()->get_connection_handler()->disconnect();
826 $this->get_plugin()->log( 'Disconnected due to invalid authorization. Please try connecting again.' );
827 }
828 }
829
830 // At this point we could not validate the response and assume a failed attempt.
831 throw new Framework\SV_WC_API_Exception( implode( ' | ', $errors ) );
832 }
833
834 /**
835 * Performs a remote request with the Square API class.
836 *
837 * @since 2.0.0
838 *
839 * @param Object $square_api the square API class instance
840 * @param string $method the class method to call
841 * @param array $args the args to send with the method call
842 * @throws Framework\SV_WC_API_Exception
843 */
844 protected function do_square_request( $square_api, $method, $args ) {
845
846 if ( ! is_callable( [ $square_api, $method ] ) ) {
847 throw new Framework\SV_WC_API_Exception( 'Invalid API method' );
848 }
849
850 try {
851
852 // perform the request
853 $response = call_user_func_array( [ $square_api, $method ], $args );
854
855 if ( is_array( $response ) && $this->request->get_with_http_info() ) {
856 $this->response_code = isset( $response[1] ) ? (int) $response[1] : 400;
857 $this->response_headers = isset( $response[2] ) ? (array) $response[2] : [];
858 $this->raw_response_body = isset( $response[0] ) ? $response[0] : [];
859 } else {
860 $this->raw_response_body = $response;
861 }
862
863 } catch ( SquareConnect\ApiException $exception ) {
864
865 $this->response_code = $exception->getCode();
866 $this->response_headers = $exception->getResponseHeaders();
867 $this->raw_response_body = $exception->getResponseBody();
868 }
869 }
870
871
872 /**
873 * Gets the main plugin instance.
874 *
875 * @since 2.0.0
876 *
877 * @return \WooCommerce\Square\Plugin
878 */
879 public function get_plugin() {
880
881 return wc_square();
882 }
883
884
885 }
886