WooCommerce Square - Version 1.0.27

Version Description

  • 2018-02-19 =
  • Fix - In some cases request timeouts are not set long enough causing timeout errors.
  • Fix - Square to WC sync sets products with 0 quantity to In Stock.
  • Fix - Potential issue with Square to WC sync when response is not an array.
  • Fix - When description is more than 4095 characters, sync fails to Square.
  • Fix - Add checks to product object before scheduling an event to prevent errors in cron job.
  • Fix - Add check to prevent auto inventory poll from running when a manual sync is in progress.

=

Download this release

Release Info

Developer royho
Plugin Icon 128x128 WooCommerce Square
Version 1.0.27
Comparing to
See all releases

Code changes from version 1.0.26 to 1.0.27

assets/js/wc-square-admin-scripts.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(e){"use strict";e.wc_square_admin={sync:function(o,c){var r={security:wc_square_local.ajaxSyncNonce,process:parseInt(o,10),action:"wc-to-square"===c?"wc_to_square":"square_to_wc"};e.ajax({type:"POST",data:r,url:wc_square_local.admin_ajax_url}).done(function(o){"done"===o.process?(e("body").trigger("woocommerce_square_wc_to_square_sync_complete",[o]),e("table.form-table").unblock(),e(".wc-square-progress-bar span").css({width:o.percentage+"%"}).parent(".wc-square-progress-bar").fadeOut("slow",function(){alert(o.message)})):(e(".wc-square-progress-bar span").css({width:o.percentage+"%"}),e.wc_square_admin.sync(parseInt(o.process,10),o.type))}).fail(function(o,c,r){e("table.form-table").unblock(),console.log(r),alert(r)})},init:function(){e(".woocommerce_page_wc-settings").on("click","#wc-to-square, #square-to-wc",function(o){o.preventDefault();if(confirm(wc_square_local.i18n.confirm_sync)){var c=e(this).parents("table.form-table"),r=e('<div class="wc-square-progress-bar wc-square-stripes"><span class="step"></span></div>');e(".wc-square-progress-bar").remove(),c.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),c.after(r),e.wc_square_admin.sync(0,e(this).attr("id"))}}),e(document.body).on("change","#woocommerce_square_testmode",function(){e(this).is(":checked")?(e("#woocommerce_square_application_id").parents("tr").eq(0).hide(),e("#woocommerce_square_token").parents("tr").eq(0).hide(),e("#woocommerce_square_sandbox_application_id").parents("tr").eq(0).show(),e("#woocommerce_square_sandbox_token").parents("tr").eq(0).show()):(e("#woocommerce_square_application_id").parents("tr").eq(0).show(),e("#woocommerce_square_token").parents("tr").eq(0).show(),e("#woocommerce_square_sandbox_application_id").parents("tr").eq(0).hide(),e("#woocommerce_square_sandbox_token").parents("tr").eq(0).hide())}),e("#woocommerce_square_testmode").trigger("change"),e(document.body).on("change","#woocommerce_squareconnect_sync_products",function(){e(this).is(":checked")?(e("#woocommerce_squareconnect_sync_categories").parents("tr").eq(0).show(),e("#woocommerce_squareconnect_sync_inventory").parents("tr").eq(0).show(),e("#woocommerce_squareconnect_sync_images").parents("tr").eq(0).show()):(e("#woocommerce_squareconnect_sync_categories").parents("tr").eq(0).hide(),e("#woocommerce_squareconnect_sync_inventory").parents("tr").eq(0).hide(),e("#woocommerce_squareconnect_sync_images").parents("tr").eq(0).hide())}),e("#woocommerce_squareconnect_sync_products").trigger("change")}},e.wc_square_admin.init()});
1
+ jQuery(document).ready(function(e){"use strict";e.wc_square_admin={sync:function(o,c){var r={security:wc_square_local.ajaxSyncNonce,process:parseInt(o,10),action:"wc-to-square"===c?"wc_to_square":"square_to_wc"};e.ajax({type:"POST",data:r,url:wc_square_local.admin_ajax_url}).done(function(o){"done"===o.process?(e("body").trigger("woocommerce_square_wc_to_square_sync_complete",[o]),e("table.form-table").unblock(),e(".wc-square-progress-bar span").css({width:o.percentage+"%"}).parent(".wc-square-progress-bar").fadeOut("slow",function(){alert(o.message)})):(e(".wc-square-progress-bar span").css({width:o.percentage+"%"}),e.wc_square_admin.sync(parseInt(o.process,10),o.type))}).fail(function(o,c,r){e("table.form-table").unblock(),console.log(r),alert(r)})},init:function(){e(".woocommerce_page_wc-settings").on("click","#wc-to-square, #square-to-wc",function(o){if(o.preventDefault(),confirm(wc_square_local.i18n.confirm_sync)){var c=e(this).parents("table.form-table"),r=e('<div class="wc-square-progress-bar wc-square-stripes"><span class="step"></span></div>');e(".wc-square-progress-bar").remove(),c.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),c.after(r),e.wc_square_admin.sync(0,e(this).attr("id"))}}),e(document.body).on("change","#woocommerce_square_testmode",function(){e(this).is(":checked")?(e("#woocommerce_square_application_id").parents("tr").eq(0).hide(),e("#woocommerce_square_token").parents("tr").eq(0).hide(),e("#woocommerce_square_sandbox_application_id").parents("tr").eq(0).show(),e("#woocommerce_square_sandbox_token").parents("tr").eq(0).show()):(e("#woocommerce_square_application_id").parents("tr").eq(0).show(),e("#woocommerce_square_token").parents("tr").eq(0).show(),e("#woocommerce_square_sandbox_application_id").parents("tr").eq(0).hide(),e("#woocommerce_square_sandbox_token").parents("tr").eq(0).hide())}),e("#woocommerce_square_testmode").trigger("change"),e(document.body).on("change","#woocommerce_squareconnect_sync_products",function(){e(this).is(":checked")?(e("#woocommerce_squareconnect_sync_categories").parents("tr").eq(0).show(),e("#woocommerce_squareconnect_sync_inventory").parents("tr").eq(0).show(),e("#woocommerce_squareconnect_sync_images").parents("tr").eq(0).show()):(e("#woocommerce_squareconnect_sync_categories").parents("tr").eq(0).hide(),e("#woocommerce_squareconnect_sync_inventory").parents("tr").eq(0).hide(),e("#woocommerce_squareconnect_sync_images").parents("tr").eq(0).hide())}),e("#woocommerce_squareconnect_sync_products").trigger("change")}},e.wc_square_admin.init()});
assets/js/wc-square-payments.min.js CHANGED
@@ -1 +1 @@
1
- !function(e){"use strict";var o;e.wc_square_payments={init:function(){e(document.body).on("updated_checkout",function(){e.wc_square_payments.loadForm()}),e("form#order_review").length&&e.wc_square_payments.loadForm();var o=square_params.custom_form_trigger_element;o.length&&e(document.body).on("click",o,function(){e.wc_square_payments.loadForm()}),e(document.body).on("click","#payment_method_square",function(){e(".payment_box.payment_method_square").css({display:"block",visibility:"visible",height:"auto"})})},loadForm:function(){e("#payment_method_square").length&&(e("#payment_method_square").is(":checked")||e(".payment_box.payment_method_square").css({display:"block",visibility:"hidden",height:"0"}),"object"===e.type(o)&&o.destroy(),(o=new SqPaymentForm({env:square_params.environment,applicationId:square_params.application_id,inputClass:"sq-input",cardNumber:{elementId:"sq-card-number",placeholder:square_params.placeholder_card_number},cvv:{elementId:"sq-cvv",placeholder:square_params.placeholder_card_cvv},expirationDate:{elementId:"sq-expiration-date",placeholder:square_params.placeholder_card_expiration},postalCode:{elementId:"sq-postal-code",placeholder:square_params.placeholder_card_postal_code},callbacks:{cardNonceResponseReceived:function(o,r,a){if(o){var t="";t+='<ul class="woocommerce_error woocommerce-error">',e(o).each(function(e,o){t+="<li>"+o.message+"</li>"}),t+="</ul>",e(".payment_method_square fieldset").eq(0).prepend(t)}else{var n=e("form.woocommerce-checkout, form#order_review");n.append('<input type="hidden" class="square-nonce" name="square_nonce" value="'+r+'" />'),n.submit()}},paymentFormLoaded:function(){o.setPostalCode(e("#billing_postcode").val())},unsupportedBrowserDetected:function(){var o="";o+='<ul class="woocommerce_error woocommerce-error">',o+="<li>"+square_params.unsupported_browser+"</li>",o+="</ul>",e(".payment_method_square fieldset").eq(0).prepend(o)}},inputStyles:e.parseJSON(square_params.payment_form_input_styles)})).build(),e("form.woocommerce-checkout").on("checkout_place_order_square",function(r){return e(".payment_method_square .woocommerce-error").remove(),!e("#payment_method_square").is(":checked")||0!==e("input.square-nonce").size()||(o.requestCardNonce(),!1)}),e("form#order_review").on("submit",function(r){return e(".payment_method_square .woocommerce-error").remove(),!e("#payment_method_square").is(":checked")||0!==e("input.square-nonce").size()||(o.requestCardNonce(),!1)}),e(document.body).on("checkout_error",function(){e("input.square-nonce").remove()}),setTimeout(function(){e("#payment_method_square").is(":checked")||e(".payment_box.payment_method_square").css({display:"none",visibility:"visible",height:"auto"})},1e3))}},e.wc_square_payments.init()}(jQuery);
1
+ !function(e){"use strict";var o;e.wc_square_payments={init:function(){e(document.body).on("updated_checkout",function(){e.wc_square_payments.loadForm()}),e("form#order_review").length&&e.wc_square_payments.loadForm();var o=square_params.custom_form_trigger_element;o.length&&e(document.body).on("click",o,function(){e.wc_square_payments.loadForm()}),e(document.body).on("click","#payment_method_square",function(){e(".payment_box.payment_method_square").css({display:"block",visibility:"visible",height:"auto"})})},loadForm:function(){e("#payment_method_square").length&&(e("#payment_method_square").is(":checked")||e(".payment_box.payment_method_square").css({display:"block",visibility:"hidden",height:"0"}),"object"===e.type(o)&&o.destroy(),(o=new SqPaymentForm({env:square_params.environment,applicationId:square_params.application_id,inputClass:"sq-input",cardNumber:{elementId:"sq-card-number",placeholder:square_params.placeholder_card_number},cvv:{elementId:"sq-cvv",placeholder:square_params.placeholder_card_cvv},expirationDate:{elementId:"sq-expiration-date",placeholder:square_params.placeholder_card_expiration},postalCode:{elementId:"sq-postal-code",placeholder:square_params.placeholder_card_postal_code},callbacks:{cardNonceResponseReceived:function(o,r,a){if(o){var t="";t+='<ul class="woocommerce_error woocommerce-error">',e(o).each(function(e,o){t+="<li>"+o.message+"</li>"}),t+="</ul>",e(".payment_method_square fieldset").eq(0).prepend(t)}else{var n=e("form.woocommerce-checkout, form#order_review");n.append('<input type="hidden" class="square-nonce" name="square_nonce" value="'+r+'" />'),n.submit()}},paymentFormLoaded:function(){o.setPostalCode(e("#billing_postcode").val())},unsupportedBrowserDetected:function(){var o="";o+='<ul class="woocommerce_error woocommerce-error">',o+="<li>"+square_params.unsupported_browser+"</li>",o+="</ul>",e(".payment_method_square fieldset").eq(0).prepend(o)}},inputStyles:e.parseJSON(square_params.payment_form_input_styles)})).build(),e("form.woocommerce-checkout").on("checkout_place_order_square",function(r){return e(".payment_method_square .woocommerce-error").remove(),!e("#payment_method_square").is(":checked")||0!==e("input.square-nonce").size()||(o.requestCardNonce(),!1)}),e("form#order_review").on("submit",function(r){return e(".payment_method_square .woocommerce-error").remove(),!e("#payment_method_square").is(":checked")||0!==e("input.square-nonce").size()||(o.requestCardNonce(),!1)}),e(document.body).on("checkout_error",function(){e("input.square-nonce").remove()}),setTimeout(function(){e("#payment_method_square").is(":checked")||e(".payment_box.payment_method_square").css({display:"none",visibility:"visible",height:"auto"})},1e3))}},e.wc_square_payments.init()}(jQuery);
changelog.txt CHANGED
@@ -1,5 +1,13 @@
1
  *** WooCommerce Square Changelog ***
2
 
 
 
 
 
 
 
 
 
3
  2018-01-29 - version 1.0.26
4
  * Fix - Call to undefined method causes error.
5
 
1
  *** WooCommerce Square Changelog ***
2
 
3
+ 2018-02-19 - version 1.0.27
4
+ * Fix - In some cases request timeouts are not set long enough causing timeout errors.
5
+ * Fix - Square to WC sync sets products with 0 quantity to In Stock.
6
+ * Fix - Potential issue with Square to WC sync when response is not an array.
7
+ * Fix - When description is more than 4095 characters, sync fails to Square.
8
+ * Fix - Add checks to product object before scheduling an event to prevent errors in cron job.
9
+ * Fix - Add check to prevent auto inventory poll from running when a manual sync is in progress.
10
+
11
  2018-01-29 - version 1.0.26
12
  * Fix - Call to undefined method causes error.
13
 
includes/admin/class-wc-square-bulk-sync-handler.php CHANGED
@@ -25,6 +25,18 @@ class WC_Square_Bulk_Sync_Handler {
25
  add_action( 'wp_ajax_wc_to_square', array( $this, 'wc_to_square_ajax' ) );
26
  }
27
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  /**
29
  * Process Square to WC ajax
30
  *
@@ -35,6 +47,8 @@ class WC_Square_Bulk_Sync_Handler {
35
  public function square_to_wc_ajax() {
36
  check_ajax_referer( 'square-sync', 'security' );
37
 
 
 
38
  /**
39
  * Fires if a valid bulk Square to WC sync is being processed.
40
  *
@@ -64,9 +78,7 @@ class WC_Square_Bulk_Sync_Handler {
64
  // if a WC to Square process still needs to be completed reset the caches
65
  // as the two processes ( WC -> Square and Square -> WC ) use the same cache
66
  if ( 'wc_to_square' === get_transient( 'sq_wc_sync_current_process' ) ) {
67
-
68
- $this->connect->delete_all_caches();
69
-
70
  }
71
 
72
  // set Square->WC as the current active process
@@ -97,7 +109,7 @@ class WC_Square_Bulk_Sync_Handler {
97
  // run this only on first process
98
  if ( $process === 0 ) {
99
  $square_items = $this->connect->get_square_products();
100
- $square_item_ids = ! empty( $square_items ) ? array_unique( wp_list_pluck( $square_items, 'id' ) ) : array();
101
 
102
  // cache it
103
  set_transient( 'wc_square_processing_total_count', count( $square_item_ids ), $cache_age );
@@ -138,7 +150,7 @@ class WC_Square_Bulk_Sync_Handler {
138
  $this->send_sync_email( $emails, __( 'Sync Completed', 'woocommerce-square' ) );
139
 
140
  // reset the processed ids
141
- $this->connect->delete_all_caches();
142
 
143
  $message = __( 'Sync completed', 'woocommerce-square' );
144
  }
@@ -157,6 +169,8 @@ class WC_Square_Bulk_Sync_Handler {
157
  public function wc_to_square_ajax() {
158
  check_ajax_referer( 'square-sync', 'security' );
159
 
 
 
160
  $settings = get_option( 'woocommerce_squareconnect_settings' );
161
  $emails = ! empty( $settings['sync_email'] ) ? $settings['sync_email'] : '';
162
 
@@ -179,9 +193,7 @@ class WC_Square_Bulk_Sync_Handler {
179
  // if a Square to WC process still needs to be completed reset the caches
180
  // as the two processes ( WC -> Square and Square -> WC ) use the same cache
181
  if ( 'square_to_wc' === get_transient( 'sq_wc_sync_current_process' ) ) {
182
-
183
- $this->connect->delete_all_caches();
184
-
185
  }
186
 
187
  // set WC->Square as the current active process
@@ -242,7 +254,7 @@ class WC_Square_Bulk_Sync_Handler {
242
  $this->send_sync_email( $emails, __( 'Sync Completed', 'woocommerce-square' ) );
243
 
244
  // reset the processed ids
245
- $this->connect->delete_all_caches();
246
 
247
  $message = __( 'Sync completed', 'woocommerce-square' );
248
  }
25
  add_action( 'wp_ajax_wc_to_square', array( $this, 'wc_to_square_ajax' ) );
26
  }
27
 
28
+ /**
29
+ * Sets manual sync processing flag to prevent
30
+ * other processes from running such as inventory
31
+ * polling.
32
+ *
33
+ * @since 1.0.27
34
+ */
35
+ public function sync_processing() {
36
+ $cache_age = apply_filters( 'woocommerce_square_manual_sync_processing_cache', 2 * HOUR_IN_SECONDS );
37
+ set_transient( 'wc_square_manual_sync_processing', 'yes', $cache_age );
38
+ }
39
+
40
  /**
41
  * Process Square to WC ajax
42
  *
47
  public function square_to_wc_ajax() {
48
  check_ajax_referer( 'square-sync', 'security' );
49
 
50
+ $this->sync_processing();
51
+
52
  /**
53
  * Fires if a valid bulk Square to WC sync is being processed.
54
  *
78
  // if a WC to Square process still needs to be completed reset the caches
79
  // as the two processes ( WC -> Square and Square -> WC ) use the same cache
80
  if ( 'wc_to_square' === get_transient( 'sq_wc_sync_current_process' ) ) {
81
+ WC_Square_Utils::delete_transients();
 
 
82
  }
83
 
84
  // set Square->WC as the current active process
109
  // run this only on first process
110
  if ( $process === 0 ) {
111
  $square_items = $this->connect->get_square_products();
112
+ $square_item_ids = ! empty( $square_items ) ? array_unique( wp_list_pluck( (array) $square_items, 'id' ) ) : array();
113
 
114
  // cache it
115
  set_transient( 'wc_square_processing_total_count', count( $square_item_ids ), $cache_age );
150
  $this->send_sync_email( $emails, __( 'Sync Completed', 'woocommerce-square' ) );
151
 
152
  // reset the processed ids
153
+ WC_Square_Utils::delete_transients();
154
 
155
  $message = __( 'Sync completed', 'woocommerce-square' );
156
  }
169
  public function wc_to_square_ajax() {
170
  check_ajax_referer( 'square-sync', 'security' );
171
 
172
+ $this->sync_processing();
173
+
174
  $settings = get_option( 'woocommerce_squareconnect_settings' );
175
  $emails = ! empty( $settings['sync_email'] ) ? $settings['sync_email'] : '';
176
 
193
  // if a Square to WC process still needs to be completed reset the caches
194
  // as the two processes ( WC -> Square and Square -> WC ) use the same cache
195
  if ( 'square_to_wc' === get_transient( 'sq_wc_sync_current_process' ) ) {
196
+ WC_Square_Utils::delete_transients();
 
 
197
  }
198
 
199
  // set WC->Square as the current active process
254
  $this->send_sync_email( $emails, __( 'Sync Completed', 'woocommerce-square' ) );
255
 
256
  // reset the processed ids
257
+ WC_Square_Utils::delete_transients();
258
 
259
  $message = __( 'Sync completed', 'woocommerce-square' );
260
  }
includes/class-wc-square-client.php CHANGED
@@ -124,7 +124,7 @@ class WC_Square_Client {
124
  'Content-Type' => 'application/json',
125
  ),
126
  'user-agent' => 'WooCommerceSquare/' . WC_SQUARE_VERSION . '; ' . get_bloginfo( 'url' ),
127
- 'timeout' => 0,
128
  'httpversion' => '1.1',
129
  );
130
 
124
  'Content-Type' => 'application/json',
125
  ),
126
  'user-agent' => 'WooCommerceSquare/' . WC_SQUARE_VERSION . '; ' . get_bloginfo( 'url' ),
127
+ 'timeout' => 45,
128
  'httpversion' => '1.1',
129
  );
130
 
includes/class-wc-square-connect.php CHANGED
@@ -54,7 +54,7 @@ class WC_Square_Connect {
54
  */
55
  public function add_debug_tool( $tools ) {
56
  if ( ! empty( $_GET['action'] ) && 'wcsquare_clear_transients' === $_GET['action'] && version_compare( WC_VERSION, '3.0', '<' ) ) {
57
- $this->delete_all_caches();
58
 
59
  echo '<div class="updated"><p>' . esc_html__( 'Square Sync Transients Cleared', 'woocommerce-square' ) . '</p></div>';
60
  }
@@ -72,31 +72,6 @@ class WC_Square_Connect {
72
  return $tools;
73
  }
74
 
75
- /**
76
- * Deletes cached data ( both Square and WC )
77
- *
78
- * @access public
79
- * @since 1.0.5
80
- * @version 1.0.14
81
- * @return bool
82
- */
83
- public function delete_all_caches() {
84
-
85
- delete_transient( 'wc_square_processing_total_count' );
86
-
87
- delete_transient( 'wc_square_processing_ids' );
88
-
89
- delete_transient( 'wc_square_syncing_square_inventory' );
90
-
91
- delete_transient( 'sq_wc_sync_current_process' );
92
-
93
- delete_transient( 'wc_square_inventory' );
94
-
95
- delete_transient( 'wc_square_polling' );
96
-
97
- return true;
98
- }
99
-
100
  /**
101
  * Checks to see if token is valid.
102
  *
54
  */
55
  public function add_debug_tool( $tools ) {
56
  if ( ! empty( $_GET['action'] ) && 'wcsquare_clear_transients' === $_GET['action'] && version_compare( WC_VERSION, '3.0', '<' ) ) {
57
+ WC_Square_Utils::delete_transients();
58
 
59
  echo '<div class="updated"><p>' . esc_html__( 'Square Sync Transients Cleared', 'woocommerce-square' ) . '</p></div>';
60
  }
72
  return $tools;
73
  }
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  /**
76
  * Checks to see if token is valid.
77
  *
includes/class-wc-square-inventory-poll.php CHANGED
@@ -40,9 +40,10 @@ class WC_Square_Inventory_Poll {
40
  }
41
 
42
  public function sync() {
43
- $sync = ( 'yes' === $this->integration->get_option( 'inventory_polling' ) );
 
44
 
45
- if ( $sync ) {
46
  $this->to_wc->sync_all_inventory();
47
  }
48
  }
40
  }
41
 
42
  public function sync() {
43
+ $sync = ( 'yes' === $this->integration->get_option( 'inventory_polling' ) );
44
+ $manual_sync_processing = get_transient( 'wc_square_manual_sync_processing' );
45
 
46
+ if ( $sync && ! $manual_sync_processing ) {
47
  $this->to_wc->sync_all_inventory();
48
  }
49
  }
includes/class-wc-square-sync-to-square-wp-hooks.php CHANGED
@@ -145,7 +145,7 @@ class WC_Square_Sync_To_Square_WordPress_Hooks {
145
  $this->square->sync_product( $wc_product, $this->sync_categories, $this->sync_inventory, $this->sync_images );
146
  }
147
 
148
- $this->delete_all_caches();
149
 
150
  if ( version_compare( WC_VERSION, '3.0.0', '<' ) ) {
151
  add_action( 'save_post', array( $this, 'pre_wc_30_on_save_post' ), 10, 2 );
@@ -237,6 +237,10 @@ class WC_Square_Sync_To_Square_WordPress_Hooks {
237
  * @version 1.0.16
238
  */
239
  public function schedule_on_product_set_stock( WC_Product $wc_product ) {
 
 
 
 
240
  $args = array(
241
  $wc_product,
242
  uniqid(), // this is needed due to WP not scheduling new events with same name and args
@@ -256,6 +260,10 @@ class WC_Square_Sync_To_Square_WordPress_Hooks {
256
  * @version 1.0.16
257
  */
258
  public function schedule_on_variation_set_stock( WC_Product_Variation $wc_variation ) {
 
 
 
 
259
  $args = array(
260
  $wc_variation,
261
  uniqid(), // this is needed due to WP not scheduling new events with same name and args
@@ -286,27 +294,4 @@ class WC_Square_Sync_To_Square_WordPress_Hooks {
286
  $product = version_compare( WC_VERSION, '3.0.0', '<' ) ? $wc_variation->parent : wc_get_product( $wc_variation->get_parent_id() );
287
  $this->square->sync_inventory( $product );
288
  }
289
-
290
- /**
291
- * Deletes cached data ( both Square and WC )
292
- *
293
- * @access public
294
- * @since 1.0.14
295
- * @version 1.0.14
296
- * @return bool
297
- */
298
- public function delete_all_caches() {
299
-
300
- delete_transient( 'wc_square_processing_total_count' );
301
-
302
- delete_transient( 'wc_square_processing_ids' );
303
-
304
- delete_transient( 'wc_square_syncing_square_inventory' );
305
-
306
- delete_transient( 'sq_wc_sync_current_process' );
307
-
308
- delete_transient( 'wc_square_inventory' );
309
-
310
- return true;
311
- }
312
  }
145
  $this->square->sync_product( $wc_product, $this->sync_categories, $this->sync_inventory, $this->sync_images );
146
  }
147
 
148
+ WC_Square_Utils::delete_transients();
149
 
150
  if ( version_compare( WC_VERSION, '3.0.0', '<' ) ) {
151
  add_action( 'save_post', array( $this, 'pre_wc_30_on_save_post' ), 10, 2 );
237
  * @version 1.0.16
238
  */
239
  public function schedule_on_product_set_stock( WC_Product $wc_product ) {
240
+ if ( ! is_object( $wc_product ) || empty( $wc_product ) ) {
241
+ return;
242
+ }
243
+
244
  $args = array(
245
  $wc_product,
246
  uniqid(), // this is needed due to WP not scheduling new events with same name and args
260
  * @version 1.0.16
261
  */
262
  public function schedule_on_variation_set_stock( WC_Product_Variation $wc_variation ) {
263
+ if ( ! is_object( $wc_variation ) || empty( $wc_variation ) ) {
264
+ return;
265
+ }
266
+
267
  $args = array(
268
  $wc_variation,
269
  uniqid(), // this is needed due to WP not scheduling new events with same name and args
294
  $product = version_compare( WC_VERSION, '3.0.0', '<' ) ? $wc_variation->parent : wc_get_product( $wc_variation->get_parent_id() );
295
  $this->square->sync_inventory( $product );
296
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
  }
includes/class-wc-square-sync-to-square.php CHANGED
@@ -297,6 +297,15 @@ class WC_Square_Sync_To_Square {
297
  * @return object|bool Updated Square Item object on success, boolean False on failure.
298
  */
299
  public function update_product( WC_Product $wc_product, $square_item, $include_category = false, $include_inventory = false ) {
 
 
 
 
 
 
 
 
 
300
 
301
  $square_item = $this->connect->update_square_product( $wc_product, $square_item->id, $include_category, $include_inventory );
302
 
297
  * @return object|bool Updated Square Item object on success, boolean False on failure.
298
  */
299
  public function update_product( WC_Product $wc_product, $square_item, $include_category = false, $include_inventory = false ) {
300
+ if ( empty( $square_item ) || empty( $square_item->id ) ) {
301
+ WC_Square_Sync_Logger::log( sprintf( '[WC -> Square] Error updating Square Item ID N/A (WC Product %d).', version_compare( WC_VERSION, '3.0.0', '<' ) ? $wc_product->id : $wc_product->get_id() ) );
302
+ return false;
303
+ }
304
+
305
+ if ( empty( $wc_product ) ) {
306
+ WC_Square_Sync_Logger::log( sprintf( '[WC -> Square] Error updating Square Item ID %s (WC Product N/A).', $square_item->id ) );
307
+ return false;
308
+ }
309
 
310
  $square_item = $this->connect->update_square_product( $wc_product, $square_item->id, $include_category, $include_inventory );
311
 
includes/class-wc-square-utils.php CHANGED
@@ -63,6 +63,19 @@ class WC_Square_Utils {
63
 
64
  }
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  /**
67
  * Convert a WC Product into a Square Item for Update
68
  *
@@ -77,7 +90,7 @@ class WC_Square_Utils {
77
 
78
  $formatted = array(
79
  'name' => $wc_product->get_title(),
80
- 'description' => wp_strip_all_tags( version_compare( WC_VERSION, '3.0.0', '<' ) ? $wc_product->post->post_content : $wc_product->get_description() ),
81
  'visibility' => 'PUBLIC',
82
  );
83
 
@@ -913,6 +926,8 @@ class WC_Square_Utils {
913
 
914
  delete_transient( 'wc_square_polling' );
915
 
 
 
916
  return true;
917
  }
918
  }
63
 
64
  }
65
 
66
+ /**
67
+ * Normalize description text to Square
68
+ * Square expects no HTML to be in the description and
69
+ * the limit of characters is 4095.
70
+ *
71
+ * @since 1.0.27
72
+ * @param mixed $description
73
+ * @return string
74
+ */
75
+ public static function normalize_description( $description = '' ) {
76
+ return substr( wp_strip_all_tags( $description ), 0, 4095 );
77
+ }
78
+
79
  /**
80
  * Convert a WC Product into a Square Item for Update
81
  *
90
 
91
  $formatted = array(
92
  'name' => $wc_product->get_title(),
93
+ 'description' => self::normalize_description( version_compare( WC_VERSION, '3.0.0', '<' ) ? $wc_product->post->post_content : $wc_product->get_description() ),
94
  'visibility' => 'PUBLIC',
95
  );
96
 
926
 
927
  delete_transient( 'wc_square_polling' );
928
 
929
+ delete_transient( 'wc_square_manual_sync_processing' );
930
+
931
  return true;
932
  }
933
  }
includes/class-wc-square-wc-products.php CHANGED
@@ -70,7 +70,7 @@ class WC_Square_WC_Products {
70
 
71
  // Validate ID
72
  if ( empty( $id ) ) {
73
- return new WP_Error( "woocommerce_api_invalid_{$resource_name}_id", sprintf( __( 'Invalid %s ID', 'woocommerce' ), $type ), array( 'status' => 404 ) );
74
  }
75
 
76
  // Only custom post types have per-post type/permission checks
@@ -79,7 +79,7 @@ class WC_Square_WC_Products {
79
  $post = get_post( $id );
80
 
81
  if ( null === $post ) {
82
- return new WP_Error( "woocommerce_api_no_{$resource_name}_found", sprintf( __( 'No %1$s found with the ID equal to %2$s', 'woocommerce' ), $resource_name, $id ), array( 'status' => 404 ) );
83
  }
84
 
85
  // For checking permissions, product variations are the same as the product post type
@@ -87,7 +87,7 @@ class WC_Square_WC_Products {
87
 
88
  // Validate post type
89
  if ( $type !== $post_type ) {
90
- return new WP_Error( "woocommerce_api_invalid_{$resource_name}", sprintf( __( 'Invalid %s', 'woocommerce' ), $resource_name ), array( 'status' => 404 ) );
91
  }
92
 
93
  // Validate permissions
@@ -95,19 +95,19 @@ class WC_Square_WC_Products {
95
 
96
  case 'read':
97
  if ( ! $this->is_readable( $post ) ) {
98
- return new WP_Error( "woocommerce_api_user_cannot_read_{$resource_name}", sprintf( __( 'You do not have permission to read this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) );
99
  }
100
  break;
101
 
102
  case 'edit':
103
  if ( ! $this->is_editable( $post ) ) {
104
- return new WP_Error( "woocommerce_api_user_cannot_edit_{$resource_name}", sprintf( __( 'You do not have permission to edit this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) );
105
  }
106
  break;
107
 
108
  case 'delete':
109
  if ( ! $this->is_deletable( $post ) ) {
110
- return new WP_Error( "woocommerce_api_user_cannot_delete_{$resource_name}", sprintf( __( 'You do not have permission to delete this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) );
111
  }
112
  break;
113
  }
@@ -246,21 +246,21 @@ class WC_Square_WC_Products {
246
 
247
  try {
248
  if ( ! isset( $data['product'] ) ) {
249
- throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'product' ), 400 );
250
  }
251
 
252
  $data = $data['product'];
253
 
254
  // Check permissions.
255
  if ( ! current_user_can( 'publish_products' ) ) {
256
- throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_create_product', __( 'You do not have permission to create products', 'woocommerce' ), 401 );
257
  }
258
 
259
  $data = apply_filters( 'woocommerce_api_create_product_data', $data, $this );
260
 
261
  // Check if product title is specified.
262
  if ( ! isset( $data['title'] ) ) {
263
- throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_title', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'title' ), 400 );
264
  }
265
 
266
  // Check product type.
@@ -275,7 +275,7 @@ class WC_Square_WC_Products {
275
 
276
  // Validate the product type.
277
  if ( ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_product_types() ) ) ) {
278
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_type', sprintf( __( 'Invalid product type - the product type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_product_types() ) ) ), 400 );
279
  }
280
 
281
  // Enable description html tags.
@@ -351,7 +351,7 @@ class WC_Square_WC_Products {
351
  public function edit_product( $id, $data ) {
352
  try {
353
  if ( ! isset( $data['product'] ) ) {
354
- throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'product' ), 400 );
355
  }
356
 
357
  $data = $data['product'];
@@ -402,7 +402,7 @@ class WC_Square_WC_Products {
402
 
403
  // Validate the product type.
404
  if ( isset( $data['type'] ) && ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_product_types() ) ) ) {
405
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_type', sprintf( __( 'Invalid product type - the product type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_product_types() ) ) ), 400 );
406
  }
407
 
408
  // Check for featured/gallery images, upload it and set it.
@@ -447,7 +447,7 @@ class WC_Square_WC_Products {
447
  try {
448
  // Permissions check
449
  if ( ! current_user_can( 'manage_product_terms' ) ) {
450
- throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_read_product_categories', __( 'You do not have permission to read product categories', 'woocommerce' ), 401 );
451
  }
452
 
453
  $product_categories = array();
@@ -478,18 +478,18 @@ class WC_Square_WC_Products {
478
 
479
  // Validate ID
480
  if ( empty( $id ) ) {
481
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_category_id', __( 'Invalid product category ID', 'woocommerce' ), 400 );
482
  }
483
 
484
  // Permissions check
485
  if ( ! current_user_can( 'manage_product_terms' ) ) {
486
- throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_read_product_categories', __( 'You do not have permission to read product categories', 'woocommerce' ), 401 );
487
  }
488
 
489
  $term = get_term( $id, 'product_cat' );
490
 
491
  if ( is_wp_error( $term ) || is_null( $term ) ) {
492
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_category_id', __( 'A product category with the provided ID could not be found', 'woocommerce' ), 404 );
493
  }
494
 
495
  $term_id = intval( $term->term_id );
@@ -533,12 +533,12 @@ class WC_Square_WC_Products {
533
 
534
  try {
535
  if ( ! isset( $data['product_category'] ) ) {
536
- throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_category_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'product_category' ), 400 );
537
  }
538
 
539
  // Check permissions
540
  if ( ! current_user_can( 'manage_product_terms' ) ) {
541
- throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_create_product_category', __( 'You do not have permission to create product categories', 'woocommerce' ), 401 );
542
  }
543
 
544
  $defaults = array(
@@ -558,7 +558,7 @@ class WC_Square_WC_Products {
558
  if ( $data['parent'] ) {
559
  $parent = get_term_by( 'id', $data['parent'], 'product_cat' );
560
  if ( ! $parent ) {
561
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_category_parent', __( 'Product category parent is invalid', 'woocommerce' ), 400 );
562
  }
563
  }
564
 
@@ -608,7 +608,7 @@ class WC_Square_WC_Products {
608
 
609
  try {
610
  if ( ! isset( $data['product_category'] ) ) {
611
- throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_category', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'product_category' ), 400 );
612
  }
613
 
614
  $id = absint( $id );
@@ -616,7 +616,7 @@ class WC_Square_WC_Products {
616
 
617
  // Check permissions.
618
  if ( ! current_user_can( 'manage_product_terms' ) ) {
619
- throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_edit_product_category', __( 'You do not have permission to edit product categories', 'woocommerce' ), 401 );
620
  }
621
 
622
  $data = apply_filters( 'woocommerce_api_edit_product_category_data', $data, $this );
@@ -646,7 +646,7 @@ class WC_Square_WC_Products {
646
 
647
  $update = wp_update_term( $id, 'product_cat', $data );
648
  if ( is_wp_error( $update ) ) {
649
- throw new WC_Square_API_Exception( 'woocommerce_api_cannot_edit_product_catgory', __( 'Could not edit the category', 'woocommerce' ), 400 );
650
  }
651
 
652
  if ( ! empty( $data['display'] ) ) {
@@ -923,7 +923,7 @@ class WC_Square_WC_Products {
923
  if ( ! empty( $new_sku ) ) {
924
  $unique_sku = wc_product_has_unique_sku( $product_id, $new_sku );
925
  if ( ! $unique_sku ) {
926
- throw new WC_Square_API_Exception( 'woocommerce_api_product_sku_already_exists', __( 'The SKU already exists on another product', 'woocommerce' ), 400 );
927
  } else {
928
  update_post_meta( $product_id, '_sku', $new_sku );
929
  }
@@ -1141,6 +1141,9 @@ class WC_Square_WC_Products {
1141
  update_post_meta( $product_id, '_backorders', $backorders );
1142
  } else {
1143
  $backorders = get_post_meta( $product_id, '_backorders', true );
 
 
 
1144
  }
1145
 
1146
  if ( 'grouped' === $product_type ) {
@@ -1316,7 +1319,7 @@ class WC_Square_WC_Products {
1316
  }
1317
 
1318
  // Generate a useful post title
1319
- $variation_post_title = sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce' ), $variation_id, esc_html( get_the_title( $id ) ) );
1320
 
1321
  // Update or Add post
1322
  if ( ! $variation_id ) {
@@ -1363,7 +1366,7 @@ class WC_Square_WC_Products {
1363
  if ( ! empty( $new_sku ) ) {
1364
  $unique_sku = wc_product_has_unique_sku( $variation_id, $new_sku );
1365
  if ( ! $unique_sku ) {
1366
- throw new WC_Square_API_Exception( 'woocommerce_api_product_sku_already_exists', __( 'The SKU already exists on another product', 'woocommerce' ), 400 );
1367
  } else {
1368
  update_post_meta( $variation_id, '_sku', $new_sku );
1369
  }
@@ -1819,8 +1822,8 @@ class WC_Square_WC_Products {
1819
  'created_at' => $this->format_datetime( time() ), // Default to now
1820
  'updated_at' => $this->format_datetime( time() ),
1821
  'src' => wc_placeholder_img_src(),
1822
- 'title' => __( 'Placeholder', 'woocommerce' ),
1823
- 'alt' => __( 'Placeholder', 'woocommerce' ),
1824
  'position' => 0,
1825
  );
1826
  }
@@ -1941,7 +1944,7 @@ class WC_Square_WC_Products {
1941
 
1942
  // Check parsed URL.
1943
  if ( ! $parsed_url || ! is_array( $parsed_url ) ) {
1944
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_' . $upload_for, sprintf( __( 'Invalid URL %s', 'woocommerce' ), $image_url ), 400 );
1945
  }
1946
 
1947
  // Ensure url is valid.
@@ -1949,13 +1952,13 @@ class WC_Square_WC_Products {
1949
 
1950
  // Get the file.
1951
  $response = wp_safe_remote_get( $image_url, array(
1952
- 'timeout' => 10,
1953
  ) );
1954
 
1955
  if ( is_wp_error( $response ) ) {
1956
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_remote_' . $upload_for, sprintf( __( 'Error getting remote image %s.', 'woocommerce' ), $image_url ) . ' ' . sprintf( __( 'Error: %s.', 'woocommerce' ), $response->get_error_message() ), 400 );
1957
  } elseif ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
1958
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_remote_' . $upload_for, sprintf( __( 'Error getting remote image %s.', 'woocommerce' ), $image_url ), 400 );
1959
  }
1960
 
1961
  // Ensure we have a file name and type.
@@ -1976,7 +1979,7 @@ class WC_Square_WC_Products {
1976
  $wp_filetype = wp_check_filetype( $file_name, wc_rest_allowed_image_mime_types() );
1977
 
1978
  if ( ! $wp_filetype['type'] ) {
1979
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_' . $upload_for, __( 'Invalid image type.', 'woocommerce' ), 400 );
1980
  }
1981
  }
1982
 
@@ -1993,7 +1996,7 @@ class WC_Square_WC_Products {
1993
  if ( 0 == $filesize ) {
1994
  @unlink( $upload['file'] );
1995
  unset( $upload );
1996
- throw new WC_Square_API_Exception( 'woocommerce_api_' . $upload_for . '_upload_file_error', __( 'Zero size file downloaded', 'woocommerce' ), 400 );
1997
  }
1998
 
1999
  unset( $response );
@@ -2159,7 +2162,7 @@ class WC_Square_WC_Products {
2159
  try {
2160
  // Permissions check.
2161
  if ( ! current_user_can( 'manage_product_terms' ) ) {
2162
- throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_read_product_attributes', __( 'You do not have permission to read product attributes', 'woocommerce' ), 401 );
2163
  }
2164
 
2165
  $product_attributes = array();
@@ -2198,12 +2201,12 @@ class WC_Square_WC_Products {
2198
 
2199
  // Validate ID
2200
  if ( empty( $id ) ) {
2201
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'Invalid product attribute ID', 'woocommerce' ), 400 );
2202
  }
2203
 
2204
  // Permissions check
2205
  if ( ! current_user_can( 'manage_product_terms' ) ) {
2206
- throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_read_product_attributes', __( 'You do not have permission to read product attributes', 'woocommerce' ), 401 );
2207
  }
2208
 
2209
  $attribute = $wpdb->get_row( $wpdb->prepare( "
@@ -2213,7 +2216,7 @@ class WC_Square_WC_Products {
2213
  ", $id ) );
2214
 
2215
  if ( is_wp_error( $attribute ) || is_null( $attribute ) ) {
2216
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'A product attribute with the provided ID could not be found', 'woocommerce' ), 404 );
2217
  }
2218
 
2219
  $product_attribute = array(
@@ -2245,25 +2248,25 @@ class WC_Square_WC_Products {
2245
  */
2246
  protected function validate_attribute_data( $name, $slug, $type, $order_by, $new_data = true ) {
2247
  if ( empty( $name ) ) {
2248
- throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_attribute_name', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'name' ), 400 );
2249
  }
2250
 
2251
  if ( strlen( $slug ) >= 28 ) {
2252
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), 400 );
2253
  } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) {
2254
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), 400 );
2255
  } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) {
2256
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), 400 );
2257
  }
2258
 
2259
  // Validate the attribute type
2260
  if ( ! in_array( wc_clean( $type ), array_keys( wc_get_attribute_types() ) ) ) {
2261
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_type', sprintf( __( 'Invalid product attribute type - the product attribute type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_attribute_types() ) ) ), 400 );
2262
  }
2263
 
2264
  // Validate the attribute order by
2265
  if ( ! in_array( wc_clean( $order_by ), array( 'menu_order', 'name', 'name_num', 'id' ) ) ) {
2266
- throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_order_by', sprintf( __( 'Invalid product attribute order_by type - the product attribute order_by type must be any of these: %s', 'woocommerce' ), implode( ', ', array( 'menu_order', 'name', 'name_num', 'id' ) ) ), 400 );
2267
  }
2268
 
2269
  return true;
@@ -2281,14 +2284,14 @@ class WC_Square_WC_Products {
2281
 
2282
  try {
2283
  if ( ! isset( $data['product_attribute'] ) ) {
2284
- throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_attribute_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'product_attribute' ), 400 );
2285
  }
2286
 
2287
  $data = $data['product_attribute'];
2288
 
2289
  // Check permissions.
2290
  if ( ! current_user_can( 'manage_product_terms' ) ) {
2291
- throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_create_product_attribute', __( 'You do not have permission to create product attributes', 'woocommerce' ), 401 );
2292
  }
2293
 
2294
  $data = apply_filters( 'woocommerce_api_create_product_attribute_data', $data, $this );
70
 
71
  // Validate ID
72
  if ( empty( $id ) ) {
73
+ return new WP_Error( "woocommerce_api_invalid_{$resource_name}_id", sprintf( __( 'Invalid %s ID', 'woocommerce-square' ), $type ), array( 'status' => 404 ) );
74
  }
75
 
76
  // Only custom post types have per-post type/permission checks
79
  $post = get_post( $id );
80
 
81
  if ( null === $post ) {
82
+ return new WP_Error( "woocommerce_api_no_{$resource_name}_found", sprintf( __( 'No %1$s found with the ID equal to %2$s', 'woocommerce-square' ), $resource_name, $id ), array( 'status' => 404 ) );
83
  }
84
 
85
  // For checking permissions, product variations are the same as the product post type
87
 
88
  // Validate post type
89
  if ( $type !== $post_type ) {
90
+ return new WP_Error( "woocommerce_api_invalid_{$resource_name}", sprintf( __( 'Invalid %s', 'woocommerce-square' ), $resource_name ), array( 'status' => 404 ) );
91
  }
92
 
93
  // Validate permissions
95
 
96
  case 'read':
97
  if ( ! $this->is_readable( $post ) ) {
98
+ return new WP_Error( "woocommerce_api_user_cannot_read_{$resource_name}", sprintf( __( 'You do not have permission to read this %s', 'woocommerce-square' ), $resource_name ), array( 'status' => 401 ) );
99
  }
100
  break;
101
 
102
  case 'edit':
103
  if ( ! $this->is_editable( $post ) ) {
104
+ return new WP_Error( "woocommerce_api_user_cannot_edit_{$resource_name}", sprintf( __( 'You do not have permission to edit this %s', 'woocommerce-square' ), $resource_name ), array( 'status' => 401 ) );
105
  }
106
  break;
107
 
108
  case 'delete':
109
  if ( ! $this->is_deletable( $post ) ) {
110
+ return new WP_Error( "woocommerce_api_user_cannot_delete_{$resource_name}", sprintf( __( 'You do not have permission to delete this %s', 'woocommerce-square' ), $resource_name ), array( 'status' => 401 ) );
111
  }
112
  break;
113
  }
246
 
247
  try {
248
  if ( ! isset( $data['product'] ) ) {
249
+ throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce-square' ), 'product' ), 400 );
250
  }
251
 
252
  $data = $data['product'];
253
 
254
  // Check permissions.
255
  if ( ! current_user_can( 'publish_products' ) ) {
256
+ throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_create_product', __( 'You do not have permission to create products', 'woocommerce-square' ), 401 );
257
  }
258
 
259
  $data = apply_filters( 'woocommerce_api_create_product_data', $data, $this );
260
 
261
  // Check if product title is specified.
262
  if ( ! isset( $data['title'] ) ) {
263
+ throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_title', sprintf( __( 'Missing parameter %s', 'woocommerce-square' ), 'title' ), 400 );
264
  }
265
 
266
  // Check product type.
275
 
276
  // Validate the product type.
277
  if ( ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_product_types() ) ) ) {
278
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_type', sprintf( __( 'Invalid product type - the product type must be any of these: %s', 'woocommerce-square' ), implode( ', ', array_keys( wc_get_product_types() ) ) ), 400 );
279
  }
280
 
281
  // Enable description html tags.
351
  public function edit_product( $id, $data ) {
352
  try {
353
  if ( ! isset( $data['product'] ) ) {
354
+ throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce-square' ), 'product' ), 400 );
355
  }
356
 
357
  $data = $data['product'];
402
 
403
  // Validate the product type.
404
  if ( isset( $data['type'] ) && ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_product_types() ) ) ) {
405
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_type', sprintf( __( 'Invalid product type - the product type must be any of these: %s', 'woocommerce-square' ), implode( ', ', array_keys( wc_get_product_types() ) ) ), 400 );
406
  }
407
 
408
  // Check for featured/gallery images, upload it and set it.
447
  try {
448
  // Permissions check
449
  if ( ! current_user_can( 'manage_product_terms' ) ) {
450
+ throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_read_product_categories', __( 'You do not have permission to read product categories', 'woocommerce-square' ), 401 );
451
  }
452
 
453
  $product_categories = array();
478
 
479
  // Validate ID
480
  if ( empty( $id ) ) {
481
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_category_id', __( 'Invalid product category ID', 'woocommerce-square' ), 400 );
482
  }
483
 
484
  // Permissions check
485
  if ( ! current_user_can( 'manage_product_terms' ) ) {
486
+ throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_read_product_categories', __( 'You do not have permission to read product categories', 'woocommerce-square' ), 401 );
487
  }
488
 
489
  $term = get_term( $id, 'product_cat' );
490
 
491
  if ( is_wp_error( $term ) || is_null( $term ) ) {
492
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_category_id', __( 'A product category with the provided ID could not be found', 'woocommerce-square' ), 404 );
493
  }
494
 
495
  $term_id = intval( $term->term_id );
533
 
534
  try {
535
  if ( ! isset( $data['product_category'] ) ) {
536
+ throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_category_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce-square' ), 'product_category' ), 400 );
537
  }
538
 
539
  // Check permissions
540
  if ( ! current_user_can( 'manage_product_terms' ) ) {
541
+ throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_create_product_category', __( 'You do not have permission to create product categories', 'woocommerce-square' ), 401 );
542
  }
543
 
544
  $defaults = array(
558
  if ( $data['parent'] ) {
559
  $parent = get_term_by( 'id', $data['parent'], 'product_cat' );
560
  if ( ! $parent ) {
561
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_category_parent', __( 'Product category parent is invalid', 'woocommerce-square' ), 400 );
562
  }
563
  }
564
 
608
 
609
  try {
610
  if ( ! isset( $data['product_category'] ) ) {
611
+ throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_category', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce-square' ), 'product_category' ), 400 );
612
  }
613
 
614
  $id = absint( $id );
616
 
617
  // Check permissions.
618
  if ( ! current_user_can( 'manage_product_terms' ) ) {
619
+ throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_edit_product_category', __( 'You do not have permission to edit product categories', 'woocommerce-square' ), 401 );
620
  }
621
 
622
  $data = apply_filters( 'woocommerce_api_edit_product_category_data', $data, $this );
646
 
647
  $update = wp_update_term( $id, 'product_cat', $data );
648
  if ( is_wp_error( $update ) ) {
649
+ throw new WC_Square_API_Exception( 'woocommerce_api_cannot_edit_product_catgory', __( 'Could not edit the category', 'woocommerce-square' ), 400 );
650
  }
651
 
652
  if ( ! empty( $data['display'] ) ) {
923
  if ( ! empty( $new_sku ) ) {
924
  $unique_sku = wc_product_has_unique_sku( $product_id, $new_sku );
925
  if ( ! $unique_sku ) {
926
+ throw new WC_Square_API_Exception( 'woocommerce_api_product_sku_already_exists', __( 'The SKU already exists on another product', 'woocommerce-square' ), 400 );
927
  } else {
928
  update_post_meta( $product_id, '_sku', $new_sku );
929
  }
1141
  update_post_meta( $product_id, '_backorders', $backorders );
1142
  } else {
1143
  $backorders = get_post_meta( $product_id, '_backorders', true );
1144
+ if ( '' === $backorders ) {
1145
+ $backorders = 'no';
1146
+ }
1147
  }
1148
 
1149
  if ( 'grouped' === $product_type ) {
1319
  }
1320
 
1321
  // Generate a useful post title
1322
+ $variation_post_title = sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce-square' ), $variation_id, esc_html( get_the_title( $id ) ) );
1323
 
1324
  // Update or Add post
1325
  if ( ! $variation_id ) {
1366
  if ( ! empty( $new_sku ) ) {
1367
  $unique_sku = wc_product_has_unique_sku( $variation_id, $new_sku );
1368
  if ( ! $unique_sku ) {
1369
+ throw new WC_Square_API_Exception( 'woocommerce_api_product_sku_already_exists', __( 'The SKU already exists on another product', 'woocommerce-square' ), 400 );
1370
  } else {
1371
  update_post_meta( $variation_id, '_sku', $new_sku );
1372
  }
1822
  'created_at' => $this->format_datetime( time() ), // Default to now
1823
  'updated_at' => $this->format_datetime( time() ),
1824
  'src' => wc_placeholder_img_src(),
1825
+ 'title' => __( 'Placeholder', 'woocommerce-square' ),
1826
+ 'alt' => __( 'Placeholder', 'woocommerce-square' ),
1827
  'position' => 0,
1828
  );
1829
  }
1944
 
1945
  // Check parsed URL.
1946
  if ( ! $parsed_url || ! is_array( $parsed_url ) ) {
1947
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_' . $upload_for, sprintf( __( 'Invalid URL %s', 'woocommerce-square' ), $image_url ), 400 );
1948
  }
1949
 
1950
  // Ensure url is valid.
1952
 
1953
  // Get the file.
1954
  $response = wp_safe_remote_get( $image_url, array(
1955
+ 'timeout' => 45,
1956
  ) );
1957
 
1958
  if ( is_wp_error( $response ) ) {
1959
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_remote_' . $upload_for, sprintf( __( 'Error getting remote image %s.', 'woocommerce-square' ), $image_url ) . ' ' . sprintf( __( 'Error: %s.', 'woocommerce-square' ), $response->get_error_message() ), 400 );
1960
  } elseif ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
1961
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_remote_' . $upload_for, sprintf( __( 'Error getting remote image %s.', 'woocommerce-square' ), $image_url ), 400 );
1962
  }
1963
 
1964
  // Ensure we have a file name and type.
1979
  $wp_filetype = wp_check_filetype( $file_name, wc_rest_allowed_image_mime_types() );
1980
 
1981
  if ( ! $wp_filetype['type'] ) {
1982
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_' . $upload_for, __( 'Invalid image type.', 'woocommerce-square' ), 400 );
1983
  }
1984
  }
1985
 
1996
  if ( 0 == $filesize ) {
1997
  @unlink( $upload['file'] );
1998
  unset( $upload );
1999
+ throw new WC_Square_API_Exception( 'woocommerce_api_' . $upload_for . '_upload_file_error', __( 'Zero size file downloaded', 'woocommerce-square' ), 400 );
2000
  }
2001
 
2002
  unset( $response );
2162
  try {
2163
  // Permissions check.
2164
  if ( ! current_user_can( 'manage_product_terms' ) ) {
2165
+ throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_read_product_attributes', __( 'You do not have permission to read product attributes', 'woocommerce-square' ), 401 );
2166
  }
2167
 
2168
  $product_attributes = array();
2201
 
2202
  // Validate ID
2203
  if ( empty( $id ) ) {
2204
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'Invalid product attribute ID', 'woocommerce-square' ), 400 );
2205
  }
2206
 
2207
  // Permissions check
2208
  if ( ! current_user_can( 'manage_product_terms' ) ) {
2209
+ throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_read_product_attributes', __( 'You do not have permission to read product attributes', 'woocommerce-square' ), 401 );
2210
  }
2211
 
2212
  $attribute = $wpdb->get_row( $wpdb->prepare( "
2216
  ", $id ) );
2217
 
2218
  if ( is_wp_error( $attribute ) || is_null( $attribute ) ) {
2219
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'A product attribute with the provided ID could not be found', 'woocommerce-square' ), 404 );
2220
  }
2221
 
2222
  $product_attribute = array(
2248
  */
2249
  protected function validate_attribute_data( $name, $slug, $type, $order_by, $new_data = true ) {
2250
  if ( empty( $name ) ) {
2251
+ throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_attribute_name', sprintf( __( 'Missing parameter %s', 'woocommerce-square' ), 'name' ), 400 );
2252
  }
2253
 
2254
  if ( strlen( $slug ) >= 28 ) {
2255
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce-square' ), $slug ), 400 );
2256
  } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) {
2257
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce-square' ), $slug ), 400 );
2258
  } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) {
2259
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce-square' ), $slug ), 400 );
2260
  }
2261
 
2262
  // Validate the attribute type
2263
  if ( ! in_array( wc_clean( $type ), array_keys( wc_get_attribute_types() ) ) ) {
2264
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_type', sprintf( __( 'Invalid product attribute type - the product attribute type must be any of these: %s', 'woocommerce-square' ), implode( ', ', array_keys( wc_get_attribute_types() ) ) ), 400 );
2265
  }
2266
 
2267
  // Validate the attribute order by
2268
  if ( ! in_array( wc_clean( $order_by ), array( 'menu_order', 'name', 'name_num', 'id' ) ) ) {
2269
+ throw new WC_Square_API_Exception( 'woocommerce_api_invalid_product_attribute_order_by', sprintf( __( 'Invalid product attribute order_by type - the product attribute order_by type must be any of these: %s', 'woocommerce-square' ), implode( ', ', array( 'menu_order', 'name', 'name_num', 'id' ) ) ), 400 );
2270
  }
2271
 
2272
  return true;
2284
 
2285
  try {
2286
  if ( ! isset( $data['product_attribute'] ) ) {
2287
+ throw new WC_Square_API_Exception( 'woocommerce_api_missing_product_attribute_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce-square' ), 'product_attribute' ), 400 );
2288
  }
2289
 
2290
  $data = $data['product_attribute'];
2291
 
2292
  // Check permissions.
2293
  if ( ! current_user_can( 'manage_product_terms' ) ) {
2294
+ throw new WC_Square_API_Exception( 'woocommerce_api_user_cannot_create_product_attribute', __( 'You do not have permission to create product attributes', 'woocommerce-square' ), 401 );
2295
  }
2296
 
2297
  $data = apply_filters( 'woocommerce_api_create_product_attribute_data', $data, $this );
languages/woocommerce-square.pot ADDED
@@ -0,0 +1,663 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2018 WooCommerce
2
+ # This file is distributed under the same license as the WooCommerce Square package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: WooCommerce Square 1.0.27\n"
6
+ "Report-Msgid-Bugs-To: "
7
+ "https://github.com/woocommerce/woocommerce-square/issues\n"
8
+ "POT-Creation-Date: 2018-02-19 20:34:24+00:00\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=utf-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "PO-Revision-Date: 2018-MO-DA HO:MI+ZONE\n"
13
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
+ "Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
15
+ "X-Generator: grunt-wp-i18n1.0.1\n"
16
+
17
+ #: includes/admin/class-wc-square-admin-integration.php:20
18
+ #: includes/payment/class-wc-square-gateway.php:16
19
+ msgid "Square"
20
+ msgstr ""
21
+
22
+ #: includes/admin/class-wc-square-admin-integration.php:21
23
+ msgid ""
24
+ "Connect with Square to start syncing your products and inventory and also "
25
+ "accept credit card and debit card payments in your checkout."
26
+ msgstr ""
27
+
28
+ #: includes/admin/class-wc-square-admin-integration.php:53
29
+ msgid "Business Location"
30
+ msgstr ""
31
+
32
+ #: includes/admin/class-wc-square-admin-integration.php:55
33
+ msgid ""
34
+ "Select the location you wish to link to this site. You must have <a "
35
+ "href=\"https://squareup.com/dashboard/locations\" "
36
+ "target=\"_blank\">locations</a> set in Square and approved."
37
+ msgstr ""
38
+
39
+ #: includes/admin/class-wc-square-admin-integration.php:57
40
+ msgid "Select a Location"
41
+ msgstr ""
42
+
43
+ #: includes/admin/class-wc-square-admin-integration.php:61
44
+ msgid "Notification Email"
45
+ msgstr ""
46
+
47
+ #: includes/admin/class-wc-square-admin-integration.php:63
48
+ msgid ""
49
+ "Enter the email(s) to be notified when a sync has ended. Separate each "
50
+ "email with a comma."
51
+ msgstr ""
52
+
53
+ #: includes/admin/class-wc-square-admin-integration.php:69
54
+ #: includes/payment/class-wc-square-gateway.php:149
55
+ msgid "Logging"
56
+ msgstr ""
57
+
58
+ #: includes/admin/class-wc-square-admin-integration.php:70
59
+ #: includes/payment/class-wc-square-gateway.php:150
60
+ msgid "Log debug messages"
61
+ msgstr ""
62
+
63
+ #: includes/admin/class-wc-square-admin-integration.php:72
64
+ #: includes/payment/class-wc-square-gateway.php:152
65
+ msgid "Save debug messages to the WooCommerce System Status log."
66
+ msgstr ""
67
+
68
+ #: includes/admin/class-wc-square-admin-integration.php:76
69
+ msgid "Synchronization"
70
+ msgstr ""
71
+
72
+ #: includes/admin/class-wc-square-admin-integration.php:78
73
+ msgid ""
74
+ "Determine which aspects of your product catalog to synchronize between "
75
+ "WooCommerce and Square. Products need to have SKUs set for each variation."
76
+ msgstr ""
77
+
78
+ #: includes/admin/class-wc-square-admin-integration.php:81
79
+ msgid "Enabled"
80
+ msgstr ""
81
+
82
+ #: includes/admin/class-wc-square-admin-integration.php:83
83
+ msgid "Products"
84
+ msgstr ""
85
+
86
+ #: includes/admin/class-wc-square-admin-integration.php:84
87
+ msgid ""
88
+ "Basic Product information will be synced, excluding Categories and "
89
+ "Inventory."
90
+ msgstr ""
91
+
92
+ #: includes/admin/class-wc-square-admin-integration.php:88
93
+ msgid "Include Categories"
94
+ msgstr ""
95
+
96
+ #: includes/admin/class-wc-square-admin-integration.php:90
97
+ msgid "Sync Categories"
98
+ msgstr ""
99
+
100
+ #: includes/admin/class-wc-square-admin-integration.php:91
101
+ msgid ""
102
+ "Categories will sync on creation or update, and Products will have their "
103
+ "Categories synced."
104
+ msgstr ""
105
+
106
+ #: includes/admin/class-wc-square-admin-integration.php:95
107
+ msgid "Include Inventory"
108
+ msgstr ""
109
+
110
+ #: includes/admin/class-wc-square-admin-integration.php:97
111
+ msgid "Sync Inventory"
112
+ msgstr ""
113
+
114
+ #: includes/admin/class-wc-square-admin-integration.php:98
115
+ msgid "Inventory will sync on manual update or after a Product is ordered."
116
+ msgstr ""
117
+
118
+ #: includes/admin/class-wc-square-admin-integration.php:102
119
+ msgid "Include Images"
120
+ msgstr ""
121
+
122
+ #: includes/admin/class-wc-square-admin-integration.php:104
123
+ msgid "Sync Images"
124
+ msgstr ""
125
+
126
+ #: includes/admin/class-wc-square-admin-integration.php:105
127
+ msgid "Product Image will be synced."
128
+ msgstr ""
129
+
130
+ #: includes/admin/class-wc-square-admin-integration.php:109
131
+ msgid "Square Inventory Sync"
132
+ msgstr ""
133
+
134
+ #: includes/admin/class-wc-square-admin-integration.php:111
135
+ msgid "Enable"
136
+ msgstr ""
137
+
138
+ #: includes/admin/class-wc-square-admin-integration.php:112
139
+ msgid ""
140
+ "For automatic inventory syncing from Square to WooCommerce, this needs to "
141
+ "be enabled. It will poll the inventory from Square on an hourly basis."
142
+ msgstr ""
143
+
144
+ #: includes/admin/class-wc-square-admin-integration.php:172
145
+ msgid "Connect/Disconnect"
146
+ msgstr ""
147
+
148
+ #: includes/admin/class-wc-square-admin-integration.php:177
149
+ msgid "Disconnect from Square"
150
+ msgstr ""
151
+
152
+ #: includes/admin/class-wc-square-admin-integration.php:185
153
+ msgid "Connect with Square"
154
+ msgstr ""
155
+
156
+ #: includes/admin/class-wc-square-admin-integration.php:201
157
+ msgid "Initiate a Manual Sync"
158
+ msgstr ""
159
+
160
+ #: includes/admin/class-wc-square-admin-integration.php:205
161
+ msgid "WC &rarr; Square Sync"
162
+ msgstr ""
163
+
164
+ #: includes/admin/class-wc-square-admin-integration.php:206
165
+ msgid "Click button to perform a one time sync from WooCommerce to Square."
166
+ msgstr ""
167
+
168
+ #: includes/admin/class-wc-square-admin-integration.php:209
169
+ msgid "WC &rarr; Square"
170
+ msgstr ""
171
+
172
+ #: includes/admin/class-wc-square-admin-integration.php:214
173
+ msgid "Square &rarr; WC Sync"
174
+ msgstr ""
175
+
176
+ #: includes/admin/class-wc-square-admin-integration.php:215
177
+ msgid "Click button to perform a one time sync from Square to WooCommerce."
178
+ msgstr ""
179
+
180
+ #: includes/admin/class-wc-square-admin-integration.php:218
181
+ msgid "Square &rarr; WC"
182
+ msgstr ""
183
+
184
+ #: includes/admin/class-wc-square-admin-integration.php:242
185
+ #: includes/admin/class-wc-square-admin-integration.php:277
186
+ #: woocommerce-square.php:84 woocommerce-square.php:96
187
+ msgid "Cheatin&#8217; huh?"
188
+ msgstr ""
189
+
190
+ #: includes/admin/class-wc-square-admin-product-meta-box.php:59
191
+ msgid "(Square) Disable Sync"
192
+ msgstr ""
193
+
194
+ #: includes/admin/class-wc-square-admin-product-meta-box.php:61
195
+ msgid "Check box to disable this product from syncing."
196
+ msgstr ""
197
+
198
+ #: includes/admin/class-wc-square-admin-product-meta-box.php:108
199
+ msgid "Disable Sync"
200
+ msgstr ""
201
+
202
+ #: includes/admin/class-wc-square-admin-product-meta-box.php:113
203
+ msgid "— No Change —"
204
+ msgstr ""
205
+
206
+ #: includes/admin/class-wc-square-admin-product-meta-box.php:114
207
+ msgid "Yes"
208
+ msgstr ""
209
+
210
+ #: includes/admin/class-wc-square-admin-product-meta-box.php:115
211
+ msgid "No"
212
+ msgstr ""
213
+
214
+ #: includes/admin/class-wc-square-bulk-sync-handler.php:70
215
+ #: includes/admin/class-wc-square-bulk-sync-handler.php:185
216
+ msgid "Product Sync is disabled. Sync aborted."
217
+ msgstr ""
218
+
219
+ #: includes/admin/class-wc-square-bulk-sync-handler.php:75
220
+ #: includes/admin/class-wc-square-bulk-sync-handler.php:190
221
+ msgid ""
222
+ "cURL is not available. Sync aborted. Please contact your host to install "
223
+ "cURL."
224
+ msgstr ""
225
+
226
+ #: includes/admin/class-wc-square-bulk-sync-handler.php:150
227
+ #: includes/admin/class-wc-square-bulk-sync-handler.php:254
228
+ msgid "Sync Completed"
229
+ msgstr ""
230
+
231
+ #: includes/admin/class-wc-square-bulk-sync-handler.php:155
232
+ #: includes/admin/class-wc-square-bulk-sync-handler.php:259
233
+ msgid "Sync completed"
234
+ msgstr ""
235
+
236
+ #: includes/admin/class-wc-square-bulk-sync-handler.php:266
237
+ msgid "No Products to Sync."
238
+ msgstr ""
239
+
240
+ #: includes/admin/class-wc-square-bulk-sync-handler.php:443
241
+ msgid "%s - WooCommerce Square Sync Operation"
242
+ msgstr ""
243
+
244
+ #: includes/admin/class-wc-square-bulk-sync-handler.php:448
245
+ msgid "%s"
246
+ msgstr ""
247
+
248
+ #: includes/class-wc-square-connect.php:59
249
+ msgid "Square Sync Transients Cleared"
250
+ msgstr ""
251
+
252
+ #: includes/class-wc-square-connect.php:63
253
+ msgid "Square Sync Transients"
254
+ msgstr ""
255
+
256
+ #: includes/class-wc-square-connect.php:64
257
+ msgid "Clear all transients/cache"
258
+ msgstr ""
259
+
260
+ #: includes/class-wc-square-connect.php:65
261
+ msgid ""
262
+ "This will clear all Square Sync related transients/caches to start fresh. "
263
+ "Useful when sync failed halfway through."
264
+ msgstr ""
265
+
266
+ #: includes/class-wc-square-utils.php:44
267
+ msgid "Regular"
268
+ msgstr ""
269
+
270
+ #: includes/class-wc-square-wc-products.php:73
271
+ msgid "Invalid %s ID"
272
+ msgstr ""
273
+
274
+ #: includes/class-wc-square-wc-products.php:82
275
+ msgid "No %1$s found with the ID equal to %2$s"
276
+ msgstr ""
277
+
278
+ #: includes/class-wc-square-wc-products.php:90
279
+ msgid "Invalid %s"
280
+ msgstr ""
281
+
282
+ #: includes/class-wc-square-wc-products.php:98
283
+ msgid "You do not have permission to read this %s"
284
+ msgstr ""
285
+
286
+ #: includes/class-wc-square-wc-products.php:104
287
+ msgid "You do not have permission to edit this %s"
288
+ msgstr ""
289
+
290
+ #: includes/class-wc-square-wc-products.php:110
291
+ msgid "You do not have permission to delete this %s"
292
+ msgstr ""
293
+
294
+ #: includes/class-wc-square-wc-products.php:249
295
+ #: includes/class-wc-square-wc-products.php:536
296
+ #: includes/class-wc-square-wc-products.php:2287
297
+ msgid "No %1$s data specified to create %1$s"
298
+ msgstr ""
299
+
300
+ #: includes/class-wc-square-wc-products.php:256
301
+ msgid "You do not have permission to create products"
302
+ msgstr ""
303
+
304
+ #: includes/class-wc-square-wc-products.php:263
305
+ #: includes/class-wc-square-wc-products.php:2251
306
+ msgid "Missing parameter %s"
307
+ msgstr ""
308
+
309
+ #: includes/class-wc-square-wc-products.php:278
310
+ #: includes/class-wc-square-wc-products.php:405
311
+ msgid "Invalid product type - the product type must be any of these: %s"
312
+ msgstr ""
313
+
314
+ #: includes/class-wc-square-wc-products.php:354
315
+ #: includes/class-wc-square-wc-products.php:611
316
+ msgid "No %1$s data specified to edit %1$s"
317
+ msgstr ""
318
+
319
+ #: includes/class-wc-square-wc-products.php:450
320
+ #: includes/class-wc-square-wc-products.php:486
321
+ msgid "You do not have permission to read product categories"
322
+ msgstr ""
323
+
324
+ #: includes/class-wc-square-wc-products.php:481
325
+ msgid "Invalid product category ID"
326
+ msgstr ""
327
+
328
+ #: includes/class-wc-square-wc-products.php:492
329
+ msgid "A product category with the provided ID could not be found"
330
+ msgstr ""
331
+
332
+ #: includes/class-wc-square-wc-products.php:541
333
+ msgid "You do not have permission to create product categories"
334
+ msgstr ""
335
+
336
+ #: includes/class-wc-square-wc-products.php:561
337
+ msgid "Product category parent is invalid"
338
+ msgstr ""
339
+
340
+ #: includes/class-wc-square-wc-products.php:619
341
+ msgid "You do not have permission to edit product categories"
342
+ msgstr ""
343
+
344
+ #: includes/class-wc-square-wc-products.php:649
345
+ msgid "Could not edit the category"
346
+ msgstr ""
347
+
348
+ #: includes/class-wc-square-wc-products.php:926
349
+ #: includes/class-wc-square-wc-products.php:1369
350
+ msgid "The SKU already exists on another product"
351
+ msgstr ""
352
+
353
+ #: includes/class-wc-square-wc-products.php:1322
354
+ msgid "Variation #%1$s of %2$s"
355
+ msgstr ""
356
+
357
+ #: includes/class-wc-square-wc-products.php:1825
358
+ #: includes/class-wc-square-wc-products.php:1826
359
+ msgid "Placeholder"
360
+ msgstr ""
361
+
362
+ #: includes/class-wc-square-wc-products.php:1947
363
+ msgid "Invalid URL %s"
364
+ msgstr ""
365
+
366
+ #: includes/class-wc-square-wc-products.php:1959
367
+ #: includes/class-wc-square-wc-products.php:1961
368
+ msgid "Error getting remote image %s."
369
+ msgstr ""
370
+
371
+ #: includes/class-wc-square-wc-products.php:1959
372
+ msgid "Error: %s."
373
+ msgstr ""
374
+
375
+ #: includes/class-wc-square-wc-products.php:1982
376
+ msgid "Invalid image type."
377
+ msgstr ""
378
+
379
+ #: includes/class-wc-square-wc-products.php:1999
380
+ msgid "Zero size file downloaded"
381
+ msgstr ""
382
+
383
+ #: includes/class-wc-square-wc-products.php:2165
384
+ #: includes/class-wc-square-wc-products.php:2209
385
+ msgid "You do not have permission to read product attributes"
386
+ msgstr ""
387
+
388
+ #: includes/class-wc-square-wc-products.php:2204
389
+ msgid "Invalid product attribute ID"
390
+ msgstr ""
391
+
392
+ #: includes/class-wc-square-wc-products.php:2219
393
+ msgid "A product attribute with the provided ID could not be found"
394
+ msgstr ""
395
+
396
+ #: includes/class-wc-square-wc-products.php:2255
397
+ msgid "Slug \"%s\" is too long (28 characters max). Shorten it, please."
398
+ msgstr ""
399
+
400
+ #: includes/class-wc-square-wc-products.php:2257
401
+ msgid "Slug \"%s\" is not allowed because it is a reserved term. Change it, please."
402
+ msgstr ""
403
+
404
+ #: includes/class-wc-square-wc-products.php:2259
405
+ msgid "Slug \"%s\" is already in use. Change it, please."
406
+ msgstr ""
407
+
408
+ #: includes/class-wc-square-wc-products.php:2264
409
+ msgid ""
410
+ "Invalid product attribute type - the product attribute type must be any of "
411
+ "these: %s"
412
+ msgstr ""
413
+
414
+ #: includes/class-wc-square-wc-products.php:2269
415
+ msgid ""
416
+ "Invalid product attribute order_by type - the product attribute order_by "
417
+ "type must be any of these: %s"
418
+ msgstr ""
419
+
420
+ #: includes/class-wc-square-wc-products.php:2294
421
+ msgid "You do not have permission to create product attributes"
422
+ msgstr ""
423
+
424
+ #: includes/payment/class-wc-square-gateway.php:17
425
+ msgid ""
426
+ "Square works by adding payments fields in an iframe and then sending the "
427
+ "details to Square for verification and processing."
428
+ msgstr ""
429
+
430
+ #: includes/payment/class-wc-square-gateway.php:43
431
+ msgid ""
432
+ "STAGING MODE ENABLED. In staging mode, you can use the card number "
433
+ "4111111111111111 with any CVC and a valid expiration date."
434
+ msgstr ""
435
+
436
+ #: includes/payment/class-wc-square-gateway.php:80
437
+ msgid ""
438
+ "Square is enabled, but the <a href=\"%s\">force SSL option</a> is disabled; "
439
+ "your checkout is not secured! Please enable SSL and ensure your server has "
440
+ "a valid SSL certificate."
441
+ msgstr ""
442
+
443
+ #: includes/payment/class-wc-square-gateway.php:116
444
+ msgid "Enable/Disable"
445
+ msgstr ""
446
+
447
+ #: includes/payment/class-wc-square-gateway.php:117
448
+ msgid "Enable Square"
449
+ msgstr ""
450
+
451
+ #: includes/payment/class-wc-square-gateway.php:123
452
+ msgid "Title"
453
+ msgstr ""
454
+
455
+ #: includes/payment/class-wc-square-gateway.php:125
456
+ msgid "This controls the title which the user sees during checkout."
457
+ msgstr ""
458
+
459
+ #: includes/payment/class-wc-square-gateway.php:126
460
+ msgid "Credit card (Square)"
461
+ msgstr ""
462
+
463
+ #: includes/payment/class-wc-square-gateway.php:129
464
+ msgid "Description"
465
+ msgstr ""
466
+
467
+ #: includes/payment/class-wc-square-gateway.php:131
468
+ msgid "This controls the description which the user sees during checkout."
469
+ msgstr ""
470
+
471
+ #: includes/payment/class-wc-square-gateway.php:132
472
+ msgid "Pay with your credit card via Square."
473
+ msgstr ""
474
+
475
+ #: includes/payment/class-wc-square-gateway.php:135
476
+ msgid "Delay Capture"
477
+ msgstr ""
478
+
479
+ #: includes/payment/class-wc-square-gateway.php:136
480
+ msgid "Enable Delay Capture"
481
+ msgstr ""
482
+
483
+ #: includes/payment/class-wc-square-gateway.php:138
484
+ msgid ""
485
+ "When enabled, the request will only perform an Auth on the provided card. "
486
+ "You can then later perform either a Capture or Void."
487
+ msgstr ""
488
+
489
+ #: includes/payment/class-wc-square-gateway.php:142
490
+ msgid "Create Customer"
491
+ msgstr ""
492
+
493
+ #: includes/payment/class-wc-square-gateway.php:143
494
+ msgid "Enable Create Customer"
495
+ msgstr ""
496
+
497
+ #: includes/payment/class-wc-square-gateway.php:145
498
+ msgid "When enabled, processing a payment will create a customer profile on Square."
499
+ msgstr ""
500
+
501
+ #: includes/payment/class-wc-square-gateway.php:182
502
+ msgid "Card Number"
503
+ msgstr ""
504
+
505
+ #: includes/payment/class-wc-square-gateway.php:187
506
+ msgid "Expiry (MM/YY)"
507
+ msgstr ""
508
+
509
+ #: includes/payment/class-wc-square-gateway.php:188
510
+ #: includes/payment/class-wc-square-gateway.php:255
511
+ msgid "MM / YY"
512
+ msgstr ""
513
+
514
+ #: includes/payment/class-wc-square-gateway.php:192
515
+ msgid "Card Code"
516
+ msgstr ""
517
+
518
+ #: includes/payment/class-wc-square-gateway.php:193
519
+ #: includes/payment/class-wc-square-gateway.php:256
520
+ msgid "CVV"
521
+ msgstr ""
522
+
523
+ #: includes/payment/class-wc-square-gateway.php:197
524
+ #: includes/payment/class-wc-square-gateway.php:198
525
+ #: includes/payment/class-wc-square-gateway.php:257
526
+ msgid "Card Postal Code"
527
+ msgstr ""
528
+
529
+ #: includes/payment/class-wc-square-gateway.php:254
530
+ msgid "•••• •••• •••• ••••"
531
+ msgstr ""
532
+
533
+ #: includes/payment/class-wc-square-gateway.php:315
534
+ #: includes/payment/class-wc-square-gateway.php:322
535
+ #: includes/payment/class-wc-square-gateway.php:346
536
+ msgid ""
537
+ "Error: Square was unable to complete the transaction. Please try again "
538
+ "later or use another means of payment."
539
+ msgstr ""
540
+
541
+ #: includes/payment/class-wc-square-gateway.php:327
542
+ msgid "Payment Error: "
543
+ msgstr ""
544
+
545
+ #: includes/payment/class-wc-square-gateway.php:359
546
+ #: includes/payment/class-wc-square-payments.php:131
547
+ msgid "Square charge complete (Charge ID: %s)"
548
+ msgstr ""
549
+
550
+ #: includes/payment/class-wc-square-gateway.php:368
551
+ msgid ""
552
+ "Square charge authorized (Authorized ID: %s). Process order to take "
553
+ "payment, or cancel to remove the pre-authorization."
554
+ msgstr ""
555
+
556
+ #: includes/payment/class-wc-square-gateway.php:390
557
+ #: includes/payment/class-wc-square-gateway.php:522
558
+ msgid "Error: %s"
559
+ msgstr ""
560
+
561
+ #: includes/payment/class-wc-square-gateway.php:422
562
+ msgid "Guest"
563
+ msgstr ""
564
+
565
+ #: includes/payment/class-wc-square-gateway.php:441
566
+ #: includes/payment/class-wc-square-gateway.php:442
567
+ #: includes/payment/class-wc-square-gateway.php:447
568
+ #: includes/payment/class-wc-square-gateway.php:448
569
+ msgid "Error creating customer: %s"
570
+ msgstr ""
571
+
572
+ #: includes/payment/class-wc-square-gateway.php:454
573
+ msgid "Customer created on Square: %s"
574
+ msgstr ""
575
+
576
+ #: includes/payment/class-wc-square-gateway.php:511
577
+ msgid "Refunded %1$s - Refund ID: %2$s - Reason: %3$s"
578
+ msgstr ""
579
+
580
+ #: includes/payment/class-wc-square-payments.php:83
581
+ msgid "Capture Charge"
582
+ msgstr ""
583
+
584
+ #: includes/payment/class-wc-square-payments.php:123
585
+ #: includes/payment/class-wc-square-payments.php:127
586
+ msgid "Unable to capture charge!"
587
+ msgstr ""
588
+
589
+ #: includes/payment/class-wc-square-payments.php:137
590
+ msgid "Error unable to capture charge: %s"
591
+ msgstr ""
592
+
593
+ #: includes/payment/class-wc-square-payments.php:167
594
+ #: includes/payment/class-wc-square-payments.php:170
595
+ msgid "Unable to void charge!"
596
+ msgstr ""
597
+
598
+ #: includes/payment/class-wc-square-payments.php:174
599
+ msgid "Square charge voided! (Charge ID: %s)"
600
+ msgstr ""
601
+
602
+ #: includes/payment/class-wc-square-payments.php:180
603
+ msgid "Unable to void charge!: %s"
604
+ msgstr ""
605
+
606
+ #: woocommerce-square.php:211
607
+ msgid ""
608
+ "Square requires that the <a href=\"%s\">base country/region</a> is "
609
+ "Australia, Canada, Japan, United Kingdom, or United States."
610
+ msgstr ""
611
+
612
+ #: woocommerce-square.php:219
613
+ msgid ""
614
+ "Square requires that the <a href=\"%s\">currency</a> is set to AUD, CAD, "
615
+ "GBP, JPY, or USD."
616
+ msgstr ""
617
+
618
+ #: woocommerce-square.php:330
619
+ msgid ""
620
+ "This process may take awhile depending on the amount of items that need to "
621
+ "be synced. Please do not close this tab/window or else the sync will "
622
+ "terminate. Click OK to continue to sync."
623
+ msgstr ""
624
+
625
+ #: woocommerce-square.php:388
626
+ msgid ""
627
+ "WooCommerce Square Plugin requires WooCommerce to be installed and active. "
628
+ "You can download %s here."
629
+ msgstr ""
630
+
631
+ #: woocommerce-square.php:406
632
+ msgid ""
633
+ "WooCommerce Square is almost ready. To get started, %1$sconnect your Square "
634
+ "Account.%2$s"
635
+ msgstr ""
636
+
637
+ #: woocommerce-square.php:410
638
+ msgid ""
639
+ "WooCommerce Square is almost ready. Please %1$sset your business "
640
+ "location.%2$s"
641
+ msgstr ""
642
+
643
+ #. Plugin Name of the plugin/theme
644
+ msgid "WooCommerce Square"
645
+ msgstr ""
646
+
647
+ #. Plugin URI of the plugin/theme
648
+ msgid "https://woocommerce.com/products/square/"
649
+ msgstr ""
650
+
651
+ #. Description of the plugin/theme
652
+ msgid ""
653
+ "Adds ability to sync inventory between WooCommerce and Square POS. In "
654
+ "addition, you can also make purchases through the Square payment gateway."
655
+ msgstr ""
656
+
657
+ #. Author of the plugin/theme
658
+ msgid "WooCommerce"
659
+ msgstr ""
660
+
661
+ #. Author URI of the plugin/theme
662
+ msgid "https://www.woocommerce.com/"
663
+ msgstr ""
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: credit card, square, woocommerce, inventory sync
4
  Requires at least: 4.4
5
  Tested up to: 4.9
6
  Requires PHP: 5.6
7
- Stable tag: 1.0.26
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -57,17 +57,13 @@ If you get stuck, you can ask for help in the Plugin Forum.
57
 
58
  == Changelog ==
59
 
60
- = 1.0.26 - 2018-01-29 =
61
- * Fix - Call to undefined method causes error.
62
-
63
- = 1.0.25 - 2018-01-29 =
64
- * Tweaks - Error handling.
65
- * Public release on .org
66
-
67
- = 1.0.24 - 2017-12-13 =
68
- * Fix - In some cases rounding issues occur causing payment unable to process.
69
- * Update - WC tested up to version.
70
- * Add - Readme.txt.
71
 
72
  == Upgrade Notice ==
73
 
4
  Requires at least: 4.4
5
  Tested up to: 4.9
6
  Requires PHP: 5.6
7
+ Stable tag: 1.0.27
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
 
57
 
58
  == Changelog ==
59
 
60
+ = 1.0.27 - 2018-02-19 =
61
+ * Fix - In some cases request timeouts are not set long enough causing timeout errors.
62
+ * Fix - Square to WC sync sets products with 0 quantity to In Stock.
63
+ * Fix - Potential issue with Square to WC sync when response is not an array.
64
+ * Fix - When description is more than 4095 characters, sync fails to Square.
65
+ * Fix - Add checks to product object before scheduling an event to prevent errors in cron job.
66
+ * Fix - Add check to prevent auto inventory poll from running when a manual sync is in progress.
 
 
 
 
67
 
68
  == Upgrade Notice ==
69
 
uninstall.php CHANGED
@@ -19,5 +19,6 @@ if ( defined( 'WC_REMOVE_ALL_DATA' ) && true === WC_REMOVE_ALL_DATA ) {
19
  delete_option( 'wc_square_polling' );
20
  delete_transient( 'wc_square_polling' );
21
  delete_transient( 'wc_square_locations' );
 
22
  delete_option( 'woocommerce_square_merchant_access_token' );
23
  }
19
  delete_option( 'wc_square_polling' );
20
  delete_transient( 'wc_square_polling' );
21
  delete_transient( 'wc_square_locations' );
22
+ delete_transient( 'wc_square_manual_sync_processing' );
23
  delete_option( 'woocommerce_square_merchant_access_token' );
24
  }
woocommerce-square.php CHANGED
@@ -1,13 +1,13 @@
1
  <?php
2
  /**
3
  * Plugin Name: WooCommerce Square
4
- * Version: 1.0.26
5
  * Plugin URI: https://woocommerce.com/products/square/
6
  * Description: Adds ability to sync inventory between WooCommerce and Square POS. In addition, you can also make purchases through the Square payment gateway.
7
  * Author: WooCommerce
8
  * Author URI: https://www.woocommerce.com/
9
  * Requires at least: 4.5.0
10
- * Tested up to: 4.7.2
11
  * WC requires at least: 2.6
12
  * WC tested up to: 3.3
13
  * Text Domain: woocommerce-square
@@ -23,7 +23,7 @@ if ( ! defined( 'ABSPATH' ) ) {
23
 
24
  if ( ! class_exists( 'Woocommerce_Square' ) ) :
25
 
26
- define( 'WC_SQUARE_VERSION', '1.0.26' );
27
 
28
  /**
29
  * Main class.
1
  <?php
2
  /**
3
  * Plugin Name: WooCommerce Square
4
+ * Version: 1.0.27
5
  * Plugin URI: https://woocommerce.com/products/square/
6
  * Description: Adds ability to sync inventory between WooCommerce and Square POS. In addition, you can also make purchases through the Square payment gateway.
7
  * Author: WooCommerce
8
  * Author URI: https://www.woocommerce.com/
9
  * Requires at least: 4.5.0
10
+ * Tested up to: 4.9
11
  * WC requires at least: 2.6
12
  * WC tested up to: 3.3
13
  * Text Domain: woocommerce-square
23
 
24
  if ( ! class_exists( 'Woocommerce_Square' ) ) :
25
 
26
+ define( 'WC_SQUARE_VERSION', '1.0.27' );
27
 
28
  /**
29
  * Main class.