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.