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