Version Description
- 2020.08.31 =
- Feature - Import new product variations from square to existing products in WooCommerce. PR#475
- Feature - Variations that are removed from Square will now be removed from products in WooCommerce during import. PR#475
- Feature - Upgrade to the Square Payments and Refunds API. PR#408
- Feature - New orders can be refunded up to one year after payment (up from 120 days). PR#408
- Fix - Only import products from Square that have non-empty SKUs. PR#475
- Fix - Empty product categories imported from Square into WooCommerce. PR#475
- Fix - Assign existing products to new categories imported from Square. PR#475
- Fix - Prevents loading of Square Assets on all pages except My Account -> Payment Methods & Checkout. PR#469
- Fix - Square Product Import & Product Manual Sync not triggering on mobile browsers. PR#472
- Fix - 3D Secure Verification Token is missing, Intent mismatch and other checkout errors related to SCA for merchants outside of the EU. PR#471
- Fix - Updated some of our documentation and support links in admin notices so they no longer redirect to an old URL or a 404 page. PR#474
- Fix - Use pagination to fetch inventory counts from Square. PR#478
- Fix - Display WooCommerce checkout validation errors along with Square payment form errors. PR#476
- Fix - Switching between sandbox and production environments will now show correct business locations. PR#462
- Fix - Don't wipe a customer's saved cards on when we receive an API error. PR#460
- Fix - Exclude draft and pending products from syncing from WooCommerce to Square. PR#484
- Fix - DevTools errors caused by missing minified JS files.
- Fix - PHP errors when syncing large amounts of products (
get_data() on null
andgetCursor() on a string
). PR#497
Download this release
Release Info
Developer | automattic |
Plugin | WooCommerce Square |
Version | 2.2.0 |
Comparing to | |
See all releases |
Code changes from version 2.1.6 to 2.2.0
- assets/js/admin/wc-square-admin-settings.coffee +75 -48
- assets/js/admin/wc-square-admin-settings.min.js +1 -1
- assets/js/admin/wc-square-admin-settings.min.js.map +1 -1
- assets/js/frontend/wc-square.coffee +56 -7
- assets/js/frontend/wc-square.min.js +1 -1
- assets/js/frontend/wc-square.min.js.map +1 -1
- i18n/languages/woocommerce-square.pot +225 -212
- includes/AJAX.php +37 -38
- includes/API.php +51 -42
- includes/API/Request.php +5 -5
- includes/API/Requests/Catalog.php +58 -38
- includes/API/Requests/Customers.php +3 -3
- includes/API/Requests/Inventory.php +23 -19
- includes/API/Requests/Locations.php +1 -1
- includes/API/Response.php +4 -4
- includes/API/Responses/Catalog.php +1 -1
- includes/API/Responses/Connection_Refresh_Response.php +1 -1
- includes/API/Responses/Inventory.php +2 -2
- includes/API/Responses/Locations.php +2 -2
- includes/Admin.php +115 -70
- includes/Admin/Privacy.php +7 -7
- includes/Admin/Settings_Page.php +6 -6
- includes/Admin/Sync_Page.php +47 -22
- includes/Emails/Access_Token_Email.php +16 -11
- includes/Emails/Base_Email.php +27 -20
- includes/Emails/Sync_Completed.php +26 -21
- includes/Functions.php +1 -1
- includes/Gateway.php +130 -41
- includes/Gateway/API.php +44 -8
- includes/Gateway/API/Requests/Customers.php +8 -9
- includes/Gateway/API/Requests/Orders.php +70 -44
- includes/Gateway/API/Requests/Payments.php +205 -0
- includes/Gateway/API/Requests/Refunds.php +76 -0
- includes/Gateway/API/Requests/Transactions.php +12 -12
- includes/Gateway/API/Response.php +1 -1
- includes/Gateway/API/Responses/Charge.php +5 -5
- includes/Gateway/API/Responses/Create_Customer.php +1 -1
- includes/Gateway/API/Responses/Create_Customer_Card.php +4 -4
- includes/Gateway/API/Responses/Create_Payment.php +174 -0
- includes/Gateway/API/Responses/Get_Customer.php +5 -5
- includes/Gateway/API/Responses/Refund.php +3 -4
- includes/Gateway/Card_Handler.php +110 -1
- includes/Gateway/Customer_Helper.php +24 -18
- includes/Gateway/Payment_Form.php +45 -36
- includes/Handlers/Background_Job.php +35 -24
- includes/Handlers/Category.php +12 -9
- includes/Handlers/Connection.php +28 -27
- includes/Handlers/Email.php +4 -4
- includes/Handlers/Order.php +18 -18
- includes/Handlers/Product.php +122 -102
- includes/Handlers/Product/Woo_SOR.php +26 -23
- includes/Handlers/Products.php +67 -56
- includes/Handlers/Sync.php +46 -36
- includes/Lifecycle.php +163 -86
- includes/Plugin.php +181 -105
- includes/Settings.php +195 -125
- includes/Sync/Catalog_Item.php +8 -6
- includes/Sync/Interval_Polling.php +44 -34
- includes/Sync/Job.php +1 -1
- includes/Sync/Manual_Synchronization.php +241 -184
- includes/Sync/Product_Import.php +395 -234
- includes/Sync/Records.php +33 -30
- includes/Sync/Records/Record.php +25 -22
- includes/Sync/Stepped_Job.php +9 -9
- includes/Utilities/Encryption_Utility.php +2 -3
- includes/Utilities/Money_Utility.php +10 -8
- includes/Utilities/String_Utility.php +82 -0
- readme.txt +23 -3
- templates/emails/plain/square-email.php +1 -1
- templates/emails/square-email.php +1 -1
- vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets/js/frontend/sv-wc-payment-gateway-apple-pay.min.js.map +10 -0
- vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets/js/frontend/sv-wc-payment-gateway-my-payment-methods.min.js.map +10 -0
- vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets/js/frontend/sv-wc-payment-gateway-payment-form.min.js.map +10 -0
- woocommerce-square.php +29 -17
assets/js/admin/wc-square-admin-settings.coffee
CHANGED
@@ -15,6 +15,13 @@ jQuery( document ).ready ( $ ) ->
|
|
15 |
if ( 'woocommerce_page_wc-settings' isnt pagenow )
|
16 |
return
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
# toggle the "hide products" setting depending on the SOR
|
20 |
$( '#wc_square_system_of_record' ).change( ->
|
@@ -56,26 +63,6 @@ jQuery( document ).ready ( $ ) ->
|
|
56 |
e.preventDefault()
|
57 |
$( 'button.modal-close' ).trigger( 'click' )
|
58 |
|
59 |
-
$( '#btn-ok' ).on 'click', ( e ) ->
|
60 |
-
e.preventDefault()
|
61 |
-
$( this ).unbind()
|
62 |
-
|
63 |
-
data =
|
64 |
-
action : 'wc_square_import_products_from_square'
|
65 |
-
dispatch : wc_square_admin_settings.sync_in_background
|
66 |
-
security : wc_square_admin_settings.import_products_from_square
|
67 |
-
|
68 |
-
$.post wc_square_admin_settings.ajax_url, data, ( response ) ->
|
69 |
-
|
70 |
-
message = if response.data then response.data else null
|
71 |
-
|
72 |
-
if response.success and message
|
73 |
-
alert( message )
|
74 |
-
else if not response.success and message
|
75 |
-
alert( message )
|
76 |
-
|
77 |
-
location.reload()
|
78 |
-
|
79 |
# initiate a manual sync
|
80 |
$( '#wc-square-sync' ).on 'click', ( e ) ->
|
81 |
e.preventDefault()
|
@@ -89,34 +76,62 @@ jQuery( document ).ready ( $ ) ->
|
|
89 |
e.preventDefault()
|
90 |
$( 'button.modal-close' ).trigger( 'click' )
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
114 |
location.reload()
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
|
121 |
|
122 |
# sync record handling
|
@@ -194,6 +209,17 @@ jQuery( document ).ready ( $ ) ->
|
|
194 |
|
195 |
$( 'table.records' ).unblock()
|
196 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
|
198 |
###*
|
199 |
# Returns a job sync status.
|
@@ -234,7 +260,8 @@ jQuery( document ).ready ( $ ) ->
|
|
234 |
# update progress info in table cell
|
235 |
if 'product_import' is response.data.action
|
236 |
progress += wc_square_admin_settings.i18n.skipped + ': ' + parseInt( response.data.skipped_products_count, 10 ) + '<br/>'
|
237 |
-
progress += wc_square_admin_settings.i18n.
|
|
|
238 |
else if response.data.percentage
|
239 |
progress += parseInt( response.data.percentage, 10 ) + '%'
|
240 |
|
15 |
if ( 'woocommerce_page_wc-settings' isnt pagenow )
|
16 |
return
|
17 |
|
18 |
+
if not wc_square_admin_settings.is_sandbox
|
19 |
+
# Hide sandbox settings if is_sandbox is set
|
20 |
+
$( '#wc_square_sandbox_settings' ).hide()
|
21 |
+
|
22 |
+
$( '#wc_square_sandbox_settings' ).next().hide()
|
23 |
+
|
24 |
+
$( '.wc_square_sandbox_settings' ).closest( 'tr' ).hide()
|
25 |
|
26 |
# toggle the "hide products" setting depending on the SOR
|
27 |
$( '#wc_square_system_of_record' ).change( ->
|
63 |
e.preventDefault()
|
64 |
$( 'button.modal-close' ).trigger( 'click' )
|
65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
# initiate a manual sync
|
67 |
$( '#wc-square-sync' ).on 'click', ( e ) ->
|
68 |
e.preventDefault()
|
76 |
e.preventDefault()
|
77 |
$( 'button.modal-close' ).trigger( 'click' )
|
78 |
|
79 |
+
# Listen for wc_backbone_modal_response event handler.
|
80 |
+
$( document.body ).on 'wc_backbone_modal_response', ( e, target ) ->
|
81 |
+
switch target
|
82 |
+
|
83 |
+
when 'wc-square-import-products'
|
84 |
+
# Add Block overlay since the modal exits immediately
|
85 |
+
# after wc_backbone_modal_response is triggered.
|
86 |
+
$( '#wpbody' ).block
|
87 |
+
message : null
|
88 |
+
overlayCSS :
|
89 |
+
'opacity' : '0.2'
|
90 |
+
onBlock: ->
|
91 |
+
$( '.blockUI.blockOverlay' ).css
|
92 |
+
'position': 'fixed'
|
93 |
+
return
|
94 |
+
|
95 |
+
data =
|
96 |
+
action : 'wc_square_import_products_from_square'
|
97 |
+
dispatch : wc_square_admin_settings.sync_in_background
|
98 |
+
security : wc_square_admin_settings.import_products_from_square
|
99 |
+
|
100 |
+
$.post wc_square_admin_settings.ajax_url, data, ( response ) ->
|
101 |
+
message = if response.data then response.data else null
|
102 |
+
|
103 |
+
if message
|
104 |
+
alert( message )
|
105 |
+
|
106 |
location.reload()
|
107 |
+
|
108 |
+
when 'wc-square-sync'
|
109 |
+
$( 'table.sync' ).block
|
110 |
+
message : null
|
111 |
+
overlayCSS :
|
112 |
+
'opacity' : '0.2'
|
113 |
+
$( 'table.records' ).block
|
114 |
+
message : null
|
115 |
+
overlayCSS :
|
116 |
+
'opacity' : '0.2'
|
117 |
+
$( '#wc-square_clear-sync-records' ).prop( 'disabled', true )
|
118 |
+
|
119 |
+
data =
|
120 |
+
action : 'wc_square_sync_products_with_square'
|
121 |
+
dispatch : wc_square_admin_settings.sync_in_background
|
122 |
+
security : wc_square_admin_settings.sync_products_with_square
|
123 |
+
|
124 |
+
$.post wc_square_admin_settings.ajax_url, data, ( response ) ->
|
125 |
+
if response and response.success
|
126 |
+
location.reload()
|
127 |
+
else
|
128 |
+
$( '#wc-square_clear-sync-records' ).prop( 'disabled', false )
|
129 |
+
$( 'table.sync' ).unblock()
|
130 |
+
$( 'table.records' ).unblock()
|
131 |
+
|
132 |
+
else
|
133 |
+
return
|
134 |
+
return
|
135 |
|
136 |
|
137 |
# sync record handling
|
209 |
|
210 |
$( 'table.records' ).unblock()
|
211 |
|
212 |
+
# Add explicit square environment to post data to deal with swapping between production and sandbox in the back end
|
213 |
+
$( 'form' ).submit ( e ) ->
|
214 |
+
|
215 |
+
environment = if $( '#wc_square_enable_sandbox' ).is( ':checked' ) then 'sandbox' else 'production'
|
216 |
+
|
217 |
+
$( this ).append( $( '<input>', {
|
218 |
+
type: 'hidden',
|
219 |
+
name: 'wc_square_environment',
|
220 |
+
value: environment,
|
221 |
+
} ) )
|
222 |
+
|
223 |
|
224 |
###*
|
225 |
# Returns a job sync status.
|
260 |
# update progress info in table cell
|
261 |
if 'product_import' is response.data.action
|
262 |
progress += wc_square_admin_settings.i18n.skipped + ': ' + parseInt( response.data.skipped_products_count, 10 ) + '<br/>'
|
263 |
+
progress += wc_square_admin_settings.i18n.updated + ': ' + parseInt( response.data.updated_products_count, 10 ) + '<br/>'
|
264 |
+
progress += wc_square_admin_settings.i18n.imported + ': ' + parseInt( response.data.imported_products_count, 10 )
|
265 |
else if response.data.percentage
|
266 |
progress += parseInt( response.data.percentage, 10 ) + '%'
|
267 |
|
assets/js/admin/wc-square-admin-settings.min.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
"use strict";(function(){jQuery(document).ready(function(e){var s,t,
|
2 |
//# sourceMappingURL=wc-square-admin-settings.min.js.map
|
1 |
+
"use strict";(function(){jQuery(document).ready(function(e){var s,t,a,n;if(null!=(a=window.typenow)?a:"","woocommerce_page_wc-settings"===(null!=(n=window.pagenow)?n:""))return wc_square_admin_settings.is_sandbox||(e("#wc_square_sandbox_settings").hide(),e("#wc_square_sandbox_settings").next().hide(),e(".wc_square_sandbox_settings").closest("tr").hide()),e("#wc_square_system_of_record").change(function(){var s,t,a;return a=e(this).val(),s=e("#wc_square_enable_inventory_sync"),t=s.closest("tr"),"square"===a||"woocommerce"===a?(s.next("span").html(wc_square_admin_settings.i18n.sync_inventory_label[a]),t.find(".description").html(wc_square_admin_settings.i18n.sync_inventory_description[a]),t.show()):(s.prop("checked",!1),t.hide()),"square"===a?e("#wc_square_hide_missing_products").closest("tr").show():e("#wc_square_hide_missing_products").closest("tr").hide()}).change(),e(".js-import-square-products").on("click",function(s){return s.preventDefault(),new e.WCBackboneModal.View({target:"wc-square-import-products"}),e("#btn-close").on("click",function(s){return s.preventDefault(),e("button.modal-close").trigger("click")})}),e("#wc-square-sync").on("click",function(s){return s.preventDefault(),new e.WCBackboneModal.View({target:"wc-square-sync"}),e("#btn-close").on("click",function(s){return s.preventDefault(),e("button.modal-close").trigger("click")})}),e(document.body).on("wc_backbone_modal_response",function(s,t){var a;switch(t){case"wc-square-import-products":e("#wpbody").block({message:null,overlayCSS:{opacity:"0.2"},onBlock:function(){e(".blockUI.blockOverlay").css({position:"fixed"})}}),a={action:"wc_square_import_products_from_square",dispatch:wc_square_admin_settings.sync_in_background,security:wc_square_admin_settings.import_products_from_square},e.post(wc_square_admin_settings.ajax_url,a,function(e){var s;return(s=e.data?e.data:null)&&alert(s),location.reload()});break;case"wc-square-sync":e("table.sync").block({message:null,overlayCSS:{opacity:"0.2"}}),e("table.records").block({message:null,overlayCSS:{opacity:"0.2"}}),e("#wc-square_clear-sync-records").prop("disabled",!0),a={action:"wc_square_sync_products_with_square",dispatch:wc_square_admin_settings.sync_in_background,security:wc_square_admin_settings.sync_products_with_square},e.post(wc_square_admin_settings.ajax_url,a,function(s){return s&&s.success?location.reload():(e("#wc-square_clear-sync-records").prop("disabled",!1),e("table.sync").unblock(),e("table.records").unblock())});break;default:return}}),t='<tr><td colspan="4"><em>'+wc_square_admin_settings.i18n.no_records_found+"</em></td></tr>",e("#wc-square_clear-sync-records").on("click",function(s){var a;return s.preventDefault(),e("table.records").block({message:null,overlayCSS:{opacity:"0.2"}}),a={action:"wc_square_handle_sync_records",id:"all",handle:"delete",security:wc_square_admin_settings.handle_sync_with_square_records},e.post(wc_square_admin_settings.ajax_url,a,function(s){return s&&s.success?(e("table.records tbody").html(t),e("#wc-square_clear-sync-records").prop("disabled",!0)):(s.data&&alert(s.data),console.log(s)),e("table.records").unblock()})}),e(".records .actions button.action").on("click",function(s){var a,n,r;return s.preventDefault(),e("table.records").block({message:null,overlayCSS:{opacity:"0.2"}}),r=e(this).data("id"),a=e(this).data("action"),n={action:"wc_square_handle_sync_records",id:r,handle:a,security:wc_square_admin_settings.handle_sync_with_square_records},e.post(wc_square_admin_settings.ajax_url,n,function(s){var n;return s&&s.success?(n="#record-"+r,"delete"===a?(e(n).remove(),e("table.records tbody tr").length||(e("table.records tbody").html(t),e("#wc-square_clear-sync-records").prop("disabled",!0))):"resolve"!==a&&"unsync"!==a||(e(n+" .type").html('<mark class="resolved"><span>'+wc_square_admin_settings.i18n.resolved+"</span></mark>"),e(n+" .actions").html("—"))):(s&&s.data&&alert(s.data),console.log({record:r,action:a,response:s})),e("table.records").unblock()})}),e("form").submit(function(s){var t;return t=e("#wc_square_enable_sandbox").is(":checked")?"sandbox":"production",e(this).append(e("<input>",{type:"hidden",name:"wc_square_environment",value:t}))}),s=function(t){var a,n;return(a=e("span.progress"))&&0!==a.length||(e("p.sync-result").append(' <span class="progress" style="display:block"></span>'),a=e("span.progress")),n={action:"wc_square_get_sync_with_square_status",security:wc_square_admin_settings.get_sync_with_square_status_nonce,job_id:t},e.post(wc_square_admin_settings.ajax_url,n,function(t){var n,r;if(t&&t.data)return t.success&&t.data.id?(e("table.sync .spinner").css("visibility","visible"),e("#wc-square_clear-sync-records").prop("disabled",!0),e("table.records .actions button").prop("disabled",!0),"completed"!==(r=t.data.status)&&"failed"!==r?(n=" ","product_import"===t.data.action?(n+=wc_square_admin_settings.i18n.skipped+": "+parseInt(t.data.skipped_products_count,10)+"<br/>",n+=wc_square_admin_settings.i18n.updated+": "+parseInt(t.data.updated_products_count,10)+"<br/>",n+=wc_square_admin_settings.i18n.imported+": "+parseInt(t.data.imported_products_count,10)):t.data.percentage&&(n+=parseInt(t.data.percentage,10)+"%"),a.html(n),setTimeout(function(){return s(t.data.id)},3e4)):location.reload()):(e("#wc-square_clear-sync-records").prop("disabled",!1),e("table.records .actions button").prop("disabled",!1),e("table.sync .spinner").css("visibility","hidden"),console.log(t))})},wc_square_admin_settings.existing_sync_job_id?s(wc_square_admin_settings.existing_sync_job_id):void 0})}).call(void 0);
|
2 |
//# sourceMappingURL=wc-square-admin-settings.min.js.map
|
assets/js/admin/wc-square-admin-settings.min.js.map
CHANGED
@@ -1 +1 @@
|
|
1 |
-
{"version":3,"sources":["wc-square-admin-settings.min.js"],"names":["jQuery","document","ready","$","_getSyncStatus","noRecordsFoundRow","ref","ref1","window","typenow","pagenow","change","$inventory_sync","$inventory_sync_row","system_of_record","this","val","
|
1 |
+
{"version":3,"sources":["wc-square-admin-settings.min.js"],"names":["jQuery","document","ready","$","_getSyncStatus","noRecordsFoundRow","ref","ref1","window","typenow","pagenow","wc_square_admin_settings","is_sandbox","hide","next","closest","change","$inventory_sync","$inventory_sync_row","system_of_record","this","val","html","i18n","sync_inventory_label","find","sync_inventory_description","show","prop","on","e","preventDefault","WCBackboneModal","View","target","trigger","body","data","block","message","overlayCSS","opacity","onBlock","css","position","action","dispatch","sync_in_background","security","import_products_from_square","post","ajax_url","response","alert","location","reload","sync_products_with_square","success","unblock","no_records_found","id","handle","handle_sync_with_square_records","console","log","recordId","rowId","remove","length","resolved","record","submit","environment","is","append","type","name","value","job_id","$progress","get_sync_with_square_status_nonce","progress","ref2","status","skipped","parseInt","skipped_products_count","updated","updated_products_count","imported","imported_products_count","percentage","setTimeout","existing_sync_job_id","call","undefined"],"mappings":"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","file":"wc-square-admin-settings.min.js"}
|
assets/js/frontend/wc-square.coffee
CHANGED
@@ -37,6 +37,8 @@ jQuery( document ).ready ( $ ) ->
|
|
37 |
@is_user_logged_in = args.is_user_logged_in
|
38 |
@location_id = args.location_id
|
39 |
@logging_enabled = args.logging_enabled
|
|
|
|
|
40 |
|
41 |
# which payment form?
|
42 |
if $( 'form.checkout' ).length
|
@@ -397,6 +399,9 @@ jQuery( document ).ready ( $ ) ->
|
|
397 |
handle_verify_buyer_response: ( errors, verification_result ) =>
|
398 |
|
399 |
if errors
|
|
|
|
|
|
|
400 |
return this.handle_errors( errors )
|
401 |
|
402 |
# no errors, but also no verification token
|
@@ -502,13 +507,12 @@ jQuery( document ).ready ( $ ) ->
|
|
502 |
|
503 |
if errors
|
504 |
|
505 |
-
field_order = [ "cardNumber", "expirationDate", "cvv", "postalCode" ]
|
506 |
-
|
507 |
-
# sort based on the field order
|
508 |
-
# without the brackets around a.field and b.field the precedence is different and gives different results
|
509 |
-
errors.sort (a,b) -> field_order.indexOf(a.field) - field_order.indexOf(b.field)
|
510 |
|
511 |
-
|
|
|
|
|
|
|
512 |
|
513 |
$( errors ).each ( index, error ) =>
|
514 |
|
@@ -526,7 +530,11 @@ jQuery( document ).ready ( $ ) ->
|
|
526 |
if messages.length is 0
|
527 |
messages.push( @general_error )
|
528 |
|
529 |
-
|
|
|
|
|
|
|
|
|
530 |
|
531 |
this.unblock_ui()
|
532 |
|
@@ -627,3 +635,44 @@ jQuery( document ).ready ( $ ) ->
|
|
627 |
console.error 'Square Error: ' + message
|
628 |
else
|
629 |
console.log 'Square: ' + message
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
@is_user_logged_in = args.is_user_logged_in
|
38 |
@location_id = args.location_id
|
39 |
@logging_enabled = args.logging_enabled
|
40 |
+
@ajax_wc_checkout_validate_nonce = args.ajax_wc_checkout_validate_nonce
|
41 |
+
@is_manual_order_payment = args.is_manual_order_payment
|
42 |
|
43 |
# which payment form?
|
44 |
if $( 'form.checkout' ).length
|
399 |
handle_verify_buyer_response: ( errors, verification_result ) =>
|
400 |
|
401 |
if errors
|
402 |
+
$( errors ).each ( index, error ) =>
|
403 |
+
if not error.field
|
404 |
+
error.field = 'none';
|
405 |
return this.handle_errors( errors )
|
406 |
|
407 |
# no errors, but also no verification token
|
507 |
|
508 |
if errors
|
509 |
|
510 |
+
field_order = [ "none", "cardNumber", "expirationDate", "cvv", "postalCode" ]
|
|
|
|
|
|
|
|
|
511 |
|
512 |
+
if errors.length >= 1
|
513 |
+
# sort based on the field order
|
514 |
+
# without the brackets around a.field and b.field the precedence is different and gives different results
|
515 |
+
errors.sort (a,b) -> field_order.indexOf(a.field) - field_order.indexOf(b.field)
|
516 |
|
517 |
$( errors ).each ( index, error ) =>
|
518 |
|
530 |
if messages.length is 0
|
531 |
messages.push( @general_error )
|
532 |
|
533 |
+
# Conditionally process error rendering
|
534 |
+
if not @is_add_payment_method_page and not @is_manual_order_payment
|
535 |
+
this.render_checkout_errors( messages )
|
536 |
+
else
|
537 |
+
this.render_errors( messages )
|
538 |
|
539 |
this.unblock_ui()
|
540 |
|
635 |
console.error 'Square Error: ' + message
|
636 |
else
|
637 |
console.log 'Square: ' + message
|
638 |
+
|
639 |
+
# AJAX validate WooCommerce form data.
|
640 |
+
#
|
641 |
+
# Triggered only if errors are present on Square payment form.
|
642 |
+
#
|
643 |
+
# @since 2.2
|
644 |
+
#
|
645 |
+
# @param Array square_errors Square validation errors.
|
646 |
+
render_checkout_errors: ( square_errors ) ->
|
647 |
+
ajax_url = wc_cart_fragments_params.wc_ajax_url.toString().replace( '%%endpoint%%', @id + '_checkout_handler' )
|
648 |
+
form_data = @form.serializeArray()
|
649 |
+
square_handler = this
|
650 |
+
|
651 |
+
# Add action field to data for nonce verification.
|
652 |
+
form_data.push({
|
653 |
+
name: 'wc_' + @id + '_checkout_validate_nonce', 'value': @ajax_wc_checkout_validate_nonce
|
654 |
+
})
|
655 |
+
|
656 |
+
$.ajax({
|
657 |
+
url : ajax_url,
|
658 |
+
method : 'post',
|
659 |
+
cache : false,
|
660 |
+
data : form_data,
|
661 |
+
complete : ( response ) ->
|
662 |
+
result = response.responseJSON
|
663 |
+
|
664 |
+
# If validation is not triggered and WooCommerce returns failure.
|
665 |
+
# Temporary workaround to fix problems when user email is invalid.
|
666 |
+
if result.hasOwnProperty( 'result' ) and 'failure' == result.result
|
667 |
+
$(result.messages).map ->
|
668 |
+
errors = []
|
669 |
+
$( this ).children( 'li' ).each ->
|
670 |
+
errors.push( $( this ).text().trim() )
|
671 |
+
square_errors.unshift( ...errors )
|
672 |
+
|
673 |
+
# If validation is complete and WooCommerce returns validaiton errors.
|
674 |
+
else if result.hasOwnProperty( 'success' ) and not result.success
|
675 |
+
square_errors.unshift( ...result.data.messages )
|
676 |
+
|
677 |
+
square_handler.render_errors( square_errors )
|
678 |
+
})
|
assets/js/frontend/wc-square.min.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
"use strict";function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var _createClass=function(){function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n&&e(t.prototype,n),i&&e(t,i),t}}();(function(){var e=[].indexOf;jQuery(document).ready(function(t){return window.WC_Square_Payment_Form_Handler=function(){function n(e){if(_classCallCheck(this,n),this.set_payment_fields=this.set_payment_fields.bind(this),this.get_form_params=this.get_form_params.bind(this),this.handle_input_event=this.handle_input_event.bind(this),this.handle_verify_buyer_response=this.handle_verify_buyer_response.bind(this),this.id=e.id,this.id_dasherized=e.id_dasherized,this.csc_required=e.csc_required,this.enabled_card_types=e.enabled_card_types,this.square_card_types=e.square_card_types,this.ajax_log_nonce=e.ajax_log_nonce,this.ajax_url=e.ajax_url,this.application_id=e.application_id,this.currency_code=e.currency_code,this.general_error=e.general_error,this.input_styles=e.input_styles,this.is_3ds_enabled=e.is_3d_secure_enabled,this.is_add_payment_method_page=e.is_add_payment_method_page,this.is_checkout_registration_enabled=e.is_checkout_registration_enabled,this.is_user_logged_in=e.is_user_logged_in,this.location_id=e.location_id,this.logging_enabled=e.logging_enabled,t("form.checkout").length)this.form=t("form.checkout"),this.handle_checkout_page();else if(t("form#order_review").length)this.form=t("form#order_review"),this.handle_pay_page();else{if(!t("form#add_payment_method").length)return void this.log("No payment form found!");this.form=t("form#add_payment_method"),this.handle_add_payment_method_page()}this.params=window.sv_wc_payment_gateway_payment_form_params,t(document.body).on("checkout_error",function(){return t("input[name=wc-square-credit-card-payment-nonce]").val(""),t("input[name=wc-square-credit-card-buyer-verification-token]").val("")}),t(document.body).on("click","#payment_method_"+this.id,function(){if(this.payment_form)return this.log("Recalculating payment form size"),this.payment_form.recalculateSize()})}return _createClass(n,[{key:"handle_checkout_page",value:function(){var e=this;return t(document.body).on("updated_checkout",function(){return e.set_payment_fields()}),t(document.body).on("updated_checkout",function(){return e.handle_saved_payment_methods()}),this.form.on("checkout_place_order_"+this.id,function(){return e.validate_payment_data()})}},{key:"handle_saved_payment_methods",value:function(){var e,n,i;if(i=this.id_dasherized,n=this,e=t("div.js-wc-"+i+"-new-payment-method-form"),t("input.js-wc-"+this.id_dasherized+"-payment-token").change(function(){return t("input.js-wc-"+i+"-payment-token:checked").val()?e.slideUp(200):e.slideDown(200)}).change(),t("input#createaccount").change(function(){return t(this).is(":checked")?n.show_save_payment_checkbox(i):n.hide_save_payment_checkbox(i)}),t("input#createaccount").is(":checked")||t("input#createaccount").change(),!this.is_user_logged_in&&!this.is_checkout_registration_enabled)return this.hide_save_payment_checkbox(i)}},{key:"handle_pay_page",value:function(){var e=this;return this.set_payment_fields(),this.handle_saved_payment_methods(),this.form.submit(function(){if(t("#order_review input[name=payment_method]:checked").val()===e.id)return e.validate_payment_data()})}},{key:"handle_add_payment_method_page",value:function(){var e=this;return this.set_payment_fields(),this.form.submit(function(){if(t("#add_payment_method input[name=payment_method]:checked").val()===e.id)return e.validate_payment_data()})}},{key:"set_payment_fields",value:function(){var e,n,i;if(t("#wc-"+this.id_dasherized+"-account-number-hosted").is("iframe")){this.log("Re-adding payment form"),i=this.form_fields;for(e in i)n=i[e],t(n.attr("id")).replaceWith(n);return this.handle_form_loaded()}return this.payment_form&&(this.log("Destroying payment form"),this.payment_form.destroy()),this.log("Building payment form"),this.payment_form=new SqPaymentForm(this.get_form_params()),this.payment_form.build()}},{key:"get_form_params",value:function(){var e=this;return this.form_fields={card_number:t("#wc-"+this.id_dasherized+"-account-number-hosted"),expiration:t("#wc-"+this.id_dasherized+"-expiry-hosted"),csc:t("#wc-"+this.id_dasherized+"-csc-hosted"),postal_code:t("#wc-"+this.id_dasherized+"-postal-code-hosted")},{applicationId:this.application_id,locationId:this.location_id,cardNumber:{elementId:this.form_fields.card_number.attr("id"),placeholder:this.form_fields.card_number.data("placeholder")},expirationDate:{elementId:this.form_fields.expiration.attr("id"),placeholder:this.form_fields.expiration.data("placeholder")},cvv:{elementId:this.form_fields.csc.attr("id"),placeholder:this.form_fields.csc.data("placeholder")},postalCode:{elementId:this.form_fields.postal_code.attr("id"),placeholder:this.form_fields.postal_code.data("placeholder")},inputClass:"wc-"+this.id_dasherized+"-payment-field",inputStyles:this.input_styles,callbacks:{inputEventReceived:function(t){return e.handle_input_event(t)},cardNonceResponseReceived:function(t,n,i){return e.handle_card_nonce_response(t,n,i)},unsupportedBrowserDetected:function(){return e.handle_unsupported_browser()},paymentFormLoaded:function(){return e.handle_form_loaded()}}}}},{key:"handle_form_loaded",value:function(){if(this.log("Payment form loaded"),this.payment_form.setPostalCode(t("#billing_postcode").val()),t("form.checkout").length||t("#billing_postcode").val())return t(".wc-square-credit-card-card-postal-code-parent").addClass("hidden")}},{key:"handle_input_event",value:function(e){var n;if(n=t("#"+e.elementId),"cardBrandChanged"===e.eventType)return this.handle_card_brand_change(e.cardBrand,n)}},{key:"handle_card_brand_change",value:function(n,i){var a;return this.log("Card brand changed to "+n),i.attr("class",function(e,t){return t.replace(/(^|\s)card-type-\S+/g,"")}),a="plain",null!=n&&"unknown"!==n||(n=""),null!=this.square_card_types[n]&&(n=this.square_card_types[n]),a=n&&e.call(this.enabled_card_types,n)<0?"invalid":n,t("input[name=wc-"+this.id_dasherized+"-card-type]").val(n),i.addClass("card-type-"+a)}},{key:"validate_payment_data",value:function(){var e;return!this.form.is(".processing")&&(this.has_nonce()?(this.log("Payment nonce present, placing order"),!0):(e=this.get_tokenized_payment_method_id())?!this.is_3ds_enabled||(this.has_verification_token()?(this.log("Tokenized payment verification token present, placing order"),!0):(this.log("Requesting verification token for tokenized payment"),this.block_ui(),this.payment_form.verifyBuyer(e,this.get_verification_details(),this.handle_verify_buyer_response),!1)):(this.log("Requesting payment nonce"),this.block_ui(),this.payment_form.requestCardNonce(),!1))}},{key:"get_tokenized_payment_method_id",value:function(){return t(".payment_method_"+this.id).find(".js-wc-square-credit-card-payment-token:checked").val()}},{key:"handle_card_nonce_response",value:function(e,n,i){var a;return e?this.handle_errors(e):n?(this.log("Card data received"),this.log(i),this.log_data(i,"response"),i.last_4&&t("input[name=wc-"+this.id_dasherized+"-last-four]").val(i.last_4),i.exp_month&&t("input[name=wc-"+this.id_dasherized+"-exp-month]").val(i.exp_month),i.exp_year&&t("input[name=wc-"+this.id_dasherized+"-exp-year]").val(i.exp_year),i.billing_postal_code&&t("input[name=wc-square-credit-card-payment-postcode]").val(i.billing_postal_code),t("input[name=wc-"+this.id_dasherized+"-payment-nonce]").val(n),this.is_3ds_enabled?(this.log("Verifying buyer"),void this.payment_form.verifyBuyer(n,this.get_verification_details(),this.handle_verify_buyer_response)):this.form.submit()):(a="Nonce is missing from the Square response",this.log(a,"error"),this.log_data(a,"response"),this.handle_errors())}},{key:"handle_verify_buyer_response",value:function(e,n){var i;return e?this.handle_errors(e):n&&n.token?(this.log("Verification result received"),this.log(n),t("input[name=wc-"+this.id_dasherized+"-buyer-verification-token]").val(n.token),this.form.submit()):(i="Verification token is missing from the Square response",this.log(i,"error"),this.log_data(i,"response"),this.handle_errors())}},{key:"get_verification_details",value:function(){var e,n,i,a,r,o,s,d,l,_,c;return"CHARGE"===(c={billingContact:{familyName:null!=(e=t("#billing_last_name").val())?e:"",givenName:null!=(n=t("#billing_first_name").val())?n:"",email:null!=(i=t("#billing_email").val())?i:"",country:null!=(a=t("#billing_country").val())?a:"",region:null!=(r=t("#billing_state").val())?r:"",city:null!=(o=t("#billing_city").val())?o:"",postalCode:null!=(s=t("#billing_postcode").val())?s:"",phone:null!=(d=t("#billing_phone").val())?d:"",addressLines:[null!=(l=t("#billing_address_1").val())?l:"",null!=(_=t("#billing_address_2").val())?_:""]},intent:this.get_intent()}).intent&&(c.amount=this.get_amount(),c.currencyCode=this.currency_code),this.log(c),c}},{key:"get_intent",value:function(){var e,n;return e=t("#wc-square-credit-card-tokenize-payment-method"),n=e.is("input:checkbox")?e.is(":checked"):"true"===e.val(),!this.get_tokenized_payment_method_id()&&n?"STORE":"CHARGE"}},{key:"get_amount",value:function(){return t("input[name=wc-"+this.id_dasherized+"-amount]").val()}},{key:"handle_unsupported_browser",value:function(){}},{key:"handle_errors",value:function(){var e,n,i=this,a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return this.log("Error getting payment data","error"),t("input[name=wc-square-credit-card-payment-nonce]").val(""),t("input[name=wc-square-credit-card-buyer-verification-token]").val(""),n=[],a&&(e=["cardNumber","expirationDate","cvv","postalCode"],a.sort(function(t,n){return e.indexOf(t.field)-e.indexOf(n.field)}),console.error(a),t(a).each(function(e,t){var r;return"UNSUPPORTED_CARD_BRAND"===(r=t.type)||"VALIDATION_ERROR"===r?n.push(t.message.replace(/CVV/,"CSC")):i.log_data(a,"response")})),0===n.length&&n.push(this.general_error),this.render_errors(n),this.unblock_ui()}},{key:"render_errors",value:function(e){return t(".woocommerce-error, .woocommerce-message").remove(),this.form.prepend('<ul class="woocommerce-error"><li>'+e.join("</li><li>")+"</li></ul>"),this.form.removeClass("processing").unblock(),this.form.find(".input-text, select").blur(),t("html, body").animate({scrollTop:this.form.offset().top-100},1e3)}},{key:"block_ui",value:function(){return this.form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})}},{key:"unblock_ui",value:function(){return this.form.unblock()}},{key:"hide_save_payment_checkbox",value:function(e){var n;return(n=t("input.js-wc-"+e+"-tokenize-payment-method").closest("p.form-row")).hide(),n.next().hide()}},{key:"show_save_payment_checkbox",value:function(e){var n;return(n=t("input.js-wc-"+e+"-tokenize-payment-method").closest("p.form-row")).slideDown(),n.next().show()}},{key:"has_nonce",value:function(){return t("input[name=wc-"+this.id_dasherized+"-payment-nonce]").val()}},{key:"has_verification_token",value:function(){return t("input[name=wc-"+this.id_dasherized+"-buyer-verification-token]").val()}},{key:"log_data",value:function(e,n){var i;if(this.logging_enabled)return i={action:"wc_"+this.id+"_log_js_data",security:this.ajax_log_nonce,type:n,data:e},t.ajax({url:this.ajax_url,data:i})}},{key:"log",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"notice";if(this.logging_enabled)return"error"===t?console.error("Square Error: "+e):console.log("Square: "+e)}}]),n}()})}).call(void 0);
|
2 |
//# sourceMappingURL=wc-square.min.js.map
|
1 |
+
"use strict";function _toConsumableArray(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var _createClass=function(){function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n&&e(t.prototype,n),i&&e(t,i),t}}();(function(){var e=[].indexOf;jQuery(document).ready(function(t){return window.WC_Square_Payment_Form_Handler=function(){function n(e){if(_classCallCheck(this,n),this.set_payment_fields=this.set_payment_fields.bind(this),this.get_form_params=this.get_form_params.bind(this),this.handle_input_event=this.handle_input_event.bind(this),this.handle_verify_buyer_response=this.handle_verify_buyer_response.bind(this),this.id=e.id,this.id_dasherized=e.id_dasherized,this.csc_required=e.csc_required,this.enabled_card_types=e.enabled_card_types,this.square_card_types=e.square_card_types,this.ajax_log_nonce=e.ajax_log_nonce,this.ajax_url=e.ajax_url,this.application_id=e.application_id,this.currency_code=e.currency_code,this.general_error=e.general_error,this.input_styles=e.input_styles,this.is_3ds_enabled=e.is_3d_secure_enabled,this.is_add_payment_method_page=e.is_add_payment_method_page,this.is_checkout_registration_enabled=e.is_checkout_registration_enabled,this.is_user_logged_in=e.is_user_logged_in,this.location_id=e.location_id,this.logging_enabled=e.logging_enabled,this.ajax_wc_checkout_validate_nonce=e.ajax_wc_checkout_validate_nonce,this.is_manual_order_payment=e.is_manual_order_payment,t("form.checkout").length)this.form=t("form.checkout"),this.handle_checkout_page();else if(t("form#order_review").length)this.form=t("form#order_review"),this.handle_pay_page();else{if(!t("form#add_payment_method").length)return void this.log("No payment form found!");this.form=t("form#add_payment_method"),this.handle_add_payment_method_page()}this.params=window.sv_wc_payment_gateway_payment_form_params,t(document.body).on("checkout_error",function(){return t("input[name=wc-square-credit-card-payment-nonce]").val(""),t("input[name=wc-square-credit-card-buyer-verification-token]").val("")}),t(document.body).on("click","#payment_method_"+this.id,function(){if(this.payment_form)return this.log("Recalculating payment form size"),this.payment_form.recalculateSize()})}return _createClass(n,[{key:"handle_checkout_page",value:function(){var e=this;return t(document.body).on("updated_checkout",function(){return e.set_payment_fields()}),t(document.body).on("updated_checkout",function(){return e.handle_saved_payment_methods()}),this.form.on("checkout_place_order_"+this.id,function(){return e.validate_payment_data()})}},{key:"handle_saved_payment_methods",value:function(){var e,n,i;if(i=this.id_dasherized,n=this,e=t("div.js-wc-"+i+"-new-payment-method-form"),t("input.js-wc-"+this.id_dasherized+"-payment-token").change(function(){return t("input.js-wc-"+i+"-payment-token:checked").val()?e.slideUp(200):e.slideDown(200)}).change(),t("input#createaccount").change(function(){return t(this).is(":checked")?n.show_save_payment_checkbox(i):n.hide_save_payment_checkbox(i)}),t("input#createaccount").is(":checked")||t("input#createaccount").change(),!this.is_user_logged_in&&!this.is_checkout_registration_enabled)return this.hide_save_payment_checkbox(i)}},{key:"handle_pay_page",value:function(){var e=this;return this.set_payment_fields(),this.handle_saved_payment_methods(),this.form.submit(function(){if(t("#order_review input[name=payment_method]:checked").val()===e.id)return e.validate_payment_data()})}},{key:"handle_add_payment_method_page",value:function(){var e=this;return this.set_payment_fields(),this.form.submit(function(){if(t("#add_payment_method input[name=payment_method]:checked").val()===e.id)return e.validate_payment_data()})}},{key:"set_payment_fields",value:function(){var e,n,i;if(t("#wc-"+this.id_dasherized+"-account-number-hosted").is("iframe")){this.log("Re-adding payment form"),i=this.form_fields;for(e in i)n=i[e],t(n.attr("id")).replaceWith(n);return this.handle_form_loaded()}return this.payment_form&&(this.log("Destroying payment form"),this.payment_form.destroy()),this.log("Building payment form"),this.payment_form=new SqPaymentForm(this.get_form_params()),this.payment_form.build()}},{key:"get_form_params",value:function(){var e=this;return this.form_fields={card_number:t("#wc-"+this.id_dasherized+"-account-number-hosted"),expiration:t("#wc-"+this.id_dasherized+"-expiry-hosted"),csc:t("#wc-"+this.id_dasherized+"-csc-hosted"),postal_code:t("#wc-"+this.id_dasherized+"-postal-code-hosted")},{applicationId:this.application_id,locationId:this.location_id,cardNumber:{elementId:this.form_fields.card_number.attr("id"),placeholder:this.form_fields.card_number.data("placeholder")},expirationDate:{elementId:this.form_fields.expiration.attr("id"),placeholder:this.form_fields.expiration.data("placeholder")},cvv:{elementId:this.form_fields.csc.attr("id"),placeholder:this.form_fields.csc.data("placeholder")},postalCode:{elementId:this.form_fields.postal_code.attr("id"),placeholder:this.form_fields.postal_code.data("placeholder")},inputClass:"wc-"+this.id_dasherized+"-payment-field",inputStyles:this.input_styles,callbacks:{inputEventReceived:function(t){return e.handle_input_event(t)},cardNonceResponseReceived:function(t,n,i){return e.handle_card_nonce_response(t,n,i)},unsupportedBrowserDetected:function(){return e.handle_unsupported_browser()},paymentFormLoaded:function(){return e.handle_form_loaded()}}}}},{key:"handle_form_loaded",value:function(){if(this.log("Payment form loaded"),this.payment_form.setPostalCode(t("#billing_postcode").val()),t("form.checkout").length||t("#billing_postcode").val())return t(".wc-square-credit-card-card-postal-code-parent").addClass("hidden")}},{key:"handle_input_event",value:function(e){var n;if(n=t("#"+e.elementId),"cardBrandChanged"===e.eventType)return this.handle_card_brand_change(e.cardBrand,n)}},{key:"handle_card_brand_change",value:function(n,i){var a;return this.log("Card brand changed to "+n),i.attr("class",function(e,t){return t.replace(/(^|\s)card-type-\S+/g,"")}),a="plain",null!=n&&"unknown"!==n||(n=""),null!=this.square_card_types[n]&&(n=this.square_card_types[n]),a=n&&e.call(this.enabled_card_types,n)<0?"invalid":n,t("input[name=wc-"+this.id_dasherized+"-card-type]").val(n),i.addClass("card-type-"+a)}},{key:"validate_payment_data",value:function(){var e;return!this.form.is(".processing")&&(this.has_nonce()?(this.log("Payment nonce present, placing order"),!0):(e=this.get_tokenized_payment_method_id())?!this.is_3ds_enabled||(this.has_verification_token()?(this.log("Tokenized payment verification token present, placing order"),!0):(this.log("Requesting verification token for tokenized payment"),this.block_ui(),this.payment_form.verifyBuyer(e,this.get_verification_details(),this.handle_verify_buyer_response),!1)):(this.log("Requesting payment nonce"),this.block_ui(),this.payment_form.requestCardNonce(),!1))}},{key:"get_tokenized_payment_method_id",value:function(){return t(".payment_method_"+this.id).find(".js-wc-square-credit-card-payment-token:checked").val()}},{key:"handle_card_nonce_response",value:function(e,n,i){var a;return e?this.handle_errors(e):n?(this.log("Card data received"),this.log(i),this.log_data(i,"response"),i.last_4&&t("input[name=wc-"+this.id_dasherized+"-last-four]").val(i.last_4),i.exp_month&&t("input[name=wc-"+this.id_dasherized+"-exp-month]").val(i.exp_month),i.exp_year&&t("input[name=wc-"+this.id_dasherized+"-exp-year]").val(i.exp_year),i.billing_postal_code&&t("input[name=wc-square-credit-card-payment-postcode]").val(i.billing_postal_code),t("input[name=wc-"+this.id_dasherized+"-payment-nonce]").val(n),this.is_3ds_enabled?(this.log("Verifying buyer"),void this.payment_form.verifyBuyer(n,this.get_verification_details(),this.handle_verify_buyer_response)):this.form.submit()):(a="Nonce is missing from the Square response",this.log(a,"error"),this.log_data(a,"response"),this.handle_errors())}},{key:"handle_verify_buyer_response",value:function(e,n){var i;return e?(t(e).each(function(e,t){if(!t.field)return t.field="none"}),this.handle_errors(e)):n&&n.token?(this.log("Verification result received"),this.log(n),t("input[name=wc-"+this.id_dasherized+"-buyer-verification-token]").val(n.token),this.form.submit()):(i="Verification token is missing from the Square response",this.log(i,"error"),this.log_data(i,"response"),this.handle_errors())}},{key:"get_verification_details",value:function(){var e,n,i,a,r,o,s,d,l,_,c;return"CHARGE"===(c={billingContact:{familyName:null!=(e=t("#billing_last_name").val())?e:"",givenName:null!=(n=t("#billing_first_name").val())?n:"",email:null!=(i=t("#billing_email").val())?i:"",country:null!=(a=t("#billing_country").val())?a:"",region:null!=(r=t("#billing_state").val())?r:"",city:null!=(o=t("#billing_city").val())?o:"",postalCode:null!=(s=t("#billing_postcode").val())?s:"",phone:null!=(d=t("#billing_phone").val())?d:"",addressLines:[null!=(l=t("#billing_address_1").val())?l:"",null!=(_=t("#billing_address_2").val())?_:""]},intent:this.get_intent()}).intent&&(c.amount=this.get_amount(),c.currencyCode=this.currency_code),this.log(c),c}},{key:"get_intent",value:function(){var e,n;return e=t("#wc-square-credit-card-tokenize-payment-method"),n=e.is("input:checkbox")?e.is(":checked"):"true"===e.val(),!this.get_tokenized_payment_method_id()&&n?"STORE":"CHARGE"}},{key:"get_amount",value:function(){return t("input[name=wc-"+this.id_dasherized+"-amount]").val()}},{key:"handle_unsupported_browser",value:function(){}},{key:"handle_errors",value:function(){var e,n,i=this,a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return this.log("Error getting payment data","error"),t("input[name=wc-square-credit-card-payment-nonce]").val(""),t("input[name=wc-square-credit-card-buyer-verification-token]").val(""),n=[],a&&(e=["none","cardNumber","expirationDate","cvv","postalCode"],a.length>=1&&a.sort(function(t,n){return e.indexOf(t.field)-e.indexOf(n.field)}),t(a).each(function(e,t){var r;return"UNSUPPORTED_CARD_BRAND"===(r=t.type)||"VALIDATION_ERROR"===r?n.push(t.message.replace(/CVV/,"CSC")):i.log_data(a,"response")})),0===n.length&&n.push(this.general_error),this.is_add_payment_method_page||this.is_manual_order_payment?this.render_errors(n):this.render_checkout_errors(n),this.unblock_ui()}},{key:"render_errors",value:function(e){return t(".woocommerce-error, .woocommerce-message").remove(),this.form.prepend('<ul class="woocommerce-error"><li>'+e.join("</li><li>")+"</li></ul>"),this.form.removeClass("processing").unblock(),this.form.find(".input-text, select").blur(),t("html, body").animate({scrollTop:this.form.offset().top-100},1e3)}},{key:"block_ui",value:function(){return this.form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})}},{key:"unblock_ui",value:function(){return this.form.unblock()}},{key:"hide_save_payment_checkbox",value:function(e){var n;return(n=t("input.js-wc-"+e+"-tokenize-payment-method").closest("p.form-row")).hide(),n.next().hide()}},{key:"show_save_payment_checkbox",value:function(e){var n;return(n=t("input.js-wc-"+e+"-tokenize-payment-method").closest("p.form-row")).slideDown(),n.next().show()}},{key:"has_nonce",value:function(){return t("input[name=wc-"+this.id_dasherized+"-payment-nonce]").val()}},{key:"has_verification_token",value:function(){return t("input[name=wc-"+this.id_dasherized+"-buyer-verification-token]").val()}},{key:"log_data",value:function(e,n){var i;if(this.logging_enabled)return i={action:"wc_"+this.id+"_log_js_data",security:this.ajax_log_nonce,type:n,data:e},t.ajax({url:this.ajax_url,data:i})}},{key:"log",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"notice";if(this.logging_enabled)return"error"===t?console.error("Square Error: "+e):console.log("Square: "+e)}},{key:"render_checkout_errors",value:function(e){var n,i,a;return n=wc_cart_fragments_params.wc_ajax_url.toString().replace("%%endpoint%%",this.id+"_checkout_handler"),i=this.form.serializeArray(),a=this,i.push({name:"wc_"+this.id+"_checkout_validate_nonce",value:this.ajax_wc_checkout_validate_nonce}),t.ajax({url:n,method:"post",cache:!1,data:i,complete:function(n){var i;return(i=n.responseJSON).hasOwnProperty("result")&&"failure"===i.result?t(i.messages).map(function(){var n;return n=[],t(this).children("li").each(function(){return n.push(t(this).text().trim())}),e.unshift.apply(e,_toConsumableArray(n))}):i.hasOwnProperty("success")&&!i.success&&e.unshift.apply(e,_toConsumableArray(i.data.messages)),a.render_errors(e)}})}}]),n}()})}).call(void 0);
|
2 |
//# sourceMappingURL=wc-square.min.js.map
|
assets/js/frontend/wc-square.min.js.map
CHANGED
@@ -1 +1 @@
|
|
1 |
-
{"version":3,"sources":["wc-square.min.js"],"names":["_classCallCheck","instance","Constructor","TypeError","_createClass","defineProperties","target","props","i","length","descriptor","enumerable","configurable","writable","Object","defineProperty","key","protoProps","staticProps","prototype","indexOf","jQuery","document","ready","$","window","WC_Square_Payment_Form_Handler","args","this","set_payment_fields","bind","get_form_params","handle_input_event","handle_verify_buyer_response","id","id_dasherized","csc_required","enabled_card_types","square_card_types","ajax_log_nonce","ajax_url","application_id","currency_code","general_error","input_styles","is_3ds_enabled","is_3d_secure_enabled","is_add_payment_method_page","is_checkout_registration_enabled","is_user_logged_in","location_id","logging_enabled","form","handle_checkout_page","handle_pay_page","log","handle_add_payment_method_page","params","body","on","val","payment_form","recalculateSize","value","_this","handle_saved_payment_methods","validate_payment_data","$new_payment_method_selection","form_handler","change","slideUp","slideDown","is","show_save_payment_checkbox","hide_save_payment_checkbox","_this2","submit","_this3","_","field","ref","form_fields","attr","replaceWith","handle_form_loaded","destroy","SqPaymentForm","build","_this4","card_number","expiration","csc","postal_code","applicationId","locationId","cardNumber","elementId","placeholder","data","expirationDate","cvv","postalCode","inputClass","inputStyles","callbacks","inputEventReceived","event","cardNonceResponseReceived","errors","nonce","cardData","handle_card_nonce_response","unsupportedBrowserDetected","handle_unsupported_browser","paymentFormLoaded","setPostalCode","addClass","$input","eventType","handle_card_brand_change","cardBrand","brand","card_class","c","replace","call","tokenized_card_id","has_nonce","get_tokenized_payment_method_id","has_verification_token","block_ui","verifyBuyer","get_verification_details","requestCardNonce","find","message","handle_errors","log_data","last_4","exp_month","exp_year","billing_postal_code","verification_result","token","ref1","ref2","ref3","ref4","ref5","ref6","ref7","ref8","ref9","verification_details","billingContact","familyName","givenName","email","country","region","city","phone","addressLines","intent","get_intent","amount","get_amount","currencyCode","$save_method_input","save_payment_method","field_order","messages","_this5","arguments","undefined","sort","a","b","console","error","each","index","type","push","render_errors","unblock_ui","remove","prepend","join","removeClass","unblock","blur","animate","scrollTop","offset","top","block","overlayCSS","background","opacity","$parent_row","closest","hide","next","show","ajax_data","action","security","ajax","url"],"mappings":"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","file":"wc-square.min.js"}
|
1 |
+
{"version":3,"sources":["wc-square.min.js"],"names":["_toConsumableArray","arr","Array","isArray","i","arr2","length","from","_classCallCheck","instance","Constructor","TypeError","_createClass","defineProperties","target","props","descriptor","enumerable","configurable","writable","Object","defineProperty","key","protoProps","staticProps","prototype","indexOf","jQuery","document","ready","$","window","WC_Square_Payment_Form_Handler","args","this","set_payment_fields","bind","get_form_params","handle_input_event","handle_verify_buyer_response","id","id_dasherized","csc_required","enabled_card_types","square_card_types","ajax_log_nonce","ajax_url","application_id","currency_code","general_error","input_styles","is_3ds_enabled","is_3d_secure_enabled","is_add_payment_method_page","is_checkout_registration_enabled","is_user_logged_in","location_id","logging_enabled","ajax_wc_checkout_validate_nonce","is_manual_order_payment","form","handle_checkout_page","handle_pay_page","log","handle_add_payment_method_page","params","body","on","val","payment_form","recalculateSize","value","_this","handle_saved_payment_methods","validate_payment_data","$new_payment_method_selection","form_handler","change","slideUp","slideDown","is","show_save_payment_checkbox","hide_save_payment_checkbox","_this2","submit","_this3","_","field","ref","form_fields","attr","replaceWith","handle_form_loaded","destroy","SqPaymentForm","build","_this4","card_number","expiration","csc","postal_code","applicationId","locationId","cardNumber","elementId","placeholder","data","expirationDate","cvv","postalCode","inputClass","inputStyles","callbacks","inputEventReceived","event","cardNonceResponseReceived","errors","nonce","cardData","handle_card_nonce_response","unsupportedBrowserDetected","handle_unsupported_browser","paymentFormLoaded","setPostalCode","addClass","$input","eventType","handle_card_brand_change","cardBrand","brand","card_class","c","replace","call","tokenized_card_id","has_nonce","get_tokenized_payment_method_id","has_verification_token","block_ui","verifyBuyer","get_verification_details","requestCardNonce","find","message","handle_errors","log_data","last_4","exp_month","exp_year","billing_postal_code","verification_result","each","index","error","token","ref1","ref2","ref3","ref4","ref5","ref6","ref7","ref8","ref9","verification_details","billingContact","familyName","givenName","email","country","region","city","phone","addressLines","intent","get_intent","amount","get_amount","currencyCode","$save_method_input","save_payment_method","field_order","messages","_this5","arguments","undefined","sort","a","b","type","push","render_errors","render_checkout_errors","unblock_ui","remove","prepend","join","removeClass","unblock","blur","animate","scrollTop","offset","top","block","overlayCSS","background","opacity","$parent_row","closest","hide","next","show","ajax_data","action","security","ajax","url","console","square_errors","form_data","square_handler","wc_cart_fragments_params","wc_ajax_url","toString","serializeArray","name","method","cache","complete","response","result","responseJSON","hasOwnProperty","map","children","text","trim","unshift","apply","success"],"mappings":"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","file":"wc-square.min.js"}
|
i18n/languages/woocommerce-square.pot
CHANGED
@@ -2,10 +2,10 @@
|
|
2 |
# This file is distributed under the GNU General Public License v3.0.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: WooCommerce Square 2.
|
6 |
"Report-Msgid-Bugs-To: "
|
7 |
"https://github.com/woocommerce/woocommerce-square/issues\n"
|
8 |
-
"POT-Creation-Date: 2020-
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=utf-8\n"
|
11 |
"Content-Transfer-Encoding: 8bit\n"
|
@@ -42,42 +42,42 @@ msgstr ""
|
|
42 |
msgid "Could not delete records."
|
43 |
msgstr ""
|
44 |
|
45 |
-
#: includes/AJAX.php:
|
46 |
msgid "Could not delete record."
|
47 |
msgstr ""
|
48 |
|
49 |
-
#: includes/AJAX.php:
|
50 |
msgid "Could not resolve record."
|
51 |
msgstr ""
|
52 |
|
53 |
-
#: includes/AJAX.php:
|
54 |
msgid "Could not unsync product."
|
55 |
msgstr ""
|
56 |
|
57 |
-
#: includes/AJAX.php:
|
58 |
#. translators: Placeholder: %s - error message
|
59 |
msgid "An error occurred. %s"
|
60 |
msgstr ""
|
61 |
|
62 |
-
#: includes/AJAX.php:
|
63 |
#. translators: Placeholder: %s - sync job ID
|
64 |
msgid "No sync job in progress found %s"
|
65 |
msgstr ""
|
66 |
|
67 |
-
#: includes/AJAX.php:
|
68 |
msgid "Stock must be fetched from Square before editing stock quantity"
|
69 |
msgstr ""
|
70 |
|
71 |
-
#: includes/Admin/Privacy.php:
|
72 |
-
#: includes/Gateway.php:
|
73 |
msgid "Square"
|
74 |
msgstr ""
|
75 |
|
76 |
-
#: includes/Admin/Privacy.php:
|
77 |
msgid "WooCommerce Square Customer Data"
|
78 |
msgstr ""
|
79 |
|
80 |
-
#: includes/Admin/Privacy.php:
|
81 |
#. translators: Placeholder: %1$s - <a> tag, %2$s - </a> tag
|
82 |
msgid ""
|
83 |
"By using this extension, you may be storing personal data or sharing data "
|
@@ -101,27 +101,30 @@ msgstr ""
|
|
101 |
msgid "Import Products From Square"
|
102 |
msgstr ""
|
103 |
|
104 |
-
#: includes/Admin/Settings_Page.php:175 includes/Admin/Sync_Page.php:
|
105 |
msgid "Close modal window"
|
106 |
msgstr ""
|
107 |
|
108 |
#: includes/Admin/Settings_Page.php:180
|
109 |
#. translators: Placeholders: %1$s - <strong>, %2%s - </strong>
|
110 |
msgid ""
|
111 |
-
"You are about to import all products
|
112 |
-
"product in WooCommerce for every product
|
113 |
-
"products in the trash from the previous
|
114 |
-
"the import.
|
|
|
|
|
|
|
115 |
msgstr ""
|
116 |
|
117 |
-
#: includes/Admin/Settings_Page.php:184 includes/Admin/Sync_Page.php:
|
118 |
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:133
|
119 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/admin/views/html-order-partial-capture.php:66
|
120 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway-my-payment-methods.php:227
|
121 |
msgid "Cancel"
|
122 |
msgstr ""
|
123 |
|
124 |
-
#: includes/Admin/Settings_Page.php:185 includes/Settings.php:
|
125 |
msgid "Import Products"
|
126 |
msgstr ""
|
127 |
|
@@ -129,7 +132,7 @@ msgstr ""
|
|
129 |
msgid "Sync records"
|
130 |
msgstr ""
|
131 |
|
132 |
-
#: includes/Admin/Sync_Page.php:
|
133 |
#. translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s,
|
134 |
#. $4%s - closing </strong> HTML tag
|
135 |
msgid ""
|
@@ -138,7 +141,7 @@ msgid ""
|
|
138 |
"description, category, inventory%4$s."
|
139 |
msgstr ""
|
140 |
|
141 |
-
#: includes/Admin/Sync_Page.php:
|
142 |
#. translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing
|
143 |
#. </strong> HTML tag
|
144 |
msgid ""
|
@@ -146,7 +149,7 @@ msgid ""
|
|
146 |
"set in WooCommerce."
|
147 |
msgstr ""
|
148 |
|
149 |
-
#: includes/Admin/Sync_Page.php:
|
150 |
#. translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s,
|
151 |
#. %4$s - closing </strong> HTML tag
|
152 |
msgid ""
|
@@ -155,7 +158,7 @@ msgid ""
|
|
155 |
"price, inventory, category, image%4$s."
|
156 |
msgstr ""
|
157 |
|
158 |
-
#: includes/Admin/Sync_Page.php:
|
159 |
#. translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing
|
160 |
#. </strong> HTML tag
|
161 |
msgid ""
|
@@ -163,46 +166,46 @@ msgid ""
|
|
163 |
"Square and WooCommerce."
|
164 |
msgstr ""
|
165 |
|
166 |
-
#: includes/Admin/Sync_Page.php:
|
167 |
msgid "Please connect to Square to enable product sync."
|
168 |
msgstr ""
|
169 |
|
170 |
-
#: includes/Admin/Sync_Page.php:
|
171 |
msgid "Please set the business location to enable product sync."
|
172 |
msgstr ""
|
173 |
|
174 |
-
#: includes/Admin/Sync_Page.php:
|
175 |
msgid "There are currently no products marked to be synced with Square."
|
176 |
msgstr ""
|
177 |
|
178 |
-
#: includes/Admin/Sync_Page.php:
|
179 |
msgid "A sync is currently in progress. Please try again later."
|
180 |
msgstr ""
|
181 |
|
182 |
-
#: includes/Admin/Sync_Page.php:
|
183 |
#. translators: Placeholder: %s - reason text
|
184 |
msgid "Product sync between WooCommerce and Square is currently unavailable. %s"
|
185 |
msgstr ""
|
186 |
|
187 |
-
#: includes/Admin/Sync_Page.php:
|
188 |
msgid "Synced products"
|
189 |
msgstr ""
|
190 |
|
191 |
-
#: includes/Admin/Sync_Page.php:
|
192 |
msgid "Latest sync"
|
193 |
msgstr ""
|
194 |
|
195 |
-
#: includes/Admin/Sync_Page.php:
|
196 |
msgid "Next sync"
|
197 |
msgstr ""
|
198 |
|
199 |
-
#: includes/Admin/Sync_Page.php:
|
200 |
-
#: includes/Admin/Sync_Page.php:
|
201 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway-my-payment-methods.php:426
|
202 |
msgid "Actions"
|
203 |
msgstr ""
|
204 |
|
205 |
-
#: includes/Admin/Sync_Page.php:
|
206 |
#. translators: Placeholder: %d number of products synced with Square
|
207 |
#. translators: Placeholder: %d products count
|
208 |
msgid "%d product"
|
@@ -210,66 +213,66 @@ msgid_plural "%d products"
|
|
210 |
msgstr[0] ""
|
211 |
msgstr[1] ""
|
212 |
|
213 |
-
#: includes/Admin/Sync_Page.php:
|
214 |
msgid "Importing now…"
|
215 |
msgstr ""
|
216 |
|
217 |
-
#: includes/Admin/Sync_Page.php:
|
218 |
msgid "Syncing now…"
|
219 |
msgstr ""
|
220 |
|
221 |
-
#: includes/Admin/Sync_Page.php:
|
222 |
msgid "Not synced yet."
|
223 |
msgstr ""
|
224 |
|
225 |
-
#: includes/Admin/Sync_Page.php:
|
226 |
msgid "Sync now"
|
227 |
msgstr ""
|
228 |
|
229 |
-
#: includes/Admin/Sync_Page.php:
|
230 |
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:97
|
231 |
msgid "Status"
|
232 |
msgstr ""
|
233 |
|
234 |
-
#: includes/Admin/Sync_Page.php:
|
235 |
msgid "Message"
|
236 |
msgstr ""
|
237 |
|
238 |
-
#: includes/Admin/Sync_Page.php:
|
239 |
msgid "No records found."
|
240 |
msgstr ""
|
241 |
|
242 |
-
#: includes/Admin/Sync_Page.php:
|
243 |
msgid "Sync products with Square"
|
244 |
msgstr ""
|
245 |
|
246 |
-
#: includes/Admin/Sync_Page.php:
|
247 |
msgid ""
|
248 |
"If a match is found in Square, product data in WooCommerce will be "
|
249 |
"overwritten with Square data."
|
250 |
msgstr ""
|
251 |
|
252 |
-
#: includes/Admin/Sync_Page.php:
|
253 |
msgid ""
|
254 |
"If a match is found in WooCommerce, product data in Square will be "
|
255 |
"overwritten with WooCommerce data."
|
256 |
msgstr ""
|
257 |
|
258 |
-
#: includes/Admin/Sync_Page.php:
|
259 |
msgid ""
|
260 |
"If a match is not found in Square, the product will be hidden from the "
|
261 |
"catalog in WooCommerce."
|
262 |
msgstr ""
|
263 |
|
264 |
-
#: includes/Admin/Sync_Page.php:
|
265 |
msgid "If a match is not found in Square, the product will be skipped in the sync."
|
266 |
msgstr ""
|
267 |
|
268 |
-
#: includes/Admin/Sync_Page.php:
|
269 |
msgid "If a match is not found, a new product will be created in Square."
|
270 |
msgstr ""
|
271 |
|
272 |
-
#: includes/Admin/Sync_Page.php:
|
273 |
#. translators: Placeholders: %1$s - the system of record name (e.g. Square or
|
274 |
#. WooCommerce), %3%s - unordered HTML list of additional information item(s)
|
275 |
msgid ""
|
@@ -277,51 +280,55 @@ msgid ""
|
|
277 |
"For all products synced with Square: %2$s"
|
278 |
msgstr ""
|
279 |
|
280 |
-
#: includes/Admin/Sync_Page.php:
|
281 |
msgid "Start sync"
|
282 |
msgstr ""
|
283 |
|
284 |
-
#: includes/Admin.php:
|
285 |
msgid "Synced with Square"
|
286 |
msgstr ""
|
287 |
|
288 |
-
#: includes/Admin.php:
|
289 |
msgid "Managed by Square"
|
290 |
msgstr ""
|
291 |
|
292 |
-
#: includes/Admin.php:
|
293 |
msgid "Fetch stock from Square"
|
294 |
msgstr ""
|
295 |
|
296 |
-
#: includes/Admin.php:
|
297 |
msgid "Resolved"
|
298 |
msgstr ""
|
299 |
|
300 |
-
#: includes/Admin.php:
|
301 |
msgid "No records found"
|
302 |
msgstr ""
|
303 |
|
304 |
-
#: includes/Admin.php:
|
305 |
msgid "Skipped"
|
306 |
msgstr ""
|
307 |
|
308 |
-
#: includes/Admin.php:
|
|
|
|
|
|
|
|
|
309 |
msgid "Imported"
|
310 |
msgstr ""
|
311 |
|
312 |
-
#: includes/Admin.php:
|
313 |
msgid "Enable to fetch inventory changes from Square"
|
314 |
msgstr ""
|
315 |
|
316 |
-
#: includes/Admin.php:
|
317 |
msgid "Enable to push inventory changes to Square"
|
318 |
msgstr ""
|
319 |
|
320 |
-
#: includes/Admin.php:
|
321 |
msgid "Inventory is fetched from Square periodically and updated in WooCommerce"
|
322 |
msgstr ""
|
323 |
|
324 |
-
#: includes/Admin.php:
|
325 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag
|
326 |
msgid ""
|
327 |
"Inventory is %1$salways fetched from Square%2$s periodically to account for "
|
@@ -344,14 +351,14 @@ msgid ""
|
|
344 |
"re-connect your site%2$s."
|
345 |
msgstr ""
|
346 |
|
347 |
-
#: includes/Emails/Access_Token_Email.php:
|
348 |
#: includes/Emails/Sync_Completed.php:100
|
349 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
350 |
#. </a> HTML link tag
|
351 |
msgid "%1$sInspect status logs%2$s"
|
352 |
msgstr ""
|
353 |
|
354 |
-
#: includes/Emails/Access_Token_Email.php:
|
355 |
msgid ""
|
356 |
"In order to continue accepting payments, please disconnect and re-connect "
|
357 |
"your site at "
|
@@ -364,12 +371,11 @@ msgid ""
|
|
364 |
"subject: %s"
|
365 |
msgstr ""
|
366 |
|
367 |
-
#: includes/Emails/Base_Email.php:
|
368 |
msgid "Recipient(s)"
|
369 |
msgstr ""
|
370 |
|
371 |
-
#: includes/Emails/Base_Email.php:
|
372 |
-
#. translators: Placeholder: %s default email address
|
373 |
msgid ""
|
374 |
"Enter recipients (comma separated) for this email. Defaults to admin email: "
|
375 |
"%s"
|
@@ -389,114 +395,118 @@ msgstr ""
|
|
389 |
msgid "Square sync failed"
|
390 |
msgstr ""
|
391 |
|
392 |
-
#: includes/Emails/Sync_Completed.php:
|
393 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
394 |
#. </a> HTML link tag
|
395 |
msgid "%1$sEnable logging%2$s"
|
396 |
msgstr ""
|
397 |
|
398 |
-
#: includes/Emails/Sync_Completed.php:
|
399 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
400 |
#. </a> HTML link tag, %3$s - additional action
|
401 |
msgid "The sync job has failed. %1$sClick for more details%2$s, or %3$s."
|
402 |
msgstr ""
|
403 |
|
404 |
-
#: includes/Emails/Sync_Completed.php:
|
405 |
msgid "Inspect status logs"
|
406 |
msgstr ""
|
407 |
|
408 |
-
#: includes/Emails/Sync_Completed.php:
|
409 |
msgid "Enable Logging"
|
410 |
msgstr ""
|
411 |
|
412 |
-
#: includes/Emails/Sync_Completed.php:
|
413 |
#. translators: Placeholders: %s - additional action
|
414 |
msgid "The sync job has failed. Check sync records, or %s."
|
415 |
msgstr ""
|
416 |
|
417 |
-
#: includes/Gateway/API/Requests/Orders.php:
|
418 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay.php:555
|
419 |
msgid "Discount"
|
420 |
msgstr ""
|
421 |
|
422 |
-
#: includes/Gateway/API/Requests/Orders.php:
|
423 |
-
#: includes/Gateway/API/Requests/Orders.php:
|
424 |
msgid "Adjustment"
|
425 |
msgstr ""
|
426 |
|
427 |
-
#: includes/Gateway/Payment_Form.php:
|
428 |
msgid "Postal code"
|
429 |
msgstr ""
|
430 |
|
431 |
-
#: includes/Gateway/Payment_Form.php:
|
432 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/Handlers/Abstract_Hosted_Payment_Handler.php:216
|
433 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:2758
|
434 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/integrations/class-sv-wc-payment-gateway-integration-subscriptions.php:376
|
435 |
msgid "An error occurred, please try again or try an alternate form of payment."
|
436 |
msgstr ""
|
437 |
|
438 |
-
#: includes/Gateway.php:
|
439 |
msgid "Allow customers to use Square to securely pay with their credit cards"
|
440 |
msgstr ""
|
441 |
|
442 |
-
#: includes/Gateway.php:
|
443 |
-
msgid "Refunds must be made within
|
444 |
msgstr ""
|
445 |
|
446 |
-
#: includes/Gateway.php:
|
447 |
msgid ""
|
448 |
"Could not find original transaction tender. Please refund this transaction "
|
449 |
"from your Square dashboard."
|
450 |
msgstr ""
|
451 |
|
452 |
-
#: includes/Gateway.php:
|
453 |
msgid "Customer Profiles"
|
454 |
msgstr ""
|
455 |
|
456 |
-
#: includes/
|
|
|
|
|
|
|
|
|
457 |
msgid "Clear Square Sync"
|
458 |
msgstr ""
|
459 |
|
460 |
-
#: includes/Handlers/Background_Job.php:
|
461 |
msgid "Clear"
|
462 |
msgstr ""
|
463 |
|
464 |
-
#: includes/Handlers/Background_Job.php:
|
465 |
msgid "This tool will clear any ongoing Square product syncs."
|
466 |
msgstr ""
|
467 |
|
468 |
-
#: includes/Handlers/Background_Job.php:
|
469 |
msgid "Success! You can now sync your products."
|
470 |
msgstr ""
|
471 |
|
472 |
-
#: includes/Handlers/Connection.php:103 includes/Handlers/Connection.php:
|
473 |
msgid "Sorry, you do not have permission to manage the Square connection."
|
474 |
msgstr ""
|
475 |
|
476 |
-
#: includes/Handlers/Connection.php:
|
477 |
msgid "Square Error: We could not connect to Square. No access token was given.!"
|
478 |
msgstr ""
|
479 |
|
480 |
-
#: includes/Handlers/Connection.php:
|
481 |
msgid "Disconnected successfully"
|
482 |
msgstr ""
|
483 |
|
484 |
-
#: includes/Handlers/Connection.php:
|
485 |
msgid "Connect with Square"
|
486 |
msgstr ""
|
487 |
|
488 |
-
#: includes/Handlers/Connection.php:
|
489 |
msgid "Disconnect from Square"
|
490 |
msgstr ""
|
491 |
|
492 |
-
#: includes/Handlers/Product.php:
|
493 |
#. translators: Placeholder: %s category ID
|
494 |
msgid ""
|
495 |
"Square category with id (%s) was not imported to your Store. Please run "
|
496 |
"Import Products from Square settings."
|
497 |
msgstr ""
|
498 |
|
499 |
-
#: includes/Handlers/Product.php:
|
500 |
msgid "Product not synced with Square"
|
501 |
msgstr ""
|
502 |
|
@@ -519,39 +529,39 @@ msgstr ""
|
|
519 |
msgid "%s has multiple variation attributes and cannot be synced with Square."
|
520 |
msgstr ""
|
521 |
|
522 |
-
#: includes/Handlers/Products.php:
|
523 |
msgid "Update product data with Square data"
|
524 |
msgstr ""
|
525 |
|
526 |
-
#: includes/Handlers/Products.php:
|
527 |
msgid "Send product data to Square"
|
528 |
msgstr ""
|
529 |
|
530 |
-
#: includes/Handlers/Products.php:
|
531 |
msgid "Sync with Square"
|
532 |
msgstr ""
|
533 |
|
534 |
-
#: includes/Handlers/Products.php:
|
535 |
msgid "Sync with Square?"
|
536 |
msgstr ""
|
537 |
|
538 |
-
#: includes/Handlers/Products.php:
|
539 |
msgid "No change"
|
540 |
msgstr ""
|
541 |
|
542 |
-
#: includes/Handlers/Products.php:
|
543 |
msgid "No"
|
544 |
msgstr ""
|
545 |
|
546 |
-
#: includes/Handlers/Products.php:
|
547 |
msgid "Yes"
|
548 |
msgstr ""
|
549 |
|
550 |
-
#: includes/Handlers/Products.php:
|
551 |
msgid "This product"
|
552 |
msgstr ""
|
553 |
|
554 |
-
#: includes/Handlers/Products.php:
|
555 |
#. translators: Placeholder: %1$s - date (localized), %2$s - time (localized),
|
556 |
#. %3$s - opening <a> HTML link tag, %4$s closing </a> HTML link tag
|
557 |
msgid ""
|
@@ -560,13 +570,42 @@ msgid ""
|
|
560 |
"records%4$s."
|
561 |
msgstr ""
|
562 |
|
563 |
-
#: includes/Handlers/Sync.php:
|
564 |
#. translators: Placeholder: %d number of products processed
|
565 |
msgid "Updated data for %d product."
|
566 |
msgid_plural "Updated data for %d products."
|
567 |
msgstr[0] ""
|
568 |
msgstr[1] ""
|
569 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
570 |
#: includes/Plugin.php:275
|
571 |
msgid ""
|
572 |
"Heads up! There may be a problem with your connection to Square. In order "
|
@@ -574,24 +613,24 @@ msgid ""
|
|
574 |
"site%2$s."
|
575 |
msgstr ""
|
576 |
|
577 |
-
#: includes/Plugin.php:
|
578 |
msgid "You are connected to Square!"
|
579 |
msgstr ""
|
580 |
|
581 |
-
#: includes/Plugin.php:
|
582 |
msgid "To get started, set your business location."
|
583 |
msgstr ""
|
584 |
|
585 |
-
#: includes/Plugin.php:
|
586 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
587 |
msgid "Visit the %1$splugin settings%2$s to set your business location."
|
588 |
msgstr ""
|
589 |
|
590 |
-
#: includes/Plugin.php:
|
591 |
msgid "You are ready to sync products!"
|
592 |
msgstr ""
|
593 |
|
594 |
-
#: includes/Plugin.php:
|
595 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - product count, %3$s -
|
596 |
#. </strong> tag, %4$s - <a> tag, %5$s - </a> tag
|
597 |
msgid ""
|
@@ -599,7 +638,7 @@ msgid ""
|
|
599 |
"now »%5$s"
|
600 |
msgstr ""
|
601 |
|
602 |
-
#: includes/Plugin.php:
|
603 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
604 |
#. <a> tag, %4$s - </a> tag
|
605 |
msgid ""
|
@@ -607,28 +646,28 @@ msgid ""
|
|
607 |
"products to sync data »%4$s"
|
608 |
msgstr ""
|
609 |
|
610 |
-
#: includes/Plugin.php:
|
611 |
msgid ""
|
612 |
"Heads up! Square is configured to sync product inventory, but WooCommerce "
|
613 |
"stock management is disabled. Please %1$senable stock management%2$s to "
|
614 |
"ensure product inventory counts are kept in sync."
|
615 |
msgstr ""
|
616 |
|
617 |
-
#: includes/Plugin.php:
|
618 |
msgid "To get started, connect with Square."
|
619 |
msgstr ""
|
620 |
|
621 |
-
#: includes/Plugin.php:
|
622 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
623 |
msgid "To get started, %1$sconnect with Square »%2$s"
|
624 |
msgstr ""
|
625 |
|
626 |
-
#: includes/Plugin.php:
|
627 |
#. translators: Placeholders: %1$s - plugin name
|
628 |
msgid "Thanks for installing %1$s!"
|
629 |
msgstr ""
|
630 |
|
631 |
-
#: includes/Plugin.php:
|
632 |
#. translators: Placeholders: %1$s - plugin name, %2$ - plugin version number,
|
633 |
#. %3$s - opening <a> HTML link tag, %4$s - closing </a> HTML link tag, %5$s -
|
634 |
#. opening <a> HTML link tag, %6$s - closing </a> HTML link tag
|
@@ -639,7 +678,7 @@ msgid ""
|
|
639 |
"%5$supdated documentation%6$s."
|
640 |
msgstr ""
|
641 |
|
642 |
-
#: includes/Plugin.php:
|
643 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
644 |
#. 2-character country code, %4$s - comma separated list of 2-character country
|
645 |
#. codes
|
@@ -648,7 +687,7 @@ msgid ""
|
|
648 |
"accept transactions from merchants outside of %4$s."
|
649 |
msgstr ""
|
650 |
|
651 |
-
#: includes/Plugin.php:
|
652 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
653 |
#. <a> tag, %4$s - </a> tag
|
654 |
msgid ""
|
@@ -657,7 +696,7 @@ msgid ""
|
|
657 |
"successfully with Square. %3$sRead more here%4$s on how to resolve this."
|
658 |
msgstr ""
|
659 |
|
660 |
-
#: includes/Plugin.php:
|
661 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
662 |
#. <a> tag, %4$s - </a> tag
|
663 |
msgid ""
|
@@ -665,14 +704,14 @@ msgid ""
|
|
665 |
"Square is inactive. Please disconnect and reconnect to resolve."
|
666 |
msgstr ""
|
667 |
|
668 |
-
#: includes/Plugin.php:
|
669 |
msgid ""
|
670 |
"%1$sWooCommerce Square:%2$s Product prices are entered inclusive of tax, "
|
671 |
"but Square does not support syncing tax-inclusive prices. Please make sure "
|
672 |
"your Square tax rates match your WooCommerce tax rates."
|
673 |
msgstr ""
|
674 |
|
675 |
-
#: includes/Plugin.php:
|
676 |
msgid ""
|
677 |
"Heads up! Your store currency is %1$s but your configured Square business "
|
678 |
"location currency is %2$s, so payments cannot be processed. Please "
|
@@ -684,57 +723,57 @@ msgstr ""
|
|
684 |
msgid "WooCommerce Square"
|
685 |
msgstr ""
|
686 |
|
687 |
-
#: includes/Settings.php:
|
688 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
689 |
msgid ""
|
690 |
"Sync your products and inventory and also accept credit and debit card "
|
691 |
"payments at checkout. %1$sClick here%2$s to configure payments."
|
692 |
msgstr ""
|
693 |
|
694 |
-
#: includes/Settings.php:
|
695 |
msgid ""
|
696 |
"Connect with Square to start syncing your products and inventory and also "
|
697 |
"accept credit and debit card payments at checkout."
|
698 |
msgstr ""
|
699 |
|
700 |
-
#: includes/Settings.php:
|
701 |
msgid "Enable Sandbox Mode"
|
702 |
msgstr ""
|
703 |
|
704 |
-
#: includes/Settings.php:
|
705 |
msgid "Enable to set the plugin in sandbox mode."
|
706 |
msgstr ""
|
707 |
|
708 |
-
#: includes/Settings.php:
|
709 |
msgid ""
|
710 |
"After enabling you’ll see a new Sandbox settings section with two fields; "
|
711 |
"Sandbox Application ID & Sandbox Access Token."
|
712 |
msgstr ""
|
713 |
|
714 |
-
#: includes/Settings.php:
|
715 |
msgid "Sandbox settings"
|
716 |
msgstr ""
|
717 |
|
718 |
-
#: includes/Settings.php:
|
719 |
-
#. translators: Placeholders: %1$s - URL
|
720 |
msgid "Sandbox details can be created at: %s"
|
721 |
msgstr ""
|
722 |
|
723 |
-
#: includes/Settings.php:
|
724 |
msgid "Sandbox Application ID"
|
725 |
msgstr ""
|
726 |
|
727 |
-
#: includes/Settings.php:
|
728 |
msgid ""
|
729 |
"Application ID for the Sandbox Application, see the details in the My "
|
730 |
"Applications section."
|
731 |
msgstr ""
|
732 |
|
733 |
-
#: includes/Settings.php:
|
734 |
msgid "Sandbox Access Token"
|
735 |
msgstr ""
|
736 |
|
737 |
-
#: includes/Settings.php:
|
738 |
msgid ""
|
739 |
"Access Token for the Sandbox Test Account, see the details in the Sandbox "
|
740 |
"Test Account section. Make sure you use the correct Sandbox Access Token "
|
@@ -742,11 +781,11 @@ msgid ""
|
|
742 |
"Application is assigned a different Access Token."
|
743 |
msgstr ""
|
744 |
|
745 |
-
#: includes/Settings.php:
|
746 |
msgid "Business location"
|
747 |
msgstr ""
|
748 |
|
749 |
-
#: includes/Settings.php:
|
750 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
751 |
#. <a> tag, %4$s - </a> tag
|
752 |
msgid ""
|
@@ -755,11 +794,11 @@ msgid ""
|
|
755 |
"linked."
|
756 |
msgstr ""
|
757 |
|
758 |
-
#: includes/Settings.php:
|
759 |
msgid "Product system of record"
|
760 |
msgstr ""
|
761 |
|
762 |
-
#: includes/Settings.php:
|
763 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
764 |
#. <a> tag, %4$s - </a> tag
|
765 |
msgid ""
|
@@ -768,7 +807,7 @@ msgid ""
|
|
768 |
"here%4$s to read more about choosing a system of record."
|
769 |
msgstr ""
|
770 |
|
771 |
-
#: includes/Settings.php:
|
772 |
msgid "Do not sync product data"
|
773 |
msgstr ""
|
774 |
|
@@ -776,135 +815,130 @@ msgstr ""
|
|
776 |
msgid "WooCommerce"
|
777 |
msgstr ""
|
778 |
|
779 |
-
#: includes/Settings.php:
|
780 |
msgid "Sync inventory"
|
781 |
msgstr ""
|
782 |
|
783 |
-
#: includes/Settings.php:
|
784 |
msgid "Enable to sync product inventory with Square"
|
785 |
msgstr ""
|
786 |
|
787 |
-
#: includes/Settings.php:
|
788 |
msgid "Handle missing products"
|
789 |
msgstr ""
|
790 |
|
791 |
-
#: includes/Settings.php:
|
792 |
msgid "Hide synced products when not found in Square"
|
793 |
msgstr ""
|
794 |
|
795 |
-
#: includes/Settings.php:
|
796 |
msgid ""
|
797 |
"Products not found in Square will be hidden in the WooCommerce product "
|
798 |
"catalog."
|
799 |
msgstr ""
|
800 |
|
801 |
-
#: includes/Settings.php:
|
802 |
msgid ""
|
803 |
"Run an import to create new products in this WooCommerce store for each new "
|
804 |
"product created in Square that has a unique SKU not existing in here. Needs "
|
805 |
"to be run each time new items are created in Square."
|
806 |
msgstr ""
|
807 |
|
808 |
-
#: includes/Settings.php:
|
809 |
msgid "Connection"
|
810 |
msgstr ""
|
811 |
|
812 |
-
#: includes/Settings.php:
|
813 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
814 |
msgid "Log debug messages to the %1$sWooCommerce status log%2$s"
|
815 |
msgstr ""
|
816 |
|
817 |
-
#: includes/Settings.php:
|
818 |
msgid "Please choose a location"
|
819 |
msgstr ""
|
820 |
|
821 |
-
#: includes/Settings.php:
|
822 |
msgid "Import all products from Square"
|
823 |
msgstr ""
|
824 |
|
825 |
-
#: includes/Sync/Interval_Polling.php:
|
826 |
msgid "Updated data for %d category."
|
827 |
msgid_plural "Updated data for %d categories."
|
828 |
msgstr[0] ""
|
829 |
msgstr[1] ""
|
830 |
|
831 |
-
#: includes/Sync/Manual_Synchronization.php:
|
832 |
#. translators: Placeholder: %s - product ID
|
833 |
msgid "Product %s could not be updated in Square."
|
834 |
msgstr ""
|
835 |
|
836 |
-
#: includes/Sync/Product_Import.php:
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
#: includes/Sync/Product_Import.php:269
|
841 |
-
msgid "Invalid data"
|
842 |
-
msgstr ""
|
843 |
-
|
844 |
-
#: includes/Sync/Product_Import.php:287
|
845 |
-
msgid "Missing parameter %s"
|
846 |
msgstr ""
|
847 |
|
848 |
-
#: includes/Sync/Product_Import.php:
|
849 |
-
msgid "
|
850 |
msgstr ""
|
851 |
|
852 |
-
#: includes/Sync/Product_Import.php:
|
853 |
-
|
854 |
-
msgid "Could not import \"%1$s\" from Square. %2$s"
|
855 |
msgstr ""
|
856 |
|
857 |
-
#: includes/Sync/Product_Import.php:
|
858 |
-
#. translators: Placeholders: %s -
|
859 |
-
msgid "
|
860 |
msgstr ""
|
861 |
|
862 |
-
#: includes/Sync/Product_Import.php:
|
863 |
-
#. translators: Placeholders: %
|
864 |
-
|
865 |
-
msgid "Could not import \"%1$s - %2$s\" from Square. %3$s"
|
866 |
msgstr ""
|
867 |
|
868 |
-
#: includes/Sync/Product_Import.php:
|
869 |
-
|
|
|
870 |
msgstr ""
|
871 |
|
872 |
-
#: includes/Sync/Product_Import.php:
|
873 |
-
|
|
|
874 |
msgstr ""
|
875 |
|
876 |
-
#: includes/Sync/Product_Import.php:
|
877 |
-
|
|
|
878 |
msgstr ""
|
879 |
|
880 |
-
#: includes/Sync/Records/Record.php:
|
881 |
msgid "Info"
|
882 |
msgstr ""
|
883 |
|
884 |
-
#: includes/Sync/Records/Record.php:
|
885 |
msgid "Notice"
|
886 |
msgstr ""
|
887 |
|
888 |
-
#: includes/Sync/Records/Record.php:
|
889 |
msgid "Alert"
|
890 |
msgstr ""
|
891 |
|
892 |
-
#: includes/Sync/Records/Record.php:
|
893 |
#. translators: Placeholder: %s - product name
|
894 |
msgid "%s not found in Square."
|
895 |
msgstr ""
|
896 |
|
897 |
-
#: includes/Sync/Records/Record.php:
|
898 |
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:92
|
899 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway-my-payment-methods.php:819
|
900 |
msgid "Delete"
|
901 |
msgstr ""
|
902 |
|
903 |
-
#: includes/Sync/Records/Record.php:
|
904 |
msgid "Ignore"
|
905 |
msgstr ""
|
906 |
|
907 |
-
#: includes/Sync/Records/Record.php:
|
908 |
msgid "Unlink"
|
909 |
msgstr ""
|
910 |
|
@@ -912,32 +946,32 @@ msgstr ""
|
|
912 |
msgid "Encryption is not supported on this site."
|
913 |
msgstr ""
|
914 |
|
915 |
-
#: includes/Utilities/Encryption_Utility.php:
|
916 |
msgid "%1$s encryption is not available on this site. %2$s will be used instead."
|
917 |
msgstr ""
|
918 |
|
919 |
-
#: includes/Utilities/Encryption_Utility.php:
|
920 |
msgid "No encryption method available"
|
921 |
msgstr ""
|
922 |
|
923 |
-
#: includes/Utilities/Encryption_Utility.php:
|
924 |
msgid "Data must be a non-empty string or array"
|
925 |
msgstr ""
|
926 |
|
927 |
-
#: includes/Utilities/Encryption_Utility.php:
|
928 |
-
#: includes/Utilities/Encryption_Utility.php:
|
929 |
msgid "Encryption key must be a string"
|
930 |
msgstr ""
|
931 |
|
932 |
-
#: includes/Utilities/Encryption_Utility.php:
|
933 |
msgid "Could not generate encryption vector."
|
934 |
msgstr ""
|
935 |
|
936 |
-
#: includes/Utilities/Encryption_Utility.php:
|
937 |
msgid "No decryption method available"
|
938 |
msgstr ""
|
939 |
|
940 |
-
#: includes/Utilities/Encryption_Utility.php:
|
941 |
msgid "Data must be a non-empty string"
|
942 |
msgstr ""
|
943 |
|
@@ -1329,35 +1363,14 @@ msgstr ""
|
|
1329 |
msgid "Action Group"
|
1330 |
msgstr ""
|
1331 |
|
1332 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:374
|
1333 |
-
msgid "Awesome"
|
1334 |
-
msgstr ""
|
1335 |
-
|
1336 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:375
|
1337 |
-
msgid "Fantastic"
|
1338 |
-
msgstr ""
|
1339 |
-
|
1340 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:376
|
1341 |
msgid "Cowabunga"
|
1342 |
msgstr ""
|
1343 |
|
1344 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:377
|
1345 |
-
msgid "Congratulations"
|
1346 |
-
msgstr ""
|
1347 |
-
|
1348 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:378
|
1349 |
msgid "Hot dog"
|
1350 |
msgstr ""
|
1351 |
|
1352 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:385
|
1353 |
-
#. translators: Placeholders: %1$s - plugin name, %2$s - <a> tag, %3$s - </a>
|
1354 |
-
#. tag, %4$s - <a> tag, %5$s - </a> tag
|
1355 |
-
msgid ""
|
1356 |
-
"Are you having a great experience with %1$s so far? Please consider "
|
1357 |
-
"%2$sleaving a review%3$s! If things aren't going quite as expected, we're "
|
1358 |
-
"happy to help -- please %4$sreach out to our support team%5$s."
|
1359 |
-
msgstr ""
|
1360 |
-
|
1361 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:183
|
1362 |
msgid ""
|
1363 |
"Thanks for installing %1$s! To get started, take a minute to %2$sread the "
|
@@ -3037,12 +3050,12 @@ msgstr ""
|
|
3037 |
msgid "https://www.woocommerce.com/"
|
3038 |
msgstr ""
|
3039 |
|
3040 |
-
#: includes/Admin/Sync_Page.php:
|
3041 |
msgctxt "Delete all records"
|
3042 |
msgid "Clear history"
|
3043 |
msgstr ""
|
3044 |
|
3045 |
-
#: includes/Admin/Sync_Page.php:
|
3046 |
msgctxt "Date - Time"
|
3047 |
msgid "Time"
|
3048 |
msgstr ""
|
2 |
# This file is distributed under the GNU General Public License v3.0.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: WooCommerce Square 2.2.0\n"
|
6 |
"Report-Msgid-Bugs-To: "
|
7 |
"https://github.com/woocommerce/woocommerce-square/issues\n"
|
8 |
+
"POT-Creation-Date: 2020-08-31 01:32:52+00:00\n"
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=utf-8\n"
|
11 |
"Content-Transfer-Encoding: 8bit\n"
|
42 |
msgid "Could not delete records."
|
43 |
msgstr ""
|
44 |
|
45 |
+
#: includes/AJAX.php:205
|
46 |
msgid "Could not delete record."
|
47 |
msgstr ""
|
48 |
|
49 |
+
#: includes/AJAX.php:215
|
50 |
msgid "Could not resolve record."
|
51 |
msgstr ""
|
52 |
|
53 |
+
#: includes/AJAX.php:227
|
54 |
msgid "Could not unsync product."
|
55 |
msgstr ""
|
56 |
|
57 |
+
#: includes/AJAX.php:239
|
58 |
#. translators: Placeholder: %s - error message
|
59 |
msgid "An error occurred. %s"
|
60 |
msgstr ""
|
61 |
|
62 |
+
#: includes/AJAX.php:284
|
63 |
#. translators: Placeholder: %s - sync job ID
|
64 |
msgid "No sync job in progress found %s"
|
65 |
msgstr ""
|
66 |
|
67 |
+
#: includes/AJAX.php:322
|
68 |
msgid "Stock must be fetched from Square before editing stock quantity"
|
69 |
msgstr ""
|
70 |
|
71 |
+
#: includes/Admin/Privacy.php:45 includes/Admin/Settings_Page.php:55
|
72 |
+
#: includes/Gateway.php:70 includes/Settings.php:223 includes/Settings.php:757
|
73 |
msgid "Square"
|
74 |
msgstr ""
|
75 |
|
76 |
+
#: includes/Admin/Privacy.php:47
|
77 |
msgid "WooCommerce Square Customer Data"
|
78 |
msgstr ""
|
79 |
|
80 |
+
#: includes/Admin/Privacy.php:61
|
81 |
#. translators: Placeholder: %1$s - <a> tag, %2$s - </a> tag
|
82 |
msgid ""
|
83 |
"By using this extension, you may be storing personal data or sharing data "
|
101 |
msgid "Import Products From Square"
|
102 |
msgstr ""
|
103 |
|
104 |
+
#: includes/Admin/Settings_Page.php:175 includes/Admin/Sync_Page.php:359
|
105 |
msgid "Close modal window"
|
106 |
msgstr ""
|
107 |
|
108 |
#: includes/Admin/Settings_Page.php:180
|
109 |
#. translators: Placeholders: %1$s - <strong>, %2%s - </strong>
|
110 |
msgid ""
|
111 |
+
"You are about to import all new products, variations and categories from "
|
112 |
+
"Square. This will create a new product in WooCommerce for every product "
|
113 |
+
"retrieved from Square. If you have products in the trash from the previous "
|
114 |
+
"imports, these will be ignored in the import. During this process, simple "
|
115 |
+
"products that have new variations found in Sqaure will be converted to a "
|
116 |
+
"variable product in WooCommerce. %1$sOnly use this action to perform a "
|
117 |
+
"one-time import!%2$s"
|
118 |
msgstr ""
|
119 |
|
120 |
+
#: includes/Admin/Settings_Page.php:184 includes/Admin/Sync_Page.php:393
|
121 |
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:133
|
122 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/admin/views/html-order-partial-capture.php:66
|
123 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway-my-payment-methods.php:227
|
124 |
msgid "Cancel"
|
125 |
msgstr ""
|
126 |
|
127 |
+
#: includes/Admin/Settings_Page.php:185 includes/Settings.php:244
|
128 |
msgid "Import Products"
|
129 |
msgstr ""
|
130 |
|
132 |
msgid "Sync records"
|
133 |
msgstr ""
|
134 |
|
135 |
+
#: includes/Admin/Sync_Page.php:80
|
136 |
#. translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s,
|
137 |
#. $4%s - closing </strong> HTML tag
|
138 |
msgid ""
|
141 |
"description, category, inventory%4$s."
|
142 |
msgstr ""
|
143 |
|
144 |
+
#: includes/Admin/Sync_Page.php:94
|
145 |
#. translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing
|
146 |
#. </strong> HTML tag
|
147 |
msgid ""
|
149 |
"set in WooCommerce."
|
150 |
msgstr ""
|
151 |
|
152 |
+
#: includes/Admin/Sync_Page.php:109
|
153 |
#. translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s,
|
154 |
#. %4$s - closing </strong> HTML tag
|
155 |
msgid ""
|
158 |
"price, inventory, category, image%4$s."
|
159 |
msgstr ""
|
160 |
|
161 |
+
#: includes/Admin/Sync_Page.php:126
|
162 |
#. translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing
|
163 |
#. </strong> HTML tag
|
164 |
msgid ""
|
166 |
"Square and WooCommerce."
|
167 |
msgstr ""
|
168 |
|
169 |
+
#: includes/Admin/Sync_Page.php:161
|
170 |
msgid "Please connect to Square to enable product sync."
|
171 |
msgstr ""
|
172 |
|
173 |
+
#: includes/Admin/Sync_Page.php:163
|
174 |
msgid "Please set the business location to enable product sync."
|
175 |
msgstr ""
|
176 |
|
177 |
+
#: includes/Admin/Sync_Page.php:165
|
178 |
msgid "There are currently no products marked to be synced with Square."
|
179 |
msgstr ""
|
180 |
|
181 |
+
#: includes/Admin/Sync_Page.php:167
|
182 |
msgid "A sync is currently in progress. Please try again later."
|
183 |
msgstr ""
|
184 |
|
185 |
+
#: includes/Admin/Sync_Page.php:172
|
186 |
#. translators: Placeholder: %s - reason text
|
187 |
msgid "Product sync between WooCommerce and Square is currently unavailable. %s"
|
188 |
msgstr ""
|
189 |
|
190 |
+
#: includes/Admin/Sync_Page.php:179
|
191 |
msgid "Synced products"
|
192 |
msgstr ""
|
193 |
|
194 |
+
#: includes/Admin/Sync_Page.php:180
|
195 |
msgid "Latest sync"
|
196 |
msgstr ""
|
197 |
|
198 |
+
#: includes/Admin/Sync_Page.php:181
|
199 |
msgid "Next sync"
|
200 |
msgstr ""
|
201 |
|
202 |
+
#: includes/Admin/Sync_Page.php:182 includes/Admin/Sync_Page.php:295
|
203 |
+
#: includes/Admin/Sync_Page.php:336
|
204 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway-my-payment-methods.php:426
|
205 |
msgid "Actions"
|
206 |
msgstr ""
|
207 |
|
208 |
+
#: includes/Admin/Sync_Page.php:192 includes/Emails/Sync_Completed.php:207
|
209 |
#. translators: Placeholder: %d number of products synced with Square
|
210 |
#. translators: Placeholder: %d products count
|
211 |
msgid "%d product"
|
213 |
msgstr[0] ""
|
214 |
msgstr[1] ""
|
215 |
|
216 |
+
#: includes/Admin/Sync_Page.php:210
|
217 |
msgid "Importing now…"
|
218 |
msgstr ""
|
219 |
|
220 |
+
#: includes/Admin/Sync_Page.php:212
|
221 |
msgid "Syncing now…"
|
222 |
msgstr ""
|
223 |
|
224 |
+
#: includes/Admin/Sync_Page.php:227
|
225 |
msgid "Not synced yet."
|
226 |
msgstr ""
|
227 |
|
228 |
+
#: includes/Admin/Sync_Page.php:259
|
229 |
msgid "Sync now"
|
230 |
msgstr ""
|
231 |
|
232 |
+
#: includes/Admin/Sync_Page.php:293 includes/Admin/Sync_Page.php:334
|
233 |
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:97
|
234 |
msgid "Status"
|
235 |
msgstr ""
|
236 |
|
237 |
+
#: includes/Admin/Sync_Page.php:294 includes/Admin/Sync_Page.php:335
|
238 |
msgid "Message"
|
239 |
msgstr ""
|
240 |
|
241 |
+
#: includes/Admin/Sync_Page.php:325
|
242 |
msgid "No records found."
|
243 |
msgstr ""
|
244 |
|
245 |
+
#: includes/Admin/Sync_Page.php:357
|
246 |
msgid "Sync products with Square"
|
247 |
msgstr ""
|
248 |
|
249 |
+
#: includes/Admin/Sync_Page.php:367
|
250 |
msgid ""
|
251 |
"If a match is found in Square, product data in WooCommerce will be "
|
252 |
"overwritten with Square data."
|
253 |
msgstr ""
|
254 |
|
255 |
+
#: includes/Admin/Sync_Page.php:369
|
256 |
msgid ""
|
257 |
"If a match is found in WooCommerce, product data in Square will be "
|
258 |
"overwritten with WooCommerce data."
|
259 |
msgstr ""
|
260 |
|
261 |
+
#: includes/Admin/Sync_Page.php:373
|
262 |
msgid ""
|
263 |
"If a match is not found in Square, the product will be hidden from the "
|
264 |
"catalog in WooCommerce."
|
265 |
msgstr ""
|
266 |
|
267 |
+
#: includes/Admin/Sync_Page.php:375
|
268 |
msgid "If a match is not found in Square, the product will be skipped in the sync."
|
269 |
msgstr ""
|
270 |
|
271 |
+
#: includes/Admin/Sync_Page.php:378
|
272 |
msgid "If a match is not found, a new product will be created in Square."
|
273 |
msgstr ""
|
274 |
|
275 |
+
#: includes/Admin/Sync_Page.php:385
|
276 |
#. translators: Placeholders: %1$s - the system of record name (e.g. Square or
|
277 |
#. WooCommerce), %3%s - unordered HTML list of additional information item(s)
|
278 |
msgid ""
|
280 |
"For all products synced with Square: %2$s"
|
281 |
msgstr ""
|
282 |
|
283 |
+
#: includes/Admin/Sync_Page.php:394
|
284 |
msgid "Start sync"
|
285 |
msgstr ""
|
286 |
|
287 |
+
#: includes/Admin.php:143 includes/Handlers/Products.php:177
|
288 |
msgid "Synced with Square"
|
289 |
msgstr ""
|
290 |
|
291 |
+
#: includes/Admin.php:144
|
292 |
msgid "Managed by Square"
|
293 |
msgstr ""
|
294 |
|
295 |
+
#: includes/Admin.php:145
|
296 |
msgid "Fetch stock from Square"
|
297 |
msgstr ""
|
298 |
|
299 |
+
#: includes/Admin.php:192 includes/Sync/Records/Record.php:209
|
300 |
msgid "Resolved"
|
301 |
msgstr ""
|
302 |
|
303 |
+
#: includes/Admin.php:193
|
304 |
msgid "No records found"
|
305 |
msgstr ""
|
306 |
|
307 |
+
#: includes/Admin.php:194
|
308 |
msgid "Skipped"
|
309 |
msgstr ""
|
310 |
|
311 |
+
#: includes/Admin.php:195
|
312 |
+
msgid "Updated"
|
313 |
+
msgstr ""
|
314 |
+
|
315 |
+
#: includes/Admin.php:196
|
316 |
msgid "Imported"
|
317 |
msgstr ""
|
318 |
|
319 |
+
#: includes/Admin.php:198
|
320 |
msgid "Enable to fetch inventory changes from Square"
|
321 |
msgstr ""
|
322 |
|
323 |
+
#: includes/Admin.php:199
|
324 |
msgid "Enable to push inventory changes to Square"
|
325 |
msgstr ""
|
326 |
|
327 |
+
#: includes/Admin.php:202 includes/Settings.php:233
|
328 |
msgid "Inventory is fetched from Square periodically and updated in WooCommerce"
|
329 |
msgstr ""
|
330 |
|
331 |
+
#: includes/Admin.php:205
|
332 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag
|
333 |
msgid ""
|
334 |
"Inventory is %1$salways fetched from Square%2$s periodically to account for "
|
351 |
"re-connect your site%2$s."
|
352 |
msgstr ""
|
353 |
|
354 |
+
#: includes/Emails/Access_Token_Email.php:107
|
355 |
#: includes/Emails/Sync_Completed.php:100
|
356 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
357 |
#. </a> HTML link tag
|
358 |
msgid "%1$sInspect status logs%2$s"
|
359 |
msgstr ""
|
360 |
|
361 |
+
#: includes/Emails/Access_Token_Email.php:113
|
362 |
msgid ""
|
363 |
"In order to continue accepting payments, please disconnect and re-connect "
|
364 |
"your site at "
|
371 |
"subject: %s"
|
372 |
msgstr ""
|
373 |
|
374 |
+
#: includes/Emails/Base_Email.php:114
|
375 |
msgid "Recipient(s)"
|
376 |
msgstr ""
|
377 |
|
378 |
+
#: includes/Emails/Base_Email.php:117
|
|
|
379 |
msgid ""
|
380 |
"Enter recipients (comma separated) for this email. Defaults to admin email: "
|
381 |
"%s"
|
395 |
msgid "Square sync failed"
|
396 |
msgstr ""
|
397 |
|
398 |
+
#: includes/Emails/Sync_Completed.php:107
|
399 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
400 |
#. </a> HTML link tag
|
401 |
msgid "%1$sEnable logging%2$s"
|
402 |
msgstr ""
|
403 |
|
404 |
+
#: includes/Emails/Sync_Completed.php:115
|
405 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
406 |
#. </a> HTML link tag, %3$s - additional action
|
407 |
msgid "The sync job has failed. %1$sClick for more details%2$s, or %3$s."
|
408 |
msgstr ""
|
409 |
|
410 |
+
#: includes/Emails/Sync_Completed.php:124
|
411 |
msgid "Inspect status logs"
|
412 |
msgstr ""
|
413 |
|
414 |
+
#: includes/Emails/Sync_Completed.php:126 includes/Settings.php:269
|
415 |
msgid "Enable Logging"
|
416 |
msgstr ""
|
417 |
|
418 |
+
#: includes/Emails/Sync_Completed.php:131
|
419 |
#. translators: Placeholders: %s - additional action
|
420 |
msgid "The sync job has failed. Check sync records, or %s."
|
421 |
msgstr ""
|
422 |
|
423 |
+
#: includes/Gateway/API/Requests/Orders.php:85
|
424 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay.php:555
|
425 |
msgid "Discount"
|
426 |
msgstr ""
|
427 |
|
428 |
+
#: includes/Gateway/API/Requests/Orders.php:294
|
429 |
+
#: includes/Gateway/API/Requests/Orders.php:340
|
430 |
msgid "Adjustment"
|
431 |
msgstr ""
|
432 |
|
433 |
+
#: includes/Gateway/Payment_Form.php:152
|
434 |
msgid "Postal code"
|
435 |
msgstr ""
|
436 |
|
437 |
+
#: includes/Gateway/Payment_Form.php:210 includes/Gateway.php:229
|
438 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/Handlers/Abstract_Hosted_Payment_Handler.php:216
|
439 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:2758
|
440 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/integrations/class-sv-wc-payment-gateway-integration-subscriptions.php:376
|
441 |
msgid "An error occurred, please try again or try an alternate form of payment."
|
442 |
msgstr ""
|
443 |
|
444 |
+
#: includes/Gateway.php:71
|
445 |
msgid "Allow customers to use Square to securely pay with their credit cards"
|
446 |
msgstr ""
|
447 |
|
448 |
+
#: includes/Gateway.php:426
|
449 |
+
msgid "Refunds must be made within %s of the original payment date."
|
450 |
msgstr ""
|
451 |
|
452 |
+
#: includes/Gateway.php:450
|
453 |
msgid ""
|
454 |
"Could not find original transaction tender. Please refund this transaction "
|
455 |
"from your Square dashboard."
|
456 |
msgstr ""
|
457 |
|
458 |
+
#: includes/Gateway.php:565
|
459 |
msgid "Customer Profiles"
|
460 |
msgstr ""
|
461 |
|
462 |
+
#: includes/Gateway.php:864
|
463 |
+
msgid " An error occurred, please try again or try an alternate form of payment."
|
464 |
+
msgstr ""
|
465 |
+
|
466 |
+
#: includes/Handlers/Background_Job.php:347
|
467 |
msgid "Clear Square Sync"
|
468 |
msgstr ""
|
469 |
|
470 |
+
#: includes/Handlers/Background_Job.php:348
|
471 |
msgid "Clear"
|
472 |
msgstr ""
|
473 |
|
474 |
+
#: includes/Handlers/Background_Job.php:349
|
475 |
msgid "This tool will clear any ongoing Square product syncs."
|
476 |
msgstr ""
|
477 |
|
478 |
+
#: includes/Handlers/Background_Job.php:368
|
479 |
msgid "Success! You can now sync your products."
|
480 |
msgstr ""
|
481 |
|
482 |
+
#: includes/Handlers/Connection.php:103 includes/Handlers/Connection.php:171
|
483 |
msgid "Sorry, you do not have permission to manage the Square connection."
|
484 |
msgstr ""
|
485 |
|
486 |
+
#: includes/Handlers/Connection.php:115
|
487 |
msgid "Square Error: We could not connect to Square. No access token was given.!"
|
488 |
msgstr ""
|
489 |
|
490 |
+
#: includes/Handlers/Connection.php:179
|
491 |
msgid "Disconnected successfully"
|
492 |
msgstr ""
|
493 |
|
494 |
+
#: includes/Handlers/Connection.php:386
|
495 |
msgid "Connect with Square"
|
496 |
msgstr ""
|
497 |
|
498 |
+
#: includes/Handlers/Connection.php:406
|
499 |
msgid "Disconnect from Square"
|
500 |
msgstr ""
|
501 |
|
502 |
+
#: includes/Handlers/Product.php:178
|
503 |
#. translators: Placeholder: %s category ID
|
504 |
msgid ""
|
505 |
"Square category with id (%s) was not imported to your Store. Please run "
|
506 |
"Import Products from Square settings."
|
507 |
msgstr ""
|
508 |
|
509 |
+
#: includes/Handlers/Product.php:295
|
510 |
msgid "Product not synced with Square"
|
511 |
msgstr ""
|
512 |
|
529 |
msgid "%s has multiple variation attributes and cannot be synced with Square."
|
530 |
msgstr ""
|
531 |
|
532 |
+
#: includes/Handlers/Products.php:252
|
533 |
msgid "Update product data with Square data"
|
534 |
msgstr ""
|
535 |
|
536 |
+
#: includes/Handlers/Products.php:252
|
537 |
msgid "Send product data to Square"
|
538 |
msgstr ""
|
539 |
|
540 |
+
#: includes/Handlers/Products.php:257
|
541 |
msgid "Sync with Square"
|
542 |
msgstr ""
|
543 |
|
544 |
+
#: includes/Handlers/Products.php:293
|
545 |
msgid "Sync with Square?"
|
546 |
msgstr ""
|
547 |
|
548 |
+
#: includes/Handlers/Products.php:297
|
549 |
msgid "No change"
|
550 |
msgstr ""
|
551 |
|
552 |
+
#: includes/Handlers/Products.php:299
|
553 |
msgid "No"
|
554 |
msgstr ""
|
555 |
|
556 |
+
#: includes/Handlers/Products.php:300
|
557 |
msgid "Yes"
|
558 |
msgstr ""
|
559 |
|
560 |
+
#: includes/Handlers/Products.php:306
|
561 |
msgid "This product"
|
562 |
msgstr ""
|
563 |
|
564 |
+
#: includes/Handlers/Products.php:665
|
565 |
#. translators: Placeholder: %1$s - date (localized), %2$s - time (localized),
|
566 |
#. %3$s - opening <a> HTML link tag, %4$s closing </a> HTML link tag
|
567 |
msgid ""
|
570 |
"records%4$s."
|
571 |
msgstr ""
|
572 |
|
573 |
+
#: includes/Handlers/Sync.php:327
|
574 |
#. translators: Placeholder: %d number of products processed
|
575 |
msgid "Updated data for %d product."
|
576 |
msgid_plural "Updated data for %d products."
|
577 |
msgstr[0] ""
|
578 |
msgstr[1] ""
|
579 |
|
580 |
+
#: includes/Lifecycle.php:184
|
581 |
+
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:374
|
582 |
+
msgid "Awesome"
|
583 |
+
msgstr ""
|
584 |
+
|
585 |
+
#: includes/Lifecycle.php:185
|
586 |
+
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:377
|
587 |
+
msgid "Congratulations"
|
588 |
+
msgstr ""
|
589 |
+
|
590 |
+
#: includes/Lifecycle.php:186
|
591 |
+
msgid "Great"
|
592 |
+
msgstr ""
|
593 |
+
|
594 |
+
#: includes/Lifecycle.php:187
|
595 |
+
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:375
|
596 |
+
msgid "Fantastic"
|
597 |
+
msgstr ""
|
598 |
+
|
599 |
+
#: includes/Lifecycle.php:194
|
600 |
+
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:385
|
601 |
+
#. translators: Placeholders: %1$s - plugin name, %2$s - <a> tag, %3$s - </a>
|
602 |
+
#. tag, %4$s - <a> tag, %5$s - </a> tag
|
603 |
+
msgid ""
|
604 |
+
"Are you having a great experience with %1$s so far? Please consider "
|
605 |
+
"%2$sleaving a review%3$s! If things aren't going quite as expected, we're "
|
606 |
+
"happy to help -- please %4$sreach out to our support team%5$s."
|
607 |
+
msgstr ""
|
608 |
+
|
609 |
#: includes/Plugin.php:275
|
610 |
msgid ""
|
611 |
"Heads up! There may be a problem with your connection to Square. In order "
|
613 |
"site%2$s."
|
614 |
msgstr ""
|
615 |
|
616 |
+
#: includes/Plugin.php:292
|
617 |
msgid "You are connected to Square!"
|
618 |
msgstr ""
|
619 |
|
620 |
+
#: includes/Plugin.php:299
|
621 |
msgid "To get started, set your business location."
|
622 |
msgstr ""
|
623 |
|
624 |
+
#: includes/Plugin.php:305
|
625 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
626 |
msgid "Visit the %1$splugin settings%2$s to set your business location."
|
627 |
msgstr ""
|
628 |
|
629 |
+
#: includes/Plugin.php:315
|
630 |
msgid "You are ready to sync products!"
|
631 |
msgstr ""
|
632 |
|
633 |
+
#: includes/Plugin.php:321
|
634 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - product count, %3$s -
|
635 |
#. </strong> tag, %4$s - <a> tag, %5$s - </a> tag
|
636 |
msgid ""
|
638 |
"now »%5$s"
|
639 |
msgstr ""
|
640 |
|
641 |
+
#: includes/Plugin.php:333
|
642 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
643 |
#. <a> tag, %4$s - </a> tag
|
644 |
msgid ""
|
646 |
"products to sync data »%4$s"
|
647 |
msgstr ""
|
648 |
|
649 |
+
#: includes/Plugin.php:348
|
650 |
msgid ""
|
651 |
"Heads up! Square is configured to sync product inventory, but WooCommerce "
|
652 |
"stock management is disabled. Please %1$senable stock management%2$s to "
|
653 |
"ensure product inventory counts are kept in sync."
|
654 |
msgstr ""
|
655 |
|
656 |
+
#: includes/Plugin.php:365
|
657 |
msgid "To get started, connect with Square."
|
658 |
msgstr ""
|
659 |
|
660 |
+
#: includes/Plugin.php:371
|
661 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
662 |
msgid "To get started, %1$sconnect with Square »%2$s"
|
663 |
msgstr ""
|
664 |
|
665 |
+
#: includes/Plugin.php:379
|
666 |
#. translators: Placeholders: %1$s - plugin name
|
667 |
msgid "Thanks for installing %1$s!"
|
668 |
msgstr ""
|
669 |
|
670 |
+
#: includes/Plugin.php:403
|
671 |
#. translators: Placeholders: %1$s - plugin name, %2$ - plugin version number,
|
672 |
#. %3$s - opening <a> HTML link tag, %4$s - closing </a> HTML link tag, %5$s -
|
673 |
#. opening <a> HTML link tag, %6$s - closing </a> HTML link tag
|
678 |
"%5$supdated documentation%6$s."
|
679 |
msgstr ""
|
680 |
|
681 |
+
#: includes/Plugin.php:440
|
682 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
683 |
#. 2-character country code, %4$s - comma separated list of 2-character country
|
684 |
#. codes
|
687 |
"accept transactions from merchants outside of %4$s."
|
688 |
msgstr ""
|
689 |
|
690 |
+
#: includes/Plugin.php:467
|
691 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
692 |
#. <a> tag, %4$s - </a> tag
|
693 |
msgid ""
|
696 |
"successfully with Square. %3$sRead more here%4$s on how to resolve this."
|
697 |
msgstr ""
|
698 |
|
699 |
+
#: includes/Plugin.php:510
|
700 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
701 |
#. <a> tag, %4$s - </a> tag
|
702 |
msgid ""
|
704 |
"Square is inactive. Please disconnect and reconnect to resolve."
|
705 |
msgstr ""
|
706 |
|
707 |
+
#: includes/Plugin.php:542
|
708 |
msgid ""
|
709 |
"%1$sWooCommerce Square:%2$s Product prices are entered inclusive of tax, "
|
710 |
"but Square does not support syncing tax-inclusive prices. Please make sure "
|
711 |
"your Square tax rates match your WooCommerce tax rates."
|
712 |
msgstr ""
|
713 |
|
714 |
+
#: includes/Plugin.php:573
|
715 |
msgid ""
|
716 |
"Heads up! Your store currency is %1$s but your configured Square business "
|
717 |
"location currency is %2$s, so payments cannot be processed. Please "
|
723 |
msgid "WooCommerce Square"
|
724 |
msgstr ""
|
725 |
|
726 |
+
#: includes/Settings.php:142
|
727 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
728 |
msgid ""
|
729 |
"Sync your products and inventory and also accept credit and debit card "
|
730 |
"payments at checkout. %1$sClick here%2$s to configure payments."
|
731 |
msgstr ""
|
732 |
|
733 |
+
#: includes/Settings.php:149
|
734 |
msgid ""
|
735 |
"Connect with Square to start syncing your products and inventory and also "
|
736 |
"accept credit and debit card payments at checkout."
|
737 |
msgstr ""
|
738 |
|
739 |
+
#: includes/Settings.php:160
|
740 |
msgid "Enable Sandbox Mode"
|
741 |
msgstr ""
|
742 |
|
743 |
+
#: includes/Settings.php:161
|
744 |
msgid "Enable to set the plugin in sandbox mode."
|
745 |
msgstr ""
|
746 |
|
747 |
+
#: includes/Settings.php:163
|
748 |
msgid ""
|
749 |
"After enabling you’ll see a new Sandbox settings section with two fields; "
|
750 |
"Sandbox Application ID & Sandbox Access Token."
|
751 |
msgstr ""
|
752 |
|
753 |
+
#: includes/Settings.php:168
|
754 |
msgid "Sandbox settings"
|
755 |
msgstr ""
|
756 |
|
757 |
+
#: includes/Settings.php:172
|
758 |
+
#. translators: Placeholders: %1$s - URL.
|
759 |
msgid "Sandbox details can be created at: %s"
|
760 |
msgstr ""
|
761 |
|
762 |
+
#: includes/Settings.php:179
|
763 |
msgid "Sandbox Application ID"
|
764 |
msgstr ""
|
765 |
|
766 |
+
#: includes/Settings.php:181
|
767 |
msgid ""
|
768 |
"Application ID for the Sandbox Application, see the details in the My "
|
769 |
"Applications section."
|
770 |
msgstr ""
|
771 |
|
772 |
+
#: includes/Settings.php:186
|
773 |
msgid "Sandbox Access Token"
|
774 |
msgstr ""
|
775 |
|
776 |
+
#: includes/Settings.php:188
|
777 |
msgid ""
|
778 |
"Access Token for the Sandbox Test Account, see the details in the Sandbox "
|
779 |
"Test Account section. Make sure you use the correct Sandbox Access Token "
|
781 |
"Application is assigned a different Access Token."
|
782 |
msgstr ""
|
783 |
|
784 |
+
#: includes/Settings.php:195
|
785 |
msgid "Business location"
|
786 |
msgstr ""
|
787 |
|
788 |
+
#: includes/Settings.php:200
|
789 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
790 |
#. <a> tag, %4$s - </a> tag
|
791 |
msgid ""
|
794 |
"linked."
|
795 |
msgstr ""
|
796 |
|
797 |
+
#: includes/Settings.php:210
|
798 |
msgid "Product system of record"
|
799 |
msgstr ""
|
800 |
|
801 |
+
#: includes/Settings.php:215
|
802 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
803 |
#. <a> tag, %4$s - </a> tag
|
804 |
msgid ""
|
807 |
"here%4$s to read more about choosing a system of record."
|
808 |
msgstr ""
|
809 |
|
810 |
+
#: includes/Settings.php:222
|
811 |
msgid "Do not sync product data"
|
812 |
msgstr ""
|
813 |
|
815 |
msgid "WooCommerce"
|
816 |
msgstr ""
|
817 |
|
818 |
+
#: includes/Settings.php:230
|
819 |
msgid "Sync inventory"
|
820 |
msgstr ""
|
821 |
|
822 |
+
#: includes/Settings.php:231
|
823 |
msgid "Enable to sync product inventory with Square"
|
824 |
msgstr ""
|
825 |
|
826 |
+
#: includes/Settings.php:237
|
827 |
msgid "Handle missing products"
|
828 |
msgstr ""
|
829 |
|
830 |
+
#: includes/Settings.php:238
|
831 |
msgid "Hide synced products when not found in Square"
|
832 |
msgstr ""
|
833 |
|
834 |
+
#: includes/Settings.php:240
|
835 |
msgid ""
|
836 |
"Products not found in Square will be hidden in the WooCommerce product "
|
837 |
"catalog."
|
838 |
msgstr ""
|
839 |
|
840 |
+
#: includes/Settings.php:246
|
841 |
msgid ""
|
842 |
"Run an import to create new products in this WooCommerce store for each new "
|
843 |
"product created in Square that has a unique SKU not existing in here. Needs "
|
844 |
"to be run each time new items are created in Square."
|
845 |
msgstr ""
|
846 |
|
847 |
+
#: includes/Settings.php:256
|
848 |
msgid "Connection"
|
849 |
msgstr ""
|
850 |
|
851 |
+
#: includes/Settings.php:273
|
852 |
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
853 |
msgid "Log debug messages to the %1$sWooCommerce status log%2$s"
|
854 |
msgstr ""
|
855 |
|
856 |
+
#: includes/Settings.php:321
|
857 |
msgid "Please choose a location"
|
858 |
msgstr ""
|
859 |
|
860 |
+
#: includes/Settings.php:355
|
861 |
msgid "Import all products from Square"
|
862 |
msgstr ""
|
863 |
|
864 |
+
#: includes/Sync/Interval_Polling.php:100
|
865 |
msgid "Updated data for %d category."
|
866 |
msgid_plural "Updated data for %d categories."
|
867 |
msgstr[0] ""
|
868 |
msgstr[1] ""
|
869 |
|
870 |
+
#: includes/Sync/Manual_Synchronization.php:1135
|
871 |
#. translators: Placeholder: %s - product ID
|
872 |
msgid "Product %s could not be updated in Square."
|
873 |
msgstr ""
|
874 |
|
875 |
+
#: includes/Sync/Product_Import.php:521
|
876 |
+
#. translators: Placeholders: %1$s - Square item name, %2$s - Square item
|
877 |
+
#. variation name, %3$s - failure reason
|
878 |
+
msgid "Could not import \"%1$s - %2$s\" from Square. %3$s"
|
|
|
|
|
|
|
|
|
|
|
|
|
879 |
msgstr ""
|
880 |
|
881 |
+
#: includes/Sync/Product_Import.php:572
|
882 |
+
msgid "Items with variable pricing cannot be imported."
|
883 |
msgstr ""
|
884 |
|
885 |
+
#: includes/Sync/Product_Import.php:665 includes/Sync/Product_Import.php:936
|
886 |
+
msgid "The SKU already exists on another product"
|
|
|
887 |
msgstr ""
|
888 |
|
889 |
+
#: includes/Sync/Product_Import.php:852
|
890 |
+
#. translators: Placeholders: %1$s - variation ID, %2$s - product name
|
891 |
+
msgid "Variation #%1$s of %2$s"
|
892 |
msgstr ""
|
893 |
|
894 |
+
#: includes/Sync/Product_Import.php:1230
|
895 |
+
#. translators: Placeholders: %s - missing parameter name
|
896 |
+
msgid "Missing parameter %s"
|
|
|
897 |
msgstr ""
|
898 |
|
899 |
+
#: includes/Sync/Product_Import.php:1236
|
900 |
+
#. translators: Placeholders: %s - comma separated list of valid product types
|
901 |
+
msgid "Invalid product type - the product type must be any of these: %s"
|
902 |
msgstr ""
|
903 |
|
904 |
+
#: includes/Sync/Product_Import.php:1287
|
905 |
+
#. translators: Placeholders: %1$s - Square item name, %2$s - Failure reason
|
906 |
+
msgid "Could not update %1$s from Square. %2$s"
|
907 |
msgstr ""
|
908 |
|
909 |
+
#: includes/Sync/Product_Import.php:1290
|
910 |
+
#. translators: Placeholders: %1$s - Square item name, %2$s - Failure reason
|
911 |
+
msgid "Could not import %1$s from Square. %2$s"
|
912 |
msgstr ""
|
913 |
|
914 |
+
#: includes/Sync/Records/Record.php:206
|
915 |
msgid "Info"
|
916 |
msgstr ""
|
917 |
|
918 |
+
#: includes/Sync/Records/Record.php:207
|
919 |
msgid "Notice"
|
920 |
msgstr ""
|
921 |
|
922 |
+
#: includes/Sync/Records/Record.php:208
|
923 |
msgid "Alert"
|
924 |
msgstr ""
|
925 |
|
926 |
+
#: includes/Sync/Records/Record.php:374
|
927 |
#. translators: Placeholder: %s - product name
|
928 |
msgid "%s not found in Square."
|
929 |
msgstr ""
|
930 |
|
931 |
+
#: includes/Sync/Records/Record.php:545
|
932 |
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:92
|
933 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway-my-payment-methods.php:819
|
934 |
msgid "Delete"
|
935 |
msgstr ""
|
936 |
|
937 |
+
#: includes/Sync/Records/Record.php:553
|
938 |
msgid "Ignore"
|
939 |
msgstr ""
|
940 |
|
941 |
+
#: includes/Sync/Records/Record.php:562
|
942 |
msgid "Unlink"
|
943 |
msgstr ""
|
944 |
|
946 |
msgid "Encryption is not supported on this site."
|
947 |
msgstr ""
|
948 |
|
949 |
+
#: includes/Utilities/Encryption_Utility.php:73
|
950 |
msgid "%1$s encryption is not available on this site. %2$s will be used instead."
|
951 |
msgstr ""
|
952 |
|
953 |
+
#: includes/Utilities/Encryption_Utility.php:98
|
954 |
msgid "No encryption method available"
|
955 |
msgstr ""
|
956 |
|
957 |
+
#: includes/Utilities/Encryption_Utility.php:102
|
958 |
msgid "Data must be a non-empty string or array"
|
959 |
msgstr ""
|
960 |
|
961 |
+
#: includes/Utilities/Encryption_Utility.php:106
|
962 |
+
#: includes/Utilities/Encryption_Utility.php:149
|
963 |
msgid "Encryption key must be a string"
|
964 |
msgstr ""
|
965 |
|
966 |
+
#: includes/Utilities/Encryption_Utility.php:118
|
967 |
msgid "Could not generate encryption vector."
|
968 |
msgstr ""
|
969 |
|
970 |
+
#: includes/Utilities/Encryption_Utility.php:141
|
971 |
msgid "No decryption method available"
|
972 |
msgstr ""
|
973 |
|
974 |
+
#: includes/Utilities/Encryption_Utility.php:145
|
975 |
msgid "Data must be a non-empty string"
|
976 |
msgstr ""
|
977 |
|
1363 |
msgid "Action Group"
|
1364 |
msgstr ""
|
1365 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1366 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:376
|
1367 |
msgid "Cowabunga"
|
1368 |
msgstr ""
|
1369 |
|
|
|
|
|
|
|
|
|
1370 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:378
|
1371 |
msgid "Hot dog"
|
1372 |
msgstr ""
|
1373 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1374 |
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:183
|
1375 |
msgid ""
|
1376 |
"Thanks for installing %1$s! To get started, take a minute to %2$sread the "
|
3050 |
msgid "https://www.woocommerce.com/"
|
3051 |
msgstr ""
|
3052 |
|
3053 |
+
#: includes/Admin/Sync_Page.php:287
|
3054 |
msgctxt "Delete all records"
|
3055 |
msgid "Clear history"
|
3056 |
msgstr ""
|
3057 |
|
3058 |
+
#: includes/Admin/Sync_Page.php:292 includes/Admin/Sync_Page.php:333
|
3059 |
msgctxt "Date - Time"
|
3060 |
msgid "Time"
|
3061 |
msgstr ""
|
includes/AJAX.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Product;
|
@@ -46,21 +46,21 @@ class AJAX {
|
|
46 |
public function __construct() {
|
47 |
|
48 |
// check an individual product sync status
|
49 |
-
add_action( 'wp_ajax_wc_square_get_quick_edit_product_details',
|
50 |
|
51 |
// fetch product stock from Square
|
52 |
-
add_action( 'wp_ajax_wc_square_fetch_product_stock_with_square',
|
53 |
|
54 |
-
add_action( 'wp_ajax_wc_square_import_products_from_square',
|
55 |
|
56 |
// sync all products with Square
|
57 |
-
add_action( 'wp_ajax_wc_square_sync_products_with_square',
|
58 |
|
59 |
// handle sync records
|
60 |
-
add_action( 'wp_ajax_wc_square_handle_sync_records',
|
61 |
|
62 |
// get the status of a sync job
|
63 |
-
add_action( 'wp_ajax_wc_square_get_sync_with_square_status',
|
64 |
}
|
65 |
|
66 |
|
@@ -75,7 +75,7 @@ class AJAX {
|
|
75 |
*/
|
76 |
public function is_product_synced_with_square() {
|
77 |
_deprecated_function( 'is_product_synced_with_square', '2.1.6', 'get_quick_edit_product_details' );
|
78 |
-
|
79 |
check_ajax_referer( 'is-product-synced-with-square', 'security' );
|
80 |
|
81 |
if ( isset( $_POST['product_id'] ) && ( $product = wc_get_product( $_POST['product_id'] ) ) ) {
|
@@ -83,7 +83,7 @@ class AJAX {
|
|
83 |
if ( $product->is_type( 'variable' ) && $product->has_child() ) {
|
84 |
if ( Product::has_multiple_variation_attributes( $product ) ) {
|
85 |
wp_send_json_error( 'multiple_attributes' );
|
86 |
-
}
|
87 |
wp_send_json_error( 'missing_variation_sku' );
|
88 |
}
|
89 |
} else {
|
@@ -200,26 +200,23 @@ class AJAX {
|
|
200 |
|
201 |
switch ( $action ) {
|
202 |
|
203 |
-
case 'delete'
|
204 |
-
|
205 |
$outcome = Records::delete_record( $id );
|
206 |
$error = esc_html__( 'Could not delete record.', 'woocommerce-square' );
|
207 |
|
208 |
-
|
209 |
-
|
210 |
-
case 'resolve' :
|
211 |
|
212 |
-
|
|
|
213 |
$record->resolve();
|
214 |
$outcome = $record->save();
|
215 |
}
|
216 |
|
217 |
$error = esc_html__( 'Could not resolve record.', 'woocommerce-square' );
|
218 |
|
219 |
-
|
220 |
-
|
221 |
-
case 'unsync' :
|
222 |
|
|
|
223 |
$record = Records::get_record( $id );
|
224 |
|
225 |
if ( $record && ( $product = $record->get_product() ) ) {
|
@@ -229,7 +226,7 @@ class AJAX {
|
|
229 |
|
230 |
$error = esc_html__( 'Could not unsync product.', 'woocommerce-square' );
|
231 |
|
232 |
-
|
233 |
}
|
234 |
}
|
235 |
|
@@ -264,19 +261,19 @@ class AJAX {
|
|
264 |
|
265 |
if ( $job_in_progress = $handler->get_job( $job_id ) ) {
|
266 |
|
267 |
-
$result =
|
268 |
-
'action'
|
269 |
-
'id'
|
270 |
-
'job_products_count'
|
271 |
-
'percentage'
|
272 |
-
'
|
273 |
-
'
|
274 |
-
'
|
275 |
-
|
|
|
276 |
|
277 |
wp_send_json_success( $result );
|
278 |
}
|
279 |
-
|
280 |
} catch ( \Exception $e ) {
|
281 |
|
282 |
wp_send_json_error( $e->getMessage() );
|
@@ -298,7 +295,7 @@ class AJAX {
|
|
298 |
|
299 |
check_ajax_referer( 'get-quick-edit-product-details', 'security' );
|
300 |
|
301 |
-
if ( isset( $_POST[
|
302 |
|
303 |
$is_variable = $product->is_type( 'variable' );
|
304 |
|
@@ -317,14 +314,16 @@ class AJAX {
|
|
317 |
}
|
318 |
|
319 |
$is_synced_with_square = Product::is_synced_with_square( $product ) ? 'yes' : 'no';
|
320 |
-
$is_woocommerce_sor
|
321 |
-
|
322 |
-
wp_send_json_success(
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
|
|
|
|
328 |
}
|
329 |
wp_send_json_error( 'invalid_product' );
|
330 |
}
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Product;
|
46 |
public function __construct() {
|
47 |
|
48 |
// check an individual product sync status
|
49 |
+
add_action( 'wp_ajax_wc_square_get_quick_edit_product_details', array( $this, 'get_quick_edit_product_details' ) );
|
50 |
|
51 |
// fetch product stock from Square
|
52 |
+
add_action( 'wp_ajax_wc_square_fetch_product_stock_with_square', array( $this, 'fetch_product_stock_with_square' ) );
|
53 |
|
54 |
+
add_action( 'wp_ajax_wc_square_import_products_from_square', array( $this, 'import_products_from_square' ) );
|
55 |
|
56 |
// sync all products with Square
|
57 |
+
add_action( 'wp_ajax_wc_square_sync_products_with_square', array( $this, 'sync_products_with_square' ) );
|
58 |
|
59 |
// handle sync records
|
60 |
+
add_action( 'wp_ajax_wc_square_handle_sync_records', array( $this, 'handle_sync_records' ) );
|
61 |
|
62 |
// get the status of a sync job
|
63 |
+
add_action( 'wp_ajax_wc_square_get_sync_with_square_status', array( $this, 'get_sync_with_square_job_status' ) );
|
64 |
}
|
65 |
|
66 |
|
75 |
*/
|
76 |
public function is_product_synced_with_square() {
|
77 |
_deprecated_function( 'is_product_synced_with_square', '2.1.6', 'get_quick_edit_product_details' );
|
78 |
+
|
79 |
check_ajax_referer( 'is-product-synced-with-square', 'security' );
|
80 |
|
81 |
if ( isset( $_POST['product_id'] ) && ( $product = wc_get_product( $_POST['product_id'] ) ) ) {
|
83 |
if ( $product->is_type( 'variable' ) && $product->has_child() ) {
|
84 |
if ( Product::has_multiple_variation_attributes( $product ) ) {
|
85 |
wp_send_json_error( 'multiple_attributes' );
|
86 |
+
} elseif ( ! Product::has_sku( $product ) ) {
|
87 |
wp_send_json_error( 'missing_variation_sku' );
|
88 |
}
|
89 |
} else {
|
200 |
|
201 |
switch ( $action ) {
|
202 |
|
203 |
+
case 'delete':
|
|
|
204 |
$outcome = Records::delete_record( $id );
|
205 |
$error = esc_html__( 'Could not delete record.', 'woocommerce-square' );
|
206 |
|
207 |
+
break;
|
|
|
|
|
208 |
|
209 |
+
case 'resolve':
|
210 |
+
if ( $record = Records::get_record( $id ) ) {
|
211 |
$record->resolve();
|
212 |
$outcome = $record->save();
|
213 |
}
|
214 |
|
215 |
$error = esc_html__( 'Could not resolve record.', 'woocommerce-square' );
|
216 |
|
217 |
+
break;
|
|
|
|
|
218 |
|
219 |
+
case 'unsync':
|
220 |
$record = Records::get_record( $id );
|
221 |
|
222 |
if ( $record && ( $product = $record->get_product() ) ) {
|
226 |
|
227 |
$error = esc_html__( 'Could not unsync product.', 'woocommerce-square' );
|
228 |
|
229 |
+
break;
|
230 |
}
|
231 |
}
|
232 |
|
261 |
|
262 |
if ( $job_in_progress = $handler->get_job( $job_id ) ) {
|
263 |
|
264 |
+
$result = array(
|
265 |
+
'action' => $job_in_progress->action,
|
266 |
+
'id' => $job_in_progress->id,
|
267 |
+
'job_products_count' => count( $job_in_progress->product_ids ),
|
268 |
+
'percentage' => ( (float) count( $job_in_progress->processed_product_ids ) / max( 1, count( $job_in_progress->product_ids ) ) ) * 100,
|
269 |
+
'imported_products_count' => count( $job_in_progress->processed_product_ids ),
|
270 |
+
'updated_products_count' => count( $job_in_progress->updated_product_ids ),
|
271 |
+
'skipped_products_count' => count( $job_in_progress->skipped_products ),
|
272 |
+
'status' => $job_in_progress->status,
|
273 |
+
);
|
274 |
|
275 |
wp_send_json_success( $result );
|
276 |
}
|
|
|
277 |
} catch ( \Exception $e ) {
|
278 |
|
279 |
wp_send_json_error( $e->getMessage() );
|
295 |
|
296 |
check_ajax_referer( 'get-quick-edit-product-details', 'security' );
|
297 |
|
298 |
+
if ( isset( $_POST['product_id'] ) && ( $product = wc_get_product( $_POST['product_id'] ) ) ) {
|
299 |
|
300 |
$is_variable = $product->is_type( 'variable' );
|
301 |
|
314 |
}
|
315 |
|
316 |
$is_synced_with_square = Product::is_synced_with_square( $product ) ? 'yes' : 'no';
|
317 |
+
$is_woocommerce_sor = wc_square()->get_settings_handler()->is_system_of_record_woocommerce();
|
318 |
+
|
319 |
+
wp_send_json_success(
|
320 |
+
array(
|
321 |
+
'edit_url' => $is_woocommerce_sor ? get_edit_post_link( $_POST['product_id'] ) : null,
|
322 |
+
'i18n' => $is_woocommerce_sor ? __( 'Stock must be fetched from Square before editing stock quantity', 'woocommerce-square' ) : null,
|
323 |
+
'is_synced_with_square' => $is_synced_with_square,
|
324 |
+
'is_variable' => $is_variable,
|
325 |
+
)
|
326 |
+
);
|
327 |
}
|
328 |
wp_send_json_error( 'invalid_product' );
|
329 |
}
|
includes/API.php
CHANGED
@@ -28,7 +28,7 @@ use SquareConnect;
|
|
28 |
use WooCommerce\Square\API\Requests;
|
29 |
use WooCommerce\Square\API\Responses;
|
30 |
|
31 |
-
defined( 'ABSPATH' )
|
32 |
|
33 |
/**
|
34 |
* WooCommerce Square API class
|
@@ -173,7 +173,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
173 |
* @return Responses\Catalog
|
174 |
* @throws Framework\SV_WC_API_Exception
|
175 |
*/
|
176 |
-
public function list_catalog( $cursor = '', $types =
|
177 |
|
178 |
$request = $this->get_catalog_request();
|
179 |
$request->set_list_catalog_data( $cursor, $types );
|
@@ -210,7 +210,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
210 |
* @return Responses\Catalog
|
211 |
* @throws Framework\SV_WC_API_Exception
|
212 |
*/
|
213 |
-
public function search_catalog_objects( $args =
|
214 |
|
215 |
$request = $this->get_catalog_request();
|
216 |
$request->set_search_catalog_objects_data( $args );
|
@@ -230,7 +230,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
230 |
* @return Responses\Catalog
|
231 |
* @throws Framework\SV_WC_API_Exception
|
232 |
*/
|
233 |
-
public function update_item_modifier_lists( array $item_ids, array $modifier_lists_to_enable =
|
234 |
|
235 |
$request = $this->get_catalog_request();
|
236 |
$request->set_update_item_modifier_lists_data( $item_ids, $modifier_lists_to_enable, $modifier_lists_to_disable );
|
@@ -250,7 +250,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
250 |
* @return Responses\Catalog
|
251 |
* @throws Framework\SV_WC_API_Exception
|
252 |
*/
|
253 |
-
public function update_item_taxes( array $item_ids, array $taxes_to_enable =
|
254 |
|
255 |
$request = $this->get_catalog_request();
|
256 |
$request->set_update_item_taxes_data( $item_ids, $taxes_to_enable, $taxes_to_disable );
|
@@ -299,27 +299,27 @@ class API extends Framework\SV_WC_API_Base {
|
|
299 |
|
300 |
$image = file_get_contents( $image_path );
|
301 |
|
302 |
-
$headers =
|
303 |
'accept' => 'application/json',
|
304 |
'content-type' => 'multipart/form-data; boundary="boundary"',
|
305 |
'Square-Version' => '2019-05-08',
|
306 |
'Authorization' => 'Bearer ' . wc_square()->get_settings_handler()->get_access_token(),
|
307 |
-
|
308 |
|
309 |
-
$body
|
310 |
$body .= 'Content-Disposition: form-data; name="request"' . "\r\n";
|
311 |
$body .= 'Content-Type: application/json' . "\r\n\r\n";
|
312 |
|
313 |
-
$request =
|
314 |
'idempotency_key' => wc_square()->get_idempotency_key(),
|
315 |
-
'image' =>
|
316 |
'type' => 'IMAGE',
|
317 |
'id' => '#TEMP_ID',
|
318 |
-
'image_data' =>
|
319 |
'caption' => esc_attr( $caption ),
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
|
324 |
if ( $square_item_id ) {
|
325 |
$request['object_id'] = $square_item_id;
|
@@ -337,10 +337,13 @@ class API extends Framework\SV_WC_API_Base {
|
|
337 |
|
338 |
$url = $this->client->getConfig()->getHost() . '/v2/catalog/images';
|
339 |
|
340 |
-
$response = wp_remote_post(
|
341 |
-
|
342 |
-
|
343 |
-
|
|
|
|
|
|
|
344 |
|
345 |
if ( is_wp_error( $response ) ) {
|
346 |
throw new Framework\SV_WC_API_Exception( $response->get_error_message() );
|
@@ -438,18 +441,25 @@ class API extends Framework\SV_WC_API_Base {
|
|
438 |
|
439 |
$change = new SquareConnect\Model\InventoryChange();
|
440 |
$change->setType( 'ADJUSTMENT' );
|
441 |
-
$change->setAdjustment(
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
|
|
|
|
|
|
|
|
449 |
|
450 |
-
return $this->batch_change_inventory(
|
451 |
-
|
452 |
-
|
|
|
|
|
|
|
453 |
}
|
454 |
|
455 |
|
@@ -483,7 +493,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
483 |
* @return Responses\Inventory
|
484 |
* @throws Framework\SV_WC_API_Exception
|
485 |
*/
|
486 |
-
public function batch_retrieve_inventory_changes( array $args =
|
487 |
|
488 |
$request = $this->get_inventory_request();
|
489 |
$request->set_batch_retrieve_inventory_changes_data( $args );
|
@@ -502,7 +512,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
502 |
* @return Responses\Inventory
|
503 |
* @throws Framework\SV_WC_API_Exception
|
504 |
*/
|
505 |
-
public function batch_retrieve_inventory_counts( array $args =
|
506 |
|
507 |
$request = $this->get_inventory_request();
|
508 |
$request->set_batch_retrieve_inventory_counts_data( $args );
|
@@ -561,7 +571,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
561 |
public function retrieve_inventory_count( $catalog_object_id ) {
|
562 |
|
563 |
$request = $this->get_inventory_request();
|
564 |
-
$request->set_retrieve_inventory_count_data( $catalog_object_id,
|
565 |
|
566 |
return $this->perform_request( $request );
|
567 |
}
|
@@ -683,12 +693,12 @@ class API extends Framework\SV_WC_API_Base {
|
|
683 |
case self::REQUEST_TYPE_CATALOG:
|
684 |
$request = new Requests\Catalog( $this->client );
|
685 |
$response_handler = Responses\Catalog::class;
|
686 |
-
|
687 |
|
688 |
case self::REQUEST_TYPE_INVENTORY:
|
689 |
$request = new Requests\Inventory( $this->client );
|
690 |
$response_handler = Responses\Inventory::class;
|
691 |
-
|
692 |
|
693 |
default:
|
694 |
throw new Framework\SV_WC_API_Exception( 'Invalid request type.' );
|
@@ -799,7 +809,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
799 |
return true;
|
800 |
}
|
801 |
|
802 |
-
$errors =
|
803 |
|
804 |
foreach ( $this->get_response()->get_errors() as $error ) {
|
805 |
if ( empty( $error->code ) ) {
|
@@ -809,7 +819,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
809 |
$errors[] = trim( "[{$error->code}] {$error->detail}" );
|
810 |
|
811 |
// Last attempt to refresh access token.
|
812 |
-
if ( 'ACCESS_TOKEN_EXPIRED'
|
813 |
$this->get_plugin()->log( 'Access Token Expired, attempting a refresh.' );
|
814 |
$this->get_plugin()->get_connection_handler()->refresh_connection();
|
815 |
|
@@ -823,7 +833,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
823 |
}
|
824 |
|
825 |
// if the error indicates that access token is bad, disconnect the plugin to prevent further attempts
|
826 |
-
if ( in_array( $error->code,
|
827 |
$this->get_plugin()->get_connection_handler()->disconnect();
|
828 |
$this->get_plugin()->log( 'Disconnected due to invalid authorization. Please try connecting again.' );
|
829 |
}
|
@@ -845,23 +855,22 @@ class API extends Framework\SV_WC_API_Base {
|
|
845 |
*/
|
846 |
protected function do_square_request( $square_api, $method, $args ) {
|
847 |
|
848 |
-
if ( ! is_callable(
|
849 |
throw new Framework\SV_WC_API_Exception( 'Invalid API method' );
|
850 |
}
|
851 |
|
852 |
try {
|
853 |
|
854 |
// perform the request
|
855 |
-
$response = call_user_func_array(
|
856 |
|
857 |
if ( is_array( $response ) && $this->request->get_with_http_info() ) {
|
858 |
$this->response_code = isset( $response[1] ) ? (int) $response[1] : 400;
|
859 |
-
$this->response_headers = isset( $response[2] ) ? (array) $response[2] :
|
860 |
-
$this->raw_response_body = isset( $response[0] ) ? $response[0] :
|
861 |
} else {
|
862 |
$this->raw_response_body = $response;
|
863 |
}
|
864 |
-
|
865 |
} catch ( SquareConnect\ApiException $exception ) {
|
866 |
|
867 |
$this->response_code = $exception->getCode();
|
28 |
use WooCommerce\Square\API\Requests;
|
29 |
use WooCommerce\Square\API\Responses;
|
30 |
|
31 |
+
defined( 'ABSPATH' ) || exit;
|
32 |
|
33 |
/**
|
34 |
* WooCommerce Square API class
|
173 |
* @return Responses\Catalog
|
174 |
* @throws Framework\SV_WC_API_Exception
|
175 |
*/
|
176 |
+
public function list_catalog( $cursor = '', $types = array() ) {
|
177 |
|
178 |
$request = $this->get_catalog_request();
|
179 |
$request->set_list_catalog_data( $cursor, $types );
|
210 |
* @return Responses\Catalog
|
211 |
* @throws Framework\SV_WC_API_Exception
|
212 |
*/
|
213 |
+
public function search_catalog_objects( $args = array() ) {
|
214 |
|
215 |
$request = $this->get_catalog_request();
|
216 |
$request->set_search_catalog_objects_data( $args );
|
230 |
* @return Responses\Catalog
|
231 |
* @throws Framework\SV_WC_API_Exception
|
232 |
*/
|
233 |
+
public function update_item_modifier_lists( array $item_ids, array $modifier_lists_to_enable = array(), array $modifier_lists_to_disable = array() ) {
|
234 |
|
235 |
$request = $this->get_catalog_request();
|
236 |
$request->set_update_item_modifier_lists_data( $item_ids, $modifier_lists_to_enable, $modifier_lists_to_disable );
|
250 |
* @return Responses\Catalog
|
251 |
* @throws Framework\SV_WC_API_Exception
|
252 |
*/
|
253 |
+
public function update_item_taxes( array $item_ids, array $taxes_to_enable = array(), array $taxes_to_disable = array() ) {
|
254 |
|
255 |
$request = $this->get_catalog_request();
|
256 |
$request->set_update_item_taxes_data( $item_ids, $taxes_to_enable, $taxes_to_disable );
|
299 |
|
300 |
$image = file_get_contents( $image_path );
|
301 |
|
302 |
+
$headers = array(
|
303 |
'accept' => 'application/json',
|
304 |
'content-type' => 'multipart/form-data; boundary="boundary"',
|
305 |
'Square-Version' => '2019-05-08',
|
306 |
'Authorization' => 'Bearer ' . wc_square()->get_settings_handler()->get_access_token(),
|
307 |
+
);
|
308 |
|
309 |
+
$body = '--boundary' . "\r\n";
|
310 |
$body .= 'Content-Disposition: form-data; name="request"' . "\r\n";
|
311 |
$body .= 'Content-Type: application/json' . "\r\n\r\n";
|
312 |
|
313 |
+
$request = array(
|
314 |
'idempotency_key' => wc_square()->get_idempotency_key(),
|
315 |
+
'image' => array(
|
316 |
'type' => 'IMAGE',
|
317 |
'id' => '#TEMP_ID',
|
318 |
+
'image_data' => array(
|
319 |
'caption' => esc_attr( $caption ),
|
320 |
+
),
|
321 |
+
),
|
322 |
+
);
|
323 |
|
324 |
if ( $square_item_id ) {
|
325 |
$request['object_id'] = $square_item_id;
|
337 |
|
338 |
$url = $this->client->getConfig()->getHost() . '/v2/catalog/images';
|
339 |
|
340 |
+
$response = wp_remote_post(
|
341 |
+
$url,
|
342 |
+
array(
|
343 |
+
'headers' => $headers,
|
344 |
+
'body' => $body,
|
345 |
+
)
|
346 |
+
);
|
347 |
|
348 |
if ( is_wp_error( $response ) ) {
|
349 |
throw new Framework\SV_WC_API_Exception( $response->get_error_message() );
|
441 |
|
442 |
$change = new SquareConnect\Model\InventoryChange();
|
443 |
$change->setType( 'ADJUSTMENT' );
|
444 |
+
$change->setAdjustment(
|
445 |
+
new SquareConnect\Model\InventoryAdjustment(
|
446 |
+
array(
|
447 |
+
'catalog_object_id' => $square_id,
|
448 |
+
'location_id' => $this->get_plugin()->get_settings_handler()->get_location_id(),
|
449 |
+
'quantity' => (string) absint( $amount ),
|
450 |
+
'from_state' => $from_state,
|
451 |
+
'to_state' => $to_state,
|
452 |
+
'occurred_at' => $date->format( DATE_ATOM ),
|
453 |
+
)
|
454 |
+
)
|
455 |
+
);
|
456 |
|
457 |
+
return $this->batch_change_inventory(
|
458 |
+
uniqid( '', false ),
|
459 |
+
array(
|
460 |
+
$change,
|
461 |
+
)
|
462 |
+
);
|
463 |
}
|
464 |
|
465 |
|
493 |
* @return Responses\Inventory
|
494 |
* @throws Framework\SV_WC_API_Exception
|
495 |
*/
|
496 |
+
public function batch_retrieve_inventory_changes( array $args = array() ) {
|
497 |
|
498 |
$request = $this->get_inventory_request();
|
499 |
$request->set_batch_retrieve_inventory_changes_data( $args );
|
512 |
* @return Responses\Inventory
|
513 |
* @throws Framework\SV_WC_API_Exception
|
514 |
*/
|
515 |
+
public function batch_retrieve_inventory_counts( array $args = array() ) {
|
516 |
|
517 |
$request = $this->get_inventory_request();
|
518 |
$request->set_batch_retrieve_inventory_counts_data( $args );
|
571 |
public function retrieve_inventory_count( $catalog_object_id ) {
|
572 |
|
573 |
$request = $this->get_inventory_request();
|
574 |
+
$request->set_retrieve_inventory_count_data( $catalog_object_id, array( $this->get_plugin()->get_settings_handler()->get_location_id() ) );
|
575 |
|
576 |
return $this->perform_request( $request );
|
577 |
}
|
693 |
case self::REQUEST_TYPE_CATALOG:
|
694 |
$request = new Requests\Catalog( $this->client );
|
695 |
$response_handler = Responses\Catalog::class;
|
696 |
+
break;
|
697 |
|
698 |
case self::REQUEST_TYPE_INVENTORY:
|
699 |
$request = new Requests\Inventory( $this->client );
|
700 |
$response_handler = Responses\Inventory::class;
|
701 |
+
break;
|
702 |
|
703 |
default:
|
704 |
throw new Framework\SV_WC_API_Exception( 'Invalid request type.' );
|
809 |
return true;
|
810 |
}
|
811 |
|
812 |
+
$errors = array();
|
813 |
|
814 |
foreach ( $this->get_response()->get_errors() as $error ) {
|
815 |
if ( empty( $error->code ) ) {
|
819 |
$errors[] = trim( "[{$error->code}] {$error->detail}" );
|
820 |
|
821 |
// Last attempt to refresh access token.
|
822 |
+
if ( 'ACCESS_TOKEN_EXPIRED' == $error->code ) {
|
823 |
$this->get_plugin()->log( 'Access Token Expired, attempting a refresh.' );
|
824 |
$this->get_plugin()->get_connection_handler()->refresh_connection();
|
825 |
|
833 |
}
|
834 |
|
835 |
// if the error indicates that access token is bad, disconnect the plugin to prevent further attempts
|
836 |
+
if ( in_array( $error->code, array( 'ACCESS_TOKEN_EXPIRED', 'ACCESS_TOKEN_REVOKED' ), true ) ) {
|
837 |
$this->get_plugin()->get_connection_handler()->disconnect();
|
838 |
$this->get_plugin()->log( 'Disconnected due to invalid authorization. Please try connecting again.' );
|
839 |
}
|
855 |
*/
|
856 |
protected function do_square_request( $square_api, $method, $args ) {
|
857 |
|
858 |
+
if ( ! is_callable( array( $square_api, $method ) ) ) {
|
859 |
throw new Framework\SV_WC_API_Exception( 'Invalid API method' );
|
860 |
}
|
861 |
|
862 |
try {
|
863 |
|
864 |
// perform the request
|
865 |
+
$response = call_user_func_array( array( $square_api, $method ), $args );
|
866 |
|
867 |
if ( is_array( $response ) && $this->request->get_with_http_info() ) {
|
868 |
$this->response_code = isset( $response[1] ) ? (int) $response[1] : 400;
|
869 |
+
$this->response_headers = isset( $response[2] ) ? (array) $response[2] : array();
|
870 |
+
$this->raw_response_body = isset( $response[0] ) ? $response[0] : array();
|
871 |
} else {
|
872 |
$this->raw_response_body = $response;
|
873 |
}
|
|
|
874 |
} catch ( SquareConnect\ApiException $exception ) {
|
875 |
|
876 |
$this->response_code = $exception->getCode();
|
includes/API/Request.php
CHANGED
@@ -26,7 +26,7 @@ namespace WooCommerce\Square\API;
|
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use SquareConnect\Configuration;
|
28 |
|
29 |
-
defined( 'ABSPATH' )
|
30 |
|
31 |
/**
|
32 |
* Base WooCommerce Square API request object.
|
@@ -46,7 +46,7 @@ class Request implements Framework\SV_WC_API_Request {
|
|
46 |
protected $square_api_method;
|
47 |
|
48 |
/** @var array arguments for the method call */
|
49 |
-
protected $square_api_args =
|
50 |
|
51 |
/** @var null|object the square API request model */
|
52 |
protected $square_request;
|
@@ -168,17 +168,17 @@ class Request implements Framework\SV_WC_API_Request {
|
|
168 |
|
169 |
$body = '';
|
170 |
|
171 |
-
if ( is_callable(
|
172 |
|
173 |
$body = $this->square_request->__toString();
|
174 |
|
175 |
} elseif ( is_array( $this->square_api_args ) ) {
|
176 |
|
177 |
-
$body =
|
178 |
|
179 |
foreach ( $this->square_api_args as $key => $arg ) {
|
180 |
|
181 |
-
if ( is_callable(
|
182 |
$body[ $key ] = $arg->__toString();
|
183 |
}
|
184 |
}
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use SquareConnect\Configuration;
|
28 |
|
29 |
+
defined( 'ABSPATH' ) || exit;
|
30 |
|
31 |
/**
|
32 |
* Base WooCommerce Square API request object.
|
46 |
protected $square_api_method;
|
47 |
|
48 |
/** @var array arguments for the method call */
|
49 |
+
protected $square_api_args = array();
|
50 |
|
51 |
/** @var null|object the square API request model */
|
52 |
protected $square_request;
|
168 |
|
169 |
$body = '';
|
170 |
|
171 |
+
if ( is_callable( array( $this->square_request, '__toString' ) ) ) {
|
172 |
|
173 |
$body = $this->square_request->__toString();
|
174 |
|
175 |
} elseif ( is_array( $this->square_api_args ) ) {
|
176 |
|
177 |
+
$body = array();
|
178 |
|
179 |
foreach ( $this->square_api_args as $key => $arg ) {
|
180 |
|
181 |
+
if ( is_callable( array( $arg, '__toString' ) ) ) {
|
182 |
$body[ $key ] = $arg->__toString();
|
183 |
}
|
184 |
}
|
includes/API/Requests/Catalog.php
CHANGED
@@ -28,7 +28,7 @@ use SquareConnect\Model as SquareModel;
|
|
28 |
use SquareConnect\Api\CatalogApi;
|
29 |
use WooCommerce\Square\API\Request;
|
30 |
|
31 |
-
defined( 'ABSPATH' )
|
32 |
|
33 |
/**
|
34 |
* WooCommerce Square Catalog API Request class.
|
@@ -64,7 +64,7 @@ class Catalog extends Request {
|
|
64 |
public function set_batch_delete_catalog_objects_data( array $object_ids ) {
|
65 |
|
66 |
$this->square_api_method = 'batchDeleteCatalogObjects';
|
67 |
-
$this->square_api_args =
|
68 |
}
|
69 |
|
70 |
|
@@ -82,10 +82,14 @@ class Catalog extends Request {
|
|
82 |
public function set_batch_retrieve_catalog_objects_data( array $object_ids, $include_related_objects = false ) {
|
83 |
|
84 |
$this->square_api_method = 'batchRetrieveCatalogObjects';
|
85 |
-
$this->square_api_args =
|
86 |
-
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
89 |
}
|
90 |
|
91 |
|
@@ -103,10 +107,14 @@ class Catalog extends Request {
|
|
103 |
public function set_batch_upsert_catalog_objects_data( $idempotency_key, array $batches ) {
|
104 |
|
105 |
$this->square_api_method = 'batchUpsertCatalogObjects';
|
106 |
-
$this->square_api_args =
|
107 |
-
|
108 |
-
|
109 |
-
|
|
|
|
|
|
|
|
|
110 |
}
|
111 |
|
112 |
|
@@ -121,7 +129,7 @@ class Catalog extends Request {
|
|
121 |
* @param string $cursor
|
122 |
* @param array $types
|
123 |
*/
|
124 |
-
public function set_catalog_info_data( $cursor = '', $types =
|
125 |
|
126 |
$this->square_api_method = 'catalogInfo';
|
127 |
}
|
@@ -140,7 +148,7 @@ class Catalog extends Request {
|
|
140 |
public function set_delete_catalog_object_data( $object_id ) {
|
141 |
|
142 |
$this->square_api_method = 'deleteCatalogObject';
|
143 |
-
$this->square_api_args =
|
144 |
}
|
145 |
|
146 |
|
@@ -155,13 +163,13 @@ class Catalog extends Request {
|
|
155 |
* @param string $cursor (optional) the pagination cursor
|
156 |
* @param array $types (optional) the catalog item types to filter by
|
157 |
*/
|
158 |
-
public function set_list_catalog_data( $cursor = '', $types =
|
159 |
|
160 |
$this->square_api_method = 'listCatalog';
|
161 |
-
$this->square_api_args =
|
162 |
'cursor' => $cursor,
|
163 |
-
'types' => is_array( $types ) ? implode( ',', array_map( 'strtoupper', $types ) ) : ''
|
164 |
-
|
165 |
}
|
166 |
|
167 |
|
@@ -179,7 +187,7 @@ class Catalog extends Request {
|
|
179 |
public function set_retrieve_catalog_object_data( $object_id, $include_related_objects = false ) {
|
180 |
|
181 |
$this->square_api_method = 'retrieveCatalogObject';
|
182 |
-
$this->square_api_args =
|
183 |
}
|
184 |
|
185 |
|
@@ -193,14 +201,14 @@ class Catalog extends Request {
|
|
193 |
*
|
194 |
* @param array $args see Square documentation for full list of args allowed
|
195 |
*/
|
196 |
-
public function set_search_catalog_objects_data( array $args =
|
197 |
|
198 |
// convert object types to array
|
199 |
if ( isset( $args['object_types'] ) && ! is_array( $args['object_types'] ) ) {
|
200 |
-
$args['object_types'] =
|
201 |
}
|
202 |
|
203 |
-
$defaults =
|
204 |
'cursor' => null,
|
205 |
'object_types' => null,
|
206 |
'include_deleted_objects' => null,
|
@@ -208,13 +216,13 @@ class Catalog extends Request {
|
|
208 |
'begin_time' => null,
|
209 |
'query' => null,
|
210 |
'limit' => null,
|
211 |
-
|
212 |
|
213 |
// apply defaults and remove any keys that aren't recognized
|
214 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
215 |
|
216 |
$this->square_api_method = 'searchCatalogObjects';
|
217 |
-
$this->square_api_args =
|
218 |
}
|
219 |
|
220 |
|
@@ -230,14 +238,18 @@ class Catalog extends Request {
|
|
230 |
* @param string[] $modifier_lists_to_enable array of list IDs to enable
|
231 |
* @param string[] $modifier_lists_to_disable array of list IDs to disable
|
232 |
*/
|
233 |
-
public function set_update_item_modifier_lists_data( array $item_ids, array $modifier_lists_to_enable =
|
234 |
|
235 |
$this->square_api_method = 'updateItemModifierLists';
|
236 |
-
$this->square_api_args =
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
|
|
|
|
|
|
|
|
241 |
}
|
242 |
|
243 |
|
@@ -253,14 +265,18 @@ class Catalog extends Request {
|
|
253 |
* @param string[] $taxes_to_enable array of catalog tax IDs to enable
|
254 |
* @param string[] $taxes_to_disable array of catalog tax IDs to disable
|
255 |
*/
|
256 |
-
public function set_update_item_taxes_data( array $item_ids, array $taxes_to_enable =
|
257 |
|
258 |
$this->square_api_method = 'updateItemTaxes';
|
259 |
-
$this->square_api_args =
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
|
|
|
|
|
|
|
|
264 |
}
|
265 |
|
266 |
|
@@ -278,10 +294,14 @@ class Catalog extends Request {
|
|
278 |
public function set_upsert_catalog_object_data( $idempotency_key, $object ) {
|
279 |
|
280 |
$this->square_api_method = 'upsertCatalogObject';
|
281 |
-
$this->square_api_args =
|
282 |
-
|
283 |
-
|
284 |
-
|
|
|
|
|
|
|
|
|
285 |
}
|
286 |
|
287 |
|
28 |
use SquareConnect\Api\CatalogApi;
|
29 |
use WooCommerce\Square\API\Request;
|
30 |
|
31 |
+
defined( 'ABSPATH' ) || exit;
|
32 |
|
33 |
/**
|
34 |
* WooCommerce Square Catalog API Request class.
|
64 |
public function set_batch_delete_catalog_objects_data( array $object_ids ) {
|
65 |
|
66 |
$this->square_api_method = 'batchDeleteCatalogObjects';
|
67 |
+
$this->square_api_args = array( new SquareModel\BatchDeleteCatalogObjectsRequest( array( 'object_ids' => $object_ids ) ) );
|
68 |
}
|
69 |
|
70 |
|
82 |
public function set_batch_retrieve_catalog_objects_data( array $object_ids, $include_related_objects = false ) {
|
83 |
|
84 |
$this->square_api_method = 'batchRetrieveCatalogObjects';
|
85 |
+
$this->square_api_args = array(
|
86 |
+
new SquareModel\BatchRetrieveCatalogObjectsRequest(
|
87 |
+
array(
|
88 |
+
'object_ids' => $object_ids,
|
89 |
+
'include_related_objects' => (bool) $include_related_objects,
|
90 |
+
)
|
91 |
+
),
|
92 |
+
);
|
93 |
}
|
94 |
|
95 |
|
107 |
public function set_batch_upsert_catalog_objects_data( $idempotency_key, array $batches ) {
|
108 |
|
109 |
$this->square_api_method = 'batchUpsertCatalogObjects';
|
110 |
+
$this->square_api_args = array(
|
111 |
+
new SquareModel\BatchUpsertCatalogObjectsRequest(
|
112 |
+
array(
|
113 |
+
'idempotency_key' => $idempotency_key,
|
114 |
+
'batches' => $batches,
|
115 |
+
)
|
116 |
+
),
|
117 |
+
);
|
118 |
}
|
119 |
|
120 |
|
129 |
* @param string $cursor
|
130 |
* @param array $types
|
131 |
*/
|
132 |
+
public function set_catalog_info_data( $cursor = '', $types = array() ) {
|
133 |
|
134 |
$this->square_api_method = 'catalogInfo';
|
135 |
}
|
148 |
public function set_delete_catalog_object_data( $object_id ) {
|
149 |
|
150 |
$this->square_api_method = 'deleteCatalogObject';
|
151 |
+
$this->square_api_args = array( $object_id );
|
152 |
}
|
153 |
|
154 |
|
163 |
* @param string $cursor (optional) the pagination cursor
|
164 |
* @param array $types (optional) the catalog item types to filter by
|
165 |
*/
|
166 |
+
public function set_list_catalog_data( $cursor = '', $types = array() ) {
|
167 |
|
168 |
$this->square_api_method = 'listCatalog';
|
169 |
+
$this->square_api_args = array(
|
170 |
'cursor' => $cursor,
|
171 |
+
'types' => is_array( $types ) ? implode( ',', array_map( 'strtoupper', $types ) ) : '',
|
172 |
+
);
|
173 |
}
|
174 |
|
175 |
|
187 |
public function set_retrieve_catalog_object_data( $object_id, $include_related_objects = false ) {
|
188 |
|
189 |
$this->square_api_method = 'retrieveCatalogObject';
|
190 |
+
$this->square_api_args = array( $object_id, (bool) $include_related_objects );
|
191 |
}
|
192 |
|
193 |
|
201 |
*
|
202 |
* @param array $args see Square documentation for full list of args allowed
|
203 |
*/
|
204 |
+
public function set_search_catalog_objects_data( array $args = array() ) {
|
205 |
|
206 |
// convert object types to array
|
207 |
if ( isset( $args['object_types'] ) && ! is_array( $args['object_types'] ) ) {
|
208 |
+
$args['object_types'] = array( $args['object_types'] );
|
209 |
}
|
210 |
|
211 |
+
$defaults = array(
|
212 |
'cursor' => null,
|
213 |
'object_types' => null,
|
214 |
'include_deleted_objects' => null,
|
216 |
'begin_time' => null,
|
217 |
'query' => null,
|
218 |
'limit' => null,
|
219 |
+
);
|
220 |
|
221 |
// apply defaults and remove any keys that aren't recognized
|
222 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
223 |
|
224 |
$this->square_api_method = 'searchCatalogObjects';
|
225 |
+
$this->square_api_args = array( new SquareModel\SearchCatalogObjectsRequest( $args ) );
|
226 |
}
|
227 |
|
228 |
|
238 |
* @param string[] $modifier_lists_to_enable array of list IDs to enable
|
239 |
* @param string[] $modifier_lists_to_disable array of list IDs to disable
|
240 |
*/
|
241 |
+
public function set_update_item_modifier_lists_data( array $item_ids, array $modifier_lists_to_enable = array(), array $modifier_lists_to_disable = array() ) {
|
242 |
|
243 |
$this->square_api_method = 'updateItemModifierLists';
|
244 |
+
$this->square_api_args = array(
|
245 |
+
new SquareModel\UpdateItemModifierListsRequest(
|
246 |
+
array(
|
247 |
+
'item_ids' => $item_ids,
|
248 |
+
'modifier_lists_to_enable' => $modifier_lists_to_enable,
|
249 |
+
'modifier_lists_to_disable' => $modifier_lists_to_disable,
|
250 |
+
)
|
251 |
+
),
|
252 |
+
);
|
253 |
}
|
254 |
|
255 |
|
265 |
* @param string[] $taxes_to_enable array of catalog tax IDs to enable
|
266 |
* @param string[] $taxes_to_disable array of catalog tax IDs to disable
|
267 |
*/
|
268 |
+
public function set_update_item_taxes_data( array $item_ids, array $taxes_to_enable = array(), array $taxes_to_disable = array() ) {
|
269 |
|
270 |
$this->square_api_method = 'updateItemTaxes';
|
271 |
+
$this->square_api_args = array(
|
272 |
+
new SquareModel\UpdateItemTaxesRequest(
|
273 |
+
array(
|
274 |
+
'item_ids' => $item_ids,
|
275 |
+
'taxes_to_enable' => $taxes_to_enable,
|
276 |
+
'taxes_to_disable' => $taxes_to_disable,
|
277 |
+
)
|
278 |
+
),
|
279 |
+
);
|
280 |
}
|
281 |
|
282 |
|
294 |
public function set_upsert_catalog_object_data( $idempotency_key, $object ) {
|
295 |
|
296 |
$this->square_api_method = 'upsertCatalogObject';
|
297 |
+
$this->square_api_args = array(
|
298 |
+
new SquareModel\UpsertCatalogObjectRequest(
|
299 |
+
array(
|
300 |
+
'idempotency_key' => $idempotency_key,
|
301 |
+
'object' => $object,
|
302 |
+
)
|
303 |
+
),
|
304 |
+
);
|
305 |
}
|
306 |
|
307 |
|
includes/API/Requests/Customers.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\API\Requests;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SquareConnect\Api\CustomersApi;
|
29 |
use WooCommerce\Square\API;
|
@@ -60,7 +60,7 @@ class Customers extends API\Request {
|
|
60 |
|
61 |
$this->square_api_method = 'retrieveCustomer';
|
62 |
|
63 |
-
$this->square_api_args =
|
64 |
}
|
65 |
|
66 |
|
@@ -76,7 +76,7 @@ class Customers extends API\Request {
|
|
76 |
$this->square_api_method = 'listCustomers';
|
77 |
|
78 |
if ( $cursor ) {
|
79 |
-
$this->square_api_args =
|
80 |
}
|
81 |
}
|
82 |
|
23 |
|
24 |
namespace WooCommerce\Square\API\Requests;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SquareConnect\Api\CustomersApi;
|
29 |
use WooCommerce\Square\API;
|
60 |
|
61 |
$this->square_api_method = 'retrieveCustomer';
|
62 |
|
63 |
+
$this->square_api_args = array( $customer_id );
|
64 |
}
|
65 |
|
66 |
|
76 |
$this->square_api_method = 'listCustomers';
|
77 |
|
78 |
if ( $cursor ) {
|
79 |
+
$this->square_api_args = array( 'cursor' => $cursor );
|
80 |
}
|
81 |
}
|
82 |
|
includes/API/Requests/Inventory.php
CHANGED
@@ -28,7 +28,7 @@ use SquareConnect\Model as SquareModel;
|
|
28 |
use SquareConnect\Api\InventoryApi;
|
29 |
use WooCommerce\Square\API\Request;
|
30 |
|
31 |
-
defined( 'ABSPATH' )
|
32 |
|
33 |
/**
|
34 |
* WooCommerce Square Inventory API Request class
|
@@ -66,11 +66,15 @@ class Inventory extends Request {
|
|
66 |
public function set_batch_change_inventory_data( $idempotency_key, $changes, $ignore_unchanged_counts = true ) {
|
67 |
|
68 |
$this->square_api_method = 'batchChangeInventory';
|
69 |
-
$this->square_api_args =
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
74 |
}
|
75 |
|
76 |
|
@@ -91,9 +95,9 @@ class Inventory extends Request {
|
|
91 |
* @type string $updated_before filters any changes updated before this time
|
92 |
* @type string $cursor pagination cursor
|
93 |
*/
|
94 |
-
public function set_batch_retrieve_inventory_changes_data( $args =
|
95 |
|
96 |
-
$defaults =
|
97 |
'catalog_object_ids' => null,
|
98 |
'location_ids' => null,
|
99 |
'types' => null,
|
@@ -101,13 +105,13 @@ class Inventory extends Request {
|
|
101 |
'updated_after' => null,
|
102 |
'updated_before' => null,
|
103 |
'cursor' => null,
|
104 |
-
|
105 |
|
106 |
// apply defaults and remove any keys that aren't recognized
|
107 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
108 |
|
109 |
$this->square_api_method = 'batchRetrieveInventoryChanges';
|
110 |
-
$this->square_api_args =
|
111 |
}
|
112 |
|
113 |
|
@@ -125,20 +129,20 @@ class Inventory extends Request {
|
|
125 |
* @type string $updated_after filters any changes updated after this time
|
126 |
* @type string $cursor pagination cursor
|
127 |
*/
|
128 |
-
public function set_batch_retrieve_inventory_counts_data( $args =
|
129 |
|
130 |
-
$defaults =
|
131 |
'catalog_object_ids' => null,
|
132 |
'location_ids' => null,
|
133 |
'updated_after' => null,
|
134 |
'cursor' => null,
|
135 |
-
|
136 |
|
137 |
// apply defaults and remove any keys that aren't recognized
|
138 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
139 |
|
140 |
$this->square_api_method = 'batchRetrieveInventoryCounts';
|
141 |
-
$this->square_api_args =
|
142 |
}
|
143 |
|
144 |
|
@@ -155,7 +159,7 @@ class Inventory extends Request {
|
|
155 |
public function set_retrieve_inventory_adjustment_data( $adjustment_id ) {
|
156 |
|
157 |
$this->square_api_method = 'retrieveInventoryAdjustment';
|
158 |
-
$this->square_api_args =
|
159 |
}
|
160 |
|
161 |
|
@@ -172,7 +176,7 @@ class Inventory extends Request {
|
|
172 |
public function set_retrieve_inventory_changes_data( $catalog_object_id ) {
|
173 |
|
174 |
$this->square_api_method = 'retrieveInventoryChanges';
|
175 |
-
$this->square_api_args =
|
176 |
}
|
177 |
|
178 |
|
@@ -187,10 +191,10 @@ class Inventory extends Request {
|
|
187 |
* @param string $catalog_object_id the CatalogObject ID to retrieve
|
188 |
* @param string[] $location_ids location IDs
|
189 |
*/
|
190 |
-
public function set_retrieve_inventory_count_data( $catalog_object_id, array $location_ids =
|
191 |
|
192 |
$this->square_api_method = 'retrieveInventoryCount';
|
193 |
-
$this->square_api_args =
|
194 |
}
|
195 |
|
196 |
|
@@ -207,7 +211,7 @@ class Inventory extends Request {
|
|
207 |
public function set_retrieve_inventory_physical_count_data( $physical_count_id ) {
|
208 |
|
209 |
$this->square_api_method = 'retrieveInventoryPhysicalCount';
|
210 |
-
$this->square_api_args =
|
211 |
}
|
212 |
|
213 |
|
28 |
use SquareConnect\Api\InventoryApi;
|
29 |
use WooCommerce\Square\API\Request;
|
30 |
|
31 |
+
defined( 'ABSPATH' ) || exit;
|
32 |
|
33 |
/**
|
34 |
* WooCommerce Square Inventory API Request class
|
66 |
public function set_batch_change_inventory_data( $idempotency_key, $changes, $ignore_unchanged_counts = true ) {
|
67 |
|
68 |
$this->square_api_method = 'batchChangeInventory';
|
69 |
+
$this->square_api_args = array(
|
70 |
+
new SquareModel\BatchChangeInventoryRequest(
|
71 |
+
array(
|
72 |
+
'idempotency_key' => $idempotency_key,
|
73 |
+
'changes' => $changes,
|
74 |
+
'ignore_unchanged_counts' => (bool) $ignore_unchanged_counts,
|
75 |
+
)
|
76 |
+
),
|
77 |
+
);
|
78 |
}
|
79 |
|
80 |
|
95 |
* @type string $updated_before filters any changes updated before this time
|
96 |
* @type string $cursor pagination cursor
|
97 |
*/
|
98 |
+
public function set_batch_retrieve_inventory_changes_data( $args = array() ) {
|
99 |
|
100 |
+
$defaults = array(
|
101 |
'catalog_object_ids' => null,
|
102 |
'location_ids' => null,
|
103 |
'types' => null,
|
105 |
'updated_after' => null,
|
106 |
'updated_before' => null,
|
107 |
'cursor' => null,
|
108 |
+
);
|
109 |
|
110 |
// apply defaults and remove any keys that aren't recognized
|
111 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
112 |
|
113 |
$this->square_api_method = 'batchRetrieveInventoryChanges';
|
114 |
+
$this->square_api_args = array( new SquareModel\BatchRetrieveInventoryChangesRequest( $args ) );
|
115 |
}
|
116 |
|
117 |
|
129 |
* @type string $updated_after filters any changes updated after this time
|
130 |
* @type string $cursor pagination cursor
|
131 |
*/
|
132 |
+
public function set_batch_retrieve_inventory_counts_data( $args = array() ) {
|
133 |
|
134 |
+
$defaults = array(
|
135 |
'catalog_object_ids' => null,
|
136 |
'location_ids' => null,
|
137 |
'updated_after' => null,
|
138 |
'cursor' => null,
|
139 |
+
);
|
140 |
|
141 |
// apply defaults and remove any keys that aren't recognized
|
142 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
143 |
|
144 |
$this->square_api_method = 'batchRetrieveInventoryCounts';
|
145 |
+
$this->square_api_args = array( new SquareModel\BatchRetrieveInventoryCountsRequest( $args ) );
|
146 |
}
|
147 |
|
148 |
|
159 |
public function set_retrieve_inventory_adjustment_data( $adjustment_id ) {
|
160 |
|
161 |
$this->square_api_method = 'retrieveInventoryAdjustment';
|
162 |
+
$this->square_api_args = array( $adjustment_id );
|
163 |
}
|
164 |
|
165 |
|
176 |
public function set_retrieve_inventory_changes_data( $catalog_object_id ) {
|
177 |
|
178 |
$this->square_api_method = 'retrieveInventoryChanges';
|
179 |
+
$this->square_api_args = array( $catalog_object_id );
|
180 |
}
|
181 |
|
182 |
|
191 |
* @param string $catalog_object_id the CatalogObject ID to retrieve
|
192 |
* @param string[] $location_ids location IDs
|
193 |
*/
|
194 |
+
public function set_retrieve_inventory_count_data( $catalog_object_id, array $location_ids = array() ) {
|
195 |
|
196 |
$this->square_api_method = 'retrieveInventoryCount';
|
197 |
+
$this->square_api_args = array( $catalog_object_id, $location_ids );
|
198 |
}
|
199 |
|
200 |
|
211 |
public function set_retrieve_inventory_physical_count_data( $physical_count_id ) {
|
212 |
|
213 |
$this->square_api_method = 'retrieveInventoryPhysicalCount';
|
214 |
+
$this->square_api_args = array( $physical_count_id );
|
215 |
}
|
216 |
|
217 |
|
includes/API/Requests/Locations.php
CHANGED
@@ -28,7 +28,7 @@ use SquareConnect\Model as SquareModel;
|
|
28 |
use SquareConnect\Api\LocationsApi;
|
29 |
use WooCommerce\Square\API\Request;
|
30 |
|
31 |
-
defined( 'ABSPATH' )
|
32 |
|
33 |
/**
|
34 |
* WooCommerce Square locations API Request class.
|
28 |
use SquareConnect\Api\LocationsApi;
|
29 |
use WooCommerce\Square\API\Request;
|
30 |
|
31 |
+
defined( 'ABSPATH' ) || exit;
|
32 |
|
33 |
/**
|
34 |
* WooCommerce Square locations API Request class.
|
includes/API/Response.php
CHANGED
@@ -25,7 +25,7 @@ namespace WooCommerce\Square\API;
|
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
-
defined( 'ABSPATH' )
|
29 |
|
30 |
/**
|
31 |
* Base WooCommerce Square API response object.
|
@@ -74,7 +74,7 @@ class Response implements Framework\SV_WC_API_Response {
|
|
74 |
*/
|
75 |
public function get_errors() {
|
76 |
|
77 |
-
return ! empty( $this->raw_response_data->errors ) && is_array( $this->raw_response_data->errors ) ? $this->raw_response_data->errors :
|
78 |
}
|
79 |
|
80 |
|
@@ -100,7 +100,7 @@ class Response implements Framework\SV_WC_API_Response {
|
|
100 |
*/
|
101 |
public function has_error_code( $error_code ) {
|
102 |
|
103 |
-
foreach( $this->get_errors() as $error ) {
|
104 |
if ( $error_code === $error->code ) {
|
105 |
return true;
|
106 |
}
|
@@ -118,7 +118,7 @@ class Response implements Framework\SV_WC_API_Response {
|
|
118 |
*/
|
119 |
public function to_string() {
|
120 |
|
121 |
-
return is_callable(
|
122 |
}
|
123 |
|
124 |
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
+
defined( 'ABSPATH' ) || exit;
|
29 |
|
30 |
/**
|
31 |
* Base WooCommerce Square API response object.
|
74 |
*/
|
75 |
public function get_errors() {
|
76 |
|
77 |
+
return ! empty( $this->raw_response_data->errors ) && is_array( $this->raw_response_data->errors ) ? $this->raw_response_data->errors : array();
|
78 |
}
|
79 |
|
80 |
|
100 |
*/
|
101 |
public function has_error_code( $error_code ) {
|
102 |
|
103 |
+
foreach ( $this->get_errors() as $error ) {
|
104 |
if ( $error_code === $error->code ) {
|
105 |
return true;
|
106 |
}
|
118 |
*/
|
119 |
public function to_string() {
|
120 |
|
121 |
+
return is_callable( array( $this->get_data(), '__toString' ) ) ? $this->get_data() : '';
|
122 |
}
|
123 |
|
124 |
|
includes/API/Responses/Catalog.php
CHANGED
@@ -26,7 +26,7 @@ namespace WooCommerce\Square\API\Responses;
|
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use WooCommerce\Square\API\Response;
|
28 |
|
29 |
-
defined( 'ABSPATH' )
|
30 |
|
31 |
/**
|
32 |
* Catalog response object
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use WooCommerce\Square\API\Response;
|
28 |
|
29 |
+
defined( 'ABSPATH' ) || exit;
|
30 |
|
31 |
/**
|
32 |
* Catalog response object
|
includes/API/Responses/Connection_Refresh_Response.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\API\Responses;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
23 |
|
24 |
namespace WooCommerce\Square\API\Responses;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
includes/API/Responses/Inventory.php
CHANGED
@@ -27,7 +27,7 @@ use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
|
27 |
use SquareConnect\Model\BatchRetrieveInventoryCountsResponse;
|
28 |
use WooCommerce\Square\API\Response;
|
29 |
|
30 |
-
defined( 'ABSPATH' )
|
31 |
|
32 |
/**
|
33 |
* Inventory response object
|
@@ -46,7 +46,7 @@ class Inventory extends Response {
|
|
46 |
*/
|
47 |
public function get_counts() {
|
48 |
|
49 |
-
$counts =
|
50 |
|
51 |
if ( $this->get_data() instanceof BatchRetrieveInventoryCountsResponse && is_array( $this->get_data()->getCounts() ) ) {
|
52 |
$counts = $this->get_data()->getCounts();
|
27 |
use SquareConnect\Model\BatchRetrieveInventoryCountsResponse;
|
28 |
use WooCommerce\Square\API\Response;
|
29 |
|
30 |
+
defined( 'ABSPATH' ) || exit;
|
31 |
|
32 |
/**
|
33 |
* Inventory response object
|
46 |
*/
|
47 |
public function get_counts() {
|
48 |
|
49 |
+
$counts = array();
|
50 |
|
51 |
if ( $this->get_data() instanceof BatchRetrieveInventoryCountsResponse && is_array( $this->get_data()->getCounts() ) ) {
|
52 |
$counts = $this->get_data()->getCounts();
|
includes/API/Responses/Locations.php
CHANGED
@@ -27,7 +27,7 @@ use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
|
27 |
use SquareConnect\Model as SquareModel;
|
28 |
use WooCommerce\Square\API\Response;
|
29 |
|
30 |
-
defined( 'ABSPATH' )
|
31 |
|
32 |
/**
|
33 |
* Catalog response object
|
@@ -48,7 +48,7 @@ class Locations extends Response {
|
|
48 |
*/
|
49 |
public function get_locations() {
|
50 |
|
51 |
-
return $this->get_data() ? $this->get_data()->getLocations() :
|
52 |
}
|
53 |
|
54 |
|
27 |
use SquareConnect\Model as SquareModel;
|
28 |
use WooCommerce\Square\API\Response;
|
29 |
|
30 |
+
defined( 'ABSPATH' ) || exit;
|
31 |
|
32 |
/**
|
33 |
* Catalog response object
|
48 |
*/
|
49 |
public function get_locations() {
|
50 |
|
51 |
+
return $this->get_data() ? $this->get_data()->getLocations() : array();
|
52 |
}
|
53 |
|
54 |
|
includes/Admin.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use WooCommerce\Square\Handlers\Product;
|
29 |
|
@@ -35,13 +35,25 @@ use WooCommerce\Square\Handlers\Product;
|
|
35 |
class Admin {
|
36 |
|
37 |
|
38 |
-
/**
|
|
|
|
|
|
|
|
|
39 |
private $products_handler;
|
40 |
|
41 |
-
/**
|
|
|
|
|
|
|
|
|
42 |
private $privacy_handler;
|
43 |
|
44 |
-
/**
|
|
|
|
|
|
|
|
|
45 |
private $plugin;
|
46 |
|
47 |
|
@@ -50,7 +62,7 @@ class Admin {
|
|
50 |
*
|
51 |
* @since 2.0.0
|
52 |
*
|
53 |
-
* @param Plugin $plugin plugin instance
|
54 |
*/
|
55 |
public function __construct( Plugin $plugin ) {
|
56 |
|
@@ -74,16 +86,24 @@ class Admin {
|
|
74 |
*/
|
75 |
private function add_hooks() {
|
76 |
|
77 |
-
// add the settings page
|
78 |
-
add_filter(
|
|
|
|
|
79 |
|
80 |
-
|
81 |
|
82 |
-
|
83 |
-
|
|
|
84 |
|
85 |
-
// load admin scripts
|
86 |
-
add_action(
|
|
|
|
|
|
|
|
|
|
|
87 |
}
|
88 |
|
89 |
|
@@ -97,74 +117,99 @@ class Admin {
|
|
97 |
|
98 |
if ( 'product' === $typenow ) {
|
99 |
|
100 |
-
wp_enqueue_script(
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
'
|
110 |
-
'
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
'
|
116 |
-
'
|
117 |
-
'
|
118 |
-
|
119 |
-
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
|
122 |
} elseif ( $this->get_plugin()->is_plugin_settings() ) {
|
123 |
|
124 |
-
wp_enqueue_style(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
|
126 |
-
|
127 |
|
128 |
-
if ( $sync_job
|
129 |
$existing_sync_id = $sync_job->id;
|
130 |
} else {
|
131 |
$existing_sync_id = false;
|
132 |
}
|
133 |
|
134 |
-
wp_localize_script(
|
135 |
-
|
136 |
-
'
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
'
|
150 |
-
'
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
'
|
155 |
-
'
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
'woocommerce' => sprintf(
|
160 |
-
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag */
|
161 |
-
__( 'Inventory is %1$salways fetched from Square%2$s periodically to account for sales from other channels.', 'woocommerce-square' ),
|
162 |
-
'<strong>', '</strong>'
|
163 |
),
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
}
|
169 |
}
|
170 |
|
@@ -185,7 +230,7 @@ class Admin {
|
|
185 |
*
|
186 |
* @param string[] array of product types
|
187 |
*/
|
188 |
-
return (array) apply_filters( 'wc_square_variable_product_types',
|
189 |
}
|
190 |
|
191 |
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use WooCommerce\Square\Handlers\Product;
|
29 |
|
35 |
class Admin {
|
36 |
|
37 |
|
38 |
+
/**
|
39 |
+
* Product handler.
|
40 |
+
*
|
41 |
+
* @var Handlers\Products
|
42 |
+
*/
|
43 |
private $products_handler;
|
44 |
|
45 |
+
/**
|
46 |
+
* Privacy handler.
|
47 |
+
*
|
48 |
+
* @var Admin\Privacy
|
49 |
+
*/
|
50 |
private $privacy_handler;
|
51 |
|
52 |
+
/**
|
53 |
+
* Plugin
|
54 |
+
*
|
55 |
+
* @var Plugin plugin instance
|
56 |
+
*/
|
57 |
private $plugin;
|
58 |
|
59 |
|
62 |
*
|
63 |
* @since 2.0.0
|
64 |
*
|
65 |
+
* @param Plugin $plugin plugin instance.
|
66 |
*/
|
67 |
public function __construct( Plugin $plugin ) {
|
68 |
|
86 |
*/
|
87 |
private function add_hooks() {
|
88 |
|
89 |
+
// add the settings page.
|
90 |
+
add_filter(
|
91 |
+
'woocommerce_get_settings_pages',
|
92 |
+
function ( $pages ) {
|
93 |
|
94 |
+
$pages[] = new Admin\Settings_Page( $this->get_plugin()->get_settings_handler() );
|
95 |
|
96 |
+
return $pages;
|
97 |
+
}
|
98 |
+
);
|
99 |
|
100 |
+
// load admin scripts.
|
101 |
+
add_action(
|
102 |
+
'admin_enqueue_scripts',
|
103 |
+
function() {
|
104 |
+
$this->load_scripts_styles();
|
105 |
+
}
|
106 |
+
);
|
107 |
}
|
108 |
|
109 |
|
117 |
|
118 |
if ( 'product' === $typenow ) {
|
119 |
|
120 |
+
wp_enqueue_script(
|
121 |
+
'wc-square-admin-products',
|
122 |
+
$this->get_plugin()->get_plugin_url() . '/assets/js/admin/wc-square-admin-products.min.js',
|
123 |
+
array( 'jquery' ),
|
124 |
+
Plugin::VERSION,
|
125 |
+
true
|
126 |
+
);
|
127 |
+
|
128 |
+
wp_localize_script(
|
129 |
+
'wc-square-admin-products',
|
130 |
+
'wc_square_admin_products',
|
131 |
+
array(
|
132 |
+
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
133 |
+
'settings_url' => esc_url( $this->get_plugin()->get_settings_url() ),
|
134 |
+
'variable_product_types' => $this->get_variable_product_types(),
|
135 |
+
'synced_with_square_taxonomy' => Product::SYNCED_WITH_SQUARE_TAXONOMY,
|
136 |
+
'is_product_sync_enabled' => $this->get_plugin()->get_settings_handler()->is_product_sync_enabled(),
|
137 |
+
'is_woocommerce_sor' => $this->get_plugin()->get_settings_handler()->is_system_of_record_woocommerce(),
|
138 |
+
'is_square_sor' => $this->get_plugin()->get_settings_handler()->is_system_of_record_square(),
|
139 |
+
'is_inventory_sync_enabled' => $this->get_plugin()->get_settings_handler()->is_inventory_sync_enabled(),
|
140 |
+
'get_quick_edit_product_details_nonce' => wp_create_nonce( 'get-quick-edit-product-details' ),
|
141 |
+
'fetch_product_stock_with_square_nonce' => wp_create_nonce( 'fetch-product-stock-with-square' ),
|
142 |
+
'i18n' => array(
|
143 |
+
'synced_with_square' => __( 'Synced with Square', 'woocommerce-square' ),
|
144 |
+
'managed_by_square' => __( 'Managed by Square', 'woocommerce-square' ),
|
145 |
+
'fetch_stock_with_square' => __( 'Fetch stock from Square', 'woocommerce-square' ),
|
146 |
+
),
|
147 |
+
)
|
148 |
+
);
|
149 |
|
150 |
} elseif ( $this->get_plugin()->is_plugin_settings() ) {
|
151 |
|
152 |
+
wp_enqueue_style(
|
153 |
+
'wc-square-admin',
|
154 |
+
$this->get_plugin()->get_plugin_url() . '/assets/css/admin/wc-square-admin.min.css',
|
155 |
+
array(),
|
156 |
+
Plugin::VERSION
|
157 |
+
);
|
158 |
+
|
159 |
+
wp_enqueue_script(
|
160 |
+
'wc-square-admin-settings',
|
161 |
+
$this->get_plugin()->get_plugin_url() . '/assets/js/admin/wc-square-admin-settings.min.js',
|
162 |
+
array( 'jquery', 'jquery-blockui', 'backbone', 'wc-backbone-modal' ),
|
163 |
+
Plugin::VERSION,
|
164 |
+
true
|
165 |
+
);
|
166 |
|
167 |
+
$sync_job = $this->get_plugin()->get_sync_handler()->get_job_in_progress();
|
168 |
|
169 |
+
if ( $sync_job ) {
|
170 |
$existing_sync_id = $sync_job->id;
|
171 |
} else {
|
172 |
$existing_sync_id = false;
|
173 |
}
|
174 |
|
175 |
+
wp_localize_script(
|
176 |
+
'wc-square-admin-settings',
|
177 |
+
'wc_square_admin_settings',
|
178 |
+
array(
|
179 |
+
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
180 |
+
'is_product_sync_enabled' => $this->get_plugin()->get_settings_handler()->is_product_sync_enabled(),
|
181 |
+
'is_woocommerce_sor' => $this->get_plugin()->get_settings_handler()->is_system_of_record_woocommerce(),
|
182 |
+
'is_square_sor' => $this->get_plugin()->get_settings_handler()->is_system_of_record_square(),
|
183 |
+
'is_inventory_sync_enabled' => $this->get_plugin()->get_settings_handler()->is_inventory_sync_enabled(),
|
184 |
+
'is_sandbox' => $this->get_plugin()->get_settings_handler()->is_sandbox(),
|
185 |
+
'existing_sync_job_id' => $existing_sync_id,
|
186 |
+
'sync_in_background' => $this->get_plugin()->get_sync_handler()->should_sync_in_background(),
|
187 |
+
'import_products_from_square' => wp_create_nonce( 'import-products-from-square' ),
|
188 |
+
'sync_products_with_square' => wp_create_nonce( 'sync-products-with-square' ),
|
189 |
+
'get_sync_with_square_status_nonce' => wp_create_nonce( 'get-sync-with-square-status' ),
|
190 |
+
'handle_sync_with_square_records' => wp_create_nonce( 'handle-sync-with-square-records' ),
|
191 |
+
'i18n' => array(
|
192 |
+
'resolved' => __( 'Resolved', 'woocommerce-square' ),
|
193 |
+
'no_records_found' => __( 'No records found', 'woocommerce-square' ),
|
194 |
+
'skipped' => __( 'Skipped', 'woocommerce-square' ),
|
195 |
+
'updated' => __( 'Updated', 'woocommerce-square' ),
|
196 |
+
'imported' => __( 'Imported', 'woocommerce-square' ),
|
197 |
+
'sync_inventory_label' => array(
|
198 |
+
'square' => __( 'Enable to fetch inventory changes from Square', 'woocommerce-square' ),
|
199 |
+
'woocommerce' => __( 'Enable to push inventory changes to Square', 'woocommerce-square' ),
|
|
|
|
|
|
|
|
|
200 |
),
|
201 |
+
'sync_inventory_description' => array(
|
202 |
+
'square' => __( 'Inventory is fetched from Square periodically and updated in WooCommerce', 'woocommerce-square' ),
|
203 |
+
'woocommerce' => sprintf(
|
204 |
+
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag */
|
205 |
+
__( 'Inventory is %1$salways fetched from Square%2$s periodically to account for sales from other channels.', 'woocommerce-square' ),
|
206 |
+
'<strong>',
|
207 |
+
'</strong>'
|
208 |
+
),
|
209 |
+
),
|
210 |
+
),
|
211 |
+
)
|
212 |
+
);
|
213 |
}
|
214 |
}
|
215 |
|
230 |
*
|
231 |
* @param string[] array of product types
|
232 |
*/
|
233 |
+
return (array) apply_filters( 'wc_square_variable_product_types', array( 'variable', 'variable-subscription' ) );
|
234 |
}
|
235 |
|
236 |
|
includes/Admin/Privacy.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Admin;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
@@ -42,10 +42,9 @@ class Privacy extends \WC_Abstract_Privacy {
|
|
42 |
*/
|
43 |
public function __construct() {
|
44 |
|
45 |
-
|
46 |
parent::__construct( __( 'Square', 'woocommerce-square' ) );
|
47 |
|
48 |
-
$this->add_eraser( 'woocommerce-square-customer-data', __( 'WooCommerce Square Customer Data', 'woocommerce-square' ),
|
49 |
}
|
50 |
|
51 |
|
@@ -60,7 +59,8 @@ class Privacy extends \WC_Abstract_Privacy {
|
|
60 |
sprintf(
|
61 |
/* translators: Placeholder: %1$s - <a> tag, %2$s - </a> tag */
|
62 |
__( 'By using this extension, you may be storing personal data or sharing data with an external service. %1$sLearn more about how this works, including what you may want to include in your privacy policy.%2$s', 'woocommerce-square' ),
|
63 |
-
'<a href="https://docs.woocommerce.com/document/privacy-payments/#woocommerce-square" target="_blank">',
|
|
|
64 |
)
|
65 |
);
|
66 |
}
|
@@ -82,7 +82,7 @@ class Privacy extends \WC_Abstract_Privacy {
|
|
82 |
$square_customer_id = get_user_meta( $user->ID, 'wc_square_customer_id', true );
|
83 |
|
84 |
$items_removed = false;
|
85 |
-
$messages =
|
86 |
|
87 |
if ( ! empty( $square_customer_id ) ) {
|
88 |
|
@@ -93,12 +93,12 @@ class Privacy extends \WC_Abstract_Privacy {
|
|
93 |
$messages[] = __( 'Square User Data Erased.', 'woocommerce-square' );
|
94 |
}
|
95 |
|
96 |
-
return
|
97 |
'items_removed' => $items_removed,
|
98 |
'items_retained' => false,
|
99 |
'messages' => $messages,
|
100 |
'done' => true,
|
101 |
-
|
102 |
}
|
103 |
|
104 |
|
23 |
|
24 |
namespace WooCommerce\Square\Admin;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
42 |
*/
|
43 |
public function __construct() {
|
44 |
|
|
|
45 |
parent::__construct( __( 'Square', 'woocommerce-square' ) );
|
46 |
|
47 |
+
$this->add_eraser( 'woocommerce-square-customer-data', __( 'WooCommerce Square Customer Data', 'woocommerce-square' ), array( $this, 'customer_data_eraser' ) );
|
48 |
}
|
49 |
|
50 |
|
59 |
sprintf(
|
60 |
/* translators: Placeholder: %1$s - <a> tag, %2$s - </a> tag */
|
61 |
__( 'By using this extension, you may be storing personal data or sharing data with an external service. %1$sLearn more about how this works, including what you may want to include in your privacy policy.%2$s', 'woocommerce-square' ),
|
62 |
+
'<a href="https://docs.woocommerce.com/document/privacy-payments/#woocommerce-square" target="_blank">',
|
63 |
+
'</a>'
|
64 |
)
|
65 |
);
|
66 |
}
|
82 |
$square_customer_id = get_user_meta( $user->ID, 'wc_square_customer_id', true );
|
83 |
|
84 |
$items_removed = false;
|
85 |
+
$messages = array();
|
86 |
|
87 |
if ( ! empty( $square_customer_id ) ) {
|
88 |
|
93 |
$messages[] = __( 'Square User Data Erased.', 'woocommerce-square' );
|
94 |
}
|
95 |
|
96 |
+
return array(
|
97 |
'items_removed' => $items_removed,
|
98 |
'items_retained' => false,
|
99 |
'messages' => $messages,
|
100 |
'done' => true,
|
101 |
+
);
|
102 |
}
|
103 |
|
104 |
|
includes/Admin/Settings_Page.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Admin;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square;
|
@@ -141,10 +141,10 @@ class Settings_Page extends \WC_Settings_Page {
|
|
141 |
*/
|
142 |
public function get_sections() {
|
143 |
|
144 |
-
$sections =
|
145 |
-
''
|
146 |
-
'update'
|
147 |
-
|
148 |
|
149 |
/**
|
150 |
* Filters the WooCommerce Square settings sections.
|
@@ -177,7 +177,7 @@ class Settings_Page extends \WC_Settings_Page {
|
|
177 |
</header>
|
178 |
<article>
|
179 |
<?php /* translators: Placeholders: %1$s - <strong>, %2%s - </strong> */ ?>
|
180 |
-
<?php printf( esc_html__( 'You are about to import all products from Square. This will create a new product in WooCommerce for every product retrieved from Square. If you have products in the trash from the previous imports, these will be ignored in the import. %1$sOnly use this action to perform a one-time import!%2$s', 'woocommerce-square' ), '<strong>', '</strong>' ); ?>
|
181 |
</article>
|
182 |
<footer>
|
183 |
<div class="inner">
|
23 |
|
24 |
namespace WooCommerce\Square\Admin;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square;
|
141 |
*/
|
142 |
public function get_sections() {
|
143 |
|
144 |
+
$sections = array(
|
145 |
+
'' => __( 'Settings', 'woocommerce-square' ), // this key is intentionally blank
|
146 |
+
'update' => __( 'Update', 'woocommerce-square' ),
|
147 |
+
);
|
148 |
|
149 |
/**
|
150 |
* Filters the WooCommerce Square settings sections.
|
177 |
</header>
|
178 |
<article>
|
179 |
<?php /* translators: Placeholders: %1$s - <strong>, %2%s - </strong> */ ?>
|
180 |
+
<?php printf( esc_html__( 'You are about to import all new products, variations and categories from Square. This will create a new product in WooCommerce for every product retrieved from Square. If you have products in the trash from the previous imports, these will be ignored in the import. During this process, simple products that have new variations found in Sqaure will be converted to a variable product in WooCommerce. %1$sOnly use this action to perform a one-time import!%2$s', 'woocommerce-square' ), '<strong>', '</strong>' ); ?>
|
181 |
</article>
|
182 |
<footer>
|
183 |
<div class="inner">
|
includes/Admin/Sync_Page.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Admin;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Product;
|
@@ -74,20 +74,28 @@ class Sync_Page {
|
|
74 |
|
75 |
<tr>
|
76 |
<td>
|
77 |
-
<?php
|
|
|
78 |
/* translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s, $4%s - closing </strong> HTML tag */
|
79 |
esc_html__( '%1$sSquare%2$s is the system of record. The following data from Square will overwrite WooCommerce data for synced products: %3$sname, price, description, category, inventory%4$s.', 'woocommerce-square' ),
|
80 |
-
'<strong>',
|
81 |
-
|
|
|
|
|
|
|
|
|
82 |
</td>
|
83 |
</tr>
|
84 |
<tr>
|
85 |
<td>
|
86 |
-
<?php
|
|
|
87 |
/* translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing </strong> HTML tag */
|
88 |
esc_html__( '%1$sProduct images%2$s will be imported from Square if no featured image is set in WooCommerce.', 'woocommerce-square' ),
|
89 |
-
'<strong>',
|
90 |
-
|
|
|
|
|
91 |
</td>
|
92 |
</tr>
|
93 |
|
@@ -95,11 +103,16 @@ class Sync_Page {
|
|
95 |
|
96 |
<tr>
|
97 |
<td>
|
98 |
-
<?php
|
|
|
99 |
/* translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s, %4$s - closing </strong> HTML tag */
|
100 |
esc_html__( '%1$sWooCommerce%2$s is the system of record. The following data from WooCommerce will overwrite Square data for synced products: %3$sname, price, inventory, category, image%4$s.', 'woocommerce-square' ),
|
101 |
-
'<strong>',
|
102 |
-
|
|
|
|
|
|
|
|
|
103 |
</td>
|
104 |
</tr>
|
105 |
|
@@ -107,11 +120,14 @@ class Sync_Page {
|
|
107 |
|
108 |
<tr>
|
109 |
<td>
|
110 |
-
<?php
|
|
|
111 |
/* translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing </strong> HTML tag*/
|
112 |
esc_html__( '%1$sNo chosen system of record.%2$s Products will not be synced between Square and WooCommerce.', 'woocommerce-square' ),
|
113 |
-
'<strong>',
|
114 |
-
|
|
|
|
|
115 |
</td>
|
116 |
</tr>
|
117 |
|
@@ -131,13 +147,13 @@ class Sync_Page {
|
|
131 |
|
132 |
$is_connected = wc_square()->get_settings_handler()->is_connected();
|
133 |
$sync_in_progress = $is_connected ? wc_square()->get_sync_handler()->is_sync_in_progress() : false;
|
134 |
-
$synced_products = wc_square()->get_settings_handler()->is_product_sync_enabled() ? Product::get_products_synced_with_square() :
|
135 |
$synced_count = count( $synced_products );
|
136 |
$is_product_import = false;
|
137 |
|
138 |
if ( $sync_in_progress ) {
|
139 |
|
140 |
-
$current_job
|
141 |
$is_product_import = isset( $current_job->action ) && 'product_import' === $current_job->action;
|
142 |
}
|
143 |
|
@@ -170,11 +186,13 @@ class Sync_Page {
|
|
170 |
<tr>
|
171 |
<td class="synced-products">
|
172 |
<a href="<?php echo esc_url( admin_url( 'edit.php?s&post_status=all&post_type=product&product_type=synced-with-square&stock_status&paged=1' ) ); ?>">
|
173 |
-
<?php
|
|
|
174 |
/* translators: Placeholder: %d number of products synced with Square */
|
175 |
_n( '%d product', '%d products', $synced_count, 'woocommerce-square' ),
|
176 |
$synced_count
|
177 |
-
);
|
|
|
178 |
</a>
|
179 |
<input
|
180 |
type="hidden"
|
@@ -255,12 +273,17 @@ class Sync_Page {
|
|
255 |
*/
|
256 |
private static function output_sync_records() {
|
257 |
|
258 |
-
$records = Records::get_records();
|
|
|
259 |
|
260 |
<button
|
261 |
id="wc-square_clear-sync-records"
|
262 |
class="button button-large"
|
263 |
-
<?php
|
|
|
|
|
|
|
|
|
264 |
><?php echo esc_html_x( 'Clear history', 'Delete all records', 'woocommerce-square' ); ?></button>
|
265 |
|
266 |
<table class="wc_square_table records widefat" cellspacing="0">
|
@@ -299,7 +322,7 @@ class Sync_Page {
|
|
299 |
|
300 |
<tr>
|
301 |
<td colspan="4">
|
302 |
-
<em><?php esc_html_e( 'No records found.', 'woocommerce-square' ) ?></em>
|
303 |
</td>
|
304 |
</tr>
|
305 |
|
@@ -356,12 +379,14 @@ class Sync_Page {
|
|
356 |
<?php endif; ?>
|
357 |
</ul>
|
358 |
<?php $additional_info = ob_get_clean(); ?>
|
359 |
-
<?php
|
|
|
360 |
/* translators: Placeholders: %1$s - the system of record name (e.g. Square or WooCommerce), %3%s - unordered HTML list of additional information item(s) */
|
361 |
esc_html__( 'You are about to sync products with Square. %1$s is your system of record. For all products synced with Square: %2$s', 'woocommerce-square' ),
|
362 |
$square_settings->get_system_of_record_name(),
|
363 |
$additional_info
|
364 |
-
);
|
|
|
365 |
</article>
|
366 |
<footer>
|
367 |
<div class="inner">
|
23 |
|
24 |
namespace WooCommerce\Square\Admin;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Product;
|
74 |
|
75 |
<tr>
|
76 |
<td>
|
77 |
+
<?php
|
78 |
+
printf(
|
79 |
/* translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s, $4%s - closing </strong> HTML tag */
|
80 |
esc_html__( '%1$sSquare%2$s is the system of record. The following data from Square will overwrite WooCommerce data for synced products: %3$sname, price, description, category, inventory%4$s.', 'woocommerce-square' ),
|
81 |
+
'<strong>',
|
82 |
+
'</strong>',
|
83 |
+
'<strong>',
|
84 |
+
'</strong>'
|
85 |
+
);
|
86 |
+
?>
|
87 |
</td>
|
88 |
</tr>
|
89 |
<tr>
|
90 |
<td>
|
91 |
+
<?php
|
92 |
+
printf(
|
93 |
/* translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing </strong> HTML tag */
|
94 |
esc_html__( '%1$sProduct images%2$s will be imported from Square if no featured image is set in WooCommerce.', 'woocommerce-square' ),
|
95 |
+
'<strong>',
|
96 |
+
'</strong>'
|
97 |
+
);
|
98 |
+
?>
|
99 |
</td>
|
100 |
</tr>
|
101 |
|
103 |
|
104 |
<tr>
|
105 |
<td>
|
106 |
+
<?php
|
107 |
+
printf(
|
108 |
/* translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s, %4$s - closing </strong> HTML tag */
|
109 |
esc_html__( '%1$sWooCommerce%2$s is the system of record. The following data from WooCommerce will overwrite Square data for synced products: %3$sname, price, inventory, category, image%4$s.', 'woocommerce-square' ),
|
110 |
+
'<strong>',
|
111 |
+
'</strong>',
|
112 |
+
'<strong>',
|
113 |
+
'</strong>'
|
114 |
+
);
|
115 |
+
?>
|
116 |
</td>
|
117 |
</tr>
|
118 |
|
120 |
|
121 |
<tr>
|
122 |
<td>
|
123 |
+
<?php
|
124 |
+
printf(
|
125 |
/* translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing </strong> HTML tag*/
|
126 |
esc_html__( '%1$sNo chosen system of record.%2$s Products will not be synced between Square and WooCommerce.', 'woocommerce-square' ),
|
127 |
+
'<strong>',
|
128 |
+
'</strong>'
|
129 |
+
);
|
130 |
+
?>
|
131 |
</td>
|
132 |
</tr>
|
133 |
|
147 |
|
148 |
$is_connected = wc_square()->get_settings_handler()->is_connected();
|
149 |
$sync_in_progress = $is_connected ? wc_square()->get_sync_handler()->is_sync_in_progress() : false;
|
150 |
+
$synced_products = wc_square()->get_settings_handler()->is_product_sync_enabled() ? Product::get_products_synced_with_square() : array();
|
151 |
$synced_count = count( $synced_products );
|
152 |
$is_product_import = false;
|
153 |
|
154 |
if ( $sync_in_progress ) {
|
155 |
|
156 |
+
$current_job = wc_square()->get_sync_handler()->get_job_in_progress();
|
157 |
$is_product_import = isset( $current_job->action ) && 'product_import' === $current_job->action;
|
158 |
}
|
159 |
|
186 |
<tr>
|
187 |
<td class="synced-products">
|
188 |
<a href="<?php echo esc_url( admin_url( 'edit.php?s&post_status=all&post_type=product&product_type=synced-with-square&stock_status&paged=1' ) ); ?>">
|
189 |
+
<?php
|
190 |
+
printf(
|
191 |
/* translators: Placeholder: %d number of products synced with Square */
|
192 |
_n( '%d product', '%d products', $synced_count, 'woocommerce-square' ),
|
193 |
$synced_count
|
194 |
+
);
|
195 |
+
?>
|
196 |
</a>
|
197 |
<input
|
198 |
type="hidden"
|
273 |
*/
|
274 |
private static function output_sync_records() {
|
275 |
|
276 |
+
$records = Records::get_records();
|
277 |
+
?>
|
278 |
|
279 |
<button
|
280 |
id="wc-square_clear-sync-records"
|
281 |
class="button button-large"
|
282 |
+
<?php
|
283 |
+
if ( empty( $records ) ) {
|
284 |
+
echo 'disabled="disabled"';
|
285 |
+
}
|
286 |
+
?>
|
287 |
><?php echo esc_html_x( 'Clear history', 'Delete all records', 'woocommerce-square' ); ?></button>
|
288 |
|
289 |
<table class="wc_square_table records widefat" cellspacing="0">
|
322 |
|
323 |
<tr>
|
324 |
<td colspan="4">
|
325 |
+
<em><?php esc_html_e( 'No records found.', 'woocommerce-square' ); ?></em>
|
326 |
</td>
|
327 |
</tr>
|
328 |
|
379 |
<?php endif; ?>
|
380 |
</ul>
|
381 |
<?php $additional_info = ob_get_clean(); ?>
|
382 |
+
<?php
|
383 |
+
printf(
|
384 |
/* translators: Placeholders: %1$s - the system of record name (e.g. Square or WooCommerce), %3%s - unordered HTML list of additional information item(s) */
|
385 |
esc_html__( 'You are about to sync products with Square. %1$s is your system of record. For all products synced with Square: %2$s', 'woocommerce-square' ),
|
386 |
$square_settings->get_system_of_record_name(),
|
387 |
$additional_info
|
388 |
+
);
|
389 |
+
?>
|
390 |
</article>
|
391 |
<footer>
|
392 |
<div class="inner">
|
includes/Emails/Access_Token_Email.php
CHANGED
@@ -25,7 +25,7 @@ namespace WooCommerce\Square\Emails;
|
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
-
defined( 'ABSPATH' )
|
29 |
|
30 |
/**
|
31 |
* Sync completed email.
|
@@ -44,8 +44,8 @@ class Access_Token_Email extends Base_Email {
|
|
44 |
$this->customer_email = false;
|
45 |
$this->title = __( 'Square Access Token problems', 'woocommerce-square' );
|
46 |
$this->description = __( 'This email is sent when problems with Access Token are encountered', 'woocommerce-square' );
|
47 |
-
$this->subject = _x( '[WooCommerce] There was a problem with your Square Access Token', 'Email subject', 'woocommerce-square');
|
48 |
-
$this->heading = _x( 'There was a problem with your Square Access Token', 'Email heading', 'woocommerce-square');
|
49 |
$this->body = _x( 'Heads up! There may be a problem with your connection to Square.', 'Square connection problems email body.', 'woocommerce-square' );
|
50 |
|
51 |
$this->enabled_default = 'yes';
|
@@ -85,7 +85,7 @@ class Access_Token_Email extends Base_Email {
|
|
85 |
* @param array $args optional associative array with additional arguments
|
86 |
* @return array
|
87 |
*/
|
88 |
-
protected function get_template_args( $args =
|
89 |
$html = empty( $args['plain_text'] );
|
90 |
|
91 |
$email_body = $this->body;
|
@@ -97,24 +97,29 @@ class Access_Token_Email extends Base_Email {
|
|
97 |
$email_body .= ' ' . sprintf(
|
98 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
99 |
esc_html__( 'In order to continue accepting payments, please %1$sdisconnect and re-connect your site%2$s.', 'woocommerce-square' ),
|
100 |
-
'<a href="' . esc_url( $settings_url ) .'">',
|
|
|
101 |
);
|
102 |
|
103 |
if ( $square->get_settings_handler()->is_debug_enabled() ) {
|
104 |
$email_body .= '<br/><br/>' . sprintf(
|
105 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
106 |
esc_html__( '%1$sInspect status logs%2$s', 'woocommerce-square' ),
|
107 |
-
'<a href="' . $logs_url . '">',
|
|
|
108 |
);
|
109 |
}
|
110 |
} else {
|
111 |
$email_body .= ' ' + esc_html__( 'In order to continue accepting payments, please disconnect and re-connect your site at ', 'woocommerce-square' ) . $settings_url;
|
112 |
}
|
113 |
|
114 |
-
return array_merge(
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
119 |
}
|
120 |
}
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
+
defined( 'ABSPATH' ) || exit;
|
29 |
|
30 |
/**
|
31 |
* Sync completed email.
|
44 |
$this->customer_email = false;
|
45 |
$this->title = __( 'Square Access Token problems', 'woocommerce-square' );
|
46 |
$this->description = __( 'This email is sent when problems with Access Token are encountered', 'woocommerce-square' );
|
47 |
+
$this->subject = _x( '[WooCommerce] There was a problem with your Square Access Token', 'Email subject', 'woocommerce-square' );
|
48 |
+
$this->heading = _x( 'There was a problem with your Square Access Token', 'Email heading', 'woocommerce-square' );
|
49 |
$this->body = _x( 'Heads up! There may be a problem with your connection to Square.', 'Square connection problems email body.', 'woocommerce-square' );
|
50 |
|
51 |
$this->enabled_default = 'yes';
|
85 |
* @param array $args optional associative array with additional arguments
|
86 |
* @return array
|
87 |
*/
|
88 |
+
protected function get_template_args( $args = array() ) {
|
89 |
$html = empty( $args['plain_text'] );
|
90 |
|
91 |
$email_body = $this->body;
|
97 |
$email_body .= ' ' . sprintf(
|
98 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
99 |
esc_html__( 'In order to continue accepting payments, please %1$sdisconnect and re-connect your site%2$s.', 'woocommerce-square' ),
|
100 |
+
'<a href="' . esc_url( $settings_url ) . '">',
|
101 |
+
'</a>'
|
102 |
);
|
103 |
|
104 |
if ( $square->get_settings_handler()->is_debug_enabled() ) {
|
105 |
$email_body .= '<br/><br/>' . sprintf(
|
106 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
107 |
esc_html__( '%1$sInspect status logs%2$s', 'woocommerce-square' ),
|
108 |
+
'<a href="' . $logs_url . '">',
|
109 |
+
'</a>'
|
110 |
);
|
111 |
}
|
112 |
} else {
|
113 |
$email_body .= ' ' + esc_html__( 'In order to continue accepting payments, please disconnect and re-connect your site at ', 'woocommerce-square' ) . $settings_url;
|
114 |
}
|
115 |
|
116 |
+
return array_merge(
|
117 |
+
$args,
|
118 |
+
array(
|
119 |
+
'email' => $this,
|
120 |
+
'email_heading' => $this->heading,
|
121 |
+
'email_body' => $email_body,
|
122 |
+
)
|
123 |
+
);
|
124 |
}
|
125 |
}
|
includes/Emails/Base_Email.php
CHANGED
@@ -25,7 +25,7 @@ namespace WooCommerce\Square\Emails;
|
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
-
defined( 'ABSPATH' )
|
29 |
|
30 |
/**
|
31 |
* Base email class.
|
@@ -67,7 +67,7 @@ class Base_Email extends \WC_Email {
|
|
67 |
* @since 2.1.0
|
68 |
*/
|
69 |
public function __construct() {
|
70 |
-
$this->template_base
|
71 |
|
72 |
// call parent constructor
|
73 |
parent::__construct();
|
@@ -106,16 +106,20 @@ class Base_Email extends \WC_Email {
|
|
106 |
}
|
107 |
|
108 |
// add a recipient field
|
109 |
-
$form_fields = Framework\SV_WC_Helper::array_insert_after(
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
|
|
119 |
|
120 |
// set the updated fields
|
121 |
$this->form_fields = $form_fields;
|
@@ -162,12 +166,15 @@ class Base_Email extends \WC_Email {
|
|
162 |
* @param array $args optional associative array with additional arguments
|
163 |
* @return array
|
164 |
*/
|
165 |
-
protected function get_template_args( $args =
|
166 |
-
return array_merge(
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
|
|
|
|
|
|
171 |
}
|
172 |
|
173 |
/**
|
@@ -178,7 +185,7 @@ class Base_Email extends \WC_Email {
|
|
178 |
* @return string HTML
|
179 |
*/
|
180 |
public function get_content_html() {
|
181 |
-
$args =
|
182 |
return wc_get_template_html( $this->template_html, array_merge( $args, $this->get_template_args( $args ) ) );
|
183 |
}
|
184 |
|
@@ -190,7 +197,7 @@ class Base_Email extends \WC_Email {
|
|
190 |
* @return string plain text
|
191 |
*/
|
192 |
public function get_content_plain() {
|
193 |
-
$args =
|
194 |
return wc_get_template_html( $this->template_plain, array_merge( $args, $this->get_template_args( $args ) ) );
|
195 |
}
|
196 |
}
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
+
defined( 'ABSPATH' ) || exit;
|
29 |
|
30 |
/**
|
31 |
* Base email class.
|
67 |
* @since 2.1.0
|
68 |
*/
|
69 |
public function __construct() {
|
70 |
+
$this->template_base = wc_square()->get_plugin_path() . '/templates/';
|
71 |
|
72 |
// call parent constructor
|
73 |
parent::__construct();
|
106 |
}
|
107 |
|
108 |
// add a recipient field
|
109 |
+
$form_fields = Framework\SV_WC_Helper::array_insert_after(
|
110 |
+
$form_fields,
|
111 |
+
isset( $form_fields['enabled'] ) ? 'enabled' : key( $form_fields ),
|
112 |
+
array(
|
113 |
+
'recipient' => array(
|
114 |
+
'title' => __( 'Recipient(s)', 'woocommerce-square' ),
|
115 |
+
'type' => 'text',
|
116 |
+
/* translatorsPlaceholder: %s default email address */
|
117 |
+
'description' => sprintf( __( 'Enter recipients (comma separated) for this email. Defaults to admin email: %s', 'woocommerce-square' ), '<code>' . esc_attr( get_option( 'admin_email' ) ) . '</code>' ),
|
118 |
+
'placeholder' => get_bloginfo( 'admin_email' ),
|
119 |
+
'default' => get_bloginfo( 'admin_email' ),
|
120 |
+
),
|
121 |
+
)
|
122 |
+
);
|
123 |
|
124 |
// set the updated fields
|
125 |
$this->form_fields = $form_fields;
|
166 |
* @param array $args optional associative array with additional arguments
|
167 |
* @return array
|
168 |
*/
|
169 |
+
protected function get_template_args( $args = array() ) {
|
170 |
+
return array_merge(
|
171 |
+
$args,
|
172 |
+
array(
|
173 |
+
'email' => $this,
|
174 |
+
'email_heading' => '',
|
175 |
+
'email_body' => '',
|
176 |
+
)
|
177 |
+
);
|
178 |
}
|
179 |
|
180 |
/**
|
185 |
* @return string HTML
|
186 |
*/
|
187 |
public function get_content_html() {
|
188 |
+
$args = array( 'plain_text' => false );
|
189 |
return wc_get_template_html( $this->template_html, array_merge( $args, $this->get_template_args( $args ) ) );
|
190 |
}
|
191 |
|
197 |
* @return string plain text
|
198 |
*/
|
199 |
public function get_content_plain() {
|
200 |
+
$args = array( 'plain_text' => true );
|
201 |
return wc_get_template_html( $this->template_plain, array_merge( $args, $this->get_template_args( $args ) ) );
|
202 |
}
|
203 |
}
|
includes/Emails/Sync_Completed.php
CHANGED
@@ -25,7 +25,7 @@ namespace WooCommerce\Square\Emails;
|
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
-
defined( 'ABSPATH' )
|
29 |
|
30 |
/**
|
31 |
* Sync completed email.
|
@@ -44,8 +44,8 @@ class Sync_Completed extends Base_Email {
|
|
44 |
$this->customer_email = false;
|
45 |
$this->title = __( 'Square sync completed', 'woocommerce-square' );
|
46 |
$this->description = __( 'This email is sent once a manual sync has been completed between WooCommerce and Square', 'woocommerce-square' );
|
47 |
-
$this->subject = _x( '[WooCommerce] Square sync completed', 'Email subject', 'woocommerce-square');
|
48 |
-
$this->heading = _x( 'Square sync completed for {product_count}', 'Email heading with merge tag placeholder', 'woocommerce-square');
|
49 |
$this->body = _x( 'Square sync completed for {site_title} at {sync_completed_date} {sync_completed_time}.', 'Email body with merge tag placeholders', 'woocommerce-square' );
|
50 |
|
51 |
$this->enabled_default = 'no';
|
@@ -92,32 +92,35 @@ class Sync_Completed extends Base_Email {
|
|
92 |
if ( true === $html ) {
|
93 |
$square = wc_square();
|
94 |
$settings_url = $square->get_settings_url();
|
95 |
-
$records_url = add_query_arg(
|
96 |
|
97 |
if ( $square->get_settings_handler()->is_debug_enabled() ) {
|
98 |
$action = sprintf(
|
99 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
100 |
esc_html__( '%1$sInspect status logs%2$s', 'woocommerce-square' ),
|
101 |
-
'<a href="' . esc_url( admin_url( 'admin.php?page=wc-status&tab=logs' ) ) . '">',
|
|
|
102 |
);
|
103 |
} else {
|
104 |
$action = sprintf(
|
105 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
106 |
esc_html__( '%1$sEnable logging%2$s', 'woocommerce-square' ),
|
107 |
-
'<a href="' . esc_url( $settings_url ) .'">',
|
|
|
108 |
);
|
109 |
}
|
110 |
|
111 |
$email_body .= sprintf(
|
112 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag, %3$s - additional action */
|
113 |
'<br>' . esc_html__( 'The sync job has failed. %1$sClick for more details%2$s, or %3$s.', 'woocommerce-square' ),
|
114 |
-
'<a href="' . esc_url( $records_url ) .'">',
|
|
|
115 |
strtolower( $action )
|
116 |
);
|
117 |
|
118 |
} else { // plain text
|
119 |
|
120 |
-
if (
|
121 |
$action = esc_html__( 'Inspect status logs', 'woocommerce-square' );
|
122 |
} else {
|
123 |
$action = esc_html__( 'Enable Logging', 'woocommerce-square' );
|
@@ -167,7 +170,7 @@ class Sync_Completed extends Base_Email {
|
|
167 |
if ( $job->manual && ( 'completed' === $job->status || 'failed' === $job->status ) ) {
|
168 |
// for manual jobs, send an email if the job was either completed or failed
|
169 |
$should_send = true;
|
170 |
-
}
|
171 |
// for automated jobs, send an email only if the job failed and it's been a day since the last email
|
172 |
$already_sent = get_transient( 'wc_square_failed_sync_email_sent' );
|
173 |
if ( false === $already_sent ) {
|
@@ -208,26 +211,25 @@ class Sync_Completed extends Base_Email {
|
|
208 |
if ( isset( $job->completed_at ) ) {
|
209 |
$sync_completed_date = date( wc_date_format(), strtotime( $job->completed_at ) );
|
210 |
$sync_completed_time = date( wc_time_format(), strtotime( $job->completed_at ) );
|
211 |
-
}
|
212 |
$sync_completed_date = date( wc_date_format(), strtotime( $job->failed_at ) );
|
213 |
$sync_completed_time = date( wc_time_format(), strtotime( $job->failed_at ) );
|
214 |
}
|
215 |
|
216 |
// placeholders
|
217 |
-
$email_merge_tags =
|
218 |
'product_count' => $product_count,
|
219 |
-
'sync_started_date'
|
220 |
-
'sync_started_time'
|
221 |
'sync_completed_date' => $sync_completed_date,
|
222 |
'sync_completed_time' => $sync_completed_time,
|
223 |
-
|
224 |
|
225 |
// TODO update handling when WooCommerce 3.2 is the minimum required version {FN 2019-05-03}
|
226 |
if ( Framework\SV_WC_Plugin_Compatibility::is_wc_version_gte( '3.2' ) ) {
|
227 |
foreach ( $email_merge_tags as $find => $replace ) {
|
228 |
$this->placeholders[ '{' . $find . '}' ] = $replace;
|
229 |
}
|
230 |
-
|
231 |
} else {
|
232 |
|
233 |
foreach ( $email_merge_tags as $find => $replace ) {
|
@@ -245,7 +247,7 @@ class Sync_Completed extends Base_Email {
|
|
245 |
* @param array $args optional associative array with additional arguments
|
246 |
* @return array
|
247 |
*/
|
248 |
-
protected function get_template_args( $args =
|
249 |
$sync_job = $this->get_job();
|
250 |
$html = empty( $args['plain_text'] );
|
251 |
|
@@ -257,10 +259,13 @@ class Sync_Completed extends Base_Email {
|
|
257 |
$email_body = $this->get_body_by_job_status( 'completed', $html );
|
258 |
}
|
259 |
|
260 |
-
return array_merge(
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
|
|
|
|
|
|
265 |
}
|
266 |
}
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
+
defined( 'ABSPATH' ) || exit;
|
29 |
|
30 |
/**
|
31 |
* Sync completed email.
|
44 |
$this->customer_email = false;
|
45 |
$this->title = __( 'Square sync completed', 'woocommerce-square' );
|
46 |
$this->description = __( 'This email is sent once a manual sync has been completed between WooCommerce and Square', 'woocommerce-square' );
|
47 |
+
$this->subject = _x( '[WooCommerce] Square sync completed', 'Email subject', 'woocommerce-square' );
|
48 |
+
$this->heading = _x( 'Square sync completed for {product_count}', 'Email heading with merge tag placeholder', 'woocommerce-square' );
|
49 |
$this->body = _x( 'Square sync completed for {site_title} at {sync_completed_date} {sync_completed_time}.', 'Email body with merge tag placeholders', 'woocommerce-square' );
|
50 |
|
51 |
$this->enabled_default = 'no';
|
92 |
if ( true === $html ) {
|
93 |
$square = wc_square();
|
94 |
$settings_url = $square->get_settings_url();
|
95 |
+
$records_url = add_query_arg( array( 'section' => 'update' ), $settings_url );
|
96 |
|
97 |
if ( $square->get_settings_handler()->is_debug_enabled() ) {
|
98 |
$action = sprintf(
|
99 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
100 |
esc_html__( '%1$sInspect status logs%2$s', 'woocommerce-square' ),
|
101 |
+
'<a href="' . esc_url( admin_url( 'admin.php?page=wc-status&tab=logs' ) ) . '">',
|
102 |
+
'</a>'
|
103 |
);
|
104 |
} else {
|
105 |
$action = sprintf(
|
106 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag */
|
107 |
esc_html__( '%1$sEnable logging%2$s', 'woocommerce-square' ),
|
108 |
+
'<a href="' . esc_url( $settings_url ) . '">',
|
109 |
+
'</a>'
|
110 |
);
|
111 |
}
|
112 |
|
113 |
$email_body .= sprintf(
|
114 |
/* translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing </a> HTML link tag, %3$s - additional action */
|
115 |
'<br>' . esc_html__( 'The sync job has failed. %1$sClick for more details%2$s, or %3$s.', 'woocommerce-square' ),
|
116 |
+
'<a href="' . esc_url( $records_url ) . '">',
|
117 |
+
'</a>',
|
118 |
strtolower( $action )
|
119 |
);
|
120 |
|
121 |
} else { // plain text
|
122 |
|
123 |
+
if ( wc_square()->get_settings_handler()->is_debug_enabled() ) {
|
124 |
$action = esc_html__( 'Inspect status logs', 'woocommerce-square' );
|
125 |
} else {
|
126 |
$action = esc_html__( 'Enable Logging', 'woocommerce-square' );
|
170 |
if ( $job->manual && ( 'completed' === $job->status || 'failed' === $job->status ) ) {
|
171 |
// for manual jobs, send an email if the job was either completed or failed
|
172 |
$should_send = true;
|
173 |
+
} elseif ( ! $job->manual && 'failed' === $job->status ) {
|
174 |
// for automated jobs, send an email only if the job failed and it's been a day since the last email
|
175 |
$already_sent = get_transient( 'wc_square_failed_sync_email_sent' );
|
176 |
if ( false === $already_sent ) {
|
211 |
if ( isset( $job->completed_at ) ) {
|
212 |
$sync_completed_date = date( wc_date_format(), strtotime( $job->completed_at ) );
|
213 |
$sync_completed_time = date( wc_time_format(), strtotime( $job->completed_at ) );
|
214 |
+
} elseif ( isset( $job->failed_at ) ) {
|
215 |
$sync_completed_date = date( wc_date_format(), strtotime( $job->failed_at ) );
|
216 |
$sync_completed_time = date( wc_time_format(), strtotime( $job->failed_at ) );
|
217 |
}
|
218 |
|
219 |
// placeholders
|
220 |
+
$email_merge_tags = array(
|
221 |
'product_count' => $product_count,
|
222 |
+
'sync_started_date' => isset( $job->started_at ) ? date( wc_date_format(), strtotime( $job->started_at ) ) : '',
|
223 |
+
'sync_started_time' => isset( $job->started_at ) ? date( wc_time_format(), strtotime( $job->started_at ) ) : '',
|
224 |
'sync_completed_date' => $sync_completed_date,
|
225 |
'sync_completed_time' => $sync_completed_time,
|
226 |
+
);
|
227 |
|
228 |
// TODO update handling when WooCommerce 3.2 is the minimum required version {FN 2019-05-03}
|
229 |
if ( Framework\SV_WC_Plugin_Compatibility::is_wc_version_gte( '3.2' ) ) {
|
230 |
foreach ( $email_merge_tags as $find => $replace ) {
|
231 |
$this->placeholders[ '{' . $find . '}' ] = $replace;
|
232 |
}
|
|
|
233 |
} else {
|
234 |
|
235 |
foreach ( $email_merge_tags as $find => $replace ) {
|
247 |
* @param array $args optional associative array with additional arguments
|
248 |
* @return array
|
249 |
*/
|
250 |
+
protected function get_template_args( $args = array() ) {
|
251 |
$sync_job = $this->get_job();
|
252 |
$html = empty( $args['plain_text'] );
|
253 |
|
259 |
$email_body = $this->get_body_by_job_status( 'completed', $html );
|
260 |
}
|
261 |
|
262 |
+
return array_merge(
|
263 |
+
$args,
|
264 |
+
array(
|
265 |
+
'email' => $this,
|
266 |
+
'email_heading' => $email_heading,
|
267 |
+
'email_body' => $email_body,
|
268 |
+
)
|
269 |
+
);
|
270 |
}
|
271 |
}
|
includes/Functions.php
CHANGED
@@ -21,7 +21,7 @@
|
|
21 |
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
22 |
*/
|
23 |
|
24 |
-
defined( 'ABSPATH' )
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
21 |
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
22 |
*/
|
23 |
|
24 |
+
defined( 'ABSPATH' ) || exit;
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
includes/Gateway.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Model\Customer;
|
@@ -46,6 +46,15 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
46 |
/** @var Gateway\API API base instance */
|
47 |
private $api;
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
/**
|
51 |
* Constructs the class.
|
@@ -54,39 +63,46 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
54 |
*/
|
55 |
public function __construct() {
|
56 |
|
57 |
-
parent::__construct(
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
self::
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
|
|
|
|
|
|
|
|
78 |
|
79 |
$this->view_transaction_url = 'https://squareup.com/dashboard/sales/transactions/%s';
|
80 |
|
81 |
// log accept.js requests and responses
|
82 |
-
add_action( 'wp_ajax_wc_' . $this->get_id() . '_log_js_data',
|
83 |
-
add_action( 'wp_ajax_nopriv_wc_' . $this->get_id() . '_log_js_data',
|
84 |
|
85 |
// store the Square item variation ID to order items
|
86 |
-
add_action( 'woocommerce_new_order_item',
|
87 |
|
88 |
// restore refunded Square inventory
|
89 |
-
add_action( 'woocommerce_order_fully_refunded',
|
|
|
|
|
|
|
90 |
}
|
91 |
|
92 |
|
@@ -144,6 +160,20 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
144 |
$item->save_meta_data();
|
145 |
}
|
146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
|
148 |
/**
|
149 |
* Enqueues the gateway JS.
|
@@ -151,13 +181,18 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
151 |
* @since 2.0.0
|
152 |
*/
|
153 |
protected function enqueue_gateway_assets() {
|
|
|
|
|
|
|
|
|
|
|
154 |
if ( $this->get_plugin()->get_settings_handler()->is_sandbox() ) {
|
155 |
$url = 'https://js.squareupsandbox.com/v2/paymentform';
|
156 |
} else {
|
157 |
$url = 'https://js.squareup.com/v2/paymentform';
|
158 |
}
|
159 |
|
160 |
-
wp_enqueue_script( 'wc-' . $this->get_plugin()->get_id_dasherized() . '-payment-form', $url,
|
161 |
|
162 |
parent::enqueue_gateway_assets();
|
163 |
}
|
@@ -187,7 +222,6 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
187 |
if ( ! Framework\SV_WC_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-payment-nonce' ) ) {
|
188 |
throw new Framework\SV_WC_Payment_Gateway_Exception( 'Payment nonce is missing' );
|
189 |
}
|
190 |
-
|
191 |
} catch ( Framework\SV_WC_Payment_Gateway_Exception $exception ) {
|
192 |
|
193 |
$is_valid = false;
|
@@ -227,8 +261,9 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
227 |
$order->payment->exp_year = Framework\SV_WC_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-exp-year' );
|
228 |
}
|
229 |
|
230 |
-
$order->square_order_id = $this->get_order_meta( $order, 'square_order_id' );
|
231 |
$order->square_customer_id = $order->customer_id;
|
|
|
|
|
232 |
|
233 |
// look up in the index for guest customers
|
234 |
if ( ! $order->get_user_id() ) {
|
@@ -254,7 +289,6 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
254 |
if ( ! $order->get_user_id() ) {
|
255 |
Gateway\Customer_Helper::add_customer( $order->square_customer_id, $order->get_billing_email() );
|
256 |
}
|
257 |
-
|
258 |
} catch ( \Exception $exception ) {
|
259 |
|
260 |
// log the error, but continue with payment
|
@@ -341,6 +375,9 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
341 |
if ( $response->get_square_order_id() ) {
|
342 |
$this->update_order_meta( $order, 'square_order_id', $response->get_square_order_id() );
|
343 |
}
|
|
|
|
|
|
|
344 |
}
|
345 |
|
346 |
|
@@ -358,6 +395,7 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
358 |
$order = parent::get_order_for_capture( $order, $amount );
|
359 |
|
360 |
$order->capture->location_id = $this->get_order_meta( $order, 'square_location_id' );
|
|
|
361 |
|
362 |
return $order;
|
363 |
}
|
@@ -376,13 +414,16 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
376 |
*/
|
377 |
protected function get_order_for_refund( $order, $amount, $reason ) {
|
378 |
|
379 |
-
$order
|
|
|
380 |
|
381 |
if ( $transaction_date = $this->get_order_meta( $order, 'trans_date' ) ) {
|
|
|
|
|
382 |
|
383 |
-
// throw an error if the payment
|
384 |
-
if ( current_time( 'timestamp' )
|
385 |
-
return new \WP_Error( 'wc_square_refund_age_exceeded', __( 'Refunds must be made within
|
386 |
}
|
387 |
}
|
388 |
|
@@ -392,8 +433,7 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
392 |
if ( ! $order->refund->tender_id ) {
|
393 |
|
394 |
try {
|
395 |
-
|
396 |
-
$response = $this->get_api()->get_transaction( $order->refund->trans_id, $order->refund->location_id );
|
397 |
|
398 |
if ( ! $response->get_authorization_code() ) {
|
399 |
throw new Framework\SV_WC_Plugin_Exception( 'Tender missing' );
|
@@ -483,7 +523,7 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
483 |
$order = parent::get_order_for_add_payment_method();
|
484 |
|
485 |
// if the customer doesn't have a postcode yet, use the value returned by Square JS
|
486 |
-
if ( ! $order->get_billing_postcode() && $postcode = Framework\SV_WC_Helper::get_post( 'wc-square-credit-card-payment-postcode') ) {
|
487 |
$order->set_billing_postcode( $postcode );
|
488 |
}
|
489 |
|
@@ -561,7 +601,7 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
561 |
|
562 |
foreach ( $form_fields['card_types']['default'] as $key => $type ) {
|
563 |
|
564 |
-
if ( in_array( $type,
|
565 |
unset( $form_fields['card_types']['default'][ $key ] );
|
566 |
}
|
567 |
}
|
@@ -634,7 +674,11 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
634 |
* @param bool $enabled
|
635 |
* @param Gateway $gateway_instance
|
636 |
*/
|
637 |
-
|
|
|
|
|
|
|
|
|
638 |
}
|
639 |
|
640 |
|
@@ -722,7 +766,7 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
722 |
*/
|
723 |
protected function get_method_form_fields() {
|
724 |
|
725 |
-
return
|
726 |
}
|
727 |
|
728 |
|
@@ -737,7 +781,7 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
737 |
* @param array $args arguments
|
738 |
* @return string
|
739 |
*/
|
740 |
-
public function get_customer_id( $user_id, $args =
|
741 |
|
742 |
// Square generates customer IDs
|
743 |
$args['autocreate'] = false;
|
@@ -806,5 +850,50 @@ class Gateway extends Framework\SV_WC_Payment_Gateway_Direct {
|
|
806 |
return apply_filters( 'wc_square_application_id', $square_application_id );
|
807 |
}
|
808 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
809 |
|
810 |
}
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Model\Customer;
|
46 |
/** @var Gateway\API API base instance */
|
47 |
private $api;
|
48 |
|
49 |
+
/**
|
50 |
+
* As per documentation, as of now, SCA is enabled only for UK merchants, but to be implemented for Europe.
|
51 |
+
* As other currencies get supported, add them here.
|
52 |
+
*
|
53 |
+
* @since 2.2.0
|
54 |
+
*
|
55 |
+
* @var array $sca_supported_currencies Currencies for which SCA(3DS) is supported
|
56 |
+
*/
|
57 |
+
private $sca_supported_currencies = array( 'GBP' );
|
58 |
|
59 |
/**
|
60 |
* Constructs the class.
|
63 |
*/
|
64 |
public function __construct() {
|
65 |
|
66 |
+
parent::__construct(
|
67 |
+
Plugin::GATEWAY_ID,
|
68 |
+
wc_square(),
|
69 |
+
array(
|
70 |
+
'method_title' => __( 'Square', 'woocommerce-square' ),
|
71 |
+
'method_description' => __( 'Allow customers to use Square to securely pay with their credit cards', 'woocommerce-square' ),
|
72 |
+
'payment_type' => self::PAYMENT_TYPE_CREDIT_CARD,
|
73 |
+
'supports' => array(
|
74 |
+
self::FEATURE_PRODUCTS,
|
75 |
+
self::FEATURE_CARD_TYPES,
|
76 |
+
self::FEATURE_DETAILED_CUSTOMER_DECLINE_MESSAGES,
|
77 |
+
self::FEATURE_PAYMENT_FORM,
|
78 |
+
self::FEATURE_CREDIT_CARD_AUTHORIZATION,
|
79 |
+
self::FEATURE_CREDIT_CARD_CHARGE,
|
80 |
+
self::FEATURE_CREDIT_CARD_CHARGE_VIRTUAL,
|
81 |
+
self::FEATURE_CREDIT_CARD_CAPTURE,
|
82 |
+
self::FEATURE_REFUNDS,
|
83 |
+
self::FEATURE_VOIDS,
|
84 |
+
self::FEATURE_CUSTOMER_ID,
|
85 |
+
self::FEATURE_TOKENIZATION,
|
86 |
+
self::FEATURE_ADD_PAYMENT_METHOD,
|
87 |
+
self::FEATURE_TOKEN_EDITOR,
|
88 |
+
),
|
89 |
+
)
|
90 |
+
);
|
91 |
|
92 |
$this->view_transaction_url = 'https://squareup.com/dashboard/sales/transactions/%s';
|
93 |
|
94 |
// log accept.js requests and responses
|
95 |
+
add_action( 'wp_ajax_wc_' . $this->get_id() . '_log_js_data', array( $this, 'log_js_data' ) );
|
96 |
+
add_action( 'wp_ajax_nopriv_wc_' . $this->get_id() . '_log_js_data', array( $this, 'log_js_data' ) );
|
97 |
|
98 |
// store the Square item variation ID to order items
|
99 |
+
add_action( 'woocommerce_new_order_item', array( $this, 'store_new_order_item_square_meta' ), 10, 3 );
|
100 |
|
101 |
// restore refunded Square inventory
|
102 |
+
add_action( 'woocommerce_order_fully_refunded', array( $this, 'restore_refunded_inventory' ), 10, 2 );
|
103 |
+
|
104 |
+
// AJAX Checkout validation handler.
|
105 |
+
add_action( 'wc_ajax_' . $this->get_id() . '_checkout_handler', array( $this, 'wc_ajax_square_checkout_handler' ) );
|
106 |
}
|
107 |
|
108 |
|
160 |
$item->save_meta_data();
|
161 |
}
|
162 |
|
163 |
+
/**
|
164 |
+
* Overrides enqueue of the gateway-specific assets if present, including JS, CSS, and
|
165 |
+
* localized script params
|
166 |
+
*
|
167 |
+
* @since 2.1.7
|
168 |
+
*/
|
169 |
+
protected function enqueue_payment_form_assets() {
|
170 |
+
// bail if *not* on add payment method page or checkout page.
|
171 |
+
if ( ! ( is_add_payment_method_page() || is_checkout() ) ) {
|
172 |
+
return;
|
173 |
+
}
|
174 |
+
|
175 |
+
parent::enqueue_payment_form_assets();
|
176 |
+
}
|
177 |
|
178 |
/**
|
179 |
* Enqueues the gateway JS.
|
181 |
* @since 2.0.0
|
182 |
*/
|
183 |
protected function enqueue_gateway_assets() {
|
184 |
+
// bail if *not* on add payment method page or checkout page.
|
185 |
+
if ( ! ( is_add_payment_method_page() || is_checkout() ) ) {
|
186 |
+
return;
|
187 |
+
}
|
188 |
+
|
189 |
if ( $this->get_plugin()->get_settings_handler()->is_sandbox() ) {
|
190 |
$url = 'https://js.squareupsandbox.com/v2/paymentform';
|
191 |
} else {
|
192 |
$url = 'https://js.squareup.com/v2/paymentform';
|
193 |
}
|
194 |
|
195 |
+
wp_enqueue_script( 'wc-' . $this->get_plugin()->get_id_dasherized() . '-payment-form', $url, array(), Plugin::VERSION );
|
196 |
|
197 |
parent::enqueue_gateway_assets();
|
198 |
}
|
222 |
if ( ! Framework\SV_WC_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-payment-nonce' ) ) {
|
223 |
throw new Framework\SV_WC_Payment_Gateway_Exception( 'Payment nonce is missing' );
|
224 |
}
|
|
|
225 |
} catch ( Framework\SV_WC_Payment_Gateway_Exception $exception ) {
|
226 |
|
227 |
$is_valid = false;
|
261 |
$order->payment->exp_year = Framework\SV_WC_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-exp-year' );
|
262 |
}
|
263 |
|
|
|
264 |
$order->square_customer_id = $order->customer_id;
|
265 |
+
$order->square_order_id = $this->get_order_meta( $order, 'square_order_id' );
|
266 |
+
$order->square_version = $this->get_order_meta( $order, 'square_version' );
|
267 |
|
268 |
// look up in the index for guest customers
|
269 |
if ( ! $order->get_user_id() ) {
|
289 |
if ( ! $order->get_user_id() ) {
|
290 |
Gateway\Customer_Helper::add_customer( $order->square_customer_id, $order->get_billing_email() );
|
291 |
}
|
|
|
292 |
} catch ( \Exception $exception ) {
|
293 |
|
294 |
// log the error, but continue with payment
|
375 |
if ( $response->get_square_order_id() ) {
|
376 |
$this->update_order_meta( $order, 'square_order_id', $response->get_square_order_id() );
|
377 |
}
|
378 |
+
|
379 |
+
// store the plugin version on the order
|
380 |
+
$this->update_order_meta( $order, 'square_version', Plugin::VERSION );
|
381 |
}
|
382 |
|
383 |
|
395 |
$order = parent::get_order_for_capture( $order, $amount );
|
396 |
|
397 |
$order->capture->location_id = $this->get_order_meta( $order, 'square_location_id' );
|
398 |
+
$order->square_version = $this->get_order_meta( $order, 'square_version' );
|
399 |
|
400 |
return $order;
|
401 |
}
|
414 |
*/
|
415 |
protected function get_order_for_refund( $order, $amount, $reason ) {
|
416 |
|
417 |
+
$order = parent::get_order_for_refund( $order, $amount, $reason );
|
418 |
+
$order->square_version = $this->get_order_meta( $order, 'square_version' );
|
419 |
|
420 |
if ( $transaction_date = $this->get_order_meta( $order, 'trans_date' ) ) {
|
421 |
+
// refunds with the Refunds API can be made up to 1 year after payment and up to 120 days with the Transactions API
|
422 |
+
$max_refund_time = version_compare( $order->square_version, '2.2', '>=' ) ? '+1 year' : '+120 days';
|
423 |
|
424 |
+
// throw an error if the payment cannot be refunded
|
425 |
+
if ( current_time( 'timestamp' ) >= strtotime( $max_refund_time, strtotime( $transaction_date ) ) ) {
|
426 |
+
return new \WP_Error( 'wc_square_refund_age_exceeded', sprintf( __( 'Refunds must be made within %s of the original payment date.', 'woocommerce-square' ), '+1 year' === $max_refund_time ? 'a year' : '120 days' ) );
|
427 |
}
|
428 |
}
|
429 |
|
433 |
if ( ! $order->refund->tender_id ) {
|
434 |
|
435 |
try {
|
436 |
+
$response = version_compare( $order->square_version, '2.2', '>=' ) ? $this->get_api()->get_payment( $order->refund->trans_id ) : $this->get_api()->get_transaction( $order->refund->trans_id, $order->refund->location_id );
|
|
|
437 |
|
438 |
if ( ! $response->get_authorization_code() ) {
|
439 |
throw new Framework\SV_WC_Plugin_Exception( 'Tender missing' );
|
523 |
$order = parent::get_order_for_add_payment_method();
|
524 |
|
525 |
// if the customer doesn't have a postcode yet, use the value returned by Square JS
|
526 |
+
if ( ! $order->get_billing_postcode() && $postcode = Framework\SV_WC_Helper::get_post( 'wc-square-credit-card-payment-postcode' ) ) {
|
527 |
$order->set_billing_postcode( $postcode );
|
528 |
}
|
529 |
|
601 |
|
602 |
foreach ( $form_fields['card_types']['default'] as $key => $type ) {
|
603 |
|
604 |
+
if ( in_array( $type, array( 'DISC', 'DINERS' ), true ) ) {
|
605 |
unset( $form_fields['card_types']['default'][ $key ] );
|
606 |
}
|
607 |
}
|
674 |
* @param bool $enabled
|
675 |
* @param Gateway $gateway_instance
|
676 |
*/
|
677 |
+
|
678 |
+
$base_currency = get_woocommerce_currency();
|
679 |
+
|
680 |
+
$sca_enabled_currencies = in_array( $base_currency, $this->sca_supported_currencies, true );
|
681 |
+
return apply_filters( 'wc_square_is_3d_secure_enabled', $sca_enabled_currencies, $this );
|
682 |
}
|
683 |
|
684 |
|
766 |
*/
|
767 |
protected function get_method_form_fields() {
|
768 |
|
769 |
+
return array();
|
770 |
}
|
771 |
|
772 |
|
781 |
* @param array $args arguments
|
782 |
* @return string
|
783 |
*/
|
784 |
+
public function get_customer_id( $user_id, $args = array() ) {
|
785 |
|
786 |
// Square generates customer IDs
|
787 |
$args['autocreate'] = false;
|
850 |
return apply_filters( 'wc_square_application_id', $square_application_id );
|
851 |
}
|
852 |
|
853 |
+
/**
|
854 |
+
* AJAX WooCommerce checkout validation handler
|
855 |
+
*
|
856 |
+
* Tap into woocommerce_after_checkout_validation hook
|
857 |
+
* and return WooCommerce checkout validation errors
|
858 |
+
*
|
859 |
+
* @since 2.2
|
860 |
+
*/
|
861 |
+
public function wc_ajax_square_checkout_handler() {
|
862 |
+
// Nonce verfication.
|
863 |
+
if ( ! check_ajax_referer( 'wc_' . $this->get_id() . '_checkout_validate', 'wc_' . $this->get_id() . '_checkout_validate_nonce', false ) ) {
|
864 |
+
return wp_send_json_error( __( ' An error occurred, please try again or try an alternate form of payment.', 'woocommerce-square' ) );
|
865 |
+
}
|
866 |
+
|
867 |
+
// Nonce successfully verified. Proceed with validation.
|
868 |
+
add_action( 'woocommerce_after_checkout_validation', array( $this, 'wc_ajax_square_checkout_validate' ), 10, 2 );
|
869 |
+
WC()->checkout->process_checkout();
|
870 |
+
}
|
871 |
+
|
872 |
+
/**
|
873 |
+
* Validate WooCommerce checkout data on Square JS AJAX call
|
874 |
+
*
|
875 |
+
* Returns validation errors (or success) as JSON and exits to prevent checkout
|
876 |
+
*
|
877 |
+
* @since 2.2
|
878 |
+
*
|
879 |
+
* @param array $data WooCommerce checkout POST data.
|
880 |
+
* @param WP_Error $errors WooCommerce checkout errors.
|
881 |
+
*/
|
882 |
+
public function wc_ajax_square_checkout_validate( $data, $errors = null ) {
|
883 |
+
$error_messages = null;
|
884 |
+
if ( ! is_null( $errors ) ) {
|
885 |
+
$error_messages = $errors->get_error_messages();
|
886 |
+
}
|
887 |
+
|
888 |
+
// Clear all existing notices.
|
889 |
+
wc_clear_notices();
|
890 |
+
|
891 |
+
if ( empty( $error_messages ) ) {
|
892 |
+
wp_send_json_success( 'validation_successful' );
|
893 |
+
} else {
|
894 |
+
wp_send_json_error( array( 'messages' => $error_messages ) );
|
895 |
+
}
|
896 |
+
exit;
|
897 |
+
}
|
898 |
|
899 |
}
|
includes/Gateway/API.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Model\Order;
|
@@ -73,11 +73,11 @@ class API extends \WooCommerce\Square\API {
|
|
73 |
*/
|
74 |
public function credit_card_authorization( \WC_Order $order ) {
|
75 |
|
76 |
-
$request = new API\Requests\
|
77 |
|
78 |
$request->set_authorization_data( $order );
|
79 |
|
80 |
-
$this->set_response_handler( API\Responses\
|
81 |
|
82 |
return $this->perform_request( $request );
|
83 |
}
|
@@ -94,11 +94,11 @@ class API extends \WooCommerce\Square\API {
|
|
94 |
*/
|
95 |
public function credit_card_charge( \WC_Order $order ) {
|
96 |
|
97 |
-
$request = new API\Requests\
|
98 |
|
99 |
$request->set_charge_data( $order );
|
100 |
|
101 |
-
$this->set_response_handler( API\Responses\
|
102 |
|
103 |
return $this->perform_request( $request );
|
104 |
}
|
@@ -117,7 +117,12 @@ class API extends \WooCommerce\Square\API {
|
|
117 |
|
118 |
$location_id = ! empty( $order->capture->location_id ) ? $order->capture->location_id : $this->get_location_id();
|
119 |
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
121 |
|
122 |
$request->set_capture_data( $order );
|
123 |
|
@@ -140,7 +145,12 @@ class API extends \WooCommerce\Square\API {
|
|
140 |
|
141 |
$location_id = ! empty( $order->refund->location_id ) ? $order->refund->location_id : $this->get_location_id();
|
142 |
|
143 |
-
|
|
|
|
|
|
|
|
|
|
|
144 |
|
145 |
$request->set_refund_data( $order );
|
146 |
|
@@ -163,7 +173,12 @@ class API extends \WooCommerce\Square\API {
|
|
163 |
|
164 |
$location_id = ! empty( $order->refund->location_id ) ? $order->refund->location_id : $this->get_location_id();
|
165 |
|
166 |
-
|
|
|
|
|
|
|
|
|
|
|
167 |
|
168 |
$request->set_void_data( $order );
|
169 |
|
@@ -376,6 +391,27 @@ class API extends \WooCommerce\Square\API {
|
|
376 |
}
|
377 |
|
378 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
/**
|
380 |
* Validates the parsed response.
|
381 |
*
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Model\Order;
|
73 |
*/
|
74 |
public function credit_card_authorization( \WC_Order $order ) {
|
75 |
|
76 |
+
$request = new API\Requests\Payments( $this->get_location_id(), $this->client );
|
77 |
|
78 |
$request->set_authorization_data( $order );
|
79 |
|
80 |
+
$this->set_response_handler( API\Responses\Create_Payment::class );
|
81 |
|
82 |
return $this->perform_request( $request );
|
83 |
}
|
94 |
*/
|
95 |
public function credit_card_charge( \WC_Order $order ) {
|
96 |
|
97 |
+
$request = new API\Requests\Payments( $this->get_location_id(), $this->client );
|
98 |
|
99 |
$request->set_charge_data( $order );
|
100 |
|
101 |
+
$this->set_response_handler( API\Responses\Create_Payment::class );
|
102 |
|
103 |
return $this->perform_request( $request );
|
104 |
}
|
117 |
|
118 |
$location_id = ! empty( $order->capture->location_id ) ? $order->capture->location_id : $this->get_location_id();
|
119 |
|
120 |
+
// use the Payments API to capture orders that were processed with Square v2.2+
|
121 |
+
if ( ! empty( $order->square_version ) && version_compare( $order->square_version, '2.2', '>=' ) ) {
|
122 |
+
$request = new API\Requests\Payments( $location_id, $this->client );
|
123 |
+
} else {
|
124 |
+
$request = new API\Requests\Transactions( $location_id, $this->client );
|
125 |
+
}
|
126 |
|
127 |
$request->set_capture_data( $order );
|
128 |
|
145 |
|
146 |
$location_id = ! empty( $order->refund->location_id ) ? $order->refund->location_id : $this->get_location_id();
|
147 |
|
148 |
+
// only use the Refunds API to refund orders that took payment after Square v2.2
|
149 |
+
if ( ! empty( $order->square_version ) && version_compare( $order->square_version, '2.2', '>=' ) ) {
|
150 |
+
$request = new API\Requests\Refunds( $this->client );
|
151 |
+
} else {
|
152 |
+
$request = new API\Requests\Transactions( $location_id, $this->client );
|
153 |
+
}
|
154 |
|
155 |
$request->set_refund_data( $order );
|
156 |
|
173 |
|
174 |
$location_id = ! empty( $order->refund->location_id ) ? $order->refund->location_id : $this->get_location_id();
|
175 |
|
176 |
+
// use the Payments API to void/cancel orders that were processed after Square v2.2
|
177 |
+
if ( ! empty( $order->square_version ) && version_compare( $order->square_version, '2.2', '>=' ) ) {
|
178 |
+
$request = new API\Requests\Payments( $location_id, $this->client );
|
179 |
+
} else {
|
180 |
+
$request = new API\Requests\Transactions( $location_id, $this->client );
|
181 |
+
}
|
182 |
|
183 |
$request->set_void_data( $order );
|
184 |
|
391 |
}
|
392 |
|
393 |
|
394 |
+
/**
|
395 |
+
* Gets an existing payment.
|
396 |
+
*
|
397 |
+
* @since 2.2.0
|
398 |
+
*
|
399 |
+
* @param string $payment_id transaction ID
|
400 |
+
* @return API\Responses\Create_Payment
|
401 |
+
* @throws Framework\SV_WC_API_Exception
|
402 |
+
*/
|
403 |
+
public function get_payment( $payment_id ) {
|
404 |
+
|
405 |
+
$request = new API\Requests\Payments( $this->get_location_id(), $this->client );
|
406 |
+
|
407 |
+
$request->set_get_payment_data( $payment_id );
|
408 |
+
|
409 |
+
$this->set_response_handler( API\Responses\Create_Payment::class );
|
410 |
+
|
411 |
+
return $this->perform_request( $request );
|
412 |
+
}
|
413 |
+
|
414 |
+
|
415 |
/**
|
416 |
* Validates the parsed response.
|
417 |
*
|
includes/Gateway/API/Requests/Customers.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Requests;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Model as SquareModel;
|
@@ -59,8 +59,7 @@ class Customers extends API\Requests\Customers {
|
|
59 |
|
60 |
$email = $customer->get_email();
|
61 |
|
62 |
-
// otherwise, use the order billing email
|
63 |
-
} catch ( \Exception $exception ) {
|
64 |
|
65 |
$email = $order->get_billing_email();
|
66 |
}
|
@@ -80,9 +79,9 @@ class Customers extends API\Requests\Customers {
|
|
80 |
|
81 |
$this->square_request = $customer_request;
|
82 |
|
83 |
-
$this->square_api_args =
|
84 |
$this->square_request,
|
85 |
-
|
86 |
}
|
87 |
|
88 |
|
@@ -110,10 +109,10 @@ class Customers extends API\Requests\Customers {
|
|
110 |
|
111 |
$this->square_request = $request;
|
112 |
|
113 |
-
$this->square_api_args =
|
114 |
$order->customer_id,
|
115 |
$this->square_request,
|
116 |
-
|
117 |
}
|
118 |
|
119 |
|
@@ -129,10 +128,10 @@ class Customers extends API\Requests\Customers {
|
|
129 |
|
130 |
$this->square_api_method = 'deleteCustomerCard';
|
131 |
|
132 |
-
$this->square_api_args =
|
133 |
$customer_id,
|
134 |
$card_id,
|
135 |
-
|
136 |
}
|
137 |
|
138 |
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Requests;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Model as SquareModel;
|
59 |
|
60 |
$email = $customer->get_email();
|
61 |
|
62 |
+
} catch ( \Exception $exception ) { // otherwise, use the order billing email
|
|
|
63 |
|
64 |
$email = $order->get_billing_email();
|
65 |
}
|
79 |
|
80 |
$this->square_request = $customer_request;
|
81 |
|
82 |
+
$this->square_api_args = array(
|
83 |
$this->square_request,
|
84 |
+
);
|
85 |
}
|
86 |
|
87 |
|
109 |
|
110 |
$this->square_request = $request;
|
111 |
|
112 |
+
$this->square_api_args = array(
|
113 |
$order->customer_id,
|
114 |
$this->square_request,
|
115 |
+
);
|
116 |
}
|
117 |
|
118 |
|
128 |
|
129 |
$this->square_api_method = 'deleteCustomerCard';
|
130 |
|
131 |
+
$this->square_api_args = array(
|
132 |
$customer_id,
|
133 |
$card_id,
|
134 |
+
);
|
135 |
}
|
136 |
|
137 |
|
includes/Gateway/API/Requests/Orders.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Requests;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Api\OrdersApi;
|
@@ -78,21 +78,27 @@ class Orders extends API\Request {
|
|
78 |
|
79 |
if ( $order->get_discount_total() ) {
|
80 |
|
81 |
-
$order_model->setDiscounts(
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
}
|
88 |
|
89 |
$this->square_request->setIdempotencyKey( wc_square()->get_idempotency_key( $order->unique_transaction_ref ) );
|
90 |
$this->square_request->setOrder( $order_model );
|
91 |
|
92 |
-
$this->square_api_args =
|
93 |
$location_id,
|
94 |
$this->square_request,
|
95 |
-
|
96 |
}
|
97 |
|
98 |
|
@@ -106,7 +112,7 @@ class Orders extends API\Request {
|
|
106 |
*/
|
107 |
protected function get_product_line_items( \WC_Order $order ) {
|
108 |
|
109 |
-
$line_items =
|
110 |
|
111 |
foreach ( $order->get_items() as $item ) {
|
112 |
|
@@ -144,7 +150,7 @@ class Orders extends API\Request {
|
|
144 |
*/
|
145 |
protected function get_fee_line_items( \WC_Order $order ) {
|
146 |
|
147 |
-
$line_items =
|
148 |
|
149 |
foreach ( $order->get_fees() as $item ) {
|
150 |
|
@@ -176,7 +182,7 @@ class Orders extends API\Request {
|
|
176 |
*/
|
177 |
protected function get_shipping_line_items( \WC_Order $order ) {
|
178 |
|
179 |
-
$line_items =
|
180 |
|
181 |
foreach ( $order->get_shipping_methods() as $item ) {
|
182 |
|
@@ -208,16 +214,18 @@ class Orders extends API\Request {
|
|
208 |
*/
|
209 |
protected function get_order_taxes( \WC_Order $order ) {
|
210 |
|
211 |
-
$taxes =
|
212 |
|
213 |
foreach ( $order->get_taxes() as $tax ) {
|
214 |
|
215 |
-
$tax_item = new SquareModel\OrderLineItemTax(
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
|
|
|
|
221 |
|
222 |
$pre_tax_total = (float) $order->get_total() - (float) $order->get_total_tax();
|
223 |
$total_tax = (float) $tax->get_tax_total() + (float) $tax->get_shipping_tax_total();
|
@@ -245,13 +253,15 @@ class Orders extends API\Request {
|
|
245 |
|
246 |
foreach ( $line_items as $line_item ) {
|
247 |
|
248 |
-
$applied_taxes =
|
249 |
|
250 |
foreach ( $taxes as $tax ) {
|
251 |
|
252 |
-
$applied_taxes[] = new SquareModel\OrderLineItemAppliedTax(
|
253 |
-
|
254 |
-
|
|
|
|
|
255 |
}
|
256 |
|
257 |
$line_item->setAppliedTaxes( $applied_taxes );
|
@@ -277,23 +287,31 @@ class Orders extends API\Request {
|
|
277 |
$order_model = new SquareModel\Order();
|
278 |
$order_model->setVersion( $version );
|
279 |
|
280 |
-
$order_model->setLineItems(
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
|
289 |
$this->square_request->setIdempotencyKey( wc_square()->get_idempotency_key( $order->unique_transaction_ref ) . $version );
|
290 |
$this->square_request->setOrder( $order_model );
|
291 |
|
292 |
-
$this->square_api_args =
|
293 |
$location_id,
|
294 |
$order->square_order_id,
|
295 |
$this->square_request,
|
296 |
-
|
297 |
}
|
298 |
|
299 |
|
@@ -315,24 +333,32 @@ class Orders extends API\Request {
|
|
315 |
$order_model = new SquareModel\Order();
|
316 |
$order_model->setVersion( $version );
|
317 |
|
318 |
-
$order_model->setDiscounts(
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
327 |
|
328 |
$this->square_request->setIdempotencyKey( wc_square()->get_idempotency_key( $order->unique_transaction_ref ) . $version );
|
329 |
$this->square_request->setOrder( $order_model );
|
330 |
|
331 |
-
$this->square_api_args =
|
332 |
$location_id,
|
333 |
$order->square_order_id,
|
334 |
$this->square_request,
|
335 |
-
|
336 |
}
|
337 |
|
338 |
}
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Requests;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Api\OrdersApi;
|
78 |
|
79 |
if ( $order->get_discount_total() ) {
|
80 |
|
81 |
+
$order_model->setDiscounts(
|
82 |
+
array(
|
83 |
+
new SquareModel\OrderLineItemDiscount(
|
84 |
+
array(
|
85 |
+
'name' => __( 'Discount', 'woocommerce-square' ),
|
86 |
+
'type' => 'FIXED_AMOUNT',
|
87 |
+
'amount_money' => Money_Utility::amount_to_money( $order->get_discount_total(), $order->get_currency() ),
|
88 |
+
'scope' => 'ORDER',
|
89 |
+
)
|
90 |
+
),
|
91 |
+
)
|
92 |
+
);
|
93 |
}
|
94 |
|
95 |
$this->square_request->setIdempotencyKey( wc_square()->get_idempotency_key( $order->unique_transaction_ref ) );
|
96 |
$this->square_request->setOrder( $order_model );
|
97 |
|
98 |
+
$this->square_api_args = array(
|
99 |
$location_id,
|
100 |
$this->square_request,
|
101 |
+
);
|
102 |
}
|
103 |
|
104 |
|
112 |
*/
|
113 |
protected function get_product_line_items( \WC_Order $order ) {
|
114 |
|
115 |
+
$line_items = array();
|
116 |
|
117 |
foreach ( $order->get_items() as $item ) {
|
118 |
|
150 |
*/
|
151 |
protected function get_fee_line_items( \WC_Order $order ) {
|
152 |
|
153 |
+
$line_items = array();
|
154 |
|
155 |
foreach ( $order->get_fees() as $item ) {
|
156 |
|
182 |
*/
|
183 |
protected function get_shipping_line_items( \WC_Order $order ) {
|
184 |
|
185 |
+
$line_items = array();
|
186 |
|
187 |
foreach ( $order->get_shipping_methods() as $item ) {
|
188 |
|
214 |
*/
|
215 |
protected function get_order_taxes( \WC_Order $order ) {
|
216 |
|
217 |
+
$taxes = array();
|
218 |
|
219 |
foreach ( $order->get_taxes() as $tax ) {
|
220 |
|
221 |
+
$tax_item = new SquareModel\OrderLineItemTax(
|
222 |
+
array(
|
223 |
+
'uid' => uniqid(),
|
224 |
+
'name' => $tax->get_name(),
|
225 |
+
'type' => 'ADDITIVE',
|
226 |
+
'scope' => 'LINE_ITEM',
|
227 |
+
)
|
228 |
+
);
|
229 |
|
230 |
$pre_tax_total = (float) $order->get_total() - (float) $order->get_total_tax();
|
231 |
$total_tax = (float) $tax->get_tax_total() + (float) $tax->get_shipping_tax_total();
|
253 |
|
254 |
foreach ( $line_items as $line_item ) {
|
255 |
|
256 |
+
$applied_taxes = array();
|
257 |
|
258 |
foreach ( $taxes as $tax ) {
|
259 |
|
260 |
+
$applied_taxes[] = new SquareModel\OrderLineItemAppliedTax(
|
261 |
+
array(
|
262 |
+
'tax_uid' => $tax->getUid(),
|
263 |
+
)
|
264 |
+
);
|
265 |
}
|
266 |
|
267 |
$line_item->setAppliedTaxes( $applied_taxes );
|
287 |
$order_model = new SquareModel\Order();
|
288 |
$order_model->setVersion( $version );
|
289 |
|
290 |
+
$order_model->setLineItems(
|
291 |
+
array(
|
292 |
+
new SquareModel\OrderLineItem(
|
293 |
+
array(
|
294 |
+
'name' => __( 'Adjustment', 'woocommerce-square' ),
|
295 |
+
'quantity' => (string) 1,
|
296 |
+
'base_price_money' => new SquareModel\Money(
|
297 |
+
array(
|
298 |
+
'amount' => $amount,
|
299 |
+
'currency' => $order->get_currency(),
|
300 |
+
)
|
301 |
+
),
|
302 |
+
)
|
303 |
+
),
|
304 |
+
)
|
305 |
+
);
|
306 |
|
307 |
$this->square_request->setIdempotencyKey( wc_square()->get_idempotency_key( $order->unique_transaction_ref ) . $version );
|
308 |
$this->square_request->setOrder( $order_model );
|
309 |
|
310 |
+
$this->square_api_args = array(
|
311 |
$location_id,
|
312 |
$order->square_order_id,
|
313 |
$this->square_request,
|
314 |
+
);
|
315 |
}
|
316 |
|
317 |
|
333 |
$order_model = new SquareModel\Order();
|
334 |
$order_model->setVersion( $version );
|
335 |
|
336 |
+
$order_model->setDiscounts(
|
337 |
+
array(
|
338 |
+
new SquareModel\OrderLineItemDiscount(
|
339 |
+
array(
|
340 |
+
'name' => __( 'Adjustment', 'woocommerce-square' ),
|
341 |
+
'type' => 'FIXED_AMOUNT',
|
342 |
+
'amount_money' => new SquareModel\Money(
|
343 |
+
array(
|
344 |
+
'amount' => $amount,
|
345 |
+
'currency' => $order->get_currency(),
|
346 |
+
)
|
347 |
+
),
|
348 |
+
'scope' => 'ORDER',
|
349 |
+
)
|
350 |
+
),
|
351 |
+
)
|
352 |
+
);
|
353 |
|
354 |
$this->square_request->setIdempotencyKey( wc_square()->get_idempotency_key( $order->unique_transaction_ref ) . $version );
|
355 |
$this->square_request->setOrder( $order_model );
|
356 |
|
357 |
+
$this->square_api_args = array(
|
358 |
$location_id,
|
359 |
$order->square_order_id,
|
360 |
$this->square_request,
|
361 |
+
);
|
362 |
}
|
363 |
|
364 |
}
|
includes/Gateway/API/Requests/Payments.php
ADDED
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WooCommerce Square
|
4 |
+
*
|
5 |
+
* This source file is subject to the GNU General Public License v3.0
|
6 |
+
* that is bundled with this package in the file license.txt.
|
7 |
+
* It is also available through the world-wide-web at this URL:
|
8 |
+
* http://www.gnu.org/licenses/gpl-3.0.html
|
9 |
+
* If you did not receive a copy of the license and are unable to
|
10 |
+
* obtain it through the world-wide-web, please send an email
|
11 |
+
* to license@woocommerce.com so we can send you a copy immediately.
|
12 |
+
*
|
13 |
+
* DISCLAIMER
|
14 |
+
*
|
15 |
+
* Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
|
16 |
+
* versions in the future. If you wish to customize WooCommerce Square for your
|
17 |
+
* needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
|
18 |
+
*
|
19 |
+
* @author WooCommerce
|
20 |
+
* @copyright Copyright: (c) 2019, Automattic, Inc.
|
21 |
+
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
22 |
+
*/
|
23 |
+
|
24 |
+
namespace WooCommerce\Square\Gateway\API\Requests;
|
25 |
+
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
+
|
28 |
+
use SquareConnect\Api\PaymentsApi;
|
29 |
+
use SquareConnect\Model as SquareModel;
|
30 |
+
use WooCommerce\Square\Utilities;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* The Payments API request class.
|
34 |
+
*
|
35 |
+
* @since 2.2.0
|
36 |
+
*/
|
37 |
+
class Payments extends \WooCommerce\Square\API\Request {
|
38 |
+
|
39 |
+
/** @var string location ID */
|
40 |
+
protected $location_id;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Initializes a new payments request.
|
44 |
+
*
|
45 |
+
* @since 2.2.0
|
46 |
+
* @param string $location_id location ID
|
47 |
+
* @param \SquareConnect\ApiClient $api_client the API client
|
48 |
+
*/
|
49 |
+
public function __construct( $location_id, $api_client ) {
|
50 |
+
$this->location_id = $location_id;
|
51 |
+
$this->square_api = new PaymentsApi( $api_client );
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Sets the data for an authorization/delayed capture.
|
56 |
+
*
|
57 |
+
* @since 2.2.0
|
58 |
+
* @param \WC_Order $order order object
|
59 |
+
*/
|
60 |
+
public function set_authorization_data( \WC_Order $order ) {
|
61 |
+
$this->set_charge_data( $order, false );
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Sets the data for a charge.
|
66 |
+
*
|
67 |
+
* @since 2.2.0
|
68 |
+
*
|
69 |
+
* @param \WC_Order $order
|
70 |
+
* @param bool $capture whether to immediately capture the charge
|
71 |
+
*/
|
72 |
+
public function set_charge_data( \WC_Order $order, $capture = true ) {
|
73 |
+
|
74 |
+
$this->square_api_method = 'createPayment';
|
75 |
+
$this->square_request = new SquareModel\CreatePaymentRequest();
|
76 |
+
|
77 |
+
$this->square_request->setIdempotencyKey( wc_square()->get_idempotency_key( $order->unique_transaction_ref ) );
|
78 |
+
$this->square_request->setAmountMoney( Utilities\Money_Utility::amount_to_money( $order->payment_total, $order->get_currency() ) );
|
79 |
+
$this->square_request->setReferenceId( $order->get_order_number() );
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Filters the Square payment order note (legacy filter).
|
83 |
+
*
|
84 |
+
* @since 2.2.0
|
85 |
+
*
|
86 |
+
* @param string $description the order note (description)
|
87 |
+
* @param \WC_Order $order the order object
|
88 |
+
*/
|
89 |
+
$description = (string) apply_filters( 'wc_square_payment_order_note', $order->description, $order );
|
90 |
+
|
91 |
+
$this->square_request->setNote( Utilities\String_Utility::truncate( $description, 500 ) );
|
92 |
+
|
93 |
+
$this->square_request->setAutocomplete( $capture );
|
94 |
+
|
95 |
+
if ( ! empty( $order->square_customer_id ) ) {
|
96 |
+
$this->square_request->setCustomerId( $order->square_customer_id );
|
97 |
+
}
|
98 |
+
|
99 |
+
// payment token (card ID) or card nonce (from JS)
|
100 |
+
$this->square_request->setSourceId( ! empty( $order->payment->token ) ? $order->payment->token : $order->payment->nonce );
|
101 |
+
|
102 |
+
// 3DS / SCA verification token (from JS)
|
103 |
+
if ( ! empty( $order->payment->verification_token ) ) {
|
104 |
+
$this->square_request->setVerificationToken( $order->payment->verification_token );
|
105 |
+
}
|
106 |
+
|
107 |
+
if ( ! empty( $this->location_id ) ) {
|
108 |
+
$this->square_request->setLocationId( $this->location_id );
|
109 |
+
}
|
110 |
+
|
111 |
+
$billing_address = new SquareModel\Address();
|
112 |
+
$billing_address->setFirstName( $order->get_billing_first_name() );
|
113 |
+
$billing_address->setLastName( $order->get_billing_last_name() );
|
114 |
+
$billing_address->setOrganization( $order->get_billing_company() );
|
115 |
+
$billing_address->setAddressLine1( $order->get_billing_address_1() );
|
116 |
+
$billing_address->setAddressLine2( $order->get_billing_address_2() );
|
117 |
+
$billing_address->setLocality( $order->get_billing_city() );
|
118 |
+
$billing_address->setAdministrativeDistrictLevel1( $order->get_billing_state() );
|
119 |
+
$billing_address->setPostalCode( $order->get_billing_postcode() );
|
120 |
+
$billing_address->setCountry( $order->get_billing_country() );
|
121 |
+
|
122 |
+
$this->square_request->setBillingAddress( $billing_address );
|
123 |
+
|
124 |
+
if ( $order->get_shipping_address_1( 'edit' ) || $order->get_shipping_address_2( 'edit' ) ) {
|
125 |
+
|
126 |
+
$shipping_address = new SquareModel\Address();
|
127 |
+
$shipping_address->setFirstName( $order->get_shipping_first_name() );
|
128 |
+
$shipping_address->setLastName( $order->get_shipping_last_name() );
|
129 |
+
$shipping_address->setAddressLine1( $order->get_shipping_address_1() );
|
130 |
+
$shipping_address->setAddressLine2( $order->get_shipping_address_2() );
|
131 |
+
$shipping_address->setLocality( $order->get_shipping_city() );
|
132 |
+
$shipping_address->setAdministrativeDistrictLevel1( $order->get_shipping_state() );
|
133 |
+
$shipping_address->setPostalCode( $order->get_shipping_postcode() );
|
134 |
+
$shipping_address->setCountry( $order->get_shipping_country() );
|
135 |
+
|
136 |
+
$this->square_request->setShippingAddress( $shipping_address );
|
137 |
+
}
|
138 |
+
|
139 |
+
$this->square_request->setBuyerEmailAddress( $order->get_billing_email() );
|
140 |
+
|
141 |
+
if ( ! empty( $order->square_order_id ) ) {
|
142 |
+
$this->square_request->setOrderId( $order->square_order_id );
|
143 |
+
}
|
144 |
+
|
145 |
+
$this->square_api_args = array(
|
146 |
+
$this->square_request,
|
147 |
+
);
|
148 |
+
}
|
149 |
+
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Sets the data for capturing a payment.
|
153 |
+
*
|
154 |
+
* @since 2.2.0
|
155 |
+
*
|
156 |
+
* @param \WC_Order $order order object
|
157 |
+
*/
|
158 |
+
public function set_capture_data( \WC_Order $order ) {
|
159 |
+
$this->square_api_method = 'completePayment';
|
160 |
+
$this->square_api_args = array( $order->capture->trans_id );
|
161 |
+
}
|
162 |
+
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Sets the data for voiding/cancelling a payment.
|
166 |
+
*
|
167 |
+
* @since 2.2.0
|
168 |
+
*
|
169 |
+
* @param \WC_Order $order order object
|
170 |
+
*/
|
171 |
+
public function set_void_data( \WC_Order $order ) {
|
172 |
+
$this->square_api_method = 'cancelPayment';
|
173 |
+
$this->square_api_args = array( $order->refund->trans_id );
|
174 |
+
}
|
175 |
+
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Sets the data for getting a Payment.
|
179 |
+
*
|
180 |
+
* @since 2.2.0
|
181 |
+
*
|
182 |
+
* @param string $payment_id payment ID
|
183 |
+
*/
|
184 |
+
public function set_get_payment_data( $payment_id ) {
|
185 |
+
$this->square_api_method = 'getPayment';
|
186 |
+
$this->square_api_args = array( $payment_id );
|
187 |
+
}
|
188 |
+
|
189 |
+
|
190 |
+
/** Getter methods ************************************************************************************************/
|
191 |
+
|
192 |
+
|
193 |
+
/** Gets the location ID for this request.
|
194 |
+
*
|
195 |
+
* All requests in this type must have a location ID.
|
196 |
+
*
|
197 |
+
* @since 2.0.0
|
198 |
+
*
|
199 |
+
* @return string
|
200 |
+
*/
|
201 |
+
protected function get_location_id() {
|
202 |
+
|
203 |
+
return $this->location_id;
|
204 |
+
}
|
205 |
+
}
|
includes/Gateway/API/Requests/Refunds.php
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WooCommerce Square
|
4 |
+
*
|
5 |
+
* This source file is subject to the GNU General Public License v3.0
|
6 |
+
* that is bundled with this package in the file license.txt.
|
7 |
+
* It is also available through the world-wide-web at this URL:
|
8 |
+
* http://www.gnu.org/licenses/gpl-3.0.html
|
9 |
+
* If you did not receive a copy of the license and are unable to
|
10 |
+
* obtain it through the world-wide-web, please send an email
|
11 |
+
* to license@woocommerce.com so we can send you a copy immediately.
|
12 |
+
*
|
13 |
+
* DISCLAIMER
|
14 |
+
*
|
15 |
+
* Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
|
16 |
+
* versions in the future. If you wish to customize WooCommerce Square for your
|
17 |
+
* needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
|
18 |
+
*
|
19 |
+
* @author WooCommerce
|
20 |
+
* @copyright Copyright: (c) 2019, Automattic, Inc.
|
21 |
+
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
22 |
+
*/
|
23 |
+
|
24 |
+
namespace WooCommerce\Square\Gateway\API\Requests;
|
25 |
+
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
+
|
28 |
+
use SquareConnect\Api\RefundsApi;
|
29 |
+
use SquareConnect\Model\RefundPaymentRequest;
|
30 |
+
use WooCommerce\Square\Utilities\Money_Utility;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* The Refunds API request class.
|
34 |
+
*
|
35 |
+
* @since 2.2.0
|
36 |
+
*/
|
37 |
+
class Refunds extends \WooCommerce\Square\API\Request {
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Initializes a new refund request.
|
41 |
+
*
|
42 |
+
* @since 2.2.0
|
43 |
+
* @param \SquareConnect\ApiClient $api_client the API client
|
44 |
+
*/
|
45 |
+
public function __construct( $api_client ) {
|
46 |
+
$this->square_api = new RefundsApi( $api_client );
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Sets the data for refund a payment.
|
52 |
+
*
|
53 |
+
* @since 2.2.0
|
54 |
+
*
|
55 |
+
* @param \WC_Order $order order object
|
56 |
+
*/
|
57 |
+
public function set_refund_data( \WC_Order $order ) {
|
58 |
+
|
59 |
+
$this->square_api_method = 'refundPayment';
|
60 |
+
|
61 |
+
// The refund objects are sorted by date DESC, so the last one created will be at the start of the array
|
62 |
+
$refunds = $order->get_refunds();
|
63 |
+
$refund_obj = $refunds[0];
|
64 |
+
|
65 |
+
$this->square_request = new RefundPaymentRequest();
|
66 |
+
$this->square_request->setIdempotencyKey( wc_square()->get_idempotency_key( $order->get_id() . ':' . $refund_obj->get_id() ) );
|
67 |
+
$this->square_request->setPaymentId( $order->refund->tender_id );
|
68 |
+
$this->square_request->setReason( $order->refund->reason );
|
69 |
+
|
70 |
+
$this->square_request->setAmountMoney( Money_Utility::amount_to_money( $order->refund->amount, $order->get_currency() ) );
|
71 |
+
|
72 |
+
$this->square_api_args = array(
|
73 |
+
$this->square_request,
|
74 |
+
);
|
75 |
+
}
|
76 |
+
}
|
includes/Gateway/API/Requests/Transactions.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Requests;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Api\TransactionsApi;
|
@@ -148,10 +148,10 @@ class Transactions extends \WooCommerce\Square\API\Request {
|
|
148 |
$this->square_request->setOrderId( $order->square_order_id );
|
149 |
}
|
150 |
|
151 |
-
$this->square_api_args =
|
152 |
$this->get_location_id(),
|
153 |
$this->square_request,
|
154 |
-
|
155 |
}
|
156 |
|
157 |
|
@@ -166,10 +166,10 @@ class Transactions extends \WooCommerce\Square\API\Request {
|
|
166 |
|
167 |
$this->square_api_method = 'captureTransaction';
|
168 |
|
169 |
-
$this->square_api_args =
|
170 |
$this->get_location_id(),
|
171 |
$order->capture->trans_id,
|
172 |
-
|
173 |
}
|
174 |
|
175 |
|
@@ -185,7 +185,7 @@ class Transactions extends \WooCommerce\Square\API\Request {
|
|
185 |
$this->square_api_method = 'createRefund';
|
186 |
|
187 |
// The refund objects are sorted by date DESC, so the last one created will be at the start of the array
|
188 |
-
$refunds
|
189 |
$refund_obj = $refunds[0];
|
190 |
|
191 |
$this->square_request = new CreateRefundRequest();
|
@@ -195,11 +195,11 @@ class Transactions extends \WooCommerce\Square\API\Request {
|
|
195 |
|
196 |
$this->square_request->setAmountMoney( Money_Utility::amount_to_money( $order->refund->amount, $order->get_currency() ) );
|
197 |
|
198 |
-
$this->square_api_args =
|
199 |
$this->get_location_id(),
|
200 |
$order->refund->trans_id,
|
201 |
$this->square_request,
|
202 |
-
|
203 |
}
|
204 |
|
205 |
|
@@ -214,10 +214,10 @@ class Transactions extends \WooCommerce\Square\API\Request {
|
|
214 |
|
215 |
$this->square_api_method = 'voidTransaction';
|
216 |
|
217 |
-
$this->square_api_args =
|
218 |
$this->get_location_id(),
|
219 |
$order->refund->trans_id,
|
220 |
-
|
221 |
}
|
222 |
|
223 |
|
@@ -232,10 +232,10 @@ class Transactions extends \WooCommerce\Square\API\Request {
|
|
232 |
|
233 |
$this->square_api_method = 'retrieveTransaction';
|
234 |
|
235 |
-
$this->square_api_args =
|
236 |
$this->get_location_id(),
|
237 |
$transaction_id,
|
238 |
-
|
239 |
}
|
240 |
|
241 |
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Requests;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Api\TransactionsApi;
|
148 |
$this->square_request->setOrderId( $order->square_order_id );
|
149 |
}
|
150 |
|
151 |
+
$this->square_api_args = array(
|
152 |
$this->get_location_id(),
|
153 |
$this->square_request,
|
154 |
+
);
|
155 |
}
|
156 |
|
157 |
|
166 |
|
167 |
$this->square_api_method = 'captureTransaction';
|
168 |
|
169 |
+
$this->square_api_args = array(
|
170 |
$this->get_location_id(),
|
171 |
$order->capture->trans_id,
|
172 |
+
);
|
173 |
}
|
174 |
|
175 |
|
185 |
$this->square_api_method = 'createRefund';
|
186 |
|
187 |
// The refund objects are sorted by date DESC, so the last one created will be at the start of the array
|
188 |
+
$refunds = $order->get_refunds();
|
189 |
$refund_obj = $refunds[0];
|
190 |
|
191 |
$this->square_request = new CreateRefundRequest();
|
195 |
|
196 |
$this->square_request->setAmountMoney( Money_Utility::amount_to_money( $order->refund->amount, $order->get_currency() ) );
|
197 |
|
198 |
+
$this->square_api_args = array(
|
199 |
$this->get_location_id(),
|
200 |
$order->refund->trans_id,
|
201 |
$this->square_request,
|
202 |
+
);
|
203 |
}
|
204 |
|
205 |
|
214 |
|
215 |
$this->square_api_method = 'voidTransaction';
|
216 |
|
217 |
+
$this->square_api_args = array(
|
218 |
$this->get_location_id(),
|
219 |
$order->refund->trans_id,
|
220 |
+
);
|
221 |
}
|
222 |
|
223 |
|
232 |
|
233 |
$this->square_api_method = 'retrieveTransaction';
|
234 |
|
235 |
+
$this->square_api_args = array(
|
236 |
$this->get_location_id(),
|
237 |
$transaction_id,
|
238 |
+
);
|
239 |
}
|
240 |
|
241 |
|
includes/Gateway/API/Response.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Gateway;
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Gateway;
|
includes/Gateway/API/Responses/Charge.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Responses;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
@@ -153,19 +153,19 @@ class Charge extends \WooCommerce\Square\Gateway\API\Response implements Framewo
|
|
153 |
|
154 |
case 'CARD_DECLINED':
|
155 |
$message_id = 'card_declined';
|
156 |
-
|
157 |
|
158 |
case 'INVALID_EXPIRATION':
|
159 |
$message_id = 'card_expiry_invalid';
|
160 |
-
|
161 |
|
162 |
case 'VERIFY_AVS_FAILURE':
|
163 |
$message_id = 'avs_mismatch';
|
164 |
-
|
165 |
|
166 |
case 'VERIFY_CVV_FAILURE':
|
167 |
$message_id = 'csc_mismatch';
|
168 |
-
|
169 |
}
|
170 |
|
171 |
$helper = new Framework\SV_WC_Payment_Gateway_API_Response_Message_Helper();
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Responses;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
153 |
|
154 |
case 'CARD_DECLINED':
|
155 |
$message_id = 'card_declined';
|
156 |
+
break;
|
157 |
|
158 |
case 'INVALID_EXPIRATION':
|
159 |
$message_id = 'card_expiry_invalid';
|
160 |
+
break;
|
161 |
|
162 |
case 'VERIFY_AVS_FAILURE':
|
163 |
$message_id = 'avs_mismatch';
|
164 |
+
break;
|
165 |
|
166 |
case 'VERIFY_CVV_FAILURE':
|
167 |
$message_id = 'csc_mismatch';
|
168 |
+
break;
|
169 |
}
|
170 |
|
171 |
$helper = new Framework\SV_WC_Payment_Gateway_API_Response_Message_Helper();
|
includes/Gateway/API/Responses/Create_Customer.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Responses;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Responses;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
includes/Gateway/API/Responses/Create_Customer_Card.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Responses;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
@@ -46,7 +46,7 @@ class Create_Customer_Card extends \WooCommerce\Square\Gateway\API\Response impl
|
|
46 |
*/
|
47 |
public function get_payment_token() {
|
48 |
|
49 |
-
$card
|
50 |
$token = null;
|
51 |
|
52 |
if ( $card ) {
|
@@ -55,13 +55,13 @@ class Create_Customer_Card extends \WooCommerce\Square\Gateway\API\Response impl
|
|
55 |
|
56 |
$token = new Framework\SV_WC_Payment_Gateway_Payment_Token(
|
57 |
$card->getId(),
|
58 |
-
|
59 |
'type' => 'credit_card',
|
60 |
'card_type' => $card_type,
|
61 |
'last_four' => $card->getLast4(),
|
62 |
'exp_month' => $card->getExpMonth(),
|
63 |
'exp_year' => $card->getExpYear(),
|
64 |
-
|
65 |
);
|
66 |
}
|
67 |
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Responses;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
46 |
*/
|
47 |
public function get_payment_token() {
|
48 |
|
49 |
+
$card = $this->get_data() instanceof \SquareConnect\Model\CreateCustomerCardResponse ? $this->get_data()->getCard() : null;
|
50 |
$token = null;
|
51 |
|
52 |
if ( $card ) {
|
55 |
|
56 |
$token = new Framework\SV_WC_Payment_Gateway_Payment_Token(
|
57 |
$card->getId(),
|
58 |
+
array(
|
59 |
'type' => 'credit_card',
|
60 |
'card_type' => $card_type,
|
61 |
'last_four' => $card->getLast4(),
|
62 |
'exp_month' => $card->getExpMonth(),
|
63 |
'exp_year' => $card->getExpYear(),
|
64 |
+
)
|
65 |
);
|
66 |
}
|
67 |
|
includes/Gateway/API/Responses/Create_Payment.php
ADDED
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WooCommerce Square
|
4 |
+
*
|
5 |
+
* This source file is subject to the GNU General Public License v3.0
|
6 |
+
* that is bundled with this package in the file license.txt.
|
7 |
+
* It is also available through the world-wide-web at this URL:
|
8 |
+
* http://www.gnu.org/licenses/gpl-3.0.html
|
9 |
+
* If you did not receive a copy of the license and are unable to
|
10 |
+
* obtain it through the world-wide-web, please send an email
|
11 |
+
* to license@woocommerce.com so we can send you a copy immediately.
|
12 |
+
*
|
13 |
+
* DISCLAIMER
|
14 |
+
*
|
15 |
+
* Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
|
16 |
+
* versions in the future. If you wish to customize WooCommerce Square for your
|
17 |
+
* needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
|
18 |
+
*
|
19 |
+
* @author WooCommerce
|
20 |
+
* @copyright Copyright: (c) 2019, Automattic, Inc.
|
21 |
+
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
22 |
+
*/
|
23 |
+
|
24 |
+
namespace WooCommerce\Square\Gateway\API\Responses;
|
25 |
+
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
+
|
28 |
+
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* The Create Payment API response object.
|
32 |
+
*
|
33 |
+
* @since 2.2.0
|
34 |
+
*
|
35 |
+
* @method \SquareConnect\Model\CreatePaymentResponse get_data()
|
36 |
+
*/
|
37 |
+
class Create_Payment extends \WooCommerce\Square\Gateway\API\Response implements Framework\SV_WC_Payment_Gateway_API_Authorization_Response {
|
38 |
+
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Determines if the charge was held.
|
42 |
+
*
|
43 |
+
* @since 2.2.0
|
44 |
+
*
|
45 |
+
* @return bool
|
46 |
+
*/
|
47 |
+
public function transaction_held() {
|
48 |
+
|
49 |
+
$held = parent::transaction_held();
|
50 |
+
|
51 |
+
// ensure the tender is CAPTURED
|
52 |
+
if ( $this->get_payment() ) {
|
53 |
+
$held = 'AUTHORIZED' === $this->get_payment()->getCardDetails()->getStatus();
|
54 |
+
}
|
55 |
+
|
56 |
+
return $held;
|
57 |
+
}
|
58 |
+
|
59 |
+
|
60 |
+
/** Getter methods ************************************************************************************************/
|
61 |
+
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Gets the authorization code.
|
65 |
+
*
|
66 |
+
* @since 2.2.0
|
67 |
+
*
|
68 |
+
* @return string
|
69 |
+
*/
|
70 |
+
public function get_authorization_code() {
|
71 |
+
|
72 |
+
return $this->get_payment() ? $this->get_payment()->getId() : '';
|
73 |
+
}
|
74 |
+
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Gets the transaction (payment) ID.
|
78 |
+
*
|
79 |
+
* @since 2.2.0
|
80 |
+
*
|
81 |
+
* @return string
|
82 |
+
*/
|
83 |
+
public function get_transaction_id() {
|
84 |
+
|
85 |
+
return $this->get_payment() ? $this->get_payment()->getId() : '';
|
86 |
+
}
|
87 |
+
|
88 |
+
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Gets the location ID.
|
92 |
+
*
|
93 |
+
* @since 2.2.0
|
94 |
+
*
|
95 |
+
* @return string
|
96 |
+
*/
|
97 |
+
public function get_location_id() {
|
98 |
+
|
99 |
+
return $this->get_payment() ? $this->get_payment()->getLocationId() : '';
|
100 |
+
}
|
101 |
+
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Gets the Square order ID, if any.
|
105 |
+
*
|
106 |
+
* @since 2.2.0
|
107 |
+
*
|
108 |
+
* @return string
|
109 |
+
*/
|
110 |
+
public function get_square_order_id() {
|
111 |
+
|
112 |
+
return $this->get_payment() ? $this->get_payment()->getOrderId() : '';
|
113 |
+
}
|
114 |
+
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Gets the Square payment object.
|
118 |
+
*
|
119 |
+
* @since 2.2.0
|
120 |
+
*
|
121 |
+
* @return \SquareConnect\Model\Payment|null
|
122 |
+
*/
|
123 |
+
public function get_payment() {
|
124 |
+
|
125 |
+
return ! $this->has_errors() && $this->get_data()->getPayment() ? $this->get_data()->getPayment() : null;
|
126 |
+
}
|
127 |
+
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Gets the message to display to the user.
|
131 |
+
*
|
132 |
+
* @since 2.0.0
|
133 |
+
*
|
134 |
+
* @return string
|
135 |
+
*/
|
136 |
+
public function get_user_message() {
|
137 |
+
|
138 |
+
$message_id = '';
|
139 |
+
|
140 |
+
switch ( $this->get_status_code() ) {
|
141 |
+
case 'CARD_DECLINED':
|
142 |
+
$message_id = 'card_declined';
|
143 |
+
break;
|
144 |
+
|
145 |
+
case 'INVALID_EXPIRATION':
|
146 |
+
$message_id = 'card_expiry_invalid';
|
147 |
+
break;
|
148 |
+
|
149 |
+
case 'VERIFY_AVS_FAILURE':
|
150 |
+
$message_id = 'avs_mismatch';
|
151 |
+
break;
|
152 |
+
|
153 |
+
case 'VERIFY_CVV_FAILURE':
|
154 |
+
$message_id = 'csc_mismatch';
|
155 |
+
break;
|
156 |
+
}
|
157 |
+
|
158 |
+
$helper = new Framework\SV_WC_Payment_Gateway_API_Response_Message_Helper();
|
159 |
+
|
160 |
+
return $helper->get_user_message( $message_id );
|
161 |
+
}
|
162 |
+
|
163 |
+
|
164 |
+
/** No-op methods *************************************************************************************************/
|
165 |
+
|
166 |
+
|
167 |
+
public function get_avs_result() { }
|
168 |
+
|
169 |
+
public function get_csc_result() { }
|
170 |
+
|
171 |
+
public function csc_match() { }
|
172 |
+
|
173 |
+
|
174 |
+
}
|
includes/Gateway/API/Responses/Get_Customer.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Responses;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
@@ -46,8 +46,8 @@ class Get_Customer extends \WooCommerce\Square\Gateway\API\Response implements F
|
|
46 |
*/
|
47 |
public function get_payment_tokens() {
|
48 |
|
49 |
-
$cards = $this->get_data() instanceof \SquareConnect\Model\RetrieveCustomerResponse ? $this->get_data()->getCustomer()->getCards() :
|
50 |
-
$tokens =
|
51 |
|
52 |
if ( is_array( $cards ) ) {
|
53 |
|
@@ -58,13 +58,13 @@ class Get_Customer extends \WooCommerce\Square\Gateway\API\Response implements F
|
|
58 |
|
59 |
$tokens[ $token_id ] = new Framework\SV_WC_Payment_Gateway_Payment_Token(
|
60 |
$token_id,
|
61 |
-
|
62 |
'type' => 'credit_card',
|
63 |
'card_type' => $card_type,
|
64 |
'last_four' => $card->getLast4(),
|
65 |
'exp_month' => $card->getExpMonth(),
|
66 |
'exp_year' => $card->getExpYear(),
|
67 |
-
|
68 |
);
|
69 |
}
|
70 |
}
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Responses;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
46 |
*/
|
47 |
public function get_payment_tokens() {
|
48 |
|
49 |
+
$cards = $this->get_data() instanceof \SquareConnect\Model\RetrieveCustomerResponse ? $this->get_data()->getCustomer()->getCards() : array();
|
50 |
+
$tokens = array();
|
51 |
|
52 |
if ( is_array( $cards ) ) {
|
53 |
|
58 |
|
59 |
$tokens[ $token_id ] = new Framework\SV_WC_Payment_Gateway_Payment_Token(
|
60 |
$token_id,
|
61 |
+
array(
|
62 |
'type' => 'credit_card',
|
63 |
'card_type' => $card_type,
|
64 |
'last_four' => $card->getLast4(),
|
65 |
'exp_month' => $card->getExpMonth(),
|
66 |
'exp_year' => $card->getExpYear(),
|
67 |
+
)
|
68 |
);
|
69 |
}
|
70 |
}
|
includes/Gateway/API/Responses/Refund.php
CHANGED
@@ -23,14 +23,14 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Responses;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
/**
|
29 |
* The refund API response object.
|
30 |
*
|
31 |
* @since 2.0.0
|
32 |
*
|
33 |
-
* @method \SquareConnect\Model\CreateRefundResponse get_data()
|
34 |
*/
|
35 |
class Refund extends \WooCommerce\Square\Gateway\API\Response {
|
36 |
|
@@ -43,8 +43,7 @@ class Refund extends \WooCommerce\Square\Gateway\API\Response {
|
|
43 |
* @return bool
|
44 |
*/
|
45 |
public function transaction_approved() {
|
46 |
-
|
47 |
-
return parent::transaction_approved() && ( 'APPROVED' === $this->get_status_code() || 'PENDING' === $this->get_status_code() );
|
48 |
}
|
49 |
|
50 |
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway\API\Responses;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
/**
|
29 |
* The refund API response object.
|
30 |
*
|
31 |
* @since 2.0.0
|
32 |
*
|
33 |
+
* @method \SquareConnect\Model\CreateRefundResponse|GetPaymentRefundResponse get_data()
|
34 |
*/
|
35 |
class Refund extends \WooCommerce\Square\Gateway\API\Response {
|
36 |
|
43 |
* @return bool
|
44 |
*/
|
45 |
public function transaction_approved() {
|
46 |
+
return parent::transaction_approved() && ( in_array( $this->get_status_code(), array( 'APPROVED', 'COMPLETED', 'PENDING' ), true ) );
|
|
|
47 |
}
|
48 |
|
49 |
|
includes/Gateway/Card_Handler.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
@@ -69,5 +69,114 @@ class Card_Handler extends Framework\SV_WC_Payment_Gateway_Payment_Tokens_Handle
|
|
69 |
return 'NOT_FOUND' === $response->get_status_code();
|
70 |
}
|
71 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
|
73 |
}
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
69 |
return 'NOT_FOUND' === $response->get_status_code();
|
70 |
}
|
71 |
|
72 |
+
/**
|
73 |
+
* Gets the available payment tokens for a user as an associative array of
|
74 |
+
* payment token to SV_WC_Payment_Gateway_Payment_Token
|
75 |
+
*
|
76 |
+
* @since 2.2.0
|
77 |
+
* @param int $user_id WordPress user identifier, or 0 for guest
|
78 |
+
* @param array $args optional arguments, can include
|
79 |
+
* `customer_id` - if not provided, this will be looked up based on $user_id
|
80 |
+
* `environment_id` - defaults to plugin current environment
|
81 |
+
* @return array array of string token to SV_WC_Payment_Gateway_Payment_Token object
|
82 |
+
*/
|
83 |
+
public function get_tokens( $user_id, $args = array() ) {
|
84 |
+
// default to current environment
|
85 |
+
if ( ! isset( $args['environment_id'] ) ) {
|
86 |
+
$args['environment_id'] = $this->get_environment_id();
|
87 |
+
}
|
88 |
+
|
89 |
+
if ( ! isset( $args['customer_id'] ) ) {
|
90 |
+
$args['customer_id'] = $this->get_gateway()->get_customer_id( $user_id, array( 'environment_id' => $args['environment_id'] ) );
|
91 |
+
}
|
92 |
+
|
93 |
+
$environment_id = $args['environment_id'];
|
94 |
+
$customer_id = $args['customer_id'];
|
95 |
+
$transient_key = $this->get_transient_key( $user_id );
|
96 |
+
|
97 |
+
// return tokens cached during a single request
|
98 |
+
if ( isset( $this->tokens[ $environment_id ][ $user_id ] ) ) {
|
99 |
+
return $this->tokens[ $environment_id ][ $user_id ];
|
100 |
+
}
|
101 |
+
|
102 |
+
// return tokens cached in transient
|
103 |
+
if ( $transient_key ) {
|
104 |
+
$this->tokens[ $environment_id ][ $user_id ] = get_transient( $transient_key );
|
105 |
+
|
106 |
+
if ( false !== $this->tokens[ $environment_id ][ $user_id ] ) {
|
107 |
+
return $this->tokens[ $environment_id ][ $user_id ];
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
$this->tokens[ $environment_id ][ $user_id ] = array();
|
112 |
+
$tokens = array();
|
113 |
+
|
114 |
+
// retrieve the datastore persisted tokens first, so we have them for
|
115 |
+
// gateways that don't support fetching them over an API, as well as the
|
116 |
+
// default token for those that do
|
117 |
+
if ( $user_id ) {
|
118 |
+
$_tokens = get_user_meta( $user_id, $this->get_user_meta_name( $environment_id ), true );
|
119 |
+
|
120 |
+
// from database format
|
121 |
+
if ( is_array( $_tokens ) ) {
|
122 |
+
foreach ( $_tokens as $token => $data ) {
|
123 |
+
$tokens[ $token ] = $this->build_token( $token, $data );
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
$this->tokens[ $environment_id ][ $user_id ] = $tokens;
|
128 |
+
}
|
129 |
+
|
130 |
+
if ( $customer_id ) {
|
131 |
+
try {
|
132 |
+
// retrieve the payment method tokes from the remote API
|
133 |
+
$response = $this->get_gateway()->get_api()->get_tokenized_payment_methods( $customer_id );
|
134 |
+
|
135 |
+
// Only update local tokens when the response has no errors or the customer is not found in Square
|
136 |
+
if ( ! $response->has_errors() || 'NOT_FOUND' === $response->get_status_code() ) {
|
137 |
+
$this->tokens[ $environment_id ][ $user_id ] = $response->get_payment_tokens();
|
138 |
+
|
139 |
+
// check for a default from the persisted set, if any
|
140 |
+
$default_token = null;
|
141 |
+
foreach ( $tokens as $default_token ) {
|
142 |
+
if ( $default_token->is_default() ) {
|
143 |
+
break;
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
// mark the corresponding token from the API as the default one
|
148 |
+
if ( $default_token && $default_token->is_default() && isset( $this->tokens[ $environment_id ][ $user_id ][ $default_token->get_id() ] ) ) {
|
149 |
+
$this->tokens[ $environment_id ][ $user_id ][ $default_token->get_id() ]->set_default( true );
|
150 |
+
}
|
151 |
+
|
152 |
+
// merge local token data with remote data, sometimes local data is more robust
|
153 |
+
$this->tokens[ $environment_id ][ $user_id ] = $this->merge_token_data( $tokens, $this->tokens[ $environment_id ][ $user_id ] );
|
154 |
+
|
155 |
+
// persist locally after merging
|
156 |
+
$this->update_tokens( $user_id, $this->tokens[ $environment_id ][ $user_id ], $environment_id );
|
157 |
+
}
|
158 |
+
} catch ( Framework\SV_WC_Plugin_Exception $e ) {
|
159 |
+
|
160 |
+
// communication or other error
|
161 |
+
$this->get_gateway()->add_debug_message( $e->getMessage(), 'error' );
|
162 |
+
|
163 |
+
$this->tokens[ $environment_id ][ $user_id ] = $tokens;
|
164 |
+
}
|
165 |
+
}
|
166 |
+
|
167 |
+
// set the payment type image url, if any, for convenience
|
168 |
+
foreach ( $this->tokens[ $environment_id ][ $user_id ] as $key => $token ) {
|
169 |
+
$this->tokens[ $environment_id ][ $user_id ][ $key ]->set_image_url( $this->get_gateway()->get_payment_method_image_url( $token->is_credit_card() ? $token->get_card_type() : 'echeck' ) );
|
170 |
+
}
|
171 |
+
|
172 |
+
if ( $transient_key ) {
|
173 |
+
set_transient( $transient_key, $this->tokens[ $environment_id ][ $user_id ], HOUR_IN_SECONDS );
|
174 |
+
}
|
175 |
+
|
176 |
+
do_action( 'wc_payment_gateway_square_credit_card_payment_tokens_loaded', $this->tokens[ $environment_id ][ $user_id ], $this );
|
177 |
+
|
178 |
+
return $this->tokens[ $environment_id ][ $user_id ];
|
179 |
+
}
|
180 |
+
|
181 |
|
182 |
}
|
includes/Gateway/Customer_Helper.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
@@ -40,8 +40,8 @@ class Customer_Helper {
|
|
40 |
public static function add_customers( array $customers ) {
|
41 |
global $wpdb;
|
42 |
|
43 |
-
$placeholders =
|
44 |
-
$values =
|
45 |
|
46 |
$query = "INSERT INTO {$wpdb->prefix}woocommerce_square_customers (square_id, email_address) VALUES ";
|
47 |
|
@@ -81,10 +81,10 @@ class Customer_Helper {
|
|
81 |
|
82 |
if ( is_email( $email_address ) ) {
|
83 |
|
84 |
-
$params =
|
85 |
'square_id' => wc_clean( $square_id ),
|
86 |
'email_address' => wc_clean( $email_address ),
|
87 |
-
|
88 |
|
89 |
if ( $user_id && is_numeric( $user_id ) ) {
|
90 |
$params['user_id'] = (int) $user_id;
|
@@ -111,10 +111,12 @@ class Customer_Helper {
|
|
111 |
|
112 |
if ( is_email( $email_address ) ) {
|
113 |
|
114 |
-
$square_id = $wpdb->get_var(
|
115 |
-
|
116 |
-
|
117 |
-
|
|
|
|
|
118 |
}
|
119 |
|
120 |
return $square_id;
|
@@ -124,14 +126,16 @@ class Customer_Helper {
|
|
124 |
public static function get_customers_by_email( $email_address ) {
|
125 |
global $wpdb;
|
126 |
|
127 |
-
$square_ids =
|
128 |
|
129 |
if ( is_email( $email_address ) ) {
|
130 |
|
131 |
-
$square_ids = $wpdb->get_col(
|
132 |
-
|
133 |
-
|
134 |
-
|
|
|
|
|
135 |
}
|
136 |
|
137 |
return $square_ids;
|
@@ -149,10 +153,12 @@ class Customer_Helper {
|
|
149 |
public static function is_customer_indexed( $square_id ) {
|
150 |
global $wpdb;
|
151 |
|
152 |
-
$result = $wpdb->get_var(
|
153 |
-
|
154 |
-
|
155 |
-
|
|
|
|
|
156 |
|
157 |
return (bool) $result;
|
158 |
}
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
40 |
public static function add_customers( array $customers ) {
|
41 |
global $wpdb;
|
42 |
|
43 |
+
$placeholders = array();
|
44 |
+
$values = array();
|
45 |
|
46 |
$query = "INSERT INTO {$wpdb->prefix}woocommerce_square_customers (square_id, email_address) VALUES ";
|
47 |
|
81 |
|
82 |
if ( is_email( $email_address ) ) {
|
83 |
|
84 |
+
$params = array(
|
85 |
'square_id' => wc_clean( $square_id ),
|
86 |
'email_address' => wc_clean( $email_address ),
|
87 |
+
);
|
88 |
|
89 |
if ( $user_id && is_numeric( $user_id ) ) {
|
90 |
$params['user_id'] = (int) $user_id;
|
111 |
|
112 |
if ( is_email( $email_address ) ) {
|
113 |
|
114 |
+
$square_id = $wpdb->get_var(
|
115 |
+
$wpdb->prepare(
|
116 |
+
"SELECT square_id FROM {$wpdb->prefix}woocommerce_square_customers WHERE email_address = %s",
|
117 |
+
$email_address
|
118 |
+
)
|
119 |
+
);
|
120 |
}
|
121 |
|
122 |
return $square_id;
|
126 |
public static function get_customers_by_email( $email_address ) {
|
127 |
global $wpdb;
|
128 |
|
129 |
+
$square_ids = array();
|
130 |
|
131 |
if ( is_email( $email_address ) ) {
|
132 |
|
133 |
+
$square_ids = $wpdb->get_col(
|
134 |
+
$wpdb->prepare(
|
135 |
+
"SELECT square_id FROM {$wpdb->prefix}woocommerce_square_customers WHERE email_address = %s",
|
136 |
+
$email_address
|
137 |
+
)
|
138 |
+
);
|
139 |
}
|
140 |
|
141 |
return $square_ids;
|
153 |
public static function is_customer_indexed( $square_id ) {
|
154 |
global $wpdb;
|
155 |
|
156 |
+
$result = $wpdb->get_var(
|
157 |
+
$wpdb->prepare(
|
158 |
+
"SELECT * FROM {$wpdb->prefix}woocommerce_square_customers WHERE square_id = %s",
|
159 |
+
$square_id
|
160 |
+
)
|
161 |
+
);
|
162 |
|
163 |
return (bool) $result;
|
164 |
}
|
includes/Gateway/Payment_Form.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
@@ -45,7 +45,7 @@ class Payment_Form extends Framework\SV_WC_Payment_Gateway_Payment_Form {
|
|
45 |
*/
|
46 |
public function render_supplementary_billing_info() {
|
47 |
|
48 |
-
$billing_data =
|
49 |
$billing_data_source = null;
|
50 |
|
51 |
if ( is_checkout_pay_page() ) {
|
@@ -53,7 +53,6 @@ class Payment_Form extends Framework\SV_WC_Payment_Gateway_Payment_Form {
|
|
53 |
if ( $order = wc_get_order( $this->get_gateway()->get_checkout_pay_page_order_id() ) ) {
|
54 |
$billing_data_source = $order;
|
55 |
}
|
56 |
-
|
57 |
} elseif ( WC()->customer && ! is_checkout() ) {
|
58 |
|
59 |
$billing_data_source = WC()->customer;
|
@@ -61,27 +60,30 @@ class Payment_Form extends Framework\SV_WC_Payment_Gateway_Payment_Form {
|
|
61 |
|
62 |
if ( $billing_data_source ) {
|
63 |
|
64 |
-
$billing_data =
|
65 |
|
66 |
// 3d secure requires the full billing info
|
67 |
if ( $this->get_gateway()->is_3d_secure_enabled() ) {
|
68 |
|
69 |
-
$billing_data = array_merge(
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
|
|
|
|
|
|
80 |
}
|
81 |
}
|
82 |
|
83 |
foreach ( $billing_data as $key => $value ) {
|
84 |
-
echo '<input type="hidden" id="'. esc_attr( $key ) . '" value="' . esc_attr( $value ) . '" />';
|
85 |
}
|
86 |
|
87 |
if ( is_checkout_pay_page() ) {
|
@@ -110,14 +112,14 @@ class Payment_Form extends Framework\SV_WC_Payment_Gateway_Payment_Form {
|
|
110 |
|
111 |
parent::render_payment_fields();
|
112 |
|
113 |
-
$fields =
|
114 |
'card-type',
|
115 |
'last-four',
|
116 |
'exp-month',
|
117 |
'exp-year',
|
118 |
'payment-nonce',
|
119 |
'payment-postcode',
|
120 |
-
|
121 |
|
122 |
if ( $this->get_gateway()->is_3d_secure_enabled() ) {
|
123 |
$fields[] = 'buyer-verification-token';
|
@@ -145,23 +147,23 @@ class Payment_Form extends Framework\SV_WC_Payment_Gateway_Payment_Form {
|
|
145 |
$fields = parent::get_credit_card_fields();
|
146 |
|
147 |
// Square JS requires a postal code field for the form, but this is pre-filled and hidden
|
148 |
-
$fields['card-postal-code'] =
|
149 |
'id' => 'wc-' . $this->get_gateway()->get_id_dasherized() . '-postal-code',
|
150 |
'label' => __( 'Postal code', 'woocommerce-square' ),
|
151 |
-
'class' =>
|
152 |
'required' => true,
|
153 |
-
'input_class' =>
|
154 |
-
|
155 |
|
156 |
-
foreach (
|
157 |
|
158 |
if ( isset( $fields[ $field_key ] ) ) {
|
159 |
|
160 |
// parent div classes - contains both the label and hosted field container div
|
161 |
-
$fields[ $field_key ]['class'] = array_merge( $fields[ $field_key ]['class'],
|
162 |
|
163 |
// hosted field container classes - contains the iframe element
|
164 |
-
$fields[ $field_key ]['input_class'] = array_merge( $fields[ $field_key ]['input_class'],
|
165 |
}
|
166 |
}
|
167 |
|
@@ -180,7 +182,12 @@ class Payment_Form extends Framework\SV_WC_Payment_Gateway_Payment_Form {
|
|
180 |
|
181 |
?>
|
182 |
<div class="form-row <?php echo implode( ' ', array_map( 'sanitize_html_class', $field['class'] ) ); ?>">
|
183 |
-
<label for="<?php echo esc_attr( $field['id'] ) . '-hosted'; ?>"
|
|
|
|
|
|
|
|
|
|
|
184 |
<div id="<?php echo esc_attr( $field['id'] ) . '-hosted'; ?>" class="<?php echo implode( ' ', array_map( 'sanitize_html_class', $field['input_class'] ) ); ?>" data-placeholder="<?php echo isset( $field['placeholder'] ) ? esc_attr( $field['placeholder'] ) : ''; ?>"></div>
|
185 |
</div>
|
186 |
<?php
|
@@ -194,7 +201,7 @@ class Payment_Form extends Framework\SV_WC_Payment_Gateway_Payment_Form {
|
|
194 |
*/
|
195 |
public function render_js() {
|
196 |
|
197 |
-
$args =
|
198 |
'application_id' => $this->get_gateway()->get_application_id(),
|
199 |
'ajax_log_nonce' => wp_create_nonce( 'wc_' . $this->get_gateway()->get_id() . '_log_js_data' ),
|
200 |
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
@@ -209,30 +216,32 @@ class Payment_Form extends Framework\SV_WC_Payment_Gateway_Payment_Form {
|
|
209 |
'is_add_payment_method_page' => is_add_payment_method_page(),
|
210 |
'location_id' => wc_square()->get_settings_handler()->get_location_id(),
|
211 |
'logging_enabled' => $this->get_gateway()->debug_log(),
|
212 |
-
|
|
|
|
|
213 |
|
214 |
// map the unique square card type string to our framework standards
|
215 |
-
$square_card_types =
|
216 |
Framework\SV_WC_Payment_Gateway_Helper::CARD_TYPE_MASTERCARD => 'masterCard',
|
217 |
Framework\SV_WC_Payment_Gateway_Helper::CARD_TYPE_AMEX => 'americanExpress',
|
218 |
Framework\SV_WC_Payment_Gateway_Helper::CARD_TYPE_DINERSCLUB => 'discoverDiners',
|
219 |
Framework\SV_WC_Payment_Gateway_Helper::CARD_TYPE_JCB => 'JCB',
|
220 |
-
|
221 |
|
222 |
-
$card_types = is_array( $this->get_gateway()->get_card_types() ) ? $this->get_gateway()->get_card_types() :
|
223 |
|
224 |
-
$framework_card_types = array_map(
|
225 |
$square_card_types = array_merge( array_combine( $framework_card_types, $framework_card_types ), $square_card_types );
|
226 |
|
227 |
$args['enabled_card_types'] = $framework_card_types;
|
228 |
$args['square_card_types'] = array_flip( $square_card_types );
|
229 |
|
230 |
-
$input_styles =
|
231 |
-
|
232 |
'backgroundColor' => 'transparent',
|
233 |
'fontSize' => '1.3em',
|
234 |
-
|
235 |
-
|
236 |
|
237 |
/**
|
238 |
* Filters the the Square payment form input styles.
|
23 |
|
24 |
namespace WooCommerce\Square\Gateway;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
45 |
*/
|
46 |
public function render_supplementary_billing_info() {
|
47 |
|
48 |
+
$billing_data = array();
|
49 |
$billing_data_source = null;
|
50 |
|
51 |
if ( is_checkout_pay_page() ) {
|
53 |
if ( $order = wc_get_order( $this->get_gateway()->get_checkout_pay_page_order_id() ) ) {
|
54 |
$billing_data_source = $order;
|
55 |
}
|
|
|
56 |
} elseif ( WC()->customer && ! is_checkout() ) {
|
57 |
|
58 |
$billing_data_source = WC()->customer;
|
60 |
|
61 |
if ( $billing_data_source ) {
|
62 |
|
63 |
+
$billing_data = array( 'billing_postcode' => $billing_data_source->get_billing_postcode() );
|
64 |
|
65 |
// 3d secure requires the full billing info
|
66 |
if ( $this->get_gateway()->is_3d_secure_enabled() ) {
|
67 |
|
68 |
+
$billing_data = array_merge(
|
69 |
+
$billing_data,
|
70 |
+
array(
|
71 |
+
'billing_first_name' => $billing_data_source->get_billing_first_name(),
|
72 |
+
'billing_last_name' => $billing_data_source->get_billing_last_name(),
|
73 |
+
'billing_email' => $billing_data_source->get_billing_email(),
|
74 |
+
'billing_country' => $billing_data_source->get_billing_country(),
|
75 |
+
'billing_address_1' => $billing_data_source->get_billing_address_1(),
|
76 |
+
'billing_address_2' => $billing_data_source->get_billing_address_2(),
|
77 |
+
'billing_state' => $billing_data_source->get_billing_state(),
|
78 |
+
'billing_city' => $billing_data_source->get_billing_city(),
|
79 |
+
'billing_phone' => $billing_data_source->get_billing_phone(),
|
80 |
+
)
|
81 |
+
);
|
82 |
}
|
83 |
}
|
84 |
|
85 |
foreach ( $billing_data as $key => $value ) {
|
86 |
+
echo '<input type="hidden" id="' . esc_attr( $key ) . '" value="' . esc_attr( $value ) . '" />';
|
87 |
}
|
88 |
|
89 |
if ( is_checkout_pay_page() ) {
|
112 |
|
113 |
parent::render_payment_fields();
|
114 |
|
115 |
+
$fields = array(
|
116 |
'card-type',
|
117 |
'last-four',
|
118 |
'exp-month',
|
119 |
'exp-year',
|
120 |
'payment-nonce',
|
121 |
'payment-postcode',
|
122 |
+
);
|
123 |
|
124 |
if ( $this->get_gateway()->is_3d_secure_enabled() ) {
|
125 |
$fields[] = 'buyer-verification-token';
|
147 |
$fields = parent::get_credit_card_fields();
|
148 |
|
149 |
// Square JS requires a postal code field for the form, but this is pre-filled and hidden
|
150 |
+
$fields['card-postal-code'] = array(
|
151 |
'id' => 'wc-' . $this->get_gateway()->get_id_dasherized() . '-postal-code',
|
152 |
'label' => __( 'Postal code', 'woocommerce-square' ),
|
153 |
+
'class' => array( 'form-row-wide' ),
|
154 |
'required' => true,
|
155 |
+
'input_class' => array( 'js-sv-wc-payment-gateway-credit-card-form-input', 'js-sv-wc-payment-gateway-credit-card-form-postal-code' ),
|
156 |
+
);
|
157 |
|
158 |
+
foreach ( array( 'card-number', 'card-expiry', 'card-csc', 'card-postal-code' ) as $field_key ) {
|
159 |
|
160 |
if ( isset( $fields[ $field_key ] ) ) {
|
161 |
|
162 |
// parent div classes - contains both the label and hosted field container div
|
163 |
+
$fields[ $field_key ]['class'] = array_merge( $fields[ $field_key ]['class'], array( "wc-{$this->get_gateway()->get_id_dasherized()}-{$field_key}-parent", "wc-{$this->get_gateway()->get_id_dasherized()}-hosted-field-parent" ) );
|
164 |
|
165 |
// hosted field container classes - contains the iframe element
|
166 |
+
$fields[ $field_key ]['input_class'] = array_merge( $fields[ $field_key ]['input_class'], array( "wc-{$this->get_gateway()->get_id_dasherized()}-hosted-field-{$field_key}", "wc-{$this->get_gateway()->get_id_dasherized()}-hosted-field" ) );
|
167 |
}
|
168 |
}
|
169 |
|
182 |
|
183 |
?>
|
184 |
<div class="form-row <?php echo implode( ' ', array_map( 'sanitize_html_class', $field['class'] ) ); ?>">
|
185 |
+
<label for="<?php echo esc_attr( $field['id'] ) . '-hosted'; ?>">
|
186 |
+
<?php
|
187 |
+
echo esc_html( $field['label'] );
|
188 |
+
if ( $field['required'] ) :
|
189 |
+
?>
|
190 |
+
<abbr class="required" title="required"> *</abbr> <?php endif; ?></label>
|
191 |
<div id="<?php echo esc_attr( $field['id'] ) . '-hosted'; ?>" class="<?php echo implode( ' ', array_map( 'sanitize_html_class', $field['input_class'] ) ); ?>" data-placeholder="<?php echo isset( $field['placeholder'] ) ? esc_attr( $field['placeholder'] ) : ''; ?>"></div>
|
192 |
</div>
|
193 |
<?php
|
201 |
*/
|
202 |
public function render_js() {
|
203 |
|
204 |
+
$args = array(
|
205 |
'application_id' => $this->get_gateway()->get_application_id(),
|
206 |
'ajax_log_nonce' => wp_create_nonce( 'wc_' . $this->get_gateway()->get_id() . '_log_js_data' ),
|
207 |
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
216 |
'is_add_payment_method_page' => is_add_payment_method_page(),
|
217 |
'location_id' => wc_square()->get_settings_handler()->get_location_id(),
|
218 |
'logging_enabled' => $this->get_gateway()->debug_log(),
|
219 |
+
'ajax_wc_checkout_validate_nonce' => wp_create_nonce( 'wc_' . $this->get_gateway()->get_id() . '_checkout_validate' ),
|
220 |
+
'is_manual_order_payment' => is_checkout() && is_wc_endpoint_url( 'order-pay' ),
|
221 |
+
);
|
222 |
|
223 |
// map the unique square card type string to our framework standards
|
224 |
+
$square_card_types = array(
|
225 |
Framework\SV_WC_Payment_Gateway_Helper::CARD_TYPE_MASTERCARD => 'masterCard',
|
226 |
Framework\SV_WC_Payment_Gateway_Helper::CARD_TYPE_AMEX => 'americanExpress',
|
227 |
Framework\SV_WC_Payment_Gateway_Helper::CARD_TYPE_DINERSCLUB => 'discoverDiners',
|
228 |
Framework\SV_WC_Payment_Gateway_Helper::CARD_TYPE_JCB => 'JCB',
|
229 |
+
);
|
230 |
|
231 |
+
$card_types = is_array( $this->get_gateway()->get_card_types() ) ? $this->get_gateway()->get_card_types() : array();
|
232 |
|
233 |
+
$framework_card_types = array_map( array( Framework\SV_WC_Payment_Gateway_Helper::class, 'normalize_card_type' ), $card_types );
|
234 |
$square_card_types = array_merge( array_combine( $framework_card_types, $framework_card_types ), $square_card_types );
|
235 |
|
236 |
$args['enabled_card_types'] = $framework_card_types;
|
237 |
$args['square_card_types'] = array_flip( $square_card_types );
|
238 |
|
239 |
+
$input_styles = array(
|
240 |
+
array(
|
241 |
'backgroundColor' => 'transparent',
|
242 |
'fontSize' => '1.3em',
|
243 |
+
),
|
244 |
+
);
|
245 |
|
246 |
/**
|
247 |
* Filters the the Square payment form input styles.
|
includes/Handlers/Background_Job.php
CHANGED
@@ -30,7 +30,7 @@ use WooCommerce\Square\Sync\Manual_Synchronization;
|
|
30 |
use WooCommerce\Square\Sync\Product_Import;
|
31 |
use WooCommerce\Square\Sync\Records;
|
32 |
|
33 |
-
defined( 'ABSPATH' )
|
34 |
|
35 |
/**
|
36 |
* Product and Inventory Synchronization handler class.
|
@@ -62,16 +62,19 @@ class Background_Job extends Framework\SV_WP_Background_Job_Handler {
|
|
62 |
|
63 |
$this->maybe_increase_time_limit();
|
64 |
|
65 |
-
add_action( "{$this->identifier}_job_complete",
|
66 |
-
add_action( "{$this->identifier}_job_failed",
|
67 |
-
add_filter( "{$this->identifier}_default_time_limit",
|
68 |
|
69 |
// ensures the queue lock time never expires before our timeout does
|
70 |
-
add_filter(
|
|
|
|
|
71 |
|
72 |
-
|
73 |
|
74 |
-
|
|
|
75 |
}
|
76 |
|
77 |
|
@@ -87,17 +90,23 @@ class Background_Job extends Framework\SV_WP_Background_Job_Handler {
|
|
87 |
|
88 |
$sor = wc_square()->get_settings_handler()->get_system_of_record();
|
89 |
|
90 |
-
return parent::create_job(
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
}
|
102 |
|
103 |
|
@@ -169,7 +178,7 @@ class Background_Job extends Framework\SV_WP_Background_Job_Handler {
|
|
169 |
|
170 |
if ( $job instanceof Job ) {
|
171 |
$current_user_id = get_current_user_id();
|
172 |
-
$job
|
173 |
wp_set_current_user( $current_user_id );
|
174 |
}
|
175 |
|
@@ -203,10 +212,12 @@ class Background_Job extends Framework\SV_WP_Background_Job_Handler {
|
|
203 |
*/
|
204 |
public function job_failed( $job ) {
|
205 |
|
206 |
-
Records::set_record(
|
207 |
-
|
208 |
-
|
209 |
-
|
|
|
|
|
210 |
|
211 |
wc_square()->get_email_handler()->get_sync_completed_email()->trigger( $job );
|
212 |
}
|
@@ -336,7 +347,7 @@ class Background_Job extends Framework\SV_WP_Background_Job_Handler {
|
|
336 |
'name' => __( 'Clear Square Sync', 'woocommerce-square' ),
|
337 |
'button' => __( 'Clear', 'woocommerce-square' ),
|
338 |
'desc' => __( 'This tool will clear any ongoing Square product syncs.', 'woocommerce-square' ),
|
339 |
-
'callback' =>
|
340 |
);
|
341 |
|
342 |
return $tools;
|
30 |
use WooCommerce\Square\Sync\Product_Import;
|
31 |
use WooCommerce\Square\Sync\Records;
|
32 |
|
33 |
+
defined( 'ABSPATH' ) || exit;
|
34 |
|
35 |
/**
|
36 |
* Product and Inventory Synchronization handler class.
|
62 |
|
63 |
$this->maybe_increase_time_limit();
|
64 |
|
65 |
+
add_action( "{$this->identifier}_job_complete", array( $this, 'job_complete' ) );
|
66 |
+
add_action( "{$this->identifier}_job_failed", array( $this, 'job_failed' ) );
|
67 |
+
add_filter( "{$this->identifier}_default_time_limit", array( $this, 'set_default_time_limit' ) );
|
68 |
|
69 |
// ensures the queue lock time never expires before our timeout does
|
70 |
+
add_filter(
|
71 |
+
"{$this->identifier}_queue_lock_time",
|
72 |
+
function( $lock_time ) {
|
73 |
|
74 |
+
return $this->set_default_time_limit( $lock_time ) + 10;
|
75 |
|
76 |
+
}
|
77 |
+
);
|
78 |
}
|
79 |
|
80 |
|
90 |
|
91 |
$sor = wc_square()->get_settings_handler()->get_system_of_record();
|
92 |
|
93 |
+
return parent::create_job(
|
94 |
+
wp_parse_args(
|
95 |
+
$attrs,
|
96 |
+
array(
|
97 |
+
'action' => '', // job action
|
98 |
+
'catalog_processed' => false, // whether the Square catalog has been processed
|
99 |
+
'cursor' => '', // job advancement position
|
100 |
+
'manual' => false, // whether it's a sync job triggered manually
|
101 |
+
'percentage' => 0, // percentage completed
|
102 |
+
'product_ids' => array(), // products to process
|
103 |
+
'processed_product_ids' => array(), // newly imported products processed
|
104 |
+
'updated_product_ids' => array(), // updated products processed
|
105 |
+
'skipped_products' => array(), // remote product IDs that were skipped
|
106 |
+
'system_of_record' => $sor, // system of record used
|
107 |
+
)
|
108 |
+
)
|
109 |
+
);
|
110 |
}
|
111 |
|
112 |
|
178 |
|
179 |
if ( $job instanceof Job ) {
|
180 |
$current_user_id = get_current_user_id();
|
181 |
+
$job = $job->run();
|
182 |
wp_set_current_user( $current_user_id );
|
183 |
}
|
184 |
|
212 |
*/
|
213 |
public function job_failed( $job ) {
|
214 |
|
215 |
+
Records::set_record(
|
216 |
+
array(
|
217 |
+
'type' => 'alert',
|
218 |
+
'message' => 'Sync failed. Please try again',
|
219 |
+
)
|
220 |
+
);
|
221 |
|
222 |
wc_square()->get_email_handler()->get_sync_completed_email()->trigger( $job );
|
223 |
}
|
347 |
'name' => __( 'Clear Square Sync', 'woocommerce-square' ),
|
348 |
'button' => __( 'Clear', 'woocommerce-square' ),
|
349 |
'desc' => __( 'This tool will clear any ongoing Square product syncs.', 'woocommerce-square' ),
|
350 |
+
'callback' => array( $this, 'run_clear_background_jobs' ),
|
351 |
);
|
352 |
|
353 |
return $tools;
|
includes/Handlers/Category.php
CHANGED
@@ -25,7 +25,7 @@ namespace WooCommerce\Square\Handlers;
|
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
-
defined( 'ABSPATH' )
|
29 |
|
30 |
/**
|
31 |
* Category handler class.
|
@@ -51,7 +51,7 @@ class Category {
|
|
51 |
*/
|
52 |
public static function get_map() {
|
53 |
|
54 |
-
return get_option( self::CATEGORY_MAP_META_KEY,
|
55 |
}
|
56 |
|
57 |
|
@@ -86,7 +86,7 @@ class Category {
|
|
86 |
return $map[ $category_id ];
|
87 |
}
|
88 |
|
89 |
-
return
|
90 |
}
|
91 |
|
92 |
|
@@ -137,10 +137,10 @@ class Category {
|
|
137 |
|
138 |
$map = self::get_map();
|
139 |
|
140 |
-
$map[ $category_id ] =
|
141 |
'square_id' => $square_id,
|
142 |
'square_version' => $square_version,
|
143 |
-
|
144 |
|
145 |
self::update_map( $map );
|
146 |
|
@@ -182,9 +182,8 @@ class Category {
|
|
182 |
$category_id = isset( $inserted_term['term_id'] ) ? $inserted_term['term_id'] : null;
|
183 |
}
|
184 |
|
185 |
-
|
186 |
if ( $category_id ) {
|
187 |
-
wp_update_term( $category_id, 'product_cat',
|
188 |
self::update_square_meta( $category_id, $id, $version );
|
189 |
}
|
190 |
|
@@ -219,14 +218,18 @@ class Category {
|
|
219 |
public static function get_category_id_by_square_id( $square_id ) {
|
220 |
global $wpdb;
|
221 |
|
222 |
-
$query = $wpdb->prepare(
|
|
|
223 |
SELECT t.term_id FROM {$wpdb->prefix}terms AS t
|
224 |
LEFT JOIN {$wpdb->prefix}term_taxonomy AS tt ON t.term_id = tt.term_id
|
225 |
LEFT JOIN {$wpdb->prefix}termmeta AS tm ON t.term_id = tm.term_id
|
226 |
WHERE tt.taxonomy = 'product_cat'
|
227 |
AND tm.meta_key = '%s'
|
228 |
AND tm.meta_value = '%s'
|
229 |
-
|
|
|
|
|
|
|
230 |
|
231 |
return $wpdb->get_var( $query );
|
232 |
}
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
+
defined( 'ABSPATH' ) || exit;
|
29 |
|
30 |
/**
|
31 |
* Category handler class.
|
51 |
*/
|
52 |
public static function get_map() {
|
53 |
|
54 |
+
return get_option( self::CATEGORY_MAP_META_KEY, array() );
|
55 |
}
|
56 |
|
57 |
|
86 |
return $map[ $category_id ];
|
87 |
}
|
88 |
|
89 |
+
return array();
|
90 |
}
|
91 |
|
92 |
|
137 |
|
138 |
$map = self::get_map();
|
139 |
|
140 |
+
$map[ $category_id ] = array(
|
141 |
'square_id' => $square_id,
|
142 |
'square_version' => $square_version,
|
143 |
+
);
|
144 |
|
145 |
self::update_map( $map );
|
146 |
|
182 |
$category_id = isset( $inserted_term['term_id'] ) ? $inserted_term['term_id'] : null;
|
183 |
}
|
184 |
|
|
|
185 |
if ( $category_id ) {
|
186 |
+
wp_update_term( $category_id, 'product_cat', array( 'name' => $name ) );
|
187 |
self::update_square_meta( $category_id, $id, $version );
|
188 |
}
|
189 |
|
218 |
public static function get_category_id_by_square_id( $square_id ) {
|
219 |
global $wpdb;
|
220 |
|
221 |
+
$query = $wpdb->prepare(
|
222 |
+
"
|
223 |
SELECT t.term_id FROM {$wpdb->prefix}terms AS t
|
224 |
LEFT JOIN {$wpdb->prefix}term_taxonomy AS tt ON t.term_id = tt.term_id
|
225 |
LEFT JOIN {$wpdb->prefix}termmeta AS tm ON t.term_id = tm.term_id
|
226 |
WHERE tt.taxonomy = 'product_cat'
|
227 |
AND tm.meta_key = '%s'
|
228 |
AND tm.meta_value = '%s'
|
229 |
+
",
|
230 |
+
self::SQUARE_ID_META_KEY,
|
231 |
+
$square_id
|
232 |
+
);
|
233 |
|
234 |
return $wpdb->get_var( $query );
|
235 |
}
|
includes/Handlers/Connection.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Handlers;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Model\ListCustomersResponse;
|
@@ -75,15 +75,15 @@ class Connection {
|
|
75 |
*/
|
76 |
protected function add_hooks() {
|
77 |
|
78 |
-
add_action( 'admin_action_wc_' . $this->get_plugin()->get_id() . '_connected',
|
79 |
|
80 |
-
add_action( 'admin_action_wc_' . $this->get_plugin()->get_id() . '_disconnect',
|
81 |
|
82 |
// refresh the connection, triggered by Action Scheduler
|
83 |
-
add_action( 'wc_' . $this->get_plugin()->get_id() . '_refresh_connection',
|
84 |
|
85 |
// index customers, triggered by Action Scheduler
|
86 |
-
add_action( 'wc_' . $this->get_plugin()->get_id() . '_index_customers',
|
87 |
}
|
88 |
|
89 |
|
@@ -107,13 +107,16 @@ class Connection {
|
|
107 |
|
108 |
if ( empty( $access_token ) ) {
|
109 |
$this->get_plugin()->log( 'Error: No access token was received.' );
|
110 |
-
add_action(
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
|
|
|
|
|
|
117 |
return;
|
118 |
}
|
119 |
|
@@ -228,7 +231,7 @@ class Connection {
|
|
228 |
// Make sure that all refresh actions are cancelled before scheduling it.
|
229 |
$this->unschedule_refresh();
|
230 |
|
231 |
-
as_schedule_single_action( time() + $interval, 'wc_' . $this->get_plugin()->get_id() . '_refresh_connection',
|
232 |
}
|
233 |
|
234 |
|
@@ -257,12 +260,12 @@ class Connection {
|
|
257 |
return;
|
258 |
}
|
259 |
|
260 |
-
$request =
|
261 |
-
'body'
|
262 |
'token' => $this->get_plugin()->get_settings_handler()->get_refresh_token(),
|
263 |
-
|
264 |
'timeout' => 45,
|
265 |
-
|
266 |
|
267 |
// make the request
|
268 |
$response = wp_remote_post( $this->get_refresh_url(), $request );
|
@@ -288,7 +291,7 @@ class Connection {
|
|
288 |
$this->get_plugin()->get_settings_handler()->update_access_token( $response->get_token() );
|
289 |
|
290 |
// In case square updates the refresh token.
|
291 |
-
if( $response->get_refresh_token() ) {
|
292 |
$this->get_plugin()->get_settings_handler()->update_refresh_token( $response->get_refresh_token() );
|
293 |
$this->get_plugin()->log( 'Connection successfully refreshed.' );
|
294 |
}
|
@@ -314,7 +317,7 @@ class Connection {
|
|
314 |
* @since 2.0.0
|
315 |
*/
|
316 |
protected function unschedule_refresh() {
|
317 |
-
as_unschedule_all_actions( 'wc_' . $this->get_plugin()->get_id() . '_refresh_connection',
|
318 |
}
|
319 |
|
320 |
|
@@ -343,10 +346,8 @@ class Connection {
|
|
343 |
$this->schedule_customer_index( $response->get_data()->getCursor() );
|
344 |
}
|
345 |
}
|
346 |
-
|
347 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
348 |
|
349 |
-
|
350 |
}
|
351 |
}
|
352 |
|
@@ -360,8 +361,8 @@ class Connection {
|
|
360 |
*/
|
361 |
protected function schedule_customer_index( $cursor = '' ) {
|
362 |
|
363 |
-
if ( false === as_next_scheduled_action( 'wc_' . $this->get_plugin()->get_id() . '_index_customers',
|
364 |
-
as_schedule_single_action( time(), 'wc_' . $this->get_plugin()->get_id() . '_index_customers',
|
365 |
}
|
366 |
}
|
367 |
|
@@ -438,10 +439,10 @@ class Connection {
|
|
438 |
$action = 'wc_' . $this->get_plugin()->get_id() . '_connected';
|
439 |
$redirect_url = wp_nonce_url( add_query_arg( 'action', $action, admin_url() ), $action );
|
440 |
|
441 |
-
$args =
|
442 |
'redirect' => urlencode( urlencode( $redirect_url ) ),
|
443 |
'scopes' => implode( ',', $this->get_scopes() ),
|
444 |
-
|
445 |
|
446 |
return add_query_arg( $args, $url );
|
447 |
}
|
@@ -484,7 +485,7 @@ class Connection {
|
|
484 |
*/
|
485 |
protected function get_scopes() {
|
486 |
|
487 |
-
$scopes =
|
488 |
'MERCHANT_PROFILE_READ',
|
489 |
'PAYMENTS_READ',
|
490 |
'PAYMENTS_WRITE',
|
@@ -497,7 +498,7 @@ class Connection {
|
|
497 |
'ITEMS_WRITE',
|
498 |
'INVENTORY_READ',
|
499 |
'INVENTORY_WRITE',
|
500 |
-
|
501 |
|
502 |
return (array) apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_connection_scopes', $scopes );
|
503 |
}
|
23 |
|
24 |
namespace WooCommerce\Square\Handlers;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use SquareConnect\Model\ListCustomersResponse;
|
75 |
*/
|
76 |
protected function add_hooks() {
|
77 |
|
78 |
+
add_action( 'admin_action_wc_' . $this->get_plugin()->get_id() . '_connected', array( $this, 'handle_connected' ) );
|
79 |
|
80 |
+
add_action( 'admin_action_wc_' . $this->get_plugin()->get_id() . '_disconnect', array( $this, 'handle_disconnect' ) );
|
81 |
|
82 |
// refresh the connection, triggered by Action Scheduler
|
83 |
+
add_action( 'wc_' . $this->get_plugin()->get_id() . '_refresh_connection', array( $this, 'refresh_connection' ) );
|
84 |
|
85 |
// index customers, triggered by Action Scheduler
|
86 |
+
add_action( 'wc_' . $this->get_plugin()->get_id() . '_index_customers', array( $this, 'index_customers' ) );
|
87 |
}
|
88 |
|
89 |
|
107 |
|
108 |
if ( empty( $access_token ) ) {
|
109 |
$this->get_plugin()->log( 'Error: No access token was received.' );
|
110 |
+
add_action(
|
111 |
+
'admin_notices',
|
112 |
+
function () {
|
113 |
+
?>
|
114 |
+
<div class="notice notice-error is-dismissible">
|
115 |
+
<p><?php _e( 'Square Error: We could not connect to Square. No access token was given.!', 'woocommerce-square' ); ?></p>
|
116 |
+
</div>
|
117 |
+
<?php
|
118 |
+
}
|
119 |
+
);
|
120 |
return;
|
121 |
}
|
122 |
|
231 |
// Make sure that all refresh actions are cancelled before scheduling it.
|
232 |
$this->unschedule_refresh();
|
233 |
|
234 |
+
as_schedule_single_action( time() + $interval, 'wc_' . $this->get_plugin()->get_id() . '_refresh_connection', array(), $this->get_plugin()->get_id() );
|
235 |
}
|
236 |
|
237 |
|
260 |
return;
|
261 |
}
|
262 |
|
263 |
+
$request = array(
|
264 |
+
'body' => array(
|
265 |
'token' => $this->get_plugin()->get_settings_handler()->get_refresh_token(),
|
266 |
+
),
|
267 |
'timeout' => 45,
|
268 |
+
);
|
269 |
|
270 |
// make the request
|
271 |
$response = wp_remote_post( $this->get_refresh_url(), $request );
|
291 |
$this->get_plugin()->get_settings_handler()->update_access_token( $response->get_token() );
|
292 |
|
293 |
// In case square updates the refresh token.
|
294 |
+
if ( $response->get_refresh_token() ) {
|
295 |
$this->get_plugin()->get_settings_handler()->update_refresh_token( $response->get_refresh_token() );
|
296 |
$this->get_plugin()->log( 'Connection successfully refreshed.' );
|
297 |
}
|
317 |
* @since 2.0.0
|
318 |
*/
|
319 |
protected function unschedule_refresh() {
|
320 |
+
as_unschedule_all_actions( 'wc_' . $this->get_plugin()->get_id() . '_refresh_connection', array(), $this->get_plugin()->get_id() );
|
321 |
}
|
322 |
|
323 |
|
346 |
$this->schedule_customer_index( $response->get_data()->getCursor() );
|
347 |
}
|
348 |
}
|
|
|
349 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
350 |
|
|
|
351 |
}
|
352 |
}
|
353 |
|
361 |
*/
|
362 |
protected function schedule_customer_index( $cursor = '' ) {
|
363 |
|
364 |
+
if ( false === as_next_scheduled_action( 'wc_' . $this->get_plugin()->get_id() . '_index_customers', array( $cursor ), $this->get_plugin()->get_id() ) ) {
|
365 |
+
as_schedule_single_action( time(), 'wc_' . $this->get_plugin()->get_id() . '_index_customers', array( $cursor ), $this->get_plugin()->get_id() );
|
366 |
}
|
367 |
}
|
368 |
|
439 |
$action = 'wc_' . $this->get_plugin()->get_id() . '_connected';
|
440 |
$redirect_url = wp_nonce_url( add_query_arg( 'action', $action, admin_url() ), $action );
|
441 |
|
442 |
+
$args = array(
|
443 |
'redirect' => urlencode( urlencode( $redirect_url ) ),
|
444 |
'scopes' => implode( ',', $this->get_scopes() ),
|
445 |
+
);
|
446 |
|
447 |
return add_query_arg( $args, $url );
|
448 |
}
|
485 |
*/
|
486 |
protected function get_scopes() {
|
487 |
|
488 |
+
$scopes = array(
|
489 |
'MERCHANT_PROFILE_READ',
|
490 |
'PAYMENTS_READ',
|
491 |
'PAYMENTS_WRITE',
|
498 |
'ITEMS_WRITE',
|
499 |
'INVENTORY_READ',
|
500 |
'INVENTORY_WRITE',
|
501 |
+
);
|
502 |
|
503 |
return (array) apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_connection_scopes', $scopes );
|
504 |
}
|
includes/Handlers/Email.php
CHANGED
@@ -26,7 +26,7 @@ namespace WooCommerce\Square\Handlers;
|
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use WooCommerce\Square\Emails;
|
28 |
|
29 |
-
defined( 'ABSPATH' )
|
30 |
|
31 |
/**
|
32 |
* Emails handler class.
|
@@ -47,8 +47,8 @@ class Email {
|
|
47 |
*/
|
48 |
public function __construct() {
|
49 |
// add email handlers to WooCommerce core
|
50 |
-
add_action( 'woocommerce_loaded',
|
51 |
-
add_filter( 'woocommerce_email_classes',
|
52 |
}
|
53 |
|
54 |
/**
|
@@ -92,7 +92,7 @@ class Email {
|
|
92 |
* @param \WC_Email[] $emails associative array of email IDs and objects
|
93 |
* @return \WC_Email[]
|
94 |
*/
|
95 |
-
public function get_email_classes( $emails =
|
96 |
// init emails if uninitialized
|
97 |
$this->init_emails();
|
98 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use WooCommerce\Square\Emails;
|
28 |
|
29 |
+
defined( 'ABSPATH' ) || exit;
|
30 |
|
31 |
/**
|
32 |
* Emails handler class.
|
47 |
*/
|
48 |
public function __construct() {
|
49 |
// add email handlers to WooCommerce core
|
50 |
+
add_action( 'woocommerce_loaded', array( $this, 'init_emails' ) );
|
51 |
+
add_filter( 'woocommerce_email_classes', array( $this, 'get_email_classes' ) );
|
52 |
}
|
53 |
|
54 |
/**
|
92 |
* @param \WC_Email[] $emails associative array of email IDs and objects
|
93 |
* @return \WC_Email[]
|
94 |
*/
|
95 |
+
public function get_email_classes( $emails = array() ) {
|
96 |
// init emails if uninitialized
|
97 |
$this->init_emails();
|
98 |
|
includes/Handlers/Order.php
CHANGED
@@ -27,7 +27,7 @@ use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
|
27 |
use WooCommerce\Square\Plugin;
|
28 |
use WooCommerce\Square\Handlers\Product;
|
29 |
|
30 |
-
defined( 'ABSPATH' )
|
31 |
|
32 |
/**
|
33 |
* Order handler class.
|
@@ -39,16 +39,16 @@ class Order {
|
|
39 |
/**
|
40 |
* Array of previous stock values.
|
41 |
*
|
42 |
-
* @var
|
43 |
*/
|
44 |
-
private $previous_stock =
|
45 |
|
46 |
/**
|
47 |
* Array of product IDs that have been scheduled for sync in this request.
|
48 |
*
|
49 |
-
* @var
|
50 |
*/
|
51 |
-
private $products_to_sync =
|
52 |
|
53 |
|
54 |
/**
|
@@ -59,16 +59,16 @@ class Order {
|
|
59 |
public function __construct() {
|
60 |
|
61 |
// remove Square variation IDs from order item meta
|
62 |
-
add_action( 'woocommerce_hidden_order_itemmeta',
|
63 |
|
64 |
// ADD hooks for stock syncs based on changes from orders not from this gateway
|
65 |
-
add_action( 'woocommerce_checkout_order_processed',
|
66 |
|
67 |
// Add specific hook for paypal IPN callback
|
68 |
-
add_action( 'valid-paypal-standard-ipn-request',
|
69 |
|
70 |
// ADD hooks to listen to refunds on orders from other gateways.
|
71 |
-
add_action( 'woocommerce_order_refunded',
|
72 |
}
|
73 |
|
74 |
|
@@ -97,11 +97,11 @@ class Order {
|
|
97 |
* @param array $posted values returned from PayPal Standard IPN callback.
|
98 |
*/
|
99 |
public function maybe_sync_stock_for_order_via_paypal( $posted ) {
|
100 |
-
if ( empty( $posted[
|
101 |
return;
|
102 |
}
|
103 |
|
104 |
-
$raw_order = json_decode( $posted[
|
105 |
if ( empty( $raw_order->order_id ) ) {
|
106 |
return;
|
107 |
}
|
@@ -152,10 +152,10 @@ class Order {
|
|
152 |
|
153 |
$this->cache_previous_stock( $order );
|
154 |
|
155 |
-
add_action( 'woocommerce_product_set_stock',
|
156 |
-
add_action( 'woocommerce_variation_set_stock',
|
157 |
|
158 |
-
add_action( 'shutdown',
|
159 |
}
|
160 |
|
161 |
/**
|
@@ -225,7 +225,7 @@ class Order {
|
|
225 |
*/
|
226 |
public function maybe_sync_staged_inventory_updates() {
|
227 |
|
228 |
-
$inventory_adjustments
|
229 |
|
230 |
foreach ( $this->products_to_sync as $product_id => $adjustment ) {
|
231 |
|
@@ -272,8 +272,8 @@ class Order {
|
|
272 |
return;
|
273 |
}
|
274 |
|
275 |
-
$refund
|
276 |
-
$inventory_adjustments =
|
277 |
foreach ( $refund->get_items() as $item ) {
|
278 |
|
279 |
if ( 'line_item' !== $item->get_type() ) {
|
@@ -285,7 +285,7 @@ class Order {
|
|
285 |
continue;
|
286 |
}
|
287 |
|
288 |
-
$adjustment
|
289 |
$inventory_adjustment = Product::get_inventory_change_adjustment_type( $product, $adjustment );
|
290 |
|
291 |
if ( empty( $inventory_adjustment ) ) {
|
27 |
use WooCommerce\Square\Plugin;
|
28 |
use WooCommerce\Square\Handlers\Product;
|
29 |
|
30 |
+
defined( 'ABSPATH' ) || exit;
|
31 |
|
32 |
/**
|
33 |
* Order handler class.
|
39 |
/**
|
40 |
* Array of previous stock values.
|
41 |
*
|
42 |
+
* @var array
|
43 |
*/
|
44 |
+
private $previous_stock = array();
|
45 |
|
46 |
/**
|
47 |
* Array of product IDs that have been scheduled for sync in this request.
|
48 |
*
|
49 |
+
* @var array
|
50 |
*/
|
51 |
+
private $products_to_sync = array();
|
52 |
|
53 |
|
54 |
/**
|
59 |
public function __construct() {
|
60 |
|
61 |
// remove Square variation IDs from order item meta
|
62 |
+
add_action( 'woocommerce_hidden_order_itemmeta', array( $this, 'hide_square_order_item_meta' ) );
|
63 |
|
64 |
// ADD hooks for stock syncs based on changes from orders not from this gateway
|
65 |
+
add_action( 'woocommerce_checkout_order_processed', array( $this, 'maybe_sync_stock_for_order_via_other_gateway' ), 10, 3 );
|
66 |
|
67 |
// Add specific hook for paypal IPN callback
|
68 |
+
add_action( 'valid-paypal-standard-ipn-request', array( $this, 'maybe_sync_stock_for_order_via_paypal' ), 10, 1 );
|
69 |
|
70 |
// ADD hooks to listen to refunds on orders from other gateways.
|
71 |
+
add_action( 'woocommerce_order_refunded', array( $this, 'maybe_sync_stock_for_refund_from_other_gateway' ), 10, 2 );
|
72 |
}
|
73 |
|
74 |
|
97 |
* @param array $posted values returned from PayPal Standard IPN callback.
|
98 |
*/
|
99 |
public function maybe_sync_stock_for_order_via_paypal( $posted ) {
|
100 |
+
if ( empty( $posted['custom'] ) ) {
|
101 |
return;
|
102 |
}
|
103 |
|
104 |
+
$raw_order = json_decode( $posted['custom'] );
|
105 |
if ( empty( $raw_order->order_id ) ) {
|
106 |
return;
|
107 |
}
|
152 |
|
153 |
$this->cache_previous_stock( $order );
|
154 |
|
155 |
+
add_action( 'woocommerce_product_set_stock', array( $this, 'maybe_stage_inventory_updates_for_product' ) );
|
156 |
+
add_action( 'woocommerce_variation_set_stock', array( $this, 'maybe_stage_inventory_updates_for_product' ) );
|
157 |
|
158 |
+
add_action( 'shutdown', array( $this, 'maybe_sync_staged_inventory_updates' ) );
|
159 |
}
|
160 |
|
161 |
/**
|
225 |
*/
|
226 |
public function maybe_sync_staged_inventory_updates() {
|
227 |
|
228 |
+
$inventory_adjustments = array();
|
229 |
|
230 |
foreach ( $this->products_to_sync as $product_id => $adjustment ) {
|
231 |
|
272 |
return;
|
273 |
}
|
274 |
|
275 |
+
$refund = new \WC_Order_Refund( $refund_id );
|
276 |
+
$inventory_adjustments = array();
|
277 |
foreach ( $refund->get_items() as $item ) {
|
278 |
|
279 |
if ( 'line_item' !== $item->get_type() ) {
|
285 |
continue;
|
286 |
}
|
287 |
|
288 |
+
$adjustment = -1 * ( $item->get_quantity() ); // we want a positive value to increase the stock and a negative number to decrease it.
|
289 |
$inventory_adjustment = Product::get_inventory_change_adjustment_type( $product, $adjustment );
|
290 |
|
291 |
if ( empty( $inventory_adjustment ) ) {
|
includes/Handlers/Product.php
CHANGED
@@ -28,7 +28,7 @@ use SquareConnect\Model\CatalogObject;
|
|
28 |
use WooCommerce\Square\Utilities\Money_Utility;
|
29 |
use WooCommerce\Square\Sync\Records;
|
30 |
|
31 |
-
defined( 'ABSPATH' )
|
32 |
|
33 |
/**
|
34 |
* Product handler class.
|
@@ -62,8 +62,8 @@ class Product {
|
|
62 |
throw new \InvalidArgumentException( 'Type of $catalog_object must be an ITEM' );
|
63 |
}
|
64 |
|
65 |
-
$product->update_meta_data( self::SQUARE_ID_META_KEY,
|
66 |
-
$product->update_meta_data( self::SQUARE_VERSION_META_KEY,
|
67 |
$product->update_meta_data( self::SQUARE_IMAGE_ID_META_KEY, $catalog_object->getImageId() );
|
68 |
|
69 |
$product->save();
|
@@ -80,7 +80,7 @@ class Product {
|
|
80 |
throw new \InvalidArgumentException( 'Type of $catalog_object must be an ITEM_VARIATION' );
|
81 |
}
|
82 |
|
83 |
-
$product->update_meta_data( self::SQUARE_VARIATION_ID_META_KEY,
|
84 |
$product->update_meta_data( self::SQUARE_VARIATION_VERSION_META_KEY, $catalog_object->getVersion() );
|
85 |
|
86 |
$product->save();
|
@@ -144,7 +144,6 @@ class Product {
|
|
144 |
do_action( 'wc_square_updated_product_variation_from_square', $variation, $catalog_variation );
|
145 |
}
|
146 |
}
|
147 |
-
|
148 |
} else {
|
149 |
|
150 |
$catalog_variation = current( $catalog_variations );
|
@@ -181,17 +180,19 @@ class Product {
|
|
181 |
);
|
182 |
|
183 |
$records = Records::get_records();
|
184 |
-
foreach ($records as $record) {
|
185 |
if ( $record->get_message() === $message ) {
|
186 |
$is_recorded = true;
|
187 |
}
|
188 |
}
|
189 |
|
190 |
if ( ! isset( $is_recorded ) ) {
|
191 |
-
Records::set_record(
|
192 |
-
|
193 |
-
|
194 |
-
|
|
|
|
|
195 |
}
|
196 |
}
|
197 |
|
@@ -332,15 +333,17 @@ class Product {
|
|
332 |
*/
|
333 |
public static function init_taxonomies() {
|
334 |
|
335 |
-
register_taxonomy(
|
336 |
-
|
|
|
|
|
337 |
'hierarchical' => false,
|
338 |
'update_count_callback' => '_update_generic_term_count',
|
339 |
'show_ui' => false,
|
340 |
'show_in_nav_menus' => false,
|
341 |
'query_var' => is_admin(),
|
342 |
'rewrite' => false,
|
343 |
-
|
344 |
);
|
345 |
}
|
346 |
|
@@ -362,12 +365,12 @@ class Product {
|
|
362 |
|
363 |
$product = is_numeric( $product ) ? wc_get_product( $product ) : $product;
|
364 |
|
365 |
-
if ( ! $product instanceof \WC_Product || ! in_array( $synced,
|
366 |
return false;
|
367 |
}
|
368 |
|
369 |
// ensure only one term is associated with the product at any time
|
370 |
-
wp_delete_object_term_relationships( $product->get_id(),
|
371 |
|
372 |
// we have already set the value to "no" above by deleting the term relationship
|
373 |
// so it is safe to return with true.
|
@@ -375,7 +378,7 @@ class Product {
|
|
375 |
return true;
|
376 |
}
|
377 |
|
378 |
-
$set_term = wp_set_post_terms( $product->get_id(),
|
379 |
$success = is_array( $set_term );
|
380 |
|
381 |
// Function side effect see phpDoc for details:
|
@@ -423,7 +426,7 @@ class Product {
|
|
423 |
}
|
424 |
}
|
425 |
|
426 |
-
$terms = wp_get_post_terms( $product->get_id(), self::SYNCED_WITH_SQUARE_TAXONOMY,
|
427 |
}
|
428 |
|
429 |
return ! empty( $terms ) && 'yes' === $terms[0];
|
@@ -504,7 +507,7 @@ class Product {
|
|
504 |
|
505 |
if ( $product->is_type( 'variable' ) ) {
|
506 |
|
507 |
-
$variation_attributes =
|
508 |
|
509 |
foreach ( $product->get_attributes() as $attribute ) {
|
510 |
|
@@ -533,30 +536,32 @@ class Product {
|
|
533 |
private static function get_products_synced_status( $status ) {
|
534 |
|
535 |
$sync_status_term = get_term_by( 'name', 'yes', self::SYNCED_WITH_SQUARE_TAXONOMY );
|
536 |
-
$product_ids =
|
537 |
|
538 |
-
if ( $sync_status_term instanceof \WP_Term && in_array( $status,
|
539 |
|
540 |
-
$tax_query_args =
|
541 |
'taxonomy' => self::SYNCED_WITH_SQUARE_TAXONOMY,
|
542 |
'field' => 'id',
|
543 |
'terms' => $sync_status_term->term_id,
|
544 |
'include_children' => false,
|
545 |
-
|
546 |
|
547 |
if ( 'no' === $status ) {
|
548 |
$tax_query_args['operator'] = 'NOT IN';
|
549 |
}
|
550 |
|
551 |
-
$product_ids = get_posts(
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
|
|
559 |
|
|
|
560 |
return $product_ids;
|
561 |
}
|
562 |
|
@@ -678,7 +683,7 @@ class Product {
|
|
678 |
return self::convert_to_catalog_object( wc_get_product( $parent_id ) );
|
679 |
}
|
680 |
|
681 |
-
$variations =
|
682 |
|
683 |
if ( $product->has_child() ) {
|
684 |
|
@@ -691,27 +696,26 @@ class Product {
|
|
691 |
$variations[] = $variation;
|
692 |
}
|
693 |
}
|
694 |
-
|
695 |
} else {
|
696 |
|
697 |
$variation = self::extract_catalog_item_variation_data( $product );
|
698 |
-
$variations = $variation ?
|
699 |
}
|
700 |
|
701 |
if ( empty( $variations ) ) {
|
702 |
return null;
|
703 |
}
|
704 |
|
705 |
-
$data =
|
706 |
'type' => 'ITEM',
|
707 |
'id' => self::get_square_item_id( $product ),
|
708 |
'version' => self::get_square_version( $product ),
|
709 |
-
'present_at_location_ids' =>
|
710 |
-
'item_data' =>
|
711 |
'name' => $product->get_name(),
|
712 |
'variations' => $variations,
|
713 |
-
|
714 |
-
|
715 |
|
716 |
// TODO: Handle categories
|
717 |
|
@@ -729,22 +733,22 @@ class Product {
|
|
729 |
* @param bool $is_soft_delete whether or not this item data is for a soft-delete
|
730 |
* @return array
|
731 |
*/
|
732 |
-
public static function extract_catalog_item_data( \WC_Product $product, array $variations =
|
733 |
|
734 |
if ( ! $product ) {
|
735 |
return null;
|
736 |
}
|
737 |
|
738 |
-
$data =
|
739 |
'type' => 'ITEM',
|
740 |
'id' => self::get_square_item_id( $product ),
|
741 |
'version' => self::get_square_version( $product ),
|
742 |
-
'present_at_location_ids' =>
|
743 |
-
'item_data' =>
|
744 |
'name' => $product->get_name(),
|
745 |
'variations' => $variations,
|
746 |
-
|
747 |
-
|
748 |
|
749 |
$square_category_id = 0;
|
750 |
|
@@ -766,7 +770,7 @@ class Product {
|
|
766 |
if ( $is_soft_delete ) {
|
767 |
|
768 |
$data['present_at_all_locations'] = false;
|
769 |
-
$data['present_at_location_ids'] =
|
770 |
}
|
771 |
|
772 |
return $data;
|
@@ -804,24 +808,24 @@ class Product {
|
|
804 |
|
805 |
$item_id = self::get_square_item_id( $parent_product );
|
806 |
|
807 |
-
$data =
|
808 |
'type' => 'ITEM_VARIATION',
|
809 |
'id' => self::get_square_item_variation_id( $product ),
|
810 |
'version' => self::get_square_variation_version( $product ),
|
811 |
-
'item_variation_data' =>
|
812 |
'item_id' => $item_id,
|
813 |
'name' => $product->get_name(),
|
814 |
'sku' => $product->get_sku(),
|
815 |
'pricing_type' => 'FIXED_PRICING',
|
816 |
'price_money' => self::price_to_money( $product->get_regular_price() ),
|
817 |
'track_inventory' => true,
|
818 |
-
|
819 |
-
|
820 |
|
821 |
if ( $is_soft_delete ) {
|
822 |
|
823 |
$data['present_at_all_locations'] = false;
|
824 |
-
$data['present_at_location_ids'] =
|
825 |
}
|
826 |
}
|
827 |
|
@@ -1073,41 +1077,44 @@ class Product {
|
|
1073 |
public static function get_square_meta( $product_ids, $array_key = 'product_id' ) {
|
1074 |
global $wpdb;
|
1075 |
|
1076 |
-
$results = $square_meta =
|
1077 |
|
1078 |
if ( ! empty( $product_ids ) ) {
|
1079 |
|
1080 |
-
$meta_keys
|
1081 |
'square_item_id' => self::SQUARE_ID_META_KEY,
|
1082 |
'square_item_variation_id' => self::SQUARE_VARIATION_ID_META_KEY,
|
1083 |
'square_version' => self::SQUARE_VERSION_META_KEY,
|
1084 |
'square_variation_version' => self::SQUARE_VARIATION_VERSION_META_KEY,
|
1085 |
-
|
1086 |
|
1087 |
$array_key = array_key_exists( $array_key, $meta_keys ) ? $array_key : 'product_id';
|
1088 |
-
$post_ids_in = '(' . implode( ',', array_map( 'absint', array_merge(
|
1089 |
$meta_key_in = "('" . self::SQUARE_ID_META_KEY . "','" . self::SQUARE_VARIATION_ID_META_KEY . "','" . self::SQUARE_VERSION_META_KEY . "','" . self::SQUARE_VARIATION_VERSION_META_KEY . "')";
|
1090 |
-
$products_meta = $wpdb->get_results(
|
|
|
1091 |
SELECT post_id AS product_id, meta_key, meta_value
|
1092 |
FROM $wpdb->postmeta
|
1093 |
WHERE post_id IN $post_ids_in
|
1094 |
AND meta_key IN $meta_key_in
|
1095 |
-
|
|
|
|
|
1096 |
|
1097 |
foreach ( $products_meta as $post_meta ) {
|
1098 |
|
1099 |
if ( ! array_key_exists( (string) $post_meta['product_id'], $square_meta ) ) {
|
1100 |
-
$square_meta[ (string) $post_meta['product_id'] ] =
|
1101 |
'product_id' => (int) $post_meta['product_id'],
|
1102 |
'square_item_id' => false,
|
1103 |
'square_item_variation_id' => false,
|
1104 |
'square_version' => false,
|
1105 |
'square_variation_version' => false,
|
1106 |
-
|
1107 |
}
|
1108 |
|
1109 |
foreach ( $meta_keys as $square_meta_key => $post_meta_key ) {
|
1110 |
-
if ( isset( $post_meta[
|
1111 |
$square_meta[ $post_meta['product_id'] ][ $square_meta_key ] = $post_meta['meta_value'];
|
1112 |
break;
|
1113 |
}
|
@@ -1117,9 +1124,9 @@ class Product {
|
|
1117 |
foreach ( $product_ids as $product_id ) {
|
1118 |
|
1119 |
// sanity checks: cannot build index without a valid key
|
1120 |
-
if (
|
1121 |
-
|
1122 |
-
|
1123 |
|
1124 |
continue;
|
1125 |
}
|
@@ -1148,12 +1155,12 @@ class Product {
|
|
1148 |
$product_id = $product_id->get_id();
|
1149 |
}
|
1150 |
|
1151 |
-
return
|
1152 |
'product_id' => $product_id,
|
1153 |
'square_item_id' => self::get_square_item_id( $product_id ),
|
1154 |
'square_item_variation_id' => self::get_square_item_variation_id( $product_id ),
|
1155 |
'square_version' => self::get_square_version( $product_id ),
|
1156 |
-
|
1157 |
}
|
1158 |
|
1159 |
|
@@ -1193,23 +1200,23 @@ class Product {
|
|
1193 |
|
1194 |
case 'item_id':
|
1195 |
self::set_square_item_id( $product_id, $meta_value );
|
1196 |
-
|
1197 |
|
1198 |
case 'item_version':
|
1199 |
self::set_square_version( $product_id, $meta_value );
|
1200 |
-
|
1201 |
|
1202 |
case 'item_variation_id':
|
1203 |
self::set_square_item_variation_id( $product_id, $meta_value );
|
1204 |
-
|
1205 |
|
1206 |
case 'item_variation_version':
|
1207 |
self::set_square_variation_version( $product_id, $meta_value );
|
1208 |
-
|
1209 |
|
1210 |
case 'item_image_id':
|
1211 |
self::set_square_image_id( $product_id, $meta_value );
|
1212 |
-
|
1213 |
}
|
1214 |
}
|
1215 |
}
|
@@ -1225,25 +1232,27 @@ class Product {
|
|
1225 |
public static function clear_square_meta( $product_ids ) {
|
1226 |
global $wpdb;
|
1227 |
|
1228 |
-
$product_ids = is_array( $product_ids ) ? $product_ids :
|
1229 |
|
1230 |
-
$meta_keys =
|
1231 |
self::SQUARE_ID_META_KEY,
|
1232 |
self::SQUARE_VERSION_META_KEY,
|
1233 |
self::SQUARE_VARIATION_ID_META_KEY,
|
1234 |
self::SQUARE_VARIATION_VERSION_META_KEY,
|
1235 |
self::SQUARE_IMAGE_ID_META_KEY,
|
1236 |
-
|
1237 |
|
1238 |
$meta_key_in = '("' . implode( '","', $meta_keys ) . '")';
|
1239 |
-
$post_ids_in = '(' . implode( ',', array_map( 'absint', array_merge(
|
1240 |
|
1241 |
-
$wpdb->query(
|
|
|
1242 |
UPDATE $wpdb->postmeta
|
1243 |
SET meta_value = ''
|
1244 |
WHERE meta_key IN $meta_key_in
|
1245 |
AND post_id IN $post_ids_in;
|
1246 |
-
|
|
|
1247 |
}
|
1248 |
|
1249 |
|
@@ -1261,11 +1270,14 @@ class Product {
|
|
1261 |
|
1262 |
if ( $product ) {
|
1263 |
|
1264 |
-
self::update_square_meta(
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
|
|
|
|
|
|
1269 |
}
|
1270 |
}
|
1271 |
|
@@ -1284,16 +1296,20 @@ class Product {
|
|
1284 |
|
1285 |
if ( $square_variation_id = self::get_square_item_variation_id( $product->get_id(), false ) ) {
|
1286 |
|
1287 |
-
$inventory_change = new \SquareConnect\Model\InventoryChange(
|
1288 |
-
|
1289 |
-
|
1290 |
-
'
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
|
|
|
|
|
|
|
|
1297 |
}
|
1298 |
|
1299 |
return $inventory_change;
|
@@ -1314,7 +1330,7 @@ class Product {
|
|
1314 |
|
1315 |
$square_variation_id = self::get_square_item_variation_id( $product->get_id(), false );
|
1316 |
|
1317 |
-
if ( empty( $square_variation_id ) || 0 === $adjustment) {
|
1318 |
return null;
|
1319 |
}
|
1320 |
|
@@ -1326,17 +1342,21 @@ class Product {
|
|
1326 |
$to = 'IN_STOCK';
|
1327 |
}
|
1328 |
|
1329 |
-
$inventory_change = new \SquareConnect\Model\InventoryChange(
|
1330 |
-
|
1331 |
-
|
1332 |
-
'
|
1333 |
-
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
|
|
|
|
|
|
|
|
1340 |
|
1341 |
return $inventory_change;
|
1342 |
}
|
28 |
use WooCommerce\Square\Utilities\Money_Utility;
|
29 |
use WooCommerce\Square\Sync\Records;
|
30 |
|
31 |
+
defined( 'ABSPATH' ) || exit;
|
32 |
|
33 |
/**
|
34 |
* Product handler class.
|
62 |
throw new \InvalidArgumentException( 'Type of $catalog_object must be an ITEM' );
|
63 |
}
|
64 |
|
65 |
+
$product->update_meta_data( self::SQUARE_ID_META_KEY, $catalog_object->getId() );
|
66 |
+
$product->update_meta_data( self::SQUARE_VERSION_META_KEY, $catalog_object->getVersion() );
|
67 |
$product->update_meta_data( self::SQUARE_IMAGE_ID_META_KEY, $catalog_object->getImageId() );
|
68 |
|
69 |
$product->save();
|
80 |
throw new \InvalidArgumentException( 'Type of $catalog_object must be an ITEM_VARIATION' );
|
81 |
}
|
82 |
|
83 |
+
$product->update_meta_data( self::SQUARE_VARIATION_ID_META_KEY, $catalog_object->getId() );
|
84 |
$product->update_meta_data( self::SQUARE_VARIATION_VERSION_META_KEY, $catalog_object->getVersion() );
|
85 |
|
86 |
$product->save();
|
144 |
do_action( 'wc_square_updated_product_variation_from_square', $variation, $catalog_variation );
|
145 |
}
|
146 |
}
|
|
|
147 |
} else {
|
148 |
|
149 |
$catalog_variation = current( $catalog_variations );
|
180 |
);
|
181 |
|
182 |
$records = Records::get_records();
|
183 |
+
foreach ( $records as $record ) {
|
184 |
if ( $record->get_message() === $message ) {
|
185 |
$is_recorded = true;
|
186 |
}
|
187 |
}
|
188 |
|
189 |
if ( ! isset( $is_recorded ) ) {
|
190 |
+
Records::set_record(
|
191 |
+
array(
|
192 |
+
'type' => 'alert',
|
193 |
+
'message' => $message,
|
194 |
+
)
|
195 |
+
);
|
196 |
}
|
197 |
}
|
198 |
|
333 |
*/
|
334 |
public static function init_taxonomies() {
|
335 |
|
336 |
+
register_taxonomy(
|
337 |
+
self::SYNCED_WITH_SQUARE_TAXONOMY,
|
338 |
+
array( 'product' ),
|
339 |
+
array(
|
340 |
'hierarchical' => false,
|
341 |
'update_count_callback' => '_update_generic_term_count',
|
342 |
'show_ui' => false,
|
343 |
'show_in_nav_menus' => false,
|
344 |
'query_var' => is_admin(),
|
345 |
'rewrite' => false,
|
346 |
+
)
|
347 |
);
|
348 |
}
|
349 |
|
365 |
|
366 |
$product = is_numeric( $product ) ? wc_get_product( $product ) : $product;
|
367 |
|
368 |
+
if ( ! $product instanceof \WC_Product || ! in_array( $synced, array( 'yes', 'no' ), true ) ) {
|
369 |
return false;
|
370 |
}
|
371 |
|
372 |
// ensure only one term is associated with the product at any time
|
373 |
+
wp_delete_object_term_relationships( $product->get_id(), array( self::SYNCED_WITH_SQUARE_TAXONOMY ) );
|
374 |
|
375 |
// we have already set the value to "no" above by deleting the term relationship
|
376 |
// so it is safe to return with true.
|
378 |
return true;
|
379 |
}
|
380 |
|
381 |
+
$set_term = wp_set_post_terms( $product->get_id(), array( $synced ), self::SYNCED_WITH_SQUARE_TAXONOMY );
|
382 |
$success = is_array( $set_term );
|
383 |
|
384 |
// Function side effect see phpDoc for details:
|
426 |
}
|
427 |
}
|
428 |
|
429 |
+
$terms = wp_get_post_terms( $product->get_id(), self::SYNCED_WITH_SQUARE_TAXONOMY, array( 'fields' => 'names' ) );
|
430 |
}
|
431 |
|
432 |
return ! empty( $terms ) && 'yes' === $terms[0];
|
507 |
|
508 |
if ( $product->is_type( 'variable' ) ) {
|
509 |
|
510 |
+
$variation_attributes = array();
|
511 |
|
512 |
foreach ( $product->get_attributes() as $attribute ) {
|
513 |
|
536 |
private static function get_products_synced_status( $status ) {
|
537 |
|
538 |
$sync_status_term = get_term_by( 'name', 'yes', self::SYNCED_WITH_SQUARE_TAXONOMY );
|
539 |
+
$product_ids = array();
|
540 |
|
541 |
+
if ( $sync_status_term instanceof \WP_Term && in_array( $status, array( 'yes', 'no' ), true ) ) {
|
542 |
|
543 |
+
$tax_query_args = array(
|
544 |
'taxonomy' => self::SYNCED_WITH_SQUARE_TAXONOMY,
|
545 |
'field' => 'id',
|
546 |
'terms' => $sync_status_term->term_id,
|
547 |
'include_children' => false,
|
548 |
+
);
|
549 |
|
550 |
if ( 'no' === $status ) {
|
551 |
$tax_query_args['operator'] = 'NOT IN';
|
552 |
}
|
553 |
|
554 |
+
$product_ids = get_posts(
|
555 |
+
array(
|
556 |
+
'post_type' => array( 'product', 'product_variation' ),
|
557 |
+
'post_status' => array( 'private', 'publish' ),
|
558 |
+
'fields' => 'ids',
|
559 |
+
'nopaging' => true,
|
560 |
+
'tax_query' => array( $tax_query_args ),
|
561 |
+
)
|
562 |
+
);
|
563 |
|
564 |
+
}
|
565 |
return $product_ids;
|
566 |
}
|
567 |
|
683 |
return self::convert_to_catalog_object( wc_get_product( $parent_id ) );
|
684 |
}
|
685 |
|
686 |
+
$variations = array();
|
687 |
|
688 |
if ( $product->has_child() ) {
|
689 |
|
696 |
$variations[] = $variation;
|
697 |
}
|
698 |
}
|
|
|
699 |
} else {
|
700 |
|
701 |
$variation = self::extract_catalog_item_variation_data( $product );
|
702 |
+
$variations = $variation ? array( $variation ) : array();
|
703 |
}
|
704 |
|
705 |
if ( empty( $variations ) ) {
|
706 |
return null;
|
707 |
}
|
708 |
|
709 |
+
$data = array(
|
710 |
'type' => 'ITEM',
|
711 |
'id' => self::get_square_item_id( $product ),
|
712 |
'version' => self::get_square_version( $product ),
|
713 |
+
'present_at_location_ids' => array( wc_square()->get_settings_handler()->get_location_id() ),
|
714 |
+
'item_data' => array(
|
715 |
'name' => $product->get_name(),
|
716 |
'variations' => $variations,
|
717 |
+
),
|
718 |
+
);
|
719 |
|
720 |
// TODO: Handle categories
|
721 |
|
733 |
* @param bool $is_soft_delete whether or not this item data is for a soft-delete
|
734 |
* @return array
|
735 |
*/
|
736 |
+
public static function extract_catalog_item_data( \WC_Product $product, array $variations = array(), $is_soft_delete = false ) {
|
737 |
|
738 |
if ( ! $product ) {
|
739 |
return null;
|
740 |
}
|
741 |
|
742 |
+
$data = array(
|
743 |
'type' => 'ITEM',
|
744 |
'id' => self::get_square_item_id( $product ),
|
745 |
'version' => self::get_square_version( $product ),
|
746 |
+
'present_at_location_ids' => array( wc_square()->get_settings_handler()->get_location_id() ),
|
747 |
+
'item_data' => array(
|
748 |
'name' => $product->get_name(),
|
749 |
'variations' => $variations,
|
750 |
+
),
|
751 |
+
);
|
752 |
|
753 |
$square_category_id = 0;
|
754 |
|
770 |
if ( $is_soft_delete ) {
|
771 |
|
772 |
$data['present_at_all_locations'] = false;
|
773 |
+
$data['present_at_location_ids'] = array();
|
774 |
}
|
775 |
|
776 |
return $data;
|
808 |
|
809 |
$item_id = self::get_square_item_id( $parent_product );
|
810 |
|
811 |
+
$data = array(
|
812 |
'type' => 'ITEM_VARIATION',
|
813 |
'id' => self::get_square_item_variation_id( $product ),
|
814 |
'version' => self::get_square_variation_version( $product ),
|
815 |
+
'item_variation_data' => array(
|
816 |
'item_id' => $item_id,
|
817 |
'name' => $product->get_name(),
|
818 |
'sku' => $product->get_sku(),
|
819 |
'pricing_type' => 'FIXED_PRICING',
|
820 |
'price_money' => self::price_to_money( $product->get_regular_price() ),
|
821 |
'track_inventory' => true,
|
822 |
+
),
|
823 |
+
);
|
824 |
|
825 |
if ( $is_soft_delete ) {
|
826 |
|
827 |
$data['present_at_all_locations'] = false;
|
828 |
+
$data['present_at_location_ids'] = array();
|
829 |
}
|
830 |
}
|
831 |
|
1077 |
public static function get_square_meta( $product_ids, $array_key = 'product_id' ) {
|
1078 |
global $wpdb;
|
1079 |
|
1080 |
+
$results = $square_meta = array();
|
1081 |
|
1082 |
if ( ! empty( $product_ids ) ) {
|
1083 |
|
1084 |
+
$meta_keys = array(
|
1085 |
'square_item_id' => self::SQUARE_ID_META_KEY,
|
1086 |
'square_item_variation_id' => self::SQUARE_VARIATION_ID_META_KEY,
|
1087 |
'square_version' => self::SQUARE_VERSION_META_KEY,
|
1088 |
'square_variation_version' => self::SQUARE_VARIATION_VERSION_META_KEY,
|
1089 |
+
);
|
1090 |
|
1091 |
$array_key = array_key_exists( $array_key, $meta_keys ) ? $array_key : 'product_id';
|
1092 |
+
$post_ids_in = '(' . implode( ',', array_map( 'absint', array_merge( array( 0 ), $product_ids ) ) ) . ')';
|
1093 |
$meta_key_in = "('" . self::SQUARE_ID_META_KEY . "','" . self::SQUARE_VARIATION_ID_META_KEY . "','" . self::SQUARE_VERSION_META_KEY . "','" . self::SQUARE_VARIATION_VERSION_META_KEY . "')";
|
1094 |
+
$products_meta = $wpdb->get_results(
|
1095 |
+
"
|
1096 |
SELECT post_id AS product_id, meta_key, meta_value
|
1097 |
FROM $wpdb->postmeta
|
1098 |
WHERE post_id IN $post_ids_in
|
1099 |
AND meta_key IN $meta_key_in
|
1100 |
+
",
|
1101 |
+
ARRAY_A
|
1102 |
+
);
|
1103 |
|
1104 |
foreach ( $products_meta as $post_meta ) {
|
1105 |
|
1106 |
if ( ! array_key_exists( (string) $post_meta['product_id'], $square_meta ) ) {
|
1107 |
+
$square_meta[ (string) $post_meta['product_id'] ] = array(
|
1108 |
'product_id' => (int) $post_meta['product_id'],
|
1109 |
'square_item_id' => false,
|
1110 |
'square_item_variation_id' => false,
|
1111 |
'square_version' => false,
|
1112 |
'square_variation_version' => false,
|
1113 |
+
);
|
1114 |
}
|
1115 |
|
1116 |
foreach ( $meta_keys as $square_meta_key => $post_meta_key ) {
|
1117 |
+
if ( isset( $post_meta['meta_key'] ) && $post_meta_key === $post_meta['meta_key'] ) {
|
1118 |
$square_meta[ $post_meta['product_id'] ][ $square_meta_key ] = $post_meta['meta_value'];
|
1119 |
break;
|
1120 |
}
|
1124 |
foreach ( $product_ids as $product_id ) {
|
1125 |
|
1126 |
// sanity checks: cannot build index without a valid key
|
1127 |
+
if ( ! array_key_exists( $product_id, $square_meta )
|
1128 |
+
|| ! isset( $square_meta[ $product_id ][ $array_key ] )
|
1129 |
+
|| ! $square_meta[ (string) $product_id ][ $array_key ] ) {
|
1130 |
|
1131 |
continue;
|
1132 |
}
|
1155 |
$product_id = $product_id->get_id();
|
1156 |
}
|
1157 |
|
1158 |
+
return array(
|
1159 |
'product_id' => $product_id,
|
1160 |
'square_item_id' => self::get_square_item_id( $product_id ),
|
1161 |
'square_item_variation_id' => self::get_square_item_variation_id( $product_id ),
|
1162 |
'square_version' => self::get_square_version( $product_id ),
|
1163 |
+
);
|
1164 |
}
|
1165 |
|
1166 |
|
1200 |
|
1201 |
case 'item_id':
|
1202 |
self::set_square_item_id( $product_id, $meta_value );
|
1203 |
+
break;
|
1204 |
|
1205 |
case 'item_version':
|
1206 |
self::set_square_version( $product_id, $meta_value );
|
1207 |
+
break;
|
1208 |
|
1209 |
case 'item_variation_id':
|
1210 |
self::set_square_item_variation_id( $product_id, $meta_value );
|
1211 |
+
break;
|
1212 |
|
1213 |
case 'item_variation_version':
|
1214 |
self::set_square_variation_version( $product_id, $meta_value );
|
1215 |
+
break;
|
1216 |
|
1217 |
case 'item_image_id':
|
1218 |
self::set_square_image_id( $product_id, $meta_value );
|
1219 |
+
break;
|
1220 |
}
|
1221 |
}
|
1222 |
}
|
1232 |
public static function clear_square_meta( $product_ids ) {
|
1233 |
global $wpdb;
|
1234 |
|
1235 |
+
$product_ids = is_array( $product_ids ) ? $product_ids : array( $product_ids );
|
1236 |
|
1237 |
+
$meta_keys = array(
|
1238 |
self::SQUARE_ID_META_KEY,
|
1239 |
self::SQUARE_VERSION_META_KEY,
|
1240 |
self::SQUARE_VARIATION_ID_META_KEY,
|
1241 |
self::SQUARE_VARIATION_VERSION_META_KEY,
|
1242 |
self::SQUARE_IMAGE_ID_META_KEY,
|
1243 |
+
);
|
1244 |
|
1245 |
$meta_key_in = '("' . implode( '","', $meta_keys ) . '")';
|
1246 |
+
$post_ids_in = '(' . implode( ',', array_map( 'absint', array_merge( array( 0 ), $product_ids ) ) ) . ')';
|
1247 |
|
1248 |
+
$wpdb->query(
|
1249 |
+
"
|
1250 |
UPDATE $wpdb->postmeta
|
1251 |
SET meta_value = ''
|
1252 |
WHERE meta_key IN $meta_key_in
|
1253 |
AND post_id IN $post_ids_in;
|
1254 |
+
"
|
1255 |
+
);
|
1256 |
}
|
1257 |
|
1258 |
|
1270 |
|
1271 |
if ( $product ) {
|
1272 |
|
1273 |
+
self::update_square_meta(
|
1274 |
+
$product->get_id(),
|
1275 |
+
array(
|
1276 |
+
'item_id' => $remote_product->getId(),
|
1277 |
+
'item_version' => $remote_product->getVersion(),
|
1278 |
+
'item_image_id' => $remote_product->getImageId(),
|
1279 |
+
)
|
1280 |
+
);
|
1281 |
}
|
1282 |
}
|
1283 |
|
1296 |
|
1297 |
if ( $square_variation_id = self::get_square_item_variation_id( $product->get_id(), false ) ) {
|
1298 |
|
1299 |
+
$inventory_change = new \SquareConnect\Model\InventoryChange(
|
1300 |
+
array(
|
1301 |
+
'type' => 'PHYSICAL_COUNT',
|
1302 |
+
'physical_count' => new \SquareConnect\Model\InventoryPhysicalCount(
|
1303 |
+
array(
|
1304 |
+
'catalog_object_id' => $square_variation_id,
|
1305 |
+
'quantity' => '' . max( 0, $product->get_stock_quantity() ),
|
1306 |
+
'location_id' => wc_square()->get_settings_handler()->get_location_id(),
|
1307 |
+
'state' => 'IN_STOCK',
|
1308 |
+
'occurred_at' => date( 'Y-m-d\TH:i:sP' ),
|
1309 |
+
)
|
1310 |
+
),
|
1311 |
+
)
|
1312 |
+
);
|
1313 |
}
|
1314 |
|
1315 |
return $inventory_change;
|
1330 |
|
1331 |
$square_variation_id = self::get_square_item_variation_id( $product->get_id(), false );
|
1332 |
|
1333 |
+
if ( empty( $square_variation_id ) || 0 === $adjustment ) {
|
1334 |
return null;
|
1335 |
}
|
1336 |
|
1342 |
$to = 'IN_STOCK';
|
1343 |
}
|
1344 |
|
1345 |
+
$inventory_change = new \SquareConnect\Model\InventoryChange(
|
1346 |
+
array(
|
1347 |
+
'type' => 'ADJUSTMENT',
|
1348 |
+
'adjustment' => new \SquareConnect\Model\InventoryAdjustment(
|
1349 |
+
array(
|
1350 |
+
'catalog_object_id' => $square_variation_id,
|
1351 |
+
'location_id' => wc_square()->get_settings_handler()->get_location_id(),
|
1352 |
+
'quantity' => '' . absint( $adjustment ),
|
1353 |
+
'from_state' => $from,
|
1354 |
+
'to_state' => $to,
|
1355 |
+
'occurred_at' => date( 'Y-m-d\TH:i:sP' ),
|
1356 |
+
)
|
1357 |
+
),
|
1358 |
+
)
|
1359 |
+
);
|
1360 |
|
1361 |
return $inventory_change;
|
1362 |
}
|
includes/Handlers/Product/Woo_SOR.php
CHANGED
@@ -78,7 +78,7 @@ class Woo_SOR extends \WooCommerce\Square\Handlers\Product {
|
|
78 |
$item_data->setCategoryId( $square_category_id );
|
79 |
}
|
80 |
|
81 |
-
$catalog_variations = $item_data->getVariations() ?:
|
82 |
|
83 |
// if dealing with a variable product, try and match the variations
|
84 |
if ( $product->is_type( 'variable' ) ) {
|
@@ -108,7 +108,6 @@ class Woo_SOR extends \WooCommerce\Square\Handlers\Product {
|
|
108 |
// consider this variation taken care of
|
109 |
unset( $product_variation_ids[ $key ] );
|
110 |
}
|
111 |
-
|
112 |
} else {
|
113 |
|
114 |
unset( $catalog_variations[ $object_key ] );
|
@@ -125,18 +124,20 @@ class Woo_SOR extends \WooCommerce\Square\Handlers\Product {
|
|
125 |
continue;
|
126 |
}
|
127 |
|
128 |
-
$variation_object = new CatalogObject(
|
129 |
-
|
130 |
-
|
131 |
-
'
|
132 |
-
|
133 |
-
|
|
|
|
|
|
|
|
|
134 |
|
135 |
$catalog_variations[] = self::update_catalog_variation( $variation_object, $product_variation );
|
136 |
}
|
137 |
-
|
138 |
-
// otherwise, we have a simple product
|
139 |
-
} else {
|
140 |
|
141 |
if ( ! empty( $catalog_variations ) ) {
|
142 |
|
@@ -144,15 +145,19 @@ class Woo_SOR extends \WooCommerce\Square\Handlers\Product {
|
|
144 |
|
145 |
} else {
|
146 |
|
147 |
-
$variation_object = new CatalogObject(
|
148 |
-
|
149 |
-
|
150 |
-
'
|
151 |
-
|
152 |
-
|
|
|
|
|
|
|
|
|
153 |
}
|
154 |
|
155 |
-
$catalog_variations =
|
156 |
}
|
157 |
|
158 |
$item_data->setVariations( array_values( $catalog_variations ) );
|
@@ -258,8 +263,8 @@ class Woo_SOR extends \WooCommerce\Square\Handlers\Product {
|
|
258 |
|
259 |
$location_id = wc_square()->get_settings_handler()->get_location_id();
|
260 |
|
261 |
-
$present_location_ids = $catalog_object->getPresentAtLocationIds() ?:
|
262 |
-
$absent_location_ids = $catalog_object->getAbsentAtLocationIds() ?:
|
263 |
|
264 |
// if trashed, set as absent at our location
|
265 |
if ( $is_delete ) {
|
@@ -269,9 +274,7 @@ class Woo_SOR extends \WooCommerce\Square\Handlers\Product {
|
|
269 |
if ( false !== ( $key = array_search( $location_id, $present_location_ids, true ) ) ) {
|
270 |
unset( $present_location_ids[ $key ] );
|
271 |
}
|
272 |
-
|
273 |
-
// otherwise, it's present
|
274 |
-
} else {
|
275 |
|
276 |
$present_location_ids[] = $location_id;
|
277 |
|
78 |
$item_data->setCategoryId( $square_category_id );
|
79 |
}
|
80 |
|
81 |
+
$catalog_variations = $item_data->getVariations() ?: array();
|
82 |
|
83 |
// if dealing with a variable product, try and match the variations
|
84 |
if ( $product->is_type( 'variable' ) ) {
|
108 |
// consider this variation taken care of
|
109 |
unset( $product_variation_ids[ $key ] );
|
110 |
}
|
|
|
111 |
} else {
|
112 |
|
113 |
unset( $catalog_variations[ $object_key ] );
|
124 |
continue;
|
125 |
}
|
126 |
|
127 |
+
$variation_object = new CatalogObject(
|
128 |
+
array(
|
129 |
+
'type' => 'ITEM_VARIATION',
|
130 |
+
'item_variation_data' => new \SquareConnect\Model\CatalogItemVariation(
|
131 |
+
array(
|
132 |
+
'item_id' => $catalog_object->getId(),
|
133 |
+
)
|
134 |
+
),
|
135 |
+
)
|
136 |
+
);
|
137 |
|
138 |
$catalog_variations[] = self::update_catalog_variation( $variation_object, $product_variation );
|
139 |
}
|
140 |
+
} else { // otherwise, we have a simple product
|
|
|
|
|
141 |
|
142 |
if ( ! empty( $catalog_variations ) ) {
|
143 |
|
145 |
|
146 |
} else {
|
147 |
|
148 |
+
$variation_object = new CatalogObject(
|
149 |
+
array(
|
150 |
+
'type' => 'ITEM_VARIATION',
|
151 |
+
'item_variation_data' => new \SquareConnect\Model\CatalogItemVariation(
|
152 |
+
array(
|
153 |
+
'item_id' => $catalog_object->getId(),
|
154 |
+
)
|
155 |
+
),
|
156 |
+
)
|
157 |
+
);
|
158 |
}
|
159 |
|
160 |
+
$catalog_variations = array( self::update_catalog_variation( $variation_object, $product ) );
|
161 |
}
|
162 |
|
163 |
$item_data->setVariations( array_values( $catalog_variations ) );
|
263 |
|
264 |
$location_id = wc_square()->get_settings_handler()->get_location_id();
|
265 |
|
266 |
+
$present_location_ids = $catalog_object->getPresentAtLocationIds() ?: array();
|
267 |
+
$absent_location_ids = $catalog_object->getAbsentAtLocationIds() ?: array();
|
268 |
|
269 |
// if trashed, set as absent at our location
|
270 |
if ( $is_delete ) {
|
274 |
if ( false !== ( $key = array_search( $location_id, $present_location_ids, true ) ) ) {
|
275 |
unset( $present_location_ids[ $key ] );
|
276 |
}
|
277 |
+
} else { // otherwise, it's present
|
|
|
|
|
278 |
|
279 |
$present_location_ids[] = $location_id;
|
280 |
|
includes/Handlers/Products.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Handlers;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Product;
|
@@ -42,13 +42,13 @@ class Products {
|
|
42 |
private $product_errors;
|
43 |
|
44 |
/** @var array associative array of memoized errors being output for a product at one time */
|
45 |
-
private $output_errors =
|
46 |
|
47 |
/** @var int[] array of product IDs that have been scheduled for sync in this request */
|
48 |
-
private $products_to_sync =
|
49 |
|
50 |
/** @var int[] array of product IDs that have been scheduled for deletion in this request */
|
51 |
-
private $products_to_delete =
|
52 |
|
53 |
/** @var Square\Plugin plugin instance */
|
54 |
private $plugin;
|
@@ -63,14 +63,14 @@ class Products {
|
|
63 |
$this->plugin = $plugin;
|
64 |
|
65 |
// add common errors
|
66 |
-
$this->product_errors =
|
67 |
/* translators: Placeholder: %s - product name */
|
68 |
'missing_sku' => __( "Please add an SKU to sync %s with Square. The SKU must match the item's SKU in your Square account.", 'woocommerce-square' ),
|
69 |
/* translators: Placeholder: %s - product name */
|
70 |
'missing_variation_sku' => __( "Please add an SKU to every variation of %s for syncing with Square. Each SKU must match the corresponding item's SKU in your Square account.", 'woocommerce-square' ),
|
71 |
/* translators: Placeholder: %s - product name */
|
72 |
'multiple_attributes' => __( '%s has multiple variation attributes and cannot be synced with Square.', 'woocommerce-square' ),
|
73 |
-
|
74 |
|
75 |
// add hooks
|
76 |
$this->add_products_edit_screen_hooks();
|
@@ -89,18 +89,18 @@ class Products {
|
|
89 |
private function add_products_edit_screen_hooks() {
|
90 |
|
91 |
// adds an option to the "Filter by product type" dropdown
|
92 |
-
add_action( 'restrict_manage_posts',
|
93 |
// allow filtering products by sync status by altering results
|
94 |
-
add_filter( 'request',
|
95 |
|
96 |
// prevent copying Square data when duplicating a product automatically
|
97 |
-
add_action( 'woocommerce_product_duplicate',
|
98 |
|
99 |
// handle quick/bulk edit actions in the products edit screen for setting sync status
|
100 |
-
add_action( 'woocommerce_product_quick_edit_end',
|
101 |
-
add_action( 'woocommerce_product_bulk_edit_end',
|
102 |
-
add_action( 'woocommerce_product_quick_edit_save',
|
103 |
-
add_action( 'woocommerce_product_bulk_edit_save',
|
104 |
}
|
105 |
|
106 |
|
@@ -113,14 +113,14 @@ class Products {
|
|
113 |
*/
|
114 |
private function add_product_edit_screen_hooks() {
|
115 |
|
116 |
-
add_action( 'woocommerce_variation_options',
|
117 |
|
118 |
// handle individual products input fields for setting sync status
|
119 |
-
add_action( 'woocommerce_product_options_general_product_data',
|
120 |
-
add_action( 'woocommerce_admin_process_product_object',
|
121 |
-
add_action( 'woocommerce_before_product_object_save',
|
122 |
|
123 |
-
add_action( 'admin_notices',
|
124 |
}
|
125 |
|
126 |
|
@@ -140,7 +140,8 @@ class Products {
|
|
140 |
return;
|
141 |
}
|
142 |
|
143 |
-
?> <input type="hidden" id="wc_square_variation_manage_stock" name="variable_manage_stock[<?php echo esc_attr( $loop ); ?>]" value="1" />
|
|
|
144 |
}
|
145 |
|
146 |
|
@@ -151,10 +152,10 @@ class Products {
|
|
151 |
*/
|
152 |
private function add_product_sync_hooks() {
|
153 |
|
154 |
-
add_action( 'woocommerce_update_product',
|
155 |
-
add_action( 'trashed_post',
|
156 |
-
add_action( 'shutdown',
|
157 |
-
add_action( 'shutdown',
|
158 |
}
|
159 |
|
160 |
|
@@ -176,11 +177,13 @@ class Products {
|
|
176 |
$label = esc_html__( 'Synced with Square', 'woocommerce-square' );
|
177 |
$selected = isset( $_GET['product_type'] ) && 'synced-with-square' === $_GET['product_type'] ? 'selected=\"selected\"' : '';
|
178 |
|
179 |
-
wc_enqueue_js(
|
|
|
180 |
jQuery( document ).ready( function( $ ) {
|
181 |
-
$( 'select#dropdown_product_type' ).append( '<option value=\"synced-with-square\" ' + '" . $selected . "' + '>' + '" . $label ."' + '</option>' );
|
182 |
} );
|
183 |
-
|
|
|
184 |
}
|
185 |
|
186 |
|
@@ -194,7 +197,7 @@ class Products {
|
|
194 |
* @param array $query_vars query variables
|
195 |
* @return array
|
196 |
*/
|
197 |
-
public function filter_products_synced_with_square( $query_vars ){
|
198 |
global $typenow;
|
199 |
|
200 |
if ( 'product' === $typenow && isset( $_GET['product_type'] ) && 'synced-with-square' === $_GET['product_type'] ) {
|
@@ -203,16 +206,16 @@ class Products {
|
|
203 |
unset( $query_vars['product_type'] );
|
204 |
|
205 |
if ( ! isset( $query_vars['tax_query'] ) ) {
|
206 |
-
$query_vars['tax_query'] =
|
207 |
} else {
|
208 |
$query_vars['tax_query']['relation'] = 'AND';
|
209 |
}
|
210 |
|
211 |
-
$query_vars['tax_query'][] =
|
212 |
'taxonomy' => Product::SYNCED_WITH_SQUARE_TAXONOMY,
|
213 |
'field' => 'slug',
|
214 |
-
'terms' =>
|
215 |
-
|
216 |
}
|
217 |
|
218 |
return $query_vars;
|
@@ -242,25 +245,27 @@ class Products {
|
|
242 |
<div class="wc-square-sync-with-square options_group show_if_simple show_if_variable">
|
243 |
<?php
|
244 |
|
245 |
-
$selector
|
246 |
-
$value
|
247 |
-
$errors
|
248 |
|
249 |
$setting_label = wc_square()->get_settings_handler()->is_system_of_record_square() ? __( 'Update product data with Square data', 'woocommerce-square' ) : __( 'Send product data to Square', 'woocommerce-square' );
|
250 |
|
251 |
-
woocommerce_wp_checkbox(
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
|
|
|
|
260 |
|
261 |
?>
|
262 |
<p class="form-field wc-square-sync-with-square-errors">
|
263 |
-
<?php foreach ( $this->product_errors as $error_code => $error_message ) :
|
264 |
<?php $styles = ! in_array( $error_code, array_keys( $errors ), true ) ? 'display:none; color:#A00;' : 'display:block; color:#A00;'; ?>
|
265 |
<span class="wc-square-sync-with-square-error <?php echo sanitize_html_class( $error_code ); ?>" style="<?php echo $styles; ?>"><?php echo $this->format_product_error( $error_code, $product_object ); ?></span>
|
266 |
<?php endforeach; ?>
|
@@ -360,7 +365,13 @@ class Products {
|
|
360 |
|
361 |
foreach ( $errors as $error ) {
|
362 |
wc_square()->get_message_handler()->add_error( $error );
|
363 |
-
Records::set_record(
|
|
|
|
|
|
|
|
|
|
|
|
|
364 |
}
|
365 |
} else {
|
366 |
$this->maybe_stage_product_for_sync( $product );
|
@@ -461,13 +472,13 @@ class Products {
|
|
461 |
$default_value = 'no'; // in individual products context, the value should be always an explicit yes or no
|
462 |
}
|
463 |
|
464 |
-
$square_synced = isset( $_REQUEST[ $posted_data_key ] ) && in_array( $_REQUEST[ $posted_data_key ],
|
465 |
-
|
466 |
if ( is_string( $square_synced ) ) {
|
467 |
$errors = $this->check_product_sync_errors( $product );
|
468 |
if ( 'no' === $square_synced || empty( $errors ) ) {
|
469 |
Product::set_synced_with_square( $product, $square_synced );
|
470 |
-
}
|
471 |
foreach ( $errors as $error ) {
|
472 |
wc_square()->get_message_handler()->add_error( $error );
|
473 |
}
|
@@ -497,7 +508,7 @@ class Products {
|
|
497 |
return;
|
498 |
}
|
499 |
|
500 |
-
$errors =
|
501 |
$posted_key = '_' . Product::SYNCED_WITH_SQUARE_TAXONOMY;
|
502 |
$set_synced = isset( $_POST[ $posted_key ] ) && 'yes' === $_POST[ $posted_key ];
|
503 |
$was_synced = Product::is_synced_with_square( $product );
|
@@ -577,7 +588,6 @@ class Products {
|
|
577 |
} else {
|
578 |
wc_square()->get_api()->remove_inventory( $square_id, $change );
|
579 |
}
|
580 |
-
|
581 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
582 |
|
583 |
wc_square()->log( 'Could not adjust Square inventory for ' . $product->get_formatted_name() . '. ' . $exception->getMessage() );
|
@@ -608,7 +618,7 @@ class Products {
|
|
608 |
}
|
609 |
|
610 |
$duplicated_product->delete_meta_data( Product::SQUARE_ID_META_KEY );
|
611 |
-
$duplicated_product->delete_meta_data( Product::SQUARE_VARIATION_ID_META_KEY
|
612 |
|
613 |
if ( $duplicated_product->is_type( 'variable' ) ) {
|
614 |
|
@@ -643,7 +653,7 @@ class Products {
|
|
643 |
if ( $product && 'hidden' === $product->get_catalog_visibility() ) {
|
644 |
|
645 |
$product_id = $product->get_id();
|
646 |
-
$records = Records::get_records(
|
647 |
|
648 |
foreach ( $records as $record ) {
|
649 |
|
@@ -655,7 +665,8 @@ class Products {
|
|
655 |
esc_html__( 'The product catalog visibility has been set to "hidden", as a matching product could not be found in Square on %1$s at %2$s. %3$sCheck sync records%4$s.', 'woocommerce-square' ),
|
656 |
date_i18n( wc_date_format(), $record->get_timestamp() ),
|
657 |
date_i18n( wc_time_format(), $record->get_timestamp() ),
|
658 |
-
'<a href="' . esc_url( add_query_arg(
|
|
|
659 |
)
|
660 |
);
|
661 |
|
@@ -674,11 +685,11 @@ class Products {
|
|
674 |
* @return array errors
|
675 |
*/
|
676 |
private function check_product_sync_errors( \WC_Product $product ) {
|
677 |
-
$errors =
|
678 |
if ( $product->is_type( 'variable' ) && $product->has_child() ) {
|
679 |
if ( Product::has_multiple_variation_attributes( $product ) ) {
|
680 |
$errors['multiple_attributes'] = $this->format_product_error( 'multiple_attributes', $product );
|
681 |
-
}
|
682 |
$errors['missing_variation_sku'] = $this->format_product_error( 'missing_variation_sku', $product );
|
683 |
}
|
684 |
} else {
|
@@ -699,7 +710,7 @@ class Products {
|
|
699 |
*/
|
700 |
private function format_product_error( string $error, \WC_Product $product ) {
|
701 |
return sprintf(
|
702 |
-
$this->product_errors[$error],
|
703 |
Product::get_product_edit_link( $product )
|
704 |
);
|
705 |
}
|
23 |
|
24 |
namespace WooCommerce\Square\Handlers;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Product;
|
42 |
private $product_errors;
|
43 |
|
44 |
/** @var array associative array of memoized errors being output for a product at one time */
|
45 |
+
private $output_errors = array();
|
46 |
|
47 |
/** @var int[] array of product IDs that have been scheduled for sync in this request */
|
48 |
+
private $products_to_sync = array();
|
49 |
|
50 |
/** @var int[] array of product IDs that have been scheduled for deletion in this request */
|
51 |
+
private $products_to_delete = array();
|
52 |
|
53 |
/** @var Square\Plugin plugin instance */
|
54 |
private $plugin;
|
63 |
$this->plugin = $plugin;
|
64 |
|
65 |
// add common errors
|
66 |
+
$this->product_errors = array(
|
67 |
/* translators: Placeholder: %s - product name */
|
68 |
'missing_sku' => __( "Please add an SKU to sync %s with Square. The SKU must match the item's SKU in your Square account.", 'woocommerce-square' ),
|
69 |
/* translators: Placeholder: %s - product name */
|
70 |
'missing_variation_sku' => __( "Please add an SKU to every variation of %s for syncing with Square. Each SKU must match the corresponding item's SKU in your Square account.", 'woocommerce-square' ),
|
71 |
/* translators: Placeholder: %s - product name */
|
72 |
'multiple_attributes' => __( '%s has multiple variation attributes and cannot be synced with Square.', 'woocommerce-square' ),
|
73 |
+
);
|
74 |
|
75 |
// add hooks
|
76 |
$this->add_products_edit_screen_hooks();
|
89 |
private function add_products_edit_screen_hooks() {
|
90 |
|
91 |
// adds an option to the "Filter by product type" dropdown
|
92 |
+
add_action( 'restrict_manage_posts', array( $this, 'add_filter_products_synced_with_square_option' ) );
|
93 |
// allow filtering products by sync status by altering results
|
94 |
+
add_filter( 'request', array( $this, 'filter_products_synced_with_square' ) );
|
95 |
|
96 |
// prevent copying Square data when duplicating a product automatically
|
97 |
+
add_action( 'woocommerce_product_duplicate', array( $this, 'handle_product_duplication' ), 20, 2 );
|
98 |
|
99 |
// handle quick/bulk edit actions in the products edit screen for setting sync status
|
100 |
+
add_action( 'woocommerce_product_quick_edit_end', array( $this, 'add_quick_edit_inputs' ) );
|
101 |
+
add_action( 'woocommerce_product_bulk_edit_end', array( $this, 'add_bulk_edit_inputs' ) );
|
102 |
+
add_action( 'woocommerce_product_quick_edit_save', array( $this, 'set_synced_with_square' ) );
|
103 |
+
add_action( 'woocommerce_product_bulk_edit_save', array( $this, 'set_synced_with_square' ) );
|
104 |
}
|
105 |
|
106 |
|
113 |
*/
|
114 |
private function add_product_edit_screen_hooks() {
|
115 |
|
116 |
+
add_action( 'woocommerce_variation_options', array( $this, 'add_variation_manage_stock' ) );
|
117 |
|
118 |
// handle individual products input fields for setting sync status
|
119 |
+
add_action( 'woocommerce_product_options_general_product_data', array( $this, 'add_product_data_fields' ) );
|
120 |
+
add_action( 'woocommerce_admin_process_product_object', array( $this, 'process_product_data' ), 20 );
|
121 |
+
add_action( 'woocommerce_before_product_object_save', array( $this, 'maybe_adjust_square_stock' ) );
|
122 |
|
123 |
+
add_action( 'admin_notices', array( $this, 'add_notice_product_hidden_from_catalog' ) );
|
124 |
}
|
125 |
|
126 |
|
140 |
return;
|
141 |
}
|
142 |
|
143 |
+
?> <input type="hidden" id="wc_square_variation_manage_stock" name="variable_manage_stock[<?php echo esc_attr( $loop ); ?>]" value="1" />
|
144 |
+
<?php
|
145 |
}
|
146 |
|
147 |
|
152 |
*/
|
153 |
private function add_product_sync_hooks() {
|
154 |
|
155 |
+
add_action( 'woocommerce_update_product', array( $this, 'validate_product_update_and_sync' ) );
|
156 |
+
add_action( 'trashed_post', array( $this, 'maybe_stage_products_for_deletion' ) );
|
157 |
+
add_action( 'shutdown', array( $this, 'maybe_sync_staged_products' ) );
|
158 |
+
add_action( 'shutdown', array( $this, 'maybe_delete_staged_products' ) );
|
159 |
}
|
160 |
|
161 |
|
177 |
$label = esc_html__( 'Synced with Square', 'woocommerce-square' );
|
178 |
$selected = isset( $_GET['product_type'] ) && 'synced-with-square' === $_GET['product_type'] ? 'selected=\"selected\"' : '';
|
179 |
|
180 |
+
wc_enqueue_js(
|
181 |
+
"
|
182 |
jQuery( document ).ready( function( $ ) {
|
183 |
+
$( 'select#dropdown_product_type' ) . append( '<option value=\"synced-with-square\" ' + '" . $selected . "' + '>' + '" . $label . "' + '</option>' );
|
184 |
} );
|
185 |
+
"
|
186 |
+
);
|
187 |
}
|
188 |
|
189 |
|
197 |
* @param array $query_vars query variables
|
198 |
* @return array
|
199 |
*/
|
200 |
+
public function filter_products_synced_with_square( $query_vars ) {
|
201 |
global $typenow;
|
202 |
|
203 |
if ( 'product' === $typenow && isset( $_GET['product_type'] ) && 'synced-with-square' === $_GET['product_type'] ) {
|
206 |
unset( $query_vars['product_type'] );
|
207 |
|
208 |
if ( ! isset( $query_vars['tax_query'] ) ) {
|
209 |
+
$query_vars['tax_query'] = array();
|
210 |
} else {
|
211 |
$query_vars['tax_query']['relation'] = 'AND';
|
212 |
}
|
213 |
|
214 |
+
$query_vars['tax_query'][] = array(
|
215 |
'taxonomy' => Product::SYNCED_WITH_SQUARE_TAXONOMY,
|
216 |
'field' => 'slug',
|
217 |
+
'terms' => array( 'yes' ),
|
218 |
+
);
|
219 |
}
|
220 |
|
221 |
return $query_vars;
|
245 |
<div class="wc-square-sync-with-square options_group show_if_simple show_if_variable">
|
246 |
<?php
|
247 |
|
248 |
+
$selector = '_' . Product::SYNCED_WITH_SQUARE_TAXONOMY;
|
249 |
+
$value = Product::is_synced_with_square( $product_object ) ? 'yes' : 'no';
|
250 |
+
$errors = $this->check_product_sync_errors( $product_object );
|
251 |
|
252 |
$setting_label = wc_square()->get_settings_handler()->is_system_of_record_square() ? __( 'Update product data with Square data', 'woocommerce-square' ) : __( 'Send product data to Square', 'woocommerce-square' );
|
253 |
|
254 |
+
woocommerce_wp_checkbox(
|
255 |
+
array(
|
256 |
+
'id' => $selector,
|
257 |
+
'label' => __( 'Sync with Square', 'woocommerce-square' ),
|
258 |
+
'value' => $value,
|
259 |
+
'cbvalue' => 'yes',
|
260 |
+
'default' => 'no',
|
261 |
+
'description' => $setting_label,
|
262 |
+
'custom_attributes' => ! empty( $errors ) ? array( 'disabled' => 'disabled' ) : array(),
|
263 |
+
)
|
264 |
+
);
|
265 |
|
266 |
?>
|
267 |
<p class="form-field wc-square-sync-with-square-errors">
|
268 |
+
<?php foreach ( $this->product_errors as $error_code => $error_message ) : ?>
|
269 |
<?php $styles = ! in_array( $error_code, array_keys( $errors ), true ) ? 'display:none; color:#A00;' : 'display:block; color:#A00;'; ?>
|
270 |
<span class="wc-square-sync-with-square-error <?php echo sanitize_html_class( $error_code ); ?>" style="<?php echo $styles; ?>"><?php echo $this->format_product_error( $error_code, $product_object ); ?></span>
|
271 |
<?php endforeach; ?>
|
365 |
|
366 |
foreach ( $errors as $error ) {
|
367 |
wc_square()->get_message_handler()->add_error( $error );
|
368 |
+
Records::set_record(
|
369 |
+
array(
|
370 |
+
'type' => 'alert',
|
371 |
+
'product_id' => $product_id,
|
372 |
+
'message' => $error,
|
373 |
+
)
|
374 |
+
);
|
375 |
}
|
376 |
} else {
|
377 |
$this->maybe_stage_product_for_sync( $product );
|
472 |
$default_value = 'no'; // in individual products context, the value should be always an explicit yes or no
|
473 |
}
|
474 |
|
475 |
+
$square_synced = isset( $_REQUEST[ $posted_data_key ] ) && in_array( $_REQUEST[ $posted_data_key ], array( 'yes', 'no' ), true ) ? $_REQUEST[ $posted_data_key ] : $default_value;
|
476 |
+
|
477 |
if ( is_string( $square_synced ) ) {
|
478 |
$errors = $this->check_product_sync_errors( $product );
|
479 |
if ( 'no' === $square_synced || empty( $errors ) ) {
|
480 |
Product::set_synced_with_square( $product, $square_synced );
|
481 |
+
} elseif ( ! empty( $errors ) ) {
|
482 |
foreach ( $errors as $error ) {
|
483 |
wc_square()->get_message_handler()->add_error( $error );
|
484 |
}
|
508 |
return;
|
509 |
}
|
510 |
|
511 |
+
$errors = array();
|
512 |
$posted_key = '_' . Product::SYNCED_WITH_SQUARE_TAXONOMY;
|
513 |
$set_synced = isset( $_POST[ $posted_key ] ) && 'yes' === $_POST[ $posted_key ];
|
514 |
$was_synced = Product::is_synced_with_square( $product );
|
588 |
} else {
|
589 |
wc_square()->get_api()->remove_inventory( $square_id, $change );
|
590 |
}
|
|
|
591 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
592 |
|
593 |
wc_square()->log( 'Could not adjust Square inventory for ' . $product->get_formatted_name() . '. ' . $exception->getMessage() );
|
618 |
}
|
619 |
|
620 |
$duplicated_product->delete_meta_data( Product::SQUARE_ID_META_KEY );
|
621 |
+
$duplicated_product->delete_meta_data( Product::SQUARE_VARIATION_ID_META_KEY );
|
622 |
|
623 |
if ( $duplicated_product->is_type( 'variable' ) ) {
|
624 |
|
653 |
if ( $product && 'hidden' === $product->get_catalog_visibility() ) {
|
654 |
|
655 |
$product_id = $product->get_id();
|
656 |
+
$records = Records::get_records( array( 'product' => $product_id ) );
|
657 |
|
658 |
foreach ( $records as $record ) {
|
659 |
|
665 |
esc_html__( 'The product catalog visibility has been set to "hidden", as a matching product could not be found in Square on %1$s at %2$s. %3$sCheck sync records%4$s.', 'woocommerce-square' ),
|
666 |
date_i18n( wc_date_format(), $record->get_timestamp() ),
|
667 |
date_i18n( wc_time_format(), $record->get_timestamp() ),
|
668 |
+
'<a href="' . esc_url( add_query_arg( array( 'section' => 'update' ), wc_square()->get_settings_url() ) ) . '">',
|
669 |
+
'</a>'
|
670 |
)
|
671 |
);
|
672 |
|
685 |
* @return array errors
|
686 |
*/
|
687 |
private function check_product_sync_errors( \WC_Product $product ) {
|
688 |
+
$errors = array();
|
689 |
if ( $product->is_type( 'variable' ) && $product->has_child() ) {
|
690 |
if ( Product::has_multiple_variation_attributes( $product ) ) {
|
691 |
$errors['multiple_attributes'] = $this->format_product_error( 'multiple_attributes', $product );
|
692 |
+
} elseif ( ! Product::has_sku( $product ) ) {
|
693 |
$errors['missing_variation_sku'] = $this->format_product_error( 'missing_variation_sku', $product );
|
694 |
}
|
695 |
} else {
|
710 |
*/
|
711 |
private function format_product_error( string $error, \WC_Product $product ) {
|
712 |
return sprintf(
|
713 |
+
$this->product_errors[ $error ],
|
714 |
Product::get_product_edit_link( $product )
|
715 |
);
|
716 |
}
|
includes/Handlers/Sync.php
CHANGED
@@ -28,7 +28,7 @@ use WooCommerce\Square\Plugin;
|
|
28 |
use WooCommerce\Square\Sync\Interval_Polling;
|
29 |
use WooCommerce\Square\Sync\Records;
|
30 |
|
31 |
-
defined( 'ABSPATH' )
|
32 |
|
33 |
/**
|
34 |
* Synchronization handler class
|
@@ -73,10 +73,10 @@ class Sync {
|
|
73 |
private function add_hooks() {
|
74 |
|
75 |
// schedule the interval sync
|
76 |
-
add_action( 'init',
|
77 |
|
78 |
// run the interval sync when fired by Action Scheduler
|
79 |
-
add_action( $this->sync_scheduled_event_name,
|
80 |
}
|
81 |
|
82 |
|
@@ -115,8 +115,8 @@ class Sync {
|
|
115 |
$plugin_id = $this->get_plugin()->get_id();
|
116 |
$interval = $this->get_sync_schedule_interval();
|
117 |
|
118 |
-
if ( false === as_next_scheduled_action( $this->sync_scheduled_event_name,
|
119 |
-
as_schedule_recurring_action( time() + $interval, $interval, $this->sync_scheduled_event_name,
|
120 |
}
|
121 |
}
|
122 |
|
@@ -128,7 +128,7 @@ class Sync {
|
|
128 |
*/
|
129 |
public function unschedule_sync() {
|
130 |
|
131 |
-
as_unschedule_action( $this->sync_scheduled_event_name,
|
132 |
}
|
133 |
|
134 |
|
@@ -142,9 +142,11 @@ class Sync {
|
|
142 |
*/
|
143 |
public function start_product_import( $dispatch = true ) {
|
144 |
|
145 |
-
$job = $this->get_plugin()->get_background_job_handler()->create_job(
|
146 |
-
|
147 |
-
|
|
|
|
|
148 |
|
149 |
if ( $job ) {
|
150 |
|
@@ -166,15 +168,17 @@ class Sync {
|
|
166 |
* @param int[] $product_ids (optional) array of product IDs to sync
|
167 |
* @return \stdClass|null
|
168 |
*/
|
169 |
-
public function start_manual_sync( $dispatch = true, array $product_ids =
|
170 |
|
171 |
$product_ids = empty( $product_ids ) ? Product::get_products_synced_with_square() : $product_ids;
|
172 |
|
173 |
-
$job = $this->get_plugin()->get_background_job_handler()->create_job(
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
|
|
|
|
178 |
|
179 |
if ( $job ) {
|
180 |
|
@@ -198,11 +202,13 @@ class Sync {
|
|
198 |
*/
|
199 |
public function start_manual_deletion( array $product_ids, $dispatch = true ) {
|
200 |
|
201 |
-
$job = $this->get_plugin()->get_background_job_handler()->create_job(
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
|
|
|
|
206 |
|
207 |
if ( $job ) {
|
208 |
|
@@ -230,12 +236,14 @@ class Sync {
|
|
230 |
// use this opportunity to clear old background jobs
|
231 |
$this->get_plugin()->get_background_job_handler()->clear_all_jobs();
|
232 |
|
233 |
-
$job = $this->get_plugin()->get_background_job_handler()->create_job(
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
|
|
|
|
239 |
|
240 |
if ( $job ) {
|
241 |
$this->get_plugin()->get_background_job_handler()->dispatch();
|
@@ -276,7 +284,7 @@ class Sync {
|
|
276 |
public function is_sync_in_progress() {
|
277 |
|
278 |
return ( defined( 'DOING_SQUARE_SYNC' ) && true === DOING_SQUARE_SYNC )
|
279 |
-
|
280 |
}
|
281 |
|
282 |
|
@@ -311,14 +319,16 @@ class Sync {
|
|
311 |
// only add a record of some products were synced
|
312 |
if ( $products ) {
|
313 |
|
314 |
-
Records::set_record(
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
|
|
|
|
322 |
}
|
323 |
|
324 |
/**
|
@@ -370,7 +380,7 @@ class Sync {
|
|
370 |
$job = null;
|
371 |
}
|
372 |
|
373 |
-
return $job && isset( $job->status ) && in_array( $job->status,
|
374 |
}
|
375 |
|
376 |
|
28 |
use WooCommerce\Square\Sync\Interval_Polling;
|
29 |
use WooCommerce\Square\Sync\Records;
|
30 |
|
31 |
+
defined( 'ABSPATH' ) || exit;
|
32 |
|
33 |
/**
|
34 |
* Synchronization handler class
|
73 |
private function add_hooks() {
|
74 |
|
75 |
// schedule the interval sync
|
76 |
+
add_action( 'init', array( $this, 'schedule_sync' ) );
|
77 |
|
78 |
// run the interval sync when fired by Action Scheduler
|
79 |
+
add_action( $this->sync_scheduled_event_name, array( $this, 'start_interval_sync' ) );
|
80 |
}
|
81 |
|
82 |
|
115 |
$plugin_id = $this->get_plugin()->get_id();
|
116 |
$interval = $this->get_sync_schedule_interval();
|
117 |
|
118 |
+
if ( false === as_next_scheduled_action( $this->sync_scheduled_event_name, array(), $plugin_id ) ) {
|
119 |
+
as_schedule_recurring_action( time() + $interval, $interval, $this->sync_scheduled_event_name, array(), $plugin_id );
|
120 |
}
|
121 |
}
|
122 |
|
128 |
*/
|
129 |
public function unschedule_sync() {
|
130 |
|
131 |
+
as_unschedule_action( $this->sync_scheduled_event_name, array(), $this->get_plugin()->get_id() );
|
132 |
}
|
133 |
|
134 |
|
142 |
*/
|
143 |
public function start_product_import( $dispatch = true ) {
|
144 |
|
145 |
+
$job = $this->get_plugin()->get_background_job_handler()->create_job(
|
146 |
+
array(
|
147 |
+
'action' => 'product_import',
|
148 |
+
)
|
149 |
+
);
|
150 |
|
151 |
if ( $job ) {
|
152 |
|
168 |
* @param int[] $product_ids (optional) array of product IDs to sync
|
169 |
* @return \stdClass|null
|
170 |
*/
|
171 |
+
public function start_manual_sync( $dispatch = true, array $product_ids = array() ) {
|
172 |
|
173 |
$product_ids = empty( $product_ids ) ? Product::get_products_synced_with_square() : $product_ids;
|
174 |
|
175 |
+
$job = $this->get_plugin()->get_background_job_handler()->create_job(
|
176 |
+
array(
|
177 |
+
'action' => 'sync',
|
178 |
+
'manual' => true,
|
179 |
+
'product_ids' => $product_ids,
|
180 |
+
)
|
181 |
+
);
|
182 |
|
183 |
if ( $job ) {
|
184 |
|
202 |
*/
|
203 |
public function start_manual_deletion( array $product_ids, $dispatch = true ) {
|
204 |
|
205 |
+
$job = $this->get_plugin()->get_background_job_handler()->create_job(
|
206 |
+
array(
|
207 |
+
'action' => 'delete',
|
208 |
+
'manual' => true,
|
209 |
+
'product_ids' => $product_ids,
|
210 |
+
)
|
211 |
+
);
|
212 |
|
213 |
if ( $job ) {
|
214 |
|
236 |
// use this opportunity to clear old background jobs
|
237 |
$this->get_plugin()->get_background_job_handler()->clear_all_jobs();
|
238 |
|
239 |
+
$job = $this->get_plugin()->get_background_job_handler()->create_job(
|
240 |
+
array(
|
241 |
+
'action' => 'poll',
|
242 |
+
'manual' => false,
|
243 |
+
'catalog_last_synced_at' => $this->get_last_synced_at(),
|
244 |
+
'inventory_last_synced_at' => $this->get_inventory_last_synced_at(),
|
245 |
+
)
|
246 |
+
);
|
247 |
|
248 |
if ( $job ) {
|
249 |
$this->get_plugin()->get_background_job_handler()->dispatch();
|
284 |
public function is_sync_in_progress() {
|
285 |
|
286 |
return ( defined( 'DOING_SQUARE_SYNC' ) && true === DOING_SQUARE_SYNC )
|
287 |
+
|| null !== $this->get_job_in_progress();
|
288 |
}
|
289 |
|
290 |
|
319 |
// only add a record of some products were synced
|
320 |
if ( $products ) {
|
321 |
|
322 |
+
Records::set_record(
|
323 |
+
array(
|
324 |
+
'id' => $job && isset( $job->id ) ? $job->id : null,
|
325 |
+
'message' => sprintf(
|
326 |
+
/* translators: Placeholder: %d number of products processed */
|
327 |
+
_n( 'Updated data for %d product.', 'Updated data for %d products.', $products, 'woocommerce-square' ),
|
328 |
+
$products
|
329 |
+
),
|
330 |
+
)
|
331 |
+
);
|
332 |
}
|
333 |
|
334 |
/**
|
380 |
$job = null;
|
381 |
}
|
382 |
|
383 |
+
return $job && isset( $job->status ) && in_array( $job->status, array( 'created', 'queued', 'processing' ), true ) ? $job : null;
|
384 |
}
|
385 |
|
386 |
|
includes/Lifecycle.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Product;
|
@@ -43,18 +43,19 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
43 |
*
|
44 |
* @since 2.0.0
|
45 |
*
|
46 |
-
* @param Plugin $plugin main instance
|
47 |
*/
|
48 |
public function __construct( Plugin $plugin ) {
|
49 |
|
50 |
parent::__construct( $plugin );
|
51 |
|
52 |
-
// plugin upgrade path: maps automatically each semver to upgrade_to_x_y_z() protected method
|
53 |
-
$this->upgrade_versions =
|
54 |
'2.0.0',
|
55 |
'2.0.4',
|
56 |
'2.1.5',
|
57 |
-
|
|
|
58 |
}
|
59 |
|
60 |
|
@@ -65,7 +66,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
65 |
*/
|
66 |
protected function install() {
|
67 |
|
68 |
-
// create the db table for the customer index
|
69 |
Gateway\Customer_Helper::create_table();
|
70 |
|
71 |
/**
|
@@ -84,7 +85,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
84 |
*
|
85 |
* @since 2.0.0
|
86 |
*
|
87 |
-
* @param string $installed_version semver
|
88 |
*/
|
89 |
protected function upgrade( $installed_version ) {
|
90 |
|
@@ -109,16 +110,10 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
109 |
*/
|
110 |
protected function upgrade_to_2_0_0() {
|
111 |
|
112 |
-
// create the db table for the customer index
|
113 |
Gateway\Customer_Helper::create_table();
|
114 |
|
115 |
-
|
116 |
-
if ( function_exists( 'set_time_limit' )
|
117 |
-
&& ! ini_get( 'safe_mode' )
|
118 |
-
&& false === strpos( ini_get( 'disable_functions' ), 'set_time_limit' ) ) {
|
119 |
-
|
120 |
-
@set_time_limit( 300 );
|
121 |
-
}
|
122 |
|
123 |
// migrate all the things!
|
124 |
$syncing_products = $this->migrate_plugin_settings();
|
@@ -126,19 +121,19 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
126 |
$this->migrate_gateway_settings();
|
127 |
$this->migrate_orders();
|
128 |
|
129 |
-
// only set the products "sync" status if v2 is now configured to sync products
|
130 |
if ( $syncing_products ) {
|
131 |
|
132 |
$this->migrate_products();
|
133 |
|
134 |
-
// assume a last sync occurred before upgrading
|
135 |
$this->get_plugin()->get_sync_handler()->set_last_synced_at();
|
136 |
$this->get_plugin()->get_sync_handler()->set_inventory_last_synced_at();
|
137 |
}
|
138 |
|
139 |
$this->migrate_customers();
|
140 |
|
141 |
-
// mark upgrade complete
|
142 |
update_option( 'wc_square_updated_to_2_0_0', true );
|
143 |
}
|
144 |
|
@@ -150,8 +145,8 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
150 |
*/
|
151 |
protected function upgrade_to_2_0_4() {
|
152 |
|
153 |
-
$v1_settings = get_option( 'woocommerce_squareconnect_settings',
|
154 |
-
$v2_settings = get_option( 'wc_square_settings',
|
155 |
|
156 |
$v2_settings = $this->get_migrated_system_of_record( $v1_settings, $v2_settings );
|
157 |
|
@@ -170,6 +165,58 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
170 |
Gateway\Customer_Helper::create_table();
|
171 |
}
|
172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
/**
|
174 |
* Migrates plugin settings from v1 to v2.
|
175 |
*
|
@@ -183,20 +230,21 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
183 |
|
184 |
$this->get_plugin()->log( 'Migrating plugin settings...' );
|
185 |
|
186 |
-
// get legacy and new default settings
|
187 |
-
$new_settings = get_option( 'wc_square_settings',
|
188 |
-
$legacy_settings = get_option( 'woocommerce_squareconnect_settings',
|
189 |
-
$email_settings = get_option( 'woocommerce_wc_square_sync_completed_settings',
|
190 |
|
191 |
-
// bail if they already have v2 settings present
|
192 |
if ( ! empty( $new_settings ) ) {
|
193 |
return;
|
194 |
}
|
195 |
|
196 |
-
// handle access token first
|
197 |
-
|
|
|
198 |
|
199 |
-
// the access token was previously stored unencrypted
|
200 |
if ( ! empty( $legacy_access_token ) && Utilities\Encryption_Utility::is_encryption_supported() ) {
|
201 |
|
202 |
$encryption = new Utilities\Encryption_Utility();
|
@@ -204,46 +252,46 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
204 |
try {
|
205 |
$legacy_access_token = $encryption->encrypt_data( $legacy_access_token );
|
206 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
207 |
-
// log the event, but don't halt the process
|
208 |
$this->get_plugin()->log( 'Could not encrypt access token during upgrade. ' . $exception->getMessage() );
|
209 |
}
|
210 |
}
|
211 |
|
212 |
-
// previously only 'production' environment was assumed
|
213 |
-
$access_tokens = get_option( 'wc_square_access_tokens',
|
214 |
$access_tokens['production'] = is_string( $legacy_access_token ) ? $legacy_access_token : '';
|
215 |
|
216 |
update_option( 'wc_square_access_tokens', $access_tokens );
|
217 |
}
|
218 |
|
219 |
-
// migrate store location
|
220 |
if ( ! empty( $legacy_settings['location'] ) ) {
|
221 |
$new_settings['location_id'] = $legacy_settings['location'];
|
222 |
}
|
223 |
|
224 |
-
// toggle debug logging
|
225 |
-
$new_settings['debug_logging_enabled'] = isset( $legacy_settings['logging'] ) && in_array( $legacy_settings['logging'],
|
226 |
|
227 |
-
// set the SOR and inventory sync values
|
228 |
$new_settings = $this->get_migrated_system_of_record( $legacy_settings, $new_settings );
|
229 |
|
230 |
-
// migrate email notification settings: if there's a recipient, we enable email and pass recipient(s) to email setting
|
231 |
if ( isset( $legacy_settings['sync_email'] ) && is_string( $legacy_settings['sync_email'] ) && '' !== trim( $legacy_settings['sync_email'] ) ) {
|
232 |
$email_settings['enabled'] = 'yes';
|
233 |
-
$email_settings['recipient'] = $legacy_settings['sync_email']
|
234 |
} else {
|
235 |
$email_settings['enabled'] = 'no';
|
236 |
$email_settings['recipient'] = '';
|
237 |
}
|
238 |
|
239 |
-
// save email settings
|
240 |
update_option( 'woocommerce_wc_square_sync_completed_settings', $email_settings );
|
241 |
-
// save plugin settings
|
242 |
update_option( 'wc_square_settings', $new_settings );
|
243 |
|
244 |
$this->get_plugin()->log( 'Plugin settings migration complete.' );
|
245 |
|
246 |
-
return isset( $new_settings['system_of_record'] ) && $new_settings['system_of_record']
|
247 |
}
|
248 |
|
249 |
|
@@ -258,10 +306,10 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
258 |
|
259 |
$this->get_plugin()->log( 'Migrating gateway settings...' );
|
260 |
|
261 |
-
$legacy_settings = get_option( 'woocommerce_square_settings',
|
262 |
-
$new_settings = get_option( 'woocommerce_square_credit_card_settings',
|
263 |
|
264 |
-
// bail if they already have v2 settings present
|
265 |
if ( ! empty( $new_settings ) ) {
|
266 |
return;
|
267 |
}
|
@@ -272,18 +320,18 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
272 |
|
273 |
if ( isset( $legacy_settings['title'] ) && is_string( $legacy_settings['title'] ) ) {
|
274 |
$new_settings['title'] = $legacy_settings['title'];
|
275 |
-
|
276 |
|
277 |
if ( isset( $legacy_settings['description'] ) && is_string( $legacy_settings['description'] ) ) {
|
278 |
$new_settings['description'] = $legacy_settings['description'];
|
279 |
}
|
280 |
|
281 |
-
// note: the following is not an error, the setting on v1 intends "delayed" capture, hence authorization only, if set
|
282 |
if ( isset( $legacy_settings['capture'] ) ) {
|
283 |
$new_settings['transaction_type'] = 'yes' === $legacy_settings['capture'] ? Gateway::TRANSACTION_TYPE_AUTHORIZATION : Gateway::TRANSACTION_TYPE_CHARGE;
|
284 |
}
|
285 |
|
286 |
-
// not quite the same, since tokenization is a new thing, but we could presume the intention to let customers save their payment details
|
287 |
if ( isset( $legacy_settings['create_customer'] ) ) {
|
288 |
$new_settings['tokenization'] = 'yes' === $legacy_settings['create_customer'] ? 'yes' : 'no';
|
289 |
}
|
@@ -292,16 +340,16 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
292 |
$new_settings['debug_mode'] = 'yes' === $legacy_settings['logging'] ? 'log' : 'off';
|
293 |
}
|
294 |
|
295 |
-
// there was no card types setting in v1
|
296 |
-
$new_settings['card_types'] =
|
297 |
'VISA',
|
298 |
'MC',
|
299 |
'AMEX',
|
300 |
'JCB',
|
301 |
-
// purposefully omit dinersclub & discover
|
302 |
-
|
303 |
|
304 |
-
// save migrated settings
|
305 |
update_option( 'woocommerce_square_credit_card_settings', $new_settings );
|
306 |
|
307 |
$this->get_plugin()->log( 'Gateway settings migration complete.' );
|
@@ -320,12 +368,20 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
320 |
|
321 |
$this->get_plugin()->log( 'Migrating orders data...' );
|
322 |
|
323 |
-
// move charge captured flag in orders to SkyVerge framework meta key
|
324 |
-
$wpdb->update( $wpdb->postmeta,
|
325 |
-
|
326 |
-
// move payment ID to new gateway ID meta key value
|
327 |
-
$wpdb->update(
|
328 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
329 |
$this->get_plugin()->log( 'Orders migration complete.' );
|
330 |
}
|
331 |
|
@@ -342,42 +398,45 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
342 |
|
343 |
$this->get_plugin()->log( 'Migrating products data...' );
|
344 |
|
345 |
-
// the handling in v1 was reversed, so we want products where sync wasn't disabled
|
346 |
-
$legacy_product_ids = get_posts(
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
'
|
353 |
-
|
354 |
-
'
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
|
|
|
|
|
|
365 |
if ( ! empty( $legacy_product_ids ) ) {
|
366 |
|
367 |
-
$failed_products =
|
368 |
|
369 |
-
// ensure taxonomy is registered at this stage
|
370 |
if ( ! taxonomy_exists( Product::SYNCED_WITH_SQUARE_TAXONOMY ) ) {
|
371 |
Product::init_taxonomies();
|
372 |
}
|
373 |
|
374 |
-
// will not create the term if already exists
|
375 |
wp_create_term( 'yes', Product::SYNCED_WITH_SQUARE_TAXONOMY );
|
376 |
|
377 |
-
// set Square sync status via taxonomy term
|
378 |
foreach ( $legacy_product_ids as $i => $product_id ) {
|
379 |
|
380 |
-
$set_term = wp_set_object_terms( $product_id,
|
381 |
|
382 |
if ( ! is_array( $set_term ) ) {
|
383 |
|
@@ -387,7 +446,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
387 |
}
|
388 |
}
|
389 |
|
390 |
-
// log any errors
|
391 |
if ( ! empty( $failed_products ) ) {
|
392 |
$this->get_plugin()->log( 'Could not update sync with Square status for products with ID: ' . implode( ', ', array_unique( $failed_products ) ) . '.' );
|
393 |
}
|
@@ -407,7 +466,7 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
407 |
|
408 |
$this->get_plugin()->log( 'Migrating customer data.' );
|
409 |
|
410 |
-
$rows = (int) $wpdb->update( $wpdb->usermeta,
|
411 |
|
412 |
$this->get_plugin()->log( sprintf( '%d customers migrated', $rows ) );
|
413 |
}
|
@@ -418,8 +477,8 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
418 |
*
|
419 |
* @since 2.0.2
|
420 |
*
|
421 |
-
* @param array $v1_settings v1 plugin settings
|
422 |
-
* @param array $v2_settings v2 plugin settings
|
423 |
* @return array
|
424 |
*/
|
425 |
private function get_migrated_system_of_record( $v1_settings, $v2_settings ) {
|
@@ -434,5 +493,23 @@ class Lifecycle extends Framework\Plugin\Lifecycle {
|
|
434 |
return $v2_settings;
|
435 |
}
|
436 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
437 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
438 |
}
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Product;
|
43 |
*
|
44 |
* @since 2.0.0
|
45 |
*
|
46 |
+
* @param Plugin $plugin main instance.
|
47 |
*/
|
48 |
public function __construct( Plugin $plugin ) {
|
49 |
|
50 |
parent::__construct( $plugin );
|
51 |
|
52 |
+
// plugin upgrade path: maps automatically each semver to upgrade_to_x_y_z() protected method.
|
53 |
+
$this->upgrade_versions = array(
|
54 |
'2.0.0',
|
55 |
'2.0.4',
|
56 |
'2.1.5',
|
57 |
+
'2.2.0',
|
58 |
+
);
|
59 |
}
|
60 |
|
61 |
|
66 |
*/
|
67 |
protected function install() {
|
68 |
|
69 |
+
// create the db table for the customer index.
|
70 |
Gateway\Customer_Helper::create_table();
|
71 |
|
72 |
/**
|
85 |
*
|
86 |
* @since 2.0.0
|
87 |
*
|
88 |
+
* @param string $installed_version semver.
|
89 |
*/
|
90 |
protected function upgrade( $installed_version ) {
|
91 |
|
110 |
*/
|
111 |
protected function upgrade_to_2_0_0() {
|
112 |
|
113 |
+
// create the db table for the customer index.
|
114 |
Gateway\Customer_Helper::create_table();
|
115 |
|
116 |
+
wc_set_time_limit( 300 );
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
|
118 |
// migrate all the things!
|
119 |
$syncing_products = $this->migrate_plugin_settings();
|
121 |
$this->migrate_gateway_settings();
|
122 |
$this->migrate_orders();
|
123 |
|
124 |
+
// only set the products "sync" status if v2 is now configured to sync products.
|
125 |
if ( $syncing_products ) {
|
126 |
|
127 |
$this->migrate_products();
|
128 |
|
129 |
+
// assume a last sync occurred before upgrading.
|
130 |
$this->get_plugin()->get_sync_handler()->set_last_synced_at();
|
131 |
$this->get_plugin()->get_sync_handler()->set_inventory_last_synced_at();
|
132 |
}
|
133 |
|
134 |
$this->migrate_customers();
|
135 |
|
136 |
+
// mark upgrade complete.
|
137 |
update_option( 'wc_square_updated_to_2_0_0', true );
|
138 |
}
|
139 |
|
145 |
*/
|
146 |
protected function upgrade_to_2_0_4() {
|
147 |
|
148 |
+
$v1_settings = get_option( 'woocommerce_squareconnect_settings', array() );
|
149 |
+
$v2_settings = get_option( 'wc_square_settings', array() );
|
150 |
|
151 |
$v2_settings = $this->get_migrated_system_of_record( $v1_settings, $v2_settings );
|
152 |
|
165 |
Gateway\Customer_Helper::create_table();
|
166 |
}
|
167 |
|
168 |
+
/**
|
169 |
+
* Generates a milestone notice message.
|
170 |
+
*
|
171 |
+
* @since 2.1.7
|
172 |
+
*
|
173 |
+
* @param string $custom_message Custom text that notes what milestone was completed.
|
174 |
+
* @return string
|
175 |
+
*/
|
176 |
+
protected function generate_milestone_notice_message( $custom_message ) {
|
177 |
+
|
178 |
+
$message = '';
|
179 |
+
|
180 |
+
if ( $this->get_plugin()->get_reviews_url() ) {
|
181 |
+
|
182 |
+
// to be prepended at random to each milestone notice.
|
183 |
+
$exclamations = array(
|
184 |
+
__( 'Awesome', 'woocommerce-square' ),
|
185 |
+
__( 'Congratulations', 'woocommerce-square' ),
|
186 |
+
__( 'Great', 'woocommerce-square' ),
|
187 |
+
__( 'Fantastic', 'woocommerce-square' ),
|
188 |
+
);
|
189 |
+
|
190 |
+
$message = $exclamations[ array_rand( $exclamations ) ] . ', ' . esc_html( $custom_message ) . ' ';
|
191 |
+
|
192 |
+
$message .= sprintf(
|
193 |
+
/* translators: Placeholders: %1$s - plugin name, %2$s - <a> tag, %3$s - </a> tag, %4$s - <a> tag, %5$s - </a> tag */
|
194 |
+
__( 'Are you having a great experience with %1$s so far? Please consider %2$sleaving a review%3$s! If things aren\'t going quite as expected, we\'re happy to help -- please %4$sreach out to our support team%5$s.', 'woocommerce-square' ),
|
195 |
+
'<strong>' . esc_html( $this->get_plugin()->get_plugin_name() ) . '</strong>',
|
196 |
+
'<a href="' . esc_url( $this->get_plugin()->get_reviews_url() ) . '">',
|
197 |
+
'</a>',
|
198 |
+
'<a href="' . esc_url( $this->get_plugin()->get_support_url() ) . '">',
|
199 |
+
'</a>'
|
200 |
+
);
|
201 |
+
}
|
202 |
+
|
203 |
+
return $message;
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Upgrades to version 2.2.0.
|
208 |
+
*
|
209 |
+
* @since 2.2.0
|
210 |
+
*/
|
211 |
+
protected function upgrade_to_2_2_0() {
|
212 |
+
|
213 |
+
$v1_settings = get_option( 'wc_square_settings', array() );
|
214 |
+
|
215 |
+
$v2_settings = $this->set_environment_location_id( $v1_settings );
|
216 |
+
|
217 |
+
update_option( 'wc_square_settings', $v2_settings );
|
218 |
+
}
|
219 |
+
|
220 |
/**
|
221 |
* Migrates plugin settings from v1 to v2.
|
222 |
*
|
230 |
|
231 |
$this->get_plugin()->log( 'Migrating plugin settings...' );
|
232 |
|
233 |
+
// get legacy and new default settings.
|
234 |
+
$new_settings = get_option( 'wc_square_settings', array() );
|
235 |
+
$legacy_settings = get_option( 'woocommerce_squareconnect_settings', array() );
|
236 |
+
$email_settings = get_option( 'woocommerce_wc_square_sync_completed_settings', array() );
|
237 |
|
238 |
+
// bail if they already have v2 settings present.
|
239 |
if ( ! empty( $new_settings ) ) {
|
240 |
return;
|
241 |
}
|
242 |
|
243 |
+
// handle access token first.
|
244 |
+
$legacy_access_token = get_option( 'woocommerce_square_merchant_access_token' );
|
245 |
+
if ( $legacy_access_token ) {
|
246 |
|
247 |
+
// the access token was previously stored unencrypted.
|
248 |
if ( ! empty( $legacy_access_token ) && Utilities\Encryption_Utility::is_encryption_supported() ) {
|
249 |
|
250 |
$encryption = new Utilities\Encryption_Utility();
|
252 |
try {
|
253 |
$legacy_access_token = $encryption->encrypt_data( $legacy_access_token );
|
254 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
255 |
+
// log the event, but don't halt the process.
|
256 |
$this->get_plugin()->log( 'Could not encrypt access token during upgrade. ' . $exception->getMessage() );
|
257 |
}
|
258 |
}
|
259 |
|
260 |
+
// previously only 'production' environment was assumed.
|
261 |
+
$access_tokens = get_option( 'wc_square_access_tokens', array() );
|
262 |
$access_tokens['production'] = is_string( $legacy_access_token ) ? $legacy_access_token : '';
|
263 |
|
264 |
update_option( 'wc_square_access_tokens', $access_tokens );
|
265 |
}
|
266 |
|
267 |
+
// migrate store location.
|
268 |
if ( ! empty( $legacy_settings['location'] ) ) {
|
269 |
$new_settings['location_id'] = $legacy_settings['location'];
|
270 |
}
|
271 |
|
272 |
+
// toggle debug logging.
|
273 |
+
$new_settings['debug_logging_enabled'] = isset( $legacy_settings['logging'] ) && in_array( $legacy_settings['logging'], array( 'yes', 'no' ), true ) ? $legacy_settings['logging'] : 'no';
|
274 |
|
275 |
+
// set the SOR and inventory sync values.
|
276 |
$new_settings = $this->get_migrated_system_of_record( $legacy_settings, $new_settings );
|
277 |
|
278 |
+
// migrate email notification settings: if there's a recipient, we enable email and pass recipient(s) to email setting.
|
279 |
if ( isset( $legacy_settings['sync_email'] ) && is_string( $legacy_settings['sync_email'] ) && '' !== trim( $legacy_settings['sync_email'] ) ) {
|
280 |
$email_settings['enabled'] = 'yes';
|
281 |
+
$email_settings['recipient'] = $legacy_settings['sync_email'];
|
282 |
} else {
|
283 |
$email_settings['enabled'] = 'no';
|
284 |
$email_settings['recipient'] = '';
|
285 |
}
|
286 |
|
287 |
+
// save email settings.
|
288 |
update_option( 'woocommerce_wc_square_sync_completed_settings', $email_settings );
|
289 |
+
// save plugin settings.
|
290 |
update_option( 'wc_square_settings', $new_settings );
|
291 |
|
292 |
$this->get_plugin()->log( 'Plugin settings migration complete.' );
|
293 |
|
294 |
+
return isset( $new_settings['system_of_record'] ) && Settings::SYSTEM_OF_RECORD_DISABLED !== $new_settings['system_of_record'];
|
295 |
}
|
296 |
|
297 |
|
306 |
|
307 |
$this->get_plugin()->log( 'Migrating gateway settings...' );
|
308 |
|
309 |
+
$legacy_settings = get_option( 'woocommerce_square_settings', array() );
|
310 |
+
$new_settings = get_option( 'woocommerce_square_credit_card_settings', array() );
|
311 |
|
312 |
+
// bail if they already have v2 settings present.
|
313 |
if ( ! empty( $new_settings ) ) {
|
314 |
return;
|
315 |
}
|
320 |
|
321 |
if ( isset( $legacy_settings['title'] ) && is_string( $legacy_settings['title'] ) ) {
|
322 |
$new_settings['title'] = $legacy_settings['title'];
|
323 |
+
}
|
324 |
|
325 |
if ( isset( $legacy_settings['description'] ) && is_string( $legacy_settings['description'] ) ) {
|
326 |
$new_settings['description'] = $legacy_settings['description'];
|
327 |
}
|
328 |
|
329 |
+
// note: the following is not an error, the setting on v1 intends "delayed" capture, hence authorization only, if set.
|
330 |
if ( isset( $legacy_settings['capture'] ) ) {
|
331 |
$new_settings['transaction_type'] = 'yes' === $legacy_settings['capture'] ? Gateway::TRANSACTION_TYPE_AUTHORIZATION : Gateway::TRANSACTION_TYPE_CHARGE;
|
332 |
}
|
333 |
|
334 |
+
// not quite the same, since tokenization is a new thing, but we could presume the intention to let customers save their payment details.
|
335 |
if ( isset( $legacy_settings['create_customer'] ) ) {
|
336 |
$new_settings['tokenization'] = 'yes' === $legacy_settings['create_customer'] ? 'yes' : 'no';
|
337 |
}
|
340 |
$new_settings['debug_mode'] = 'yes' === $legacy_settings['logging'] ? 'log' : 'off';
|
341 |
}
|
342 |
|
343 |
+
// there was no card types setting in v1.
|
344 |
+
$new_settings['card_types'] = array(
|
345 |
'VISA',
|
346 |
'MC',
|
347 |
'AMEX',
|
348 |
'JCB',
|
349 |
+
// purposefully omit dinersclub & discover.
|
350 |
+
);
|
351 |
|
352 |
+
// save migrated settings.
|
353 |
update_option( 'woocommerce_square_credit_card_settings', $new_settings );
|
354 |
|
355 |
$this->get_plugin()->log( 'Gateway settings migration complete.' );
|
368 |
|
369 |
$this->get_plugin()->log( 'Migrating orders data...' );
|
370 |
|
371 |
+
// move charge captured flag in orders to SkyVerge framework meta key.
|
372 |
+
$wpdb->update( $wpdb->postmeta, array( 'meta_key' => '_wc_square_credit_card_charge_captured' ), array( 'meta_key' => '_square_charge_captured' ) ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
|
373 |
+
|
374 |
+
// move payment ID to new gateway ID meta key value.
|
375 |
+
$wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
|
376 |
+
$wpdb->postmeta,
|
377 |
+
array(
|
378 |
+
'meta_value' => 'square_credit_card', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
|
379 |
+
),
|
380 |
+
array(
|
381 |
+
'meta_key' => '_payment_method', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
|
382 |
+
'meta_value' => 'square', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
|
383 |
+
)
|
384 |
+
);
|
385 |
$this->get_plugin()->log( 'Orders migration complete.' );
|
386 |
}
|
387 |
|
398 |
|
399 |
$this->get_plugin()->log( 'Migrating products data...' );
|
400 |
|
401 |
+
// the handling in v1 was reversed, so we want products where sync wasn't disabled.
|
402 |
+
$legacy_product_ids = get_posts(
|
403 |
+
array(
|
404 |
+
'nopaging' => true,
|
405 |
+
'post_type' => 'product',
|
406 |
+
'post_status' => 'all',
|
407 |
+
'fields' => 'ids',
|
408 |
+
'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
409 |
+
|
410 |
+
'relation' => 'OR',
|
411 |
+
array(
|
412 |
+
'key' => '_wcsquare_disable_sync',
|
413 |
+
'value' => 'no',
|
414 |
+
),
|
415 |
+
array(
|
416 |
+
'key' => '_wcsquare_disable_sync',
|
417 |
+
'compare' => 'NOT EXISTS',
|
418 |
+
),
|
419 |
+
),
|
420 |
+
)
|
421 |
+
);
|
422 |
+
|
423 |
+
// in v2 we turn those products as flagged to be sync-enabled instead.
|
424 |
if ( ! empty( $legacy_product_ids ) ) {
|
425 |
|
426 |
+
$failed_products = array();
|
427 |
|
428 |
+
// ensure taxonomy is registered at this stage.
|
429 |
if ( ! taxonomy_exists( Product::SYNCED_WITH_SQUARE_TAXONOMY ) ) {
|
430 |
Product::init_taxonomies();
|
431 |
}
|
432 |
|
433 |
+
// will not create the term if already exists.
|
434 |
wp_create_term( 'yes', Product::SYNCED_WITH_SQUARE_TAXONOMY );
|
435 |
|
436 |
+
// set Square sync status via taxonomy term.
|
437 |
foreach ( $legacy_product_ids as $i => $product_id ) {
|
438 |
|
439 |
+
$set_term = wp_set_object_terms( $product_id, array( 'yes' ), Product::SYNCED_WITH_SQUARE_TAXONOMY );
|
440 |
|
441 |
if ( ! is_array( $set_term ) ) {
|
442 |
|
446 |
}
|
447 |
}
|
448 |
|
449 |
+
// log any errors.
|
450 |
if ( ! empty( $failed_products ) ) {
|
451 |
$this->get_plugin()->log( 'Could not update sync with Square status for products with ID: ' . implode( ', ', array_unique( $failed_products ) ) . '.' );
|
452 |
}
|
466 |
|
467 |
$this->get_plugin()->log( 'Migrating customer data.' );
|
468 |
|
469 |
+
$rows = (int) $wpdb->update( $wpdb->usermeta, array( 'meta_key' => 'wc_square_customer_id' ), array( 'meta_key' => '_square_customer_id' ) ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
|
470 |
|
471 |
$this->get_plugin()->log( sprintf( '%d customers migrated', $rows ) );
|
472 |
}
|
477 |
*
|
478 |
* @since 2.0.2
|
479 |
*
|
480 |
+
* @param array $v1_settings v1 plugin settings.
|
481 |
+
* @param array $v2_settings v2 plugin settings.
|
482 |
* @return array
|
483 |
*/
|
484 |
private function get_migrated_system_of_record( $v1_settings, $v2_settings ) {
|
493 |
return $v2_settings;
|
494 |
}
|
495 |
|
496 |
+
/**
|
497 |
+
* Adds environment specific location_id to, and removes general location_id from v1 setting array.
|
498 |
+
*
|
499 |
+
* @since 2.2.0
|
500 |
+
*
|
501 |
+
* @param array $v1_settings v1 plugin settings.
|
502 |
+
* @return array
|
503 |
+
*/
|
504 |
+
private function set_environment_location_id( $v1_settings ) {
|
505 |
+
|
506 |
+
$environment = isset( $v1_settings['enable_sandbox'] ) && 'yes' === $v1_settings['enable_sandbox'] ? 'sandbox' : 'production';
|
507 |
|
508 |
+
if ( ! isset( $v1_settings[ $environment . '_location_id' ] ) ) {
|
509 |
+
$v1_location_id = isset( $v1_settings['location_id'] ) ? $v1_settings['location_id'] : '';
|
510 |
+
$v1_settings[ $environment . '_location_id' ] = $v1_location_id;
|
511 |
+
}
|
512 |
+
|
513 |
+
return $v1_settings;
|
514 |
+
}
|
515 |
}
|
includes/Plugin.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Background_Job;
|
@@ -42,7 +42,7 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
42 |
|
43 |
|
44 |
/** plugin version number */
|
45 |
-
const VERSION = '2.
|
46 |
|
47 |
/** plugin ID */
|
48 |
const PLUGIN_ID = 'square';
|
@@ -91,19 +91,19 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
91 |
parent::__construct(
|
92 |
self::PLUGIN_ID,
|
93 |
self::VERSION,
|
94 |
-
|
95 |
-
'text_domain'
|
96 |
-
'gateways'
|
97 |
-
'require_ssl'
|
98 |
-
'supports'
|
99 |
self::FEATURE_CAPTURE_CHARGE,
|
100 |
self::FEATURE_CUSTOMER_ID,
|
101 |
self::FEATURE_MY_PAYMENT_METHODS,
|
102 |
-
|
103 |
-
'dependencies' =>
|
104 |
-
'php_extensions' =>
|
105 |
-
|
106 |
-
|
107 |
);
|
108 |
|
109 |
$this->includes();
|
@@ -115,10 +115,10 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
115 |
*/
|
116 |
do_action( 'wc_square_loaded' );
|
117 |
|
118 |
-
add_action( 'woocommerce_register_taxonomy',
|
119 |
|
120 |
-
add_filter( 'woocommerce_locate_template',
|
121 |
-
add_filter( 'woocommerce_locate_core_template',
|
122 |
}
|
123 |
|
124 |
|
@@ -158,7 +158,7 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
158 |
public function add_api_request_logging() {
|
159 |
|
160 |
if ( ! has_action( 'wc_' . $this->get_id() . '_api_request_performed' ) ) {
|
161 |
-
add_action( 'wc_' . $this->get_id() . '_api_request_performed',
|
162 |
}
|
163 |
}
|
164 |
|
@@ -273,13 +273,18 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
273 |
|
274 |
$message = sprintf(
|
275 |
__( 'Heads up! There may be a problem with your connection to Square. In order to continue accepting payments, please %1$sdisconnect and re-connect your site%2$s.', 'woocommerce-square' ),
|
276 |
-
'<a href="' . esc_url( $this->get_settings_url() ) . '">',
|
|
|
277 |
);
|
278 |
|
279 |
-
$this->get_admin_notice_handler()->add_admin_notice(
|
280 |
-
|
281 |
-
'
|
282 |
-
|
|
|
|
|
|
|
|
|
283 |
}
|
284 |
|
285 |
if ( $this->get_settings_handler()->is_connected() ) {
|
@@ -298,7 +303,8 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
298 |
$instruction = sprintf(
|
299 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
300 |
__( 'Visit the %1$splugin settings%2$s to set your business location.', 'woocommerce-square' ),
|
301 |
-
'<a href="' . esc_url( $this->get_settings_url() ) . '">',
|
|
|
302 |
);
|
303 |
}
|
304 |
|
@@ -313,8 +319,11 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
313 |
$instruction = sprintf(
|
314 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - product count, %3$s - </strong> tag, %4$s - <a> tag, %5$s - </a> tag */
|
315 |
__( '%1$s%2$d products%3$s are marked "sync with Square". %4$sStart a new sync now »%5$s', 'woocommerce-square' ),
|
316 |
-
'<strong>',
|
317 |
-
|
|
|
|
|
|
|
318 |
);
|
319 |
|
320 |
} else {
|
@@ -322,8 +331,10 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
322 |
$instruction = sprintf(
|
323 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
|
324 |
__( '%1$sNo products%2$s are marked "sync with Square". %3$sUpdate your products to sync data »%4$s', 'woocommerce-square' ),
|
325 |
-
'<strong>',
|
326 |
-
'
|
|
|
|
|
327 |
);
|
328 |
}
|
329 |
|
@@ -335,14 +346,18 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
335 |
|
336 |
$message = sprintf(
|
337 |
__( 'Heads up! Square is configured to sync product inventory, but WooCommerce stock management is disabled. Please %1$senable stock management%2$s to ensure product inventory counts are kept in sync.', 'woocommerce-square' ),
|
338 |
-
'<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=products§ion=inventory' ) ) . '">',
|
|
|
339 |
);
|
340 |
|
341 |
-
$this->get_admin_notice_handler()->add_admin_notice(
|
342 |
-
|
343 |
-
|
|
|
|
|
|
|
|
|
344 |
}
|
345 |
-
|
346 |
} else {
|
347 |
|
348 |
if ( $this->is_plugin_settings() ) {
|
@@ -354,7 +369,8 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
354 |
$instruction = sprintf(
|
355 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
356 |
__( 'To get started, %1$sconnect with Square »%2$s', 'woocommerce-square' ),
|
357 |
-
'<a href="' . esc_url( $this->get_settings_url() ) . '">',
|
|
|
358 |
);
|
359 |
}
|
360 |
|
@@ -387,11 +403,13 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
387 |
esc_html__( '%1$s has been updated to version %2$s. In order to continue syncing product inventory, please make sure to disconnect and reconnect with Square from the %3$splugin settings%4$s and re-sync your products. Read more in the %5$supdated documentation%6$s.', 'woocommerce-square' ),
|
388 |
'<strong>' . esc_html( $this->get_plugin_name() ) . '</strong>',
|
389 |
$this->get_version(),
|
390 |
-
'<a href="' . esc_url( $this->get_settings_url() ) . '">',
|
391 |
-
'
|
|
|
|
|
392 |
),
|
393 |
'updated-to-v2',
|
394 |
-
|
395 |
);
|
396 |
}
|
397 |
}
|
@@ -404,27 +422,32 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
404 |
*/
|
405 |
protected function add_base_location_admin_notice() {
|
406 |
|
407 |
-
$accepted_countries =
|
408 |
'US',
|
409 |
'CA',
|
410 |
'GB',
|
411 |
'AU',
|
412 |
'JP',
|
413 |
-
|
414 |
|
415 |
$base_location = wc_get_base_location();
|
416 |
|
417 |
if ( isset( $base_location['country'] ) && ! in_array( $base_location['country'], $accepted_countries, true ) ) {
|
418 |
|
419 |
-
$this->get_admin_notice_handler()->add_admin_notice(
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
|
|
|
|
|
|
|
|
|
|
428 |
}
|
429 |
}
|
430 |
|
@@ -438,14 +461,20 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
438 |
|
439 |
if ( $this->get_settings_handler()->is_product_sync_enabled() && ! $this->get_background_job_handler()->test_connection() ) {
|
440 |
|
441 |
-
$this->get_admin_notice_handler()->add_admin_notice(
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
449 |
}
|
450 |
}
|
451 |
|
@@ -459,7 +488,7 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
459 |
return;
|
460 |
}
|
461 |
|
462 |
-
$refresh_token
|
463 |
$settings_handler = $this->get_settings_handler();
|
464 |
|
465 |
if ( method_exists( $settings_handler, 'get_access_token' ) ) {
|
@@ -483,10 +512,10 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
483 |
'</strong>'
|
484 |
),
|
485 |
'wc-square-missing-refresh-token',
|
486 |
-
|
487 |
'dismissible' => false,
|
488 |
'notice_class' => 'notice-error',
|
489 |
-
|
490 |
);
|
491 |
}
|
492 |
}
|
@@ -508,12 +537,17 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
508 |
// only show for products configured as taxable and sync with Square
|
509 |
if ( $product instanceof \WC_Product && $product->is_taxable() && Product::is_synced_with_square( $product ) ) {
|
510 |
|
511 |
-
$this->get_admin_notice_handler()->add_admin_notice(
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
|
|
|
|
|
|
|
|
|
|
517 |
}
|
518 |
}
|
519 |
}
|
@@ -534,15 +568,21 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
534 |
|
535 |
if ( $this->get_settings_handler()->get_location_id() === $location->getId() && get_woocommerce_currency() !== $location->getCurrency() ) {
|
536 |
|
537 |
-
$this->get_admin_notice_handler()->add_admin_notice(
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
546 |
}
|
547 |
}
|
548 |
}
|
@@ -735,56 +775,77 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
735 |
protected function get_deprecated_hooks() {
|
736 |
|
737 |
// the following are filters, except when an action is explicitly mentioned
|
738 |
-
$v2_0_0_removed_hooks =
|
739 |
|
740 |
// to filter the locale, the default WordPress filter should be used:
|
741 |
-
'woocommerce_square_plugin_locale'
|
|
|
|
|
|
|
742 |
|
743 |
// sync square product variation properties
|
744 |
-
'woocommerce_square_currency'
|
745 |
-
'wc_square_sync_to_square_price'
|
746 |
-
'woocommerce_square_format_price'
|
747 |
-
'woocommerce_square_sync_from_square_description' =>
|
748 |
|
749 |
// we no longer filter inventory type in v2.0.0 and timeout is handled by background job differently
|
750 |
-
'woocommerce_square_inventory_type'
|
751 |
-
'woocommerce_square_inventory_sync_timeout_limit' =>
|
752 |
-
'woocommerce_square_inventory_poll_frequency'
|
753 |
|
754 |
// Square payment
|
755 |
-
'woocommerce_square_payment_form_trigger_element' =>
|
756 |
-
'woocommerce_square_payment_order_note'
|
757 |
-
|
|
|
|
|
|
|
758 |
|
759 |
// most gateway properties and settings can be mapped to new filters:
|
760 |
-
'woocommerce_square_api_url'
|
761 |
-
|
762 |
-
|
763 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
764 |
|
765 |
// API requests filters, these are handled differently and can't be mapped:
|
766 |
-
'woocommerce_square_request_args'
|
767 |
-
'woocommerce_square_request_retries'
|
768 |
|
769 |
// transients are no longer used to handle these cache types:
|
770 |
-
'woocommerce_square_business_location_cache'
|
771 |
-
'woocommerce_square_item_sku_cache'
|
772 |
-
'woocommerce_square_inventory_cache'
|
773 |
-
'woocommerce_square_sync_processing_ids_cache'
|
774 |
-
'woocommerce_square_manual_sync_processing_cache' =>
|
775 |
-
'woocommerce_square_syncing_square_ids_cache'
|
776 |
-
'woocommerce_square_syncing_wc_product_ids_cache' =>
|
777 |
|
778 |
// when a bulk sync action is triggered (action hook):
|
779 |
-
'woocommerce_square_bulk_syncing_square_to_wc'
|
780 |
|
781 |
// get_posts args filter, the new implementation has different scope:
|
782 |
-
'woocommerce_square_get_all_product_ids_args'
|
783 |
|
784 |
// idempotency key
|
785 |
-
'woocommerce_square_idempotency_key'
|
|
|
|
|
|
|
786 |
|
787 |
-
|
788 |
|
789 |
// add common array data for all removed hooks in version 2.0.0
|
790 |
foreach ( array_keys( $v2_0_0_removed_hooks ) as $hook_name ) {
|
@@ -819,10 +880,10 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
819 |
*/
|
820 |
public function get_settings_url( $gateway_id = null ) {
|
821 |
|
822 |
-
$params =
|
823 |
'page' => 'wc-settings',
|
824 |
'tab' => self::PLUGIN_ID,
|
825 |
-
|
826 |
|
827 |
return add_query_arg( $params, admin_url( 'admin.php' ) );
|
828 |
}
|
@@ -837,7 +898,7 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
837 |
*/
|
838 |
public function get_sales_page_url() {
|
839 |
|
840 |
-
return 'https://woocommerce.com/products/
|
841 |
}
|
842 |
|
843 |
|
@@ -854,6 +915,21 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
854 |
}
|
855 |
|
856 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
857 |
/**
|
858 |
* Gets the support URL.
|
859 |
*
|
@@ -863,7 +939,7 @@ class Plugin extends Framework\SV_WC_Payment_Gateway_Plugin {
|
|
863 |
*/
|
864 |
public function get_support_url() {
|
865 |
|
866 |
-
return 'https://
|
867 |
}
|
868 |
|
869 |
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Background_Job;
|
42 |
|
43 |
|
44 |
/** plugin version number */
|
45 |
+
const VERSION = '2.2.0';
|
46 |
|
47 |
/** plugin ID */
|
48 |
const PLUGIN_ID = 'square';
|
91 |
parent::__construct(
|
92 |
self::PLUGIN_ID,
|
93 |
self::VERSION,
|
94 |
+
array(
|
95 |
+
'text_domain' => 'woocommerce-square',
|
96 |
+
'gateways' => array( self::GATEWAY_ID => Gateway::class ),
|
97 |
+
'require_ssl' => true,
|
98 |
+
'supports' => array(
|
99 |
self::FEATURE_CAPTURE_CHARGE,
|
100 |
self::FEATURE_CUSTOMER_ID,
|
101 |
self::FEATURE_MY_PAYMENT_METHODS,
|
102 |
+
),
|
103 |
+
'dependencies' => array(
|
104 |
+
'php_extensions' => array( 'curl', 'json', 'mbstring' ),
|
105 |
+
),
|
106 |
+
)
|
107 |
);
|
108 |
|
109 |
$this->includes();
|
115 |
*/
|
116 |
do_action( 'wc_square_loaded' );
|
117 |
|
118 |
+
add_action( 'woocommerce_register_taxonomy', array( $this, 'init_taxonomies' ) );
|
119 |
|
120 |
+
add_filter( 'woocommerce_locate_template', array( $this, 'locate_template' ), 20, 3 );
|
121 |
+
add_filter( 'woocommerce_locate_core_template', array( $this, 'locate_template' ), 20, 3 );
|
122 |
}
|
123 |
|
124 |
|
158 |
public function add_api_request_logging() {
|
159 |
|
160 |
if ( ! has_action( 'wc_' . $this->get_id() . '_api_request_performed' ) ) {
|
161 |
+
add_action( 'wc_' . $this->get_id() . '_api_request_performed', array( $this, 'log_api_request' ), 10, 2 );
|
162 |
}
|
163 |
}
|
164 |
|
273 |
|
274 |
$message = sprintf(
|
275 |
__( 'Heads up! There may be a problem with your connection to Square. In order to continue accepting payments, please %1$sdisconnect and re-connect your site%2$s.', 'woocommerce-square' ),
|
276 |
+
'<a href="' . esc_url( $this->get_settings_url() ) . '">',
|
277 |
+
'</a>'
|
278 |
);
|
279 |
|
280 |
+
$this->get_admin_notice_handler()->add_admin_notice(
|
281 |
+
$message,
|
282 |
+
'refresh-failed',
|
283 |
+
array(
|
284 |
+
'dismissible' => false,
|
285 |
+
'notice_class' => 'notice-warning',
|
286 |
+
)
|
287 |
+
);
|
288 |
}
|
289 |
|
290 |
if ( $this->get_settings_handler()->is_connected() ) {
|
303 |
$instruction = sprintf(
|
304 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
305 |
__( 'Visit the %1$splugin settings%2$s to set your business location.', 'woocommerce-square' ),
|
306 |
+
'<a href="' . esc_url( $this->get_settings_url() ) . '">',
|
307 |
+
'</a>'
|
308 |
);
|
309 |
}
|
310 |
|
319 |
$instruction = sprintf(
|
320 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - product count, %3$s - </strong> tag, %4$s - <a> tag, %5$s - </a> tag */
|
321 |
__( '%1$s%2$d products%3$s are marked "sync with Square". %4$sStart a new sync now »%5$s', 'woocommerce-square' ),
|
322 |
+
'<strong>',
|
323 |
+
count( Product::get_products_synced_with_square() ),
|
324 |
+
'</strong>',
|
325 |
+
'<a href="' . esc_url( add_query_arg( 'section', 'update', $this->get_settings_url() ) ) . '">',
|
326 |
+
'</a>'
|
327 |
);
|
328 |
|
329 |
} else {
|
331 |
$instruction = sprintf(
|
332 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
|
333 |
__( '%1$sNo products%2$s are marked "sync with Square". %3$sUpdate your products to sync data »%4$s', 'woocommerce-square' ),
|
334 |
+
'<strong>',
|
335 |
+
'</strong>',
|
336 |
+
'<a href="' . esc_url( admin_url( 'edit.php?post_type=product' ) ) . '">',
|
337 |
+
'</a>'
|
338 |
);
|
339 |
}
|
340 |
|
346 |
|
347 |
$message = sprintf(
|
348 |
__( 'Heads up! Square is configured to sync product inventory, but WooCommerce stock management is disabled. Please %1$senable stock management%2$s to ensure product inventory counts are kept in sync.', 'woocommerce-square' ),
|
349 |
+
'<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=products§ion=inventory' ) ) . '">',
|
350 |
+
'</a>'
|
351 |
);
|
352 |
|
353 |
+
$this->get_admin_notice_handler()->add_admin_notice(
|
354 |
+
$message,
|
355 |
+
'enable-wc-sync',
|
356 |
+
array(
|
357 |
+
'notice_class' => 'notice-warning',
|
358 |
+
)
|
359 |
+
);
|
360 |
}
|
|
|
361 |
} else {
|
362 |
|
363 |
if ( $this->is_plugin_settings() ) {
|
369 |
$instruction = sprintf(
|
370 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
371 |
__( 'To get started, %1$sconnect with Square »%2$s', 'woocommerce-square' ),
|
372 |
+
'<a href="' . esc_url( $this->get_settings_url() ) . '">',
|
373 |
+
'</a>'
|
374 |
);
|
375 |
}
|
376 |
|
403 |
esc_html__( '%1$s has been updated to version %2$s. In order to continue syncing product inventory, please make sure to disconnect and reconnect with Square from the %3$splugin settings%4$s and re-sync your products. Read more in the %5$supdated documentation%6$s.', 'woocommerce-square' ),
|
404 |
'<strong>' . esc_html( $this->get_plugin_name() ) . '</strong>',
|
405 |
$this->get_version(),
|
406 |
+
'<a href="' . esc_url( $this->get_settings_url() ) . '">',
|
407 |
+
'</a>',
|
408 |
+
'<a href="' . esc_url( $this->get_documentation_url() ) . '">',
|
409 |
+
'</a>'
|
410 |
),
|
411 |
'updated-to-v2',
|
412 |
+
array( 'notice_class' => 'notice-warning' )
|
413 |
);
|
414 |
}
|
415 |
}
|
422 |
*/
|
423 |
protected function add_base_location_admin_notice() {
|
424 |
|
425 |
+
$accepted_countries = array(
|
426 |
'US',
|
427 |
'CA',
|
428 |
'GB',
|
429 |
'AU',
|
430 |
'JP',
|
431 |
+
);
|
432 |
|
433 |
$base_location = wc_get_base_location();
|
434 |
|
435 |
if ( isset( $base_location['country'] ) && ! in_array( $base_location['country'], $accepted_countries, true ) ) {
|
436 |
|
437 |
+
$this->get_admin_notice_handler()->add_admin_notice(
|
438 |
+
sprintf(
|
439 |
+
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - 2-character country code, %4$s - comma separated list of 2-character country codes */
|
440 |
+
__( '%1$sWooCommerce Square:%2$s Your base country is %3$s, but Square can’t accept transactions from merchants outside of %4$s.', 'woocommerce-square' ),
|
441 |
+
'<strong>',
|
442 |
+
'</strong>',
|
443 |
+
esc_html( $base_location['country'] ),
|
444 |
+
esc_html( Framework\SV_WC_Helper::list_array_items( $accepted_countries ) )
|
445 |
+
),
|
446 |
+
'wc-square-base-location',
|
447 |
+
array(
|
448 |
+
'notice_class' => 'notice-error',
|
449 |
+
)
|
450 |
+
);
|
451 |
}
|
452 |
}
|
453 |
|
461 |
|
462 |
if ( $this->get_settings_handler()->is_product_sync_enabled() && ! $this->get_background_job_handler()->test_connection() ) {
|
463 |
|
464 |
+
$this->get_admin_notice_handler()->add_admin_notice(
|
465 |
+
sprintf(
|
466 |
+
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
|
467 |
+
__( '%1$sWooCommerce Square:%2$s It looks like your site does not support background processing, which means large numbers of products may not sync successfully with Square. %3$sRead more here%4$s on how to resolve this.', 'woocommerce-square' ),
|
468 |
+
'<strong>',
|
469 |
+
'</strong>',
|
470 |
+
'<a href="https://docs.woocommerce.com/document/woocommerce-square/#sync-issues" target="_blank">',
|
471 |
+
'</a>'
|
472 |
+
),
|
473 |
+
'wc-square-background-processing',
|
474 |
+
array(
|
475 |
+
'notice_class' => 'notice-warning',
|
476 |
+
)
|
477 |
+
);
|
478 |
}
|
479 |
}
|
480 |
|
488 |
return;
|
489 |
}
|
490 |
|
491 |
+
$refresh_token = '';
|
492 |
$settings_handler = $this->get_settings_handler();
|
493 |
|
494 |
if ( method_exists( $settings_handler, 'get_access_token' ) ) {
|
512 |
'</strong>'
|
513 |
),
|
514 |
'wc-square-missing-refresh-token',
|
515 |
+
array(
|
516 |
'dismissible' => false,
|
517 |
'notice_class' => 'notice-error',
|
518 |
+
)
|
519 |
);
|
520 |
}
|
521 |
}
|
537 |
// only show for products configured as taxable and sync with Square
|
538 |
if ( $product instanceof \WC_Product && $product->is_taxable() && Product::is_synced_with_square( $product ) ) {
|
539 |
|
540 |
+
$this->get_admin_notice_handler()->add_admin_notice(
|
541 |
+
sprintf(
|
542 |
+
__( '%1$sWooCommerce Square:%2$s Product prices are entered inclusive of tax, but Square does not support syncing tax-inclusive prices. Please make sure your Square tax rates match your WooCommerce tax rates.', 'woocommerce-square' ),
|
543 |
+
'<strong>',
|
544 |
+
'</strong>'
|
545 |
+
),
|
546 |
+
'wc-square-tax-inclusive',
|
547 |
+
array(
|
548 |
+
'notice_class' => 'notice-warning',
|
549 |
+
)
|
550 |
+
);
|
551 |
}
|
552 |
}
|
553 |
}
|
568 |
|
569 |
if ( $this->get_settings_handler()->get_location_id() === $location->getId() && get_woocommerce_currency() !== $location->getCurrency() ) {
|
570 |
|
571 |
+
$this->get_admin_notice_handler()->add_admin_notice(
|
572 |
+
sprintf(
|
573 |
+
__( 'Heads up! Your store currency is %1$s but your configured Square business location currency is %2$s, so payments cannot be processed. Please %3$schoose a different business location%4$s or change your %5$sshop currency%6$s.', 'woocommerce-square' ),
|
574 |
+
'<strong>' . esc_html( get_woocommerce_currency() ) . '</strong>',
|
575 |
+
'<strong>' . esc_html( $location->getCurrency() ) . '</strong>',
|
576 |
+
'<a href="' . esc_url( $this->get_settings_url() ) . '">',
|
577 |
+
'</a>',
|
578 |
+
'<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings' ) ) . '">',
|
579 |
+
'</a>'
|
580 |
+
),
|
581 |
+
'wc-square-currency-mismatch',
|
582 |
+
array(
|
583 |
+
'notice_class' => 'notice-error',
|
584 |
+
)
|
585 |
+
);
|
586 |
}
|
587 |
}
|
588 |
}
|
775 |
protected function get_deprecated_hooks() {
|
776 |
|
777 |
// the following are filters, except when an action is explicitly mentioned
|
778 |
+
$v2_0_0_removed_hooks = array(
|
779 |
|
780 |
// to filter the locale, the default WordPress filter should be used:
|
781 |
+
'woocommerce_square_plugin_locale' => array(
|
782 |
+
'replacement' => 'plugin_locale',
|
783 |
+
'map' => true,
|
784 |
+
),
|
785 |
|
786 |
// sync square product variation properties
|
787 |
+
'woocommerce_square_currency' => array(), // used when passing a WooCommerce product price into a Square ItemVariation
|
788 |
+
'wc_square_sync_to_square_price' => array(), // used when passing a WooCommerce product price into a Square ItemVariation
|
789 |
+
'woocommerce_square_format_price' => array(), // formats the price coming from Square
|
790 |
+
'woocommerce_square_sync_from_square_description' => array(), // flag whether to add a description to created item
|
791 |
|
792 |
// we no longer filter inventory type in v2.0.0 and timeout is handled by background job differently
|
793 |
+
'woocommerce_square_inventory_type' => array(),
|
794 |
+
'woocommerce_square_inventory_sync_timeout_limit' => array(),
|
795 |
+
'woocommerce_square_inventory_poll_frequency' => array(),
|
796 |
|
797 |
// Square payment
|
798 |
+
'woocommerce_square_payment_form_trigger_element' => array(),
|
799 |
+
'woocommerce_square_payment_order_note' => array(
|
800 |
+
'replacement' => 'wc_square_payment_order_note',
|
801 |
+
'map' => true,
|
802 |
+
),
|
803 |
+
'woocommerce_square_description' => array(), // front end payment fields description
|
804 |
|
805 |
// most gateway properties and settings can be mapped to new filters:
|
806 |
+
'woocommerce_square_api_url' => array(
|
807 |
+
'replacement' => 'wc_square_api_url',
|
808 |
+
'map' => true,
|
809 |
+
), // filter is reinstated with name change for consistency
|
810 |
+
'woocommerce_square_payment_gateway_is_available' => array(
|
811 |
+
'replacement' => 'wc_gateway_square_credit_card_is_available',
|
812 |
+
'map' => true,
|
813 |
+
), // filter handled by SkyVerge Framework
|
814 |
+
'woocommerce_square_integration_settings_args' => array(
|
815 |
+
'replacement' => 'woocommerce_settings_api_form_fields_square',
|
816 |
+
'map' => true,
|
817 |
+
), // filters gateway settings
|
818 |
+
'woocommerce_square_integration_custom_settings' => array(
|
819 |
+
'replacement' => 'woocommerce_settings_tabs_square',
|
820 |
+
'map' => true,
|
821 |
+
), // settings action hook
|
822 |
|
823 |
// API requests filters, these are handled differently and can't be mapped:
|
824 |
+
'woocommerce_square_request_args' => array(),
|
825 |
+
'woocommerce_square_request_retries' => array(),
|
826 |
|
827 |
// transients are no longer used to handle these cache types:
|
828 |
+
'woocommerce_square_business_location_cache' => array(),
|
829 |
+
'woocommerce_square_item_sku_cache' => array(),
|
830 |
+
'woocommerce_square_inventory_cache' => array(),
|
831 |
+
'woocommerce_square_sync_processing_ids_cache' => array(),
|
832 |
+
'woocommerce_square_manual_sync_processing_cache' => array(),
|
833 |
+
'woocommerce_square_syncing_square_ids_cache' => array(),
|
834 |
+
'woocommerce_square_syncing_wc_product_ids_cache' => array(),
|
835 |
|
836 |
// when a bulk sync action is triggered (action hook):
|
837 |
+
'woocommerce_square_bulk_syncing_square_to_wc' => array(),
|
838 |
|
839 |
// get_posts args filter, the new implementation has different scope:
|
840 |
+
'woocommerce_square_get_all_product_ids_args' => array(),
|
841 |
|
842 |
// idempotency key
|
843 |
+
'woocommerce_square_idempotency_key' => array(
|
844 |
+
'replacement' => 'wc_square_idempotency_key',
|
845 |
+
'map' => true,
|
846 |
+
),
|
847 |
|
848 |
+
);
|
849 |
|
850 |
// add common array data for all removed hooks in version 2.0.0
|
851 |
foreach ( array_keys( $v2_0_0_removed_hooks ) as $hook_name ) {
|
880 |
*/
|
881 |
public function get_settings_url( $gateway_id = null ) {
|
882 |
|
883 |
+
$params = array(
|
884 |
'page' => 'wc-settings',
|
885 |
'tab' => self::PLUGIN_ID,
|
886 |
+
);
|
887 |
|
888 |
return add_query_arg( $params, admin_url( 'admin.php' ) );
|
889 |
}
|
898 |
*/
|
899 |
public function get_sales_page_url() {
|
900 |
|
901 |
+
return 'https://woocommerce.com/products/square/';
|
902 |
}
|
903 |
|
904 |
|
915 |
}
|
916 |
|
917 |
|
918 |
+
/**
|
919 |
+
* Gets the plugin reviews page URL.
|
920 |
+
*
|
921 |
+
* Used for the 'Reviews' plugin action and review prompts.
|
922 |
+
*
|
923 |
+
* @since 2.1.7
|
924 |
+
*
|
925 |
+
* @return string
|
926 |
+
*/
|
927 |
+
public function get_reviews_url() {
|
928 |
+
|
929 |
+
return $this->get_sales_page_url() ? $this->get_sales_page_url() . '#comments' : '';
|
930 |
+
}
|
931 |
+
|
932 |
+
|
933 |
/**
|
934 |
* Gets the support URL.
|
935 |
*
|
939 |
*/
|
940 |
public function get_support_url() {
|
941 |
|
942 |
+
return 'https://woocommerce.com/my-account/create-a-ticket/?select=1770503';
|
943 |
}
|
944 |
|
945 |
|
includes/Settings.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
@@ -39,26 +39,54 @@ use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
|
39 |
class Settings extends \WC_Settings_API {
|
40 |
|
41 |
|
42 |
-
/**
|
|
|
|
|
|
|
|
|
43 |
const SYSTEM_OF_RECORD_SQUARE = 'square';
|
44 |
|
45 |
-
/**
|
|
|
|
|
|
|
|
|
46 |
const SYSTEM_OF_RECORD_WOOCOMMERCE = 'woocommerce';
|
47 |
|
48 |
-
/**
|
|
|
|
|
|
|
|
|
49 |
const SYSTEM_OF_RECORD_DISABLED = 'disabled';
|
50 |
|
51 |
|
52 |
-
/**
|
|
|
|
|
|
|
|
|
53 |
protected $refresh_token;
|
54 |
|
55 |
-
/**
|
|
|
|
|
|
|
|
|
56 |
protected $access_token;
|
57 |
|
58 |
-
/**
|
|
|
|
|
|
|
|
|
59 |
protected $locations;
|
60 |
|
61 |
-
/**
|
|
|
|
|
|
|
|
|
62 |
protected $plugin;
|
63 |
|
64 |
|
@@ -67,7 +95,7 @@ class Settings extends \WC_Settings_API {
|
|
67 |
*
|
68 |
* @since 2.0.0
|
69 |
*
|
70 |
-
* @param Plugin $plugin plugin instance
|
71 |
*/
|
72 |
public function __construct( Plugin $plugin ) {
|
73 |
|
@@ -79,27 +107,24 @@ class Settings extends \WC_Settings_API {
|
|
79 |
|
80 |
$this->init_settings();
|
81 |
|
82 |
-
// remove some of our custom fields that shouldn't be saved
|
83 |
-
add_action(
|
|
|
|
|
84 |
|
85 |
-
|
86 |
|
87 |
-
|
88 |
-
} );
|
89 |
-
|
90 |
-
// Save sandbox token.
|
91 |
-
if ( $this->is_sandbox() ) {
|
92 |
-
add_action(
|
93 |
-
'woocommerce_settings_api_sanitized_fields_' . $this->id,
|
94 |
-
function( $fields ) {
|
95 |
$this->update_access_token( $fields['sandbox_token'] );
|
96 |
-
$this->access_token
|
97 |
$this->refresh_token = false; // Remove encrypted token.
|
98 |
-
$this->init_form_fields(); // Reload form fields after saving token.
|
99 |
-
return $fields;
|
100 |
}
|
101 |
-
|
102 |
-
|
|
|
|
|
|
|
|
|
103 |
}
|
104 |
|
105 |
|
@@ -115,7 +140,8 @@ class Settings extends \WC_Settings_API {
|
|
115 |
$general_description = sprintf(
|
116 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
117 |
__( 'Sync your products and inventory and also accept credit and debit card payments at checkout. %1$sClick here%2$s to configure payments.', 'woocommerce-square' ),
|
118 |
-
'<a href="' . esc_url( $this->get_plugin()->get_payment_gateway_configuration_url( $this->get_plugin()->get_gateway()->get_id() ) ) . '">',
|
|
|
119 |
);
|
120 |
|
121 |
} else {
|
@@ -123,125 +149,133 @@ class Settings extends \WC_Settings_API {
|
|
123 |
$general_description = __( 'Connect with Square to start syncing your products and inventory and also accept credit and debit card payments at checkout.', 'woocommerce-square' );
|
124 |
}
|
125 |
|
126 |
-
$fields =
|
127 |
-
'general' =>
|
128 |
'type' => 'title',
|
129 |
'description' => $general_description,
|
130 |
-
|
131 |
-
|
132 |
|
133 |
-
$fields['enable_sandbox'] =
|
134 |
'title' => __( 'Enable Sandbox Mode', 'woocommerce-square' ),
|
135 |
'label' => '<span>' . __( 'Enable to set the plugin in sandbox mode.', 'woocommerce-square' ) . '</span>',
|
136 |
'type' => 'checkbox',
|
137 |
'description' => __( 'After enabling you’ll see a new Sandbox settings section with two fields; Sandbox Application ID & Sandbox Access Token.', 'woocommerce-square' ),
|
138 |
-
|
139 |
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
$fields['sandbox_application_id'] = [
|
151 |
-
'type' => 'input',
|
152 |
-
'title' => __( 'Sandbox Application ID', 'woocommerce-square' ),
|
153 |
-
'description' => __( 'Application ID for the Sandbox Application, see the details in the My Applications section.', 'woocommerce-square' ),
|
154 |
-
];
|
155 |
-
$fields['sandbox_token'] = [
|
156 |
-
'type' => 'input',
|
157 |
-
'title' => __( 'Sandbox Access Token', 'woocommerce-square' ),
|
158 |
-
'description' => __( 'Access Token for the Sandbox Test Account, see the details in the Sandbox Test Account section. Make sure you use the correct Sandbox Access Token for your application. For a given Sandbox Test Account, each Authorized Application is assigned a different Access Token.', 'woocommerce-square' ),
|
159 |
-
];
|
160 |
-
}
|
161 |
|
162 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
if ( $this->is_connected() ) {
|
164 |
|
165 |
-
$fields['
|
166 |
'title' => __( 'Business location', 'woocommerce-square' ),
|
167 |
'type' => 'select',
|
168 |
'class' => 'wc-enhanced-select',
|
169 |
'description' => sprintf(
|
170 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
|
171 |
__( 'Select a location to link to this site. Only %1$sactive%2$s %3$slocations%4$s that support credit card processing in Square can be linked.', 'woocommerce-square' ),
|
172 |
-
'<strong>',
|
173 |
-
'
|
|
|
|
|
174 |
),
|
175 |
-
'options'
|
176 |
-
|
177 |
|
178 |
-
$fields['system_of_record'] =
|
179 |
'title' => __( 'Product system of record', 'woocommerce-square' ),
|
180 |
'type' => 'select',
|
181 |
'class' => 'wc-enhanced-select',
|
182 |
'description' => sprintf(
|
183 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
|
184 |
__( 'Choose where you will update data for synced products. Inventory in Square is %1$salways%2$s checked for adjustments when sync is enabled. %3$sClick here%4$s to read more about choosing a system of record.', 'woocommerce-square' ),
|
185 |
-
'<strong>',
|
186 |
-
'
|
|
|
|
|
187 |
),
|
188 |
-
'options'
|
189 |
self::SYSTEM_OF_RECORD_DISABLED => __( 'Do not sync product data', 'woocommerce-square' ),
|
190 |
self::SYSTEM_OF_RECORD_SQUARE => __( 'Square', 'woocommerce-square' ),
|
191 |
self::SYSTEM_OF_RECORD_WOOCOMMERCE => __( 'WooCommerce', 'woocommerce-square' ),
|
192 |
-
|
193 |
-
'default'
|
194 |
-
|
195 |
|
196 |
-
$fields['enable_inventory_sync'] =
|
197 |
'title' => __( 'Sync inventory', 'woocommerce-square' ),
|
198 |
'label' => '<span>' . __( 'Enable to sync product inventory with Square', 'woocommerce-square' ) . '</span>',
|
199 |
'type' => 'checkbox',
|
200 |
'description' => __( 'Inventory is fetched from Square periodically and updated in WooCommerce', 'woocommerce-square' ),
|
201 |
-
|
202 |
|
203 |
-
$fields['hide_missing_products'] =
|
204 |
'title' => __( 'Handle missing products', 'woocommerce-square' ),
|
205 |
'label' => __( 'Hide synced products when not found in Square', 'woocommerce-square' ),
|
206 |
'type' => 'checkbox',
|
207 |
'description' => __( 'Products not found in Square will be hidden in the WooCommerce product catalog.', 'woocommerce-square' ),
|
208 |
-
|
209 |
|
210 |
-
$fields['import_products'] =
|
211 |
'title' => __( 'Import Products', 'woocommerce-square' ),
|
212 |
'type' => 'import_products',
|
213 |
'desc_tip' => __( 'Run an import to create new products in this WooCommerce store for each new product created in Square that has a unique SKU not existing in here. Needs to be run each time new items are created in Square.', 'woocommerce-square' ),
|
214 |
-
|
215 |
}
|
216 |
|
217 |
// In sandbox mode we don't want to intially display the connect button, only disconnect.
|
218 |
if ( ! ( $this->is_sandbox() && ! $this->is_connected() ) ) {
|
219 |
$fields = array_merge(
|
220 |
$fields,
|
221 |
-
|
222 |
-
'connect' =>
|
223 |
'title' => __( 'Connection', 'woocommerce-square' ),
|
224 |
'type' => 'connect',
|
225 |
'desc_tip' => '',
|
226 |
-
|
227 |
-
|
228 |
);
|
229 |
}
|
230 |
|
231 |
// Always display these fields.
|
232 |
$fields = array_merge(
|
233 |
$fields,
|
234 |
-
|
235 |
-
'debug_logging_enabled' =>
|
236 |
'title' => __( 'Enable Logging', 'woocommerce-square' ),
|
237 |
'type' => 'checkbox',
|
238 |
'label' => sprintf(
|
239 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
240 |
__( 'Log debug messages to the %1$sWooCommerce status log%2$s', 'woocommerce-square' ),
|
241 |
-
'<a href="' . esc_url( admin_url( 'admin.php?page=wc-status&tab=logs' ) ) . '">',
|
|
|
242 |
),
|
243 |
-
|
244 |
-
|
245 |
);
|
246 |
|
247 |
$this->form_fields = $fields;
|
@@ -261,36 +295,60 @@ class Settings extends \WC_Settings_API {
|
|
261 |
|
262 |
$fields = parent::get_form_fields();
|
263 |
|
264 |
-
|
265 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
266 |
'' => __( 'Please choose a location', 'woocommerce-square' ),
|
267 |
-
|
268 |
|
269 |
if ( ! empty( $this->get_locations() ) ) {
|
270 |
-
|
271 |
foreach ( $this->get_locations() as $location ) {
|
272 |
-
|
273 |
if ( 'ACTIVE' === $location->getStatus() && in_array( 'CREDIT_CARD_PROCESSING', (array) $location->getCapabilities(), true ) ) {
|
274 |
$locations[ $location->getId() ] = $location->getName();
|
275 |
}
|
276 |
}
|
277 |
}
|
278 |
|
279 |
-
$fields[
|
280 |
-
|
281 |
}
|
282 |
|
283 |
return $fields;
|
284 |
}
|
285 |
|
286 |
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
public function generate_import_products_html( $id, $field ) {
|
288 |
|
289 |
ob_start();
|
290 |
?>
|
291 |
<tr valign="top">
|
292 |
<th scope="row" class="titledesc">
|
293 |
-
<label for="<?php echo esc_attr( $id ); ?>"><?php echo wp_kses_post( $field['title'] ); ?> <?php echo $this->get_tooltip_html( $field ); ?></label>
|
294 |
</th>
|
295 |
<td class="forminp">
|
296 |
<a href='#' class='button js-import-square-products'>
|
@@ -309,8 +367,8 @@ class Settings extends \WC_Settings_API {
|
|
309 |
*
|
310 |
* @since 2.0.0
|
311 |
*
|
312 |
-
* @param string $id field ID
|
313 |
-
* @param array
|
314 |
* @return string
|
315 |
*/
|
316 |
public function generate_connect_html( $id, $field ) {
|
@@ -319,14 +377,16 @@ class Settings extends \WC_Settings_API {
|
|
319 |
?>
|
320 |
<tr valign="top">
|
321 |
<th scope="row" class="titledesc">
|
322 |
-
<label for="<?php echo esc_attr( $id ); ?>"><?php echo wp_kses_post( $field['title'] ); ?> <?php echo $this->get_tooltip_html( $field ); ?></label>
|
323 |
</th>
|
324 |
<td class="forminp">
|
325 |
-
<?php
|
326 |
-
|
|
|
327 |
} else {
|
328 |
-
echo $this->get_plugin()->get_connection_handler()->get_connect_button_html( $this->is_sandbox() );
|
329 |
-
}
|
|
|
330 |
</td>
|
331 |
</tr>
|
332 |
<?php
|
@@ -340,12 +400,12 @@ class Settings extends \WC_Settings_API {
|
|
340 |
*
|
341 |
* @since 2.0.0
|
342 |
*
|
343 |
-
* @param string $token refresh token
|
344 |
*/
|
345 |
public function update_refresh_token( $token ) {
|
346 |
|
347 |
$refresh_tokens = $this->get_refresh_tokens();
|
348 |
-
$environment
|
349 |
|
350 |
if ( ! empty( $token ) ) {
|
351 |
|
@@ -361,7 +421,7 @@ class Settings extends \WC_Settings_API {
|
|
361 |
|
362 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
363 |
|
364 |
-
// log the event, but don't halt the process
|
365 |
$this->get_plugin()->log( 'Could not encrypt refresh token. ' . $exception->getMessage() );
|
366 |
}
|
367 |
}
|
@@ -378,7 +438,7 @@ class Settings extends \WC_Settings_API {
|
|
378 |
*
|
379 |
* @since 2.0.0
|
380 |
*
|
381 |
-
* @param string $token access token
|
382 |
*/
|
383 |
public function update_access_token( $token ) {
|
384 |
|
@@ -399,12 +459,15 @@ class Settings extends \WC_Settings_API {
|
|
399 |
|
400 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
401 |
|
402 |
-
// log the event, but don't halt the process
|
403 |
$this->get_plugin()->log( 'Could not encrypt access token. ' . $exception->getMessage() );
|
404 |
}
|
405 |
}
|
406 |
|
407 |
$access_tokens[ $environment ] = $token;
|
|
|
|
|
|
|
408 |
}
|
409 |
|
410 |
update_option( 'wc_square_access_tokens', $access_tokens );
|
@@ -441,9 +504,9 @@ class Settings extends \WC_Settings_API {
|
|
441 |
*/
|
442 |
public function clear_location_id() {
|
443 |
|
444 |
-
$settings = get_option( $this->get_option_key(),
|
445 |
|
446 |
-
$settings['
|
447 |
|
448 |
update_option( $this->get_option_key(), $settings );
|
449 |
}
|
@@ -595,8 +658,18 @@ class Settings extends \WC_Settings_API {
|
|
595 |
* @return string
|
596 |
*/
|
597 |
public function get_location_id() {
|
|
|
|
|
|
|
|
|
598 |
|
599 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
600 |
}
|
601 |
|
602 |
|
@@ -609,13 +682,12 @@ class Settings extends \WC_Settings_API {
|
|
609 |
*/
|
610 |
public function get_locations() {
|
611 |
|
612 |
-
// if locations have already been fetched, no need to fetch again
|
613 |
if ( is_array( $this->locations ) ) {
|
614 |
|
615 |
return $this->locations;
|
616 |
}
|
617 |
|
618 |
-
// don't always need to refetch when not on Settings screen
|
619 |
if ( ! $this->is_admin_settings_screen() ) {
|
620 |
|
621 |
$this->locations = get_transient( 'wc_square_locations' );
|
@@ -623,15 +695,15 @@ class Settings extends \WC_Settings_API {
|
|
623 |
|
624 |
if ( ! is_array( $this->locations ) && did_action( 'wc_square_initialized' ) ) {
|
625 |
|
626 |
-
$this->locations =
|
627 |
|
628 |
try {
|
629 |
|
630 |
-
// cache the locations returned so they can be used elsewhere
|
631 |
$this->locations = $this->get_plugin()->get_api( $this->get_access_token(), $this->is_sandbox() )->get_locations();
|
632 |
set_transient( 'wc_square_locations', $this->locations, HOUR_IN_SECONDS );
|
633 |
|
634 |
-
// check the returned IDs against what's currently configured
|
635 |
$stored_location_id = $this->get_location_id();
|
636 |
$found = ! $stored_location_id;
|
637 |
|
@@ -643,11 +715,10 @@ class Settings extends \WC_Settings_API {
|
|
643 |
}
|
644 |
}
|
645 |
|
646 |
-
// if the currently set location ID is not present in the connected account's available locations, clear it locally
|
647 |
if ( ! $found ) {
|
648 |
$this->clear_location_id();
|
649 |
}
|
650 |
-
|
651 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
652 |
|
653 |
$this->get_plugin()->log( 'Could not retrieve business locations.' );
|
@@ -682,15 +753,15 @@ class Settings extends \WC_Settings_API {
|
|
682 |
|
683 |
switch ( $this->get_system_of_record() ) {
|
684 |
|
685 |
-
case 'square'
|
686 |
$sor = __( 'Square', 'woocommerce-square' );
|
687 |
-
|
688 |
-
case 'woocommerce'
|
689 |
$sor = __( 'WooCommerce', 'woocommerce-square' );
|
690 |
-
|
691 |
-
default
|
692 |
$sor = '';
|
693 |
-
|
694 |
}
|
695 |
|
696 |
return $sor;
|
@@ -724,7 +795,7 @@ class Settings extends \WC_Settings_API {
|
|
724 |
|
725 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
726 |
|
727 |
-
// log the event, but don't halt the process
|
728 |
$this->get_plugin()->log( 'Could not decrypt refresh token. ' . $exception->getMessage() );
|
729 |
}
|
730 |
}
|
@@ -751,7 +822,7 @@ class Settings extends \WC_Settings_API {
|
|
751 |
*/
|
752 |
public function get_access_token() {
|
753 |
|
754 |
-
if ( empty( $this->access_token ) ) {
|
755 |
|
756 |
$tokens = $this->get_access_tokens();
|
757 |
$token = null;
|
@@ -770,7 +841,7 @@ class Settings extends \WC_Settings_API {
|
|
770 |
|
771 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
772 |
|
773 |
-
// log the event, but don't halt the process
|
774 |
$this->get_plugin()->log( 'Could not decrypt access token. ' . $exception->getMessage() );
|
775 |
}
|
776 |
}
|
@@ -799,7 +870,7 @@ class Settings extends \WC_Settings_API {
|
|
799 |
* @return array
|
800 |
*/
|
801 |
public function get_access_tokens() {
|
802 |
-
return (array) get_option( 'wc_square_access_tokens',
|
803 |
}
|
804 |
|
805 |
|
@@ -813,7 +884,7 @@ class Settings extends \WC_Settings_API {
|
|
813 |
* @return array
|
814 |
*/
|
815 |
public function get_refresh_tokens() {
|
816 |
-
return (array) get_option( 'wc_square_refresh_tokens',
|
817 |
}
|
818 |
|
819 |
/**
|
@@ -835,8 +906,7 @@ class Settings extends \WC_Settings_API {
|
|
835 |
* @return boolean
|
836 |
*/
|
837 |
public function is_sandbox_setting_enabled() {
|
838 |
-
|
839 |
-
return 'yes' == $this->get_enable_sandbox() || isset( $_POST['wc_square_enable_sandbox'] );
|
840 |
}
|
841 |
|
842 |
|
@@ -872,6 +942,6 @@ class Settings extends \WC_Settings_API {
|
|
872 |
* @return bool True if the current request is for the Square admin settings, otherwise false.
|
873 |
*/
|
874 |
public function is_admin_settings_screen() {
|
875 |
-
return isset( $_GET['page'], $_GET['tab'] ) && 'wc-settings' === $_GET['page'] && Plugin::PLUGIN_ID === $_GET['tab'];
|
876 |
}
|
877 |
}
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
39 |
class Settings extends \WC_Settings_API {
|
40 |
|
41 |
|
42 |
+
/**
|
43 |
+
* Square system of record.
|
44 |
+
*
|
45 |
+
* @var string square system of record indicator
|
46 |
+
*/
|
47 |
const SYSTEM_OF_RECORD_SQUARE = 'square';
|
48 |
|
49 |
+
/**
|
50 |
+
* Woocommerce system of record.
|
51 |
+
*
|
52 |
+
* @var string square system of record indicator
|
53 |
+
*/
|
54 |
const SYSTEM_OF_RECORD_WOOCOMMERCE = 'woocommerce';
|
55 |
|
56 |
+
/**
|
57 |
+
* Disabled system of record.
|
58 |
+
*
|
59 |
+
* @var string system of record indicator for disabled sync
|
60 |
+
*/
|
61 |
const SYSTEM_OF_RECORD_DISABLED = 'disabled';
|
62 |
|
63 |
|
64 |
+
/**
|
65 |
+
* Refresh token
|
66 |
+
*
|
67 |
+
* @var string un-encrypted refresh token
|
68 |
+
*/
|
69 |
protected $refresh_token;
|
70 |
|
71 |
+
/**
|
72 |
+
* Access token
|
73 |
+
*
|
74 |
+
* @var string un-encrypted access token
|
75 |
+
*/
|
76 |
protected $access_token;
|
77 |
|
78 |
+
/**
|
79 |
+
* Square business locations
|
80 |
+
*
|
81 |
+
* @var array business locations returned by the API
|
82 |
+
*/
|
83 |
protected $locations;
|
84 |
|
85 |
+
/**
|
86 |
+
* Square plugin instance
|
87 |
+
*
|
88 |
+
* @var Plugin plugin instance
|
89 |
+
*/
|
90 |
protected $plugin;
|
91 |
|
92 |
|
95 |
*
|
96 |
* @since 2.0.0
|
97 |
*
|
98 |
+
* @param Plugin $plugin plugin instance.
|
99 |
*/
|
100 |
public function __construct( Plugin $plugin ) {
|
101 |
|
107 |
|
108 |
$this->init_settings();
|
109 |
|
110 |
+
// remove some of our custom fields that shouldn't be saved.
|
111 |
+
add_action(
|
112 |
+
'woocommerce_settings_api_sanitized_fields_' . $this->id,
|
113 |
+
function( $fields ) {
|
114 |
|
115 |
+
unset( $fields['general'], $fields['connect'], $fields['import_products'] );
|
116 |
|
117 |
+
if ( $this->is_sandbox() ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
$this->update_access_token( $fields['sandbox_token'] );
|
119 |
+
$this->access_token = false; // Remove encrypted token.
|
120 |
$this->refresh_token = false; // Remove encrypted token.
|
|
|
|
|
121 |
}
|
122 |
+
|
123 |
+
$this->init_form_fields(); // Reload form fields after saving token.
|
124 |
+
|
125 |
+
return $fields;
|
126 |
+
}
|
127 |
+
);
|
128 |
}
|
129 |
|
130 |
|
140 |
$general_description = sprintf(
|
141 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
142 |
__( 'Sync your products and inventory and also accept credit and debit card payments at checkout. %1$sClick here%2$s to configure payments.', 'woocommerce-square' ),
|
143 |
+
'<a href="' . esc_url( $this->get_plugin()->get_payment_gateway_configuration_url( $this->get_plugin()->get_gateway()->get_id() ) ) . '">',
|
144 |
+
'</a>'
|
145 |
);
|
146 |
|
147 |
} else {
|
149 |
$general_description = __( 'Connect with Square to start syncing your products and inventory and also accept credit and debit card payments at checkout.', 'woocommerce-square' );
|
150 |
}
|
151 |
|
152 |
+
$fields = array(
|
153 |
+
'general' => array(
|
154 |
'type' => 'title',
|
155 |
'description' => $general_description,
|
156 |
+
),
|
157 |
+
);
|
158 |
|
159 |
+
$fields['enable_sandbox'] = array(
|
160 |
'title' => __( 'Enable Sandbox Mode', 'woocommerce-square' ),
|
161 |
'label' => '<span>' . __( 'Enable to set the plugin in sandbox mode.', 'woocommerce-square' ) . '</span>',
|
162 |
'type' => 'checkbox',
|
163 |
'description' => __( 'After enabling you’ll see a new Sandbox settings section with two fields; Sandbox Application ID & Sandbox Access Token.', 'woocommerce-square' ),
|
164 |
+
);
|
165 |
|
166 |
+
$fields['sandbox_settings'] = array(
|
167 |
+
'type' => 'title',
|
168 |
+
'title' => __( 'Sandbox settings', 'woocommerce-square' ),
|
169 |
+
'id' => 'wc_square_sandbox_settings',
|
170 |
+
'description' => sprintf(
|
171 |
+
// translators: Placeholders: %1$s - URL.
|
172 |
+
__( 'Sandbox details can be created at: %s', 'woocommerce-square' ),
|
173 |
+
sprintf( '<a href="%1$s">%1$s</a>', 'https://developer.squareup.com/apps' )
|
174 |
+
),
|
175 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
|
177 |
+
$fields['sandbox_application_id'] = array(
|
178 |
+
'type' => 'input',
|
179 |
+
'title' => __( 'Sandbox Application ID', 'woocommerce-square' ),
|
180 |
+
'class' => 'wc_square_sandbox_settings',
|
181 |
+
'description' => __( 'Application ID for the Sandbox Application, see the details in the My Applications section.', 'woocommerce-square' ),
|
182 |
+
);
|
183 |
+
|
184 |
+
$fields['sandbox_token'] = array(
|
185 |
+
'type' => 'input',
|
186 |
+
'title' => __( 'Sandbox Access Token', 'woocommerce-square' ),
|
187 |
+
'class' => 'wc_square_sandbox_settings',
|
188 |
+
'description' => __( 'Access Token for the Sandbox Test Account, see the details in the Sandbox Test Account section. Make sure you use the correct Sandbox Access Token for your application. For a given Sandbox Test Account, each Authorized Application is assigned a different Access Token.', 'woocommerce-square' ),
|
189 |
+
);
|
190 |
+
|
191 |
+
// display these fields only if connected.
|
192 |
if ( $this->is_connected() ) {
|
193 |
|
194 |
+
$fields[ $this->get_environment() . '_location_id' ] = array(
|
195 |
'title' => __( 'Business location', 'woocommerce-square' ),
|
196 |
'type' => 'select',
|
197 |
'class' => 'wc-enhanced-select',
|
198 |
'description' => sprintf(
|
199 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
|
200 |
__( 'Select a location to link to this site. Only %1$sactive%2$s %3$slocations%4$s that support credit card processing in Square can be linked.', 'woocommerce-square' ),
|
201 |
+
'<strong>',
|
202 |
+
'</strong>',
|
203 |
+
'<a href="https://docs.woocommerce.com/document/woocommerce-square/#section-4" target="_blank">',
|
204 |
+
'</a>'
|
205 |
),
|
206 |
+
'options' => array(), // this is populated on display.
|
207 |
+
);
|
208 |
|
209 |
+
$fields['system_of_record'] = array(
|
210 |
'title' => __( 'Product system of record', 'woocommerce-square' ),
|
211 |
'type' => 'select',
|
212 |
'class' => 'wc-enhanced-select',
|
213 |
'description' => sprintf(
|
214 |
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
|
215 |
__( 'Choose where you will update data for synced products. Inventory in Square is %1$salways%2$s checked for adjustments when sync is enabled. %3$sClick here%4$s to read more about choosing a system of record.', 'woocommerce-square' ),
|
216 |
+
'<strong>',
|
217 |
+
'</strong>',
|
218 |
+
'<a href="' . esc_url( wc_square()->get_documentation_url() ) . '#section-7">',
|
219 |
+
'</a>'
|
220 |
),
|
221 |
+
'options' => array(
|
222 |
self::SYSTEM_OF_RECORD_DISABLED => __( 'Do not sync product data', 'woocommerce-square' ),
|
223 |
self::SYSTEM_OF_RECORD_SQUARE => __( 'Square', 'woocommerce-square' ),
|
224 |
self::SYSTEM_OF_RECORD_WOOCOMMERCE => __( 'WooCommerce', 'woocommerce-square' ),
|
225 |
+
),
|
226 |
+
'default' => 'disabled',
|
227 |
+
);
|
228 |
|
229 |
+
$fields['enable_inventory_sync'] = array(
|
230 |
'title' => __( 'Sync inventory', 'woocommerce-square' ),
|
231 |
'label' => '<span>' . __( 'Enable to sync product inventory with Square', 'woocommerce-square' ) . '</span>',
|
232 |
'type' => 'checkbox',
|
233 |
'description' => __( 'Inventory is fetched from Square periodically and updated in WooCommerce', 'woocommerce-square' ),
|
234 |
+
);
|
235 |
|
236 |
+
$fields['hide_missing_products'] = array(
|
237 |
'title' => __( 'Handle missing products', 'woocommerce-square' ),
|
238 |
'label' => __( 'Hide synced products when not found in Square', 'woocommerce-square' ),
|
239 |
'type' => 'checkbox',
|
240 |
'description' => __( 'Products not found in Square will be hidden in the WooCommerce product catalog.', 'woocommerce-square' ),
|
241 |
+
);
|
242 |
|
243 |
+
$fields['import_products'] = array(
|
244 |
'title' => __( 'Import Products', 'woocommerce-square' ),
|
245 |
'type' => 'import_products',
|
246 |
'desc_tip' => __( 'Run an import to create new products in this WooCommerce store for each new product created in Square that has a unique SKU not existing in here. Needs to be run each time new items are created in Square.', 'woocommerce-square' ),
|
247 |
+
);
|
248 |
}
|
249 |
|
250 |
// In sandbox mode we don't want to intially display the connect button, only disconnect.
|
251 |
if ( ! ( $this->is_sandbox() && ! $this->is_connected() ) ) {
|
252 |
$fields = array_merge(
|
253 |
$fields,
|
254 |
+
array(
|
255 |
+
'connect' => array(
|
256 |
'title' => __( 'Connection', 'woocommerce-square' ),
|
257 |
'type' => 'connect',
|
258 |
'desc_tip' => '',
|
259 |
+
),
|
260 |
+
)
|
261 |
);
|
262 |
}
|
263 |
|
264 |
// Always display these fields.
|
265 |
$fields = array_merge(
|
266 |
$fields,
|
267 |
+
array(
|
268 |
+
'debug_logging_enabled' => array(
|
269 |
'title' => __( 'Enable Logging', 'woocommerce-square' ),
|
270 |
'type' => 'checkbox',
|
271 |
'label' => sprintf(
|
272 |
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
273 |
__( 'Log debug messages to the %1$sWooCommerce status log%2$s', 'woocommerce-square' ),
|
274 |
+
'<a href="' . esc_url( admin_url( 'admin.php?page=wc-status&tab=logs' ) ) . '">',
|
275 |
+
'</a>'
|
276 |
),
|
277 |
+
),
|
278 |
+
)
|
279 |
);
|
280 |
|
281 |
$this->form_fields = $fields;
|
295 |
|
296 |
$fields = parent::get_form_fields();
|
297 |
|
298 |
+
// Confirm our local enable sandbox setting matches what is sent from the front end
|
299 |
+
// to account for changes from sandbox to production incorrectly fetching sandbox locations.
|
300 |
+
if ( isset( $_POST['wc_square_environment'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
301 |
+
|
302 |
+
$environment = 'yes' === $this->settings['enable_sandbox'] ? 'sandbox' : 'production';
|
303 |
+
|
304 |
+
if ( $environment !== $_POST['wc_square_environment'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
305 |
+
return $fields;
|
306 |
+
}
|
307 |
+
}
|
308 |
+
|
309 |
+
$location_id_field_key = '';
|
310 |
+
// Get the location_id field.
|
311 |
+
foreach ( $fields as $key => $value ) {
|
312 |
+
if ( strpos( $key, 'location_id' ) ) {
|
313 |
+
$location_id_field_key = $key;
|
314 |
+
break;
|
315 |
+
}
|
316 |
+
}
|
317 |
+
|
318 |
+
if ( did_action( 'wc_square_initialized' ) && $this->is_admin_settings_screen() && ! empty( $location_id_field_key ) ) {
|
319 |
+
|
320 |
+
$locations = array(
|
321 |
'' => __( 'Please choose a location', 'woocommerce-square' ),
|
322 |
+
);
|
323 |
|
324 |
if ( ! empty( $this->get_locations() ) ) {
|
|
|
325 |
foreach ( $this->get_locations() as $location ) {
|
|
|
326 |
if ( 'ACTIVE' === $location->getStatus() && in_array( 'CREDIT_CARD_PROCESSING', (array) $location->getCapabilities(), true ) ) {
|
327 |
$locations[ $location->getId() ] = $location->getName();
|
328 |
}
|
329 |
}
|
330 |
}
|
331 |
|
332 |
+
$fields[ $location_id_field_key ]['options'] = $locations;
|
|
|
333 |
}
|
334 |
|
335 |
return $fields;
|
336 |
}
|
337 |
|
338 |
|
339 |
+
/**
|
340 |
+
* Generates the HTML for import products button.
|
341 |
+
*
|
342 |
+
* @param string $id form id.
|
343 |
+
* @param array $field form fields.
|
344 |
+
*/
|
345 |
public function generate_import_products_html( $id, $field ) {
|
346 |
|
347 |
ob_start();
|
348 |
?>
|
349 |
<tr valign="top">
|
350 |
<th scope="row" class="titledesc">
|
351 |
+
<label for="<?php echo esc_attr( $id ); ?>"><?php echo wp_kses_post( $field['title'] ); ?> <?php echo $this->get_tooltip_html( $field ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></label>
|
352 |
</th>
|
353 |
<td class="forminp">
|
354 |
<a href='#' class='button js-import-square-products'>
|
367 |
*
|
368 |
* @since 2.0.0
|
369 |
*
|
370 |
+
* @param string $id field ID.
|
371 |
+
* @param array $field field data.
|
372 |
* @return string
|
373 |
*/
|
374 |
public function generate_connect_html( $id, $field ) {
|
377 |
?>
|
378 |
<tr valign="top">
|
379 |
<th scope="row" class="titledesc">
|
380 |
+
<label for="<?php echo esc_attr( $id ); ?>"><?php echo wp_kses_post( $field['title'] ); ?> <?php echo $this->get_tooltip_html( $field ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></label>
|
381 |
</th>
|
382 |
<td class="forminp">
|
383 |
+
<?php
|
384 |
+
if ( $this->get_access_token() ) {
|
385 |
+
echo $this->get_plugin()->get_connection_handler()->get_disconnect_button_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
386 |
} else {
|
387 |
+
echo $this->get_plugin()->get_connection_handler()->get_connect_button_html( $this->is_sandbox() ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
388 |
+
}
|
389 |
+
?>
|
390 |
</td>
|
391 |
</tr>
|
392 |
<?php
|
400 |
*
|
401 |
* @since 2.0.0
|
402 |
*
|
403 |
+
* @param string $token refresh token.
|
404 |
*/
|
405 |
public function update_refresh_token( $token ) {
|
406 |
|
407 |
$refresh_tokens = $this->get_refresh_tokens();
|
408 |
+
$environment = $this->get_environment();
|
409 |
|
410 |
if ( ! empty( $token ) ) {
|
411 |
|
421 |
|
422 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
423 |
|
424 |
+
// log the event, but don't halt the process.
|
425 |
$this->get_plugin()->log( 'Could not encrypt refresh token. ' . $exception->getMessage() );
|
426 |
}
|
427 |
}
|
438 |
*
|
439 |
* @since 2.0.0
|
440 |
*
|
441 |
+
* @param string $token access token.
|
442 |
*/
|
443 |
public function update_access_token( $token ) {
|
444 |
|
459 |
|
460 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
461 |
|
462 |
+
// log the event, but don't halt the process.
|
463 |
$this->get_plugin()->log( 'Could not encrypt access token. ' . $exception->getMessage() );
|
464 |
}
|
465 |
}
|
466 |
|
467 |
$access_tokens[ $environment ] = $token;
|
468 |
+
} elseif ( isset( $access_tokens[ $environment ] ) ) {
|
469 |
+
|
470 |
+
unset( $access_tokens[ $environment ] );
|
471 |
}
|
472 |
|
473 |
update_option( 'wc_square_access_tokens', $access_tokens );
|
504 |
*/
|
505 |
public function clear_location_id() {
|
506 |
|
507 |
+
$settings = get_option( $this->get_option_key(), array() );
|
508 |
|
509 |
+
$settings[ $this->get_environment() . '_location_id' ] = '';
|
510 |
|
511 |
update_option( $this->get_option_key(), $settings );
|
512 |
}
|
658 |
* @return string
|
659 |
*/
|
660 |
public function get_location_id() {
|
661 |
+
$location_id = $this->get_option( $this->get_environment() . '_location_id' );
|
662 |
+
|
663 |
+
if ( empty( $location_id ) ) {
|
664 |
+
$square_db_version = get_option( $this->get_plugin()->get_plugin_version_name() );
|
665 |
|
666 |
+
// if the Square DB version is still pre-2.2.0, fetch the location ID using the previous option name
|
667 |
+
if ( ! empty( $square_db_version ) && version_compare( $square_db_version, '2.2.0', '<' ) ) {
|
668 |
+
$location_id = $this->get_option( 'location_id' );
|
669 |
+
}
|
670 |
+
}
|
671 |
+
|
672 |
+
return $location_id;
|
673 |
}
|
674 |
|
675 |
|
682 |
*/
|
683 |
public function get_locations() {
|
684 |
|
|
|
685 |
if ( is_array( $this->locations ) ) {
|
686 |
|
687 |
return $this->locations;
|
688 |
}
|
689 |
|
690 |
+
// don't always need to refetch when not on Settings screen.
|
691 |
if ( ! $this->is_admin_settings_screen() ) {
|
692 |
|
693 |
$this->locations = get_transient( 'wc_square_locations' );
|
695 |
|
696 |
if ( ! is_array( $this->locations ) && did_action( 'wc_square_initialized' ) ) {
|
697 |
|
698 |
+
$this->locations = array();
|
699 |
|
700 |
try {
|
701 |
|
702 |
+
// cache the locations returned so they can be used elsewhere.
|
703 |
$this->locations = $this->get_plugin()->get_api( $this->get_access_token(), $this->is_sandbox() )->get_locations();
|
704 |
set_transient( 'wc_square_locations', $this->locations, HOUR_IN_SECONDS );
|
705 |
|
706 |
+
// check the returned IDs against what's currently configured.
|
707 |
$stored_location_id = $this->get_location_id();
|
708 |
$found = ! $stored_location_id;
|
709 |
|
715 |
}
|
716 |
}
|
717 |
|
718 |
+
// if the currently set location ID is not present in the connected account's available locations, clear it locally.
|
719 |
if ( ! $found ) {
|
720 |
$this->clear_location_id();
|
721 |
}
|
|
|
722 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
723 |
|
724 |
$this->get_plugin()->log( 'Could not retrieve business locations.' );
|
753 |
|
754 |
switch ( $this->get_system_of_record() ) {
|
755 |
|
756 |
+
case 'square':
|
757 |
$sor = __( 'Square', 'woocommerce-square' );
|
758 |
+
break;
|
759 |
+
case 'woocommerce':
|
760 |
$sor = __( 'WooCommerce', 'woocommerce-square' );
|
761 |
+
break;
|
762 |
+
default:
|
763 |
$sor = '';
|
764 |
+
break;
|
765 |
}
|
766 |
|
767 |
return $sor;
|
795 |
|
796 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
797 |
|
798 |
+
// log the event, but don't halt the process.
|
799 |
$this->get_plugin()->log( 'Could not decrypt refresh token. ' . $exception->getMessage() );
|
800 |
}
|
801 |
}
|
822 |
*/
|
823 |
public function get_access_token() {
|
824 |
|
825 |
+
if ( empty( $this->access_token ) || $this->is_admin_settings_screen() ) {
|
826 |
|
827 |
$tokens = $this->get_access_tokens();
|
828 |
$token = null;
|
841 |
|
842 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
843 |
|
844 |
+
// log the event, but don't halt the process.
|
845 |
$this->get_plugin()->log( 'Could not decrypt access token. ' . $exception->getMessage() );
|
846 |
}
|
847 |
}
|
870 |
* @return array
|
871 |
*/
|
872 |
public function get_access_tokens() {
|
873 |
+
return (array) get_option( 'wc_square_access_tokens', array() );
|
874 |
}
|
875 |
|
876 |
|
884 |
* @return array
|
885 |
*/
|
886 |
public function get_refresh_tokens() {
|
887 |
+
return (array) get_option( 'wc_square_refresh_tokens', array() );
|
888 |
}
|
889 |
|
890 |
/**
|
906 |
* @return boolean
|
907 |
*/
|
908 |
public function is_sandbox_setting_enabled() {
|
909 |
+
return 'yes' === $this->get_enable_sandbox();
|
|
|
910 |
}
|
911 |
|
912 |
|
942 |
* @return bool True if the current request is for the Square admin settings, otherwise false.
|
943 |
*/
|
944 |
public function is_admin_settings_screen() {
|
945 |
+
return isset( $_GET['page'], $_GET['tab'] ) && 'wc-settings' === $_GET['page'] && Plugin::PLUGIN_ID === $_GET['tab']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
946 |
}
|
947 |
}
|
includes/Sync/Catalog_Item.php
CHANGED
@@ -26,7 +26,7 @@ namespace WooCommerce\Square\Sync;
|
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use WooCommerce\Square\Handlers\Product;
|
28 |
|
29 |
-
defined( 'ABSPATH' )
|
30 |
|
31 |
/**
|
32 |
* Class to represent a single catalog item.
|
@@ -128,19 +128,21 @@ class Catalog_Item {
|
|
128 |
|
129 |
if ( ! $catalog_object ) {
|
130 |
|
131 |
-
$catalog_object = new \SquareConnect\Model\CatalogObject(
|
132 |
-
|
133 |
-
|
|
|
|
|
134 |
}
|
135 |
|
136 |
// update the object data from the Woo product
|
137 |
$catalog_object = Product\Woo_SOR::update_catalog_item( $catalog_object, $this->product );
|
138 |
|
139 |
-
$batch_data =
|
140 |
|
141 |
$this->batch = new \SquareConnect\Model\CatalogObjectBatch( $batch_data );
|
142 |
|
143 |
-
$variations = $catalog_object->getItemData()->getVariations() ?:
|
144 |
|
145 |
$this->batch_object_count = 1 + count( $variations );
|
146 |
}
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use WooCommerce\Square\Handlers\Product;
|
28 |
|
29 |
+
defined( 'ABSPATH' ) || exit;
|
30 |
|
31 |
/**
|
32 |
* Class to represent a single catalog item.
|
128 |
|
129 |
if ( ! $catalog_object ) {
|
130 |
|
131 |
+
$catalog_object = new \SquareConnect\Model\CatalogObject(
|
132 |
+
array(
|
133 |
+
'type' => 'ITEM',
|
134 |
+
)
|
135 |
+
);
|
136 |
}
|
137 |
|
138 |
// update the object data from the Woo product
|
139 |
$catalog_object = Product\Woo_SOR::update_catalog_item( $catalog_object, $this->product );
|
140 |
|
141 |
+
$batch_data = array( 'objects' => array( $catalog_object ) );
|
142 |
|
143 |
$this->batch = new \SquareConnect\Model\CatalogObjectBatch( $batch_data );
|
144 |
|
145 |
+
$variations = $catalog_object->getItemData()->getVariations() ?: array();
|
146 |
|
147 |
$this->batch_object_count = 1 + count( $variations );
|
148 |
}
|
includes/Sync/Interval_Polling.php
CHANGED
@@ -25,10 +25,11 @@ namespace WooCommerce\Square\Sync;
|
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use SquareConnect\Model\SearchCatalogObjectsResponse;
|
|
|
28 |
use WooCommerce\Square\Handlers\Product;
|
29 |
use WooCommerce\Square\Handlers\Category;
|
30 |
|
31 |
-
defined( 'ABSPATH' )
|
32 |
|
33 |
/**
|
34 |
* Class to represent a synchronization job to poll latest product updates at intervals.
|
@@ -47,14 +48,14 @@ class Interval_Polling extends Stepped_Job {
|
|
47 |
*/
|
48 |
protected function assign_next_steps() {
|
49 |
|
50 |
-
$next_steps =
|
51 |
|
52 |
if ( $this->is_system_of_record_square() ) {
|
53 |
|
54 |
-
$next_steps =
|
55 |
'update_category_data',
|
56 |
'update_product_data',
|
57 |
-
|
58 |
}
|
59 |
|
60 |
// only pull latest inventory if enabled
|
@@ -77,10 +78,12 @@ class Interval_Polling extends Stepped_Job {
|
|
77 |
$date->setTimestamp( $this->get_attr( 'catalog_last_synced_at', (int) wc_square()->get_sync_handler()->get_last_synced_at() ) );
|
78 |
$date->setTimezone( new \DateTimeZone( 'UTC' ) );
|
79 |
|
80 |
-
$response = wc_square()->get_api()->search_catalog_objects(
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
|
|
84 |
|
85 |
$categories = $response->get_data()->getObjects();
|
86 |
|
@@ -89,14 +92,16 @@ class Interval_Polling extends Stepped_Job {
|
|
89 |
Category::import_or_update( $category );
|
90 |
}
|
91 |
|
92 |
-
Records::set_record(
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
|
|
98 |
)
|
99 |
-
|
100 |
}
|
101 |
|
102 |
$this->complete_step( 'update_category_data' );
|
@@ -115,15 +120,17 @@ class Interval_Polling extends Stepped_Job {
|
|
115 |
$date->setTimestamp( $this->get_attr( 'catalog_last_synced_at', (int) wc_square()->get_sync_handler()->get_last_synced_at() ) );
|
116 |
$date->setTimezone( new \DateTimeZone( 'UTC' ) );
|
117 |
|
118 |
-
$products_updated = $this->get_attr( 'processed_product_ids',
|
119 |
$cursor = $this->get_attr( 'update_product_data_cursor' );
|
120 |
|
121 |
-
$response = wc_square()->get_api()->search_catalog_objects(
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
|
|
|
|
127 |
|
128 |
// store the timestamp after this API request was completed
|
129 |
// we don't want to set it at the end, as counts may have changed in the time it takes to process the data
|
@@ -147,10 +154,10 @@ class Interval_Polling extends Stepped_Job {
|
|
147 |
// deleted items won't have any data to set, so don't try and update the product
|
148 |
if ( $object->getIsDeleted() ) {
|
149 |
|
150 |
-
$record =
|
151 |
'type' => 'alert',
|
152 |
'product_id' => $product->get_id(),
|
153 |
-
|
154 |
|
155 |
// if enabled, hide the product from the catalog
|
156 |
if ( wc_square()->get_settings_handler()->hide_missing_square_products() ) {
|
@@ -162,7 +169,8 @@ class Interval_Polling extends Stepped_Job {
|
|
162 |
|
163 |
$record['product_hidden'] = true;
|
164 |
|
165 |
-
} catch ( \Exception $e ) {
|
|
|
166 |
}
|
167 |
|
168 |
Records::set_record( $record );
|
@@ -181,17 +189,19 @@ class Interval_Polling extends Stepped_Job {
|
|
181 |
|
182 |
} catch ( \Exception $exception ) {
|
183 |
|
184 |
-
Records::set_record(
|
185 |
-
|
186 |
-
|
187 |
-
|
|
|
|
|
188 |
}
|
189 |
}
|
190 |
}
|
191 |
}
|
192 |
}
|
193 |
|
194 |
-
$cursor = $response->get_data()->getCursor();
|
195 |
|
196 |
$this->set_attr( 'update_product_data_cursor', $cursor );
|
197 |
$this->set_attr( 'processed_product_ids', array_unique( $products_updated ) );
|
@@ -216,10 +226,10 @@ class Interval_Polling extends Stepped_Job {
|
|
216 |
$products_updated = $this->get_attr( 'processed_product_ids' );
|
217 |
$cursor = $this->get_attr( 'update_inventory_counts_cursor' );
|
218 |
|
219 |
-
$args =
|
220 |
-
'location_ids' =>
|
221 |
'cursor' => $cursor,
|
222 |
-
|
223 |
|
224 |
$last_synced_at = $this->get_attr( 'inventory_last_synced_at' );
|
225 |
|
@@ -258,7 +268,7 @@ class Interval_Polling extends Stepped_Job {
|
|
258 |
}
|
259 |
}
|
260 |
|
261 |
-
$cursor = $response->get_data()->getCursor();
|
262 |
|
263 |
$this->set_attr( 'update_inventory_counts_cursor', $cursor );
|
264 |
$this->set_attr( 'processed_product_ids', array_unique( $products_updated ) );
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use SquareConnect\Model\SearchCatalogObjectsResponse;
|
28 |
+
use SquareConnect\Model\BatchRetrieveInventoryCountsResponse;
|
29 |
use WooCommerce\Square\Handlers\Product;
|
30 |
use WooCommerce\Square\Handlers\Category;
|
31 |
|
32 |
+
defined( 'ABSPATH' ) || exit;
|
33 |
|
34 |
/**
|
35 |
* Class to represent a synchronization job to poll latest product updates at intervals.
|
48 |
*/
|
49 |
protected function assign_next_steps() {
|
50 |
|
51 |
+
$next_steps = array();
|
52 |
|
53 |
if ( $this->is_system_of_record_square() ) {
|
54 |
|
55 |
+
$next_steps = array(
|
56 |
'update_category_data',
|
57 |
'update_product_data',
|
58 |
+
);
|
59 |
}
|
60 |
|
61 |
// only pull latest inventory if enabled
|
78 |
$date->setTimestamp( $this->get_attr( 'catalog_last_synced_at', (int) wc_square()->get_sync_handler()->get_last_synced_at() ) );
|
79 |
$date->setTimezone( new \DateTimeZone( 'UTC' ) );
|
80 |
|
81 |
+
$response = wc_square()->get_api()->search_catalog_objects(
|
82 |
+
array(
|
83 |
+
'object_types' => array( 'CATEGORY' ),
|
84 |
+
'begin_time' => $date->format( DATE_ATOM ),
|
85 |
+
)
|
86 |
+
);
|
87 |
|
88 |
$categories = $response->get_data()->getObjects();
|
89 |
|
92 |
Category::import_or_update( $category );
|
93 |
}
|
94 |
|
95 |
+
Records::set_record(
|
96 |
+
array(
|
97 |
+
'type' => 'info',
|
98 |
+
'message' => sprintf(
|
99 |
+
/* translator: Placeholder %d number of categories */
|
100 |
+
_n( 'Updated data for %d category.', 'Updated data for %d categories.', count( $categories ), 'woocommerce-square' ),
|
101 |
+
count( $categories )
|
102 |
+
),
|
103 |
)
|
104 |
+
);
|
105 |
}
|
106 |
|
107 |
$this->complete_step( 'update_category_data' );
|
120 |
$date->setTimestamp( $this->get_attr( 'catalog_last_synced_at', (int) wc_square()->get_sync_handler()->get_last_synced_at() ) );
|
121 |
$date->setTimezone( new \DateTimeZone( 'UTC' ) );
|
122 |
|
123 |
+
$products_updated = $this->get_attr( 'processed_product_ids', array() );
|
124 |
$cursor = $this->get_attr( 'update_product_data_cursor' );
|
125 |
|
126 |
+
$response = wc_square()->get_api()->search_catalog_objects(
|
127 |
+
array(
|
128 |
+
'object_types' => array( 'ITEM' ),
|
129 |
+
'include_deleted_objects' => true,
|
130 |
+
'begin_time' => $date->format( DATE_ATOM ),
|
131 |
+
'cursor' => $cursor,
|
132 |
+
)
|
133 |
+
);
|
134 |
|
135 |
// store the timestamp after this API request was completed
|
136 |
// we don't want to set it at the end, as counts may have changed in the time it takes to process the data
|
154 |
// deleted items won't have any data to set, so don't try and update the product
|
155 |
if ( $object->getIsDeleted() ) {
|
156 |
|
157 |
+
$record = array(
|
158 |
'type' => 'alert',
|
159 |
'product_id' => $product->get_id(),
|
160 |
+
);
|
161 |
|
162 |
// if enabled, hide the product from the catalog
|
163 |
if ( wc_square()->get_settings_handler()->hide_missing_square_products() ) {
|
169 |
|
170 |
$record['product_hidden'] = true;
|
171 |
|
172 |
+
} catch ( \Exception $e ) {
|
173 |
+
}
|
174 |
}
|
175 |
|
176 |
Records::set_record( $record );
|
189 |
|
190 |
} catch ( \Exception $exception ) {
|
191 |
|
192 |
+
Records::set_record(
|
193 |
+
array(
|
194 |
+
'type' => 'alert',
|
195 |
+
'product_id' => $product->get_id(),
|
196 |
+
)
|
197 |
+
);
|
198 |
}
|
199 |
}
|
200 |
}
|
201 |
}
|
202 |
}
|
203 |
|
204 |
+
$cursor = $response->get_data() instanceof SearchCatalogObjectsResponse ? $response->get_data()->getCursor() : null;
|
205 |
|
206 |
$this->set_attr( 'update_product_data_cursor', $cursor );
|
207 |
$this->set_attr( 'processed_product_ids', array_unique( $products_updated ) );
|
226 |
$products_updated = $this->get_attr( 'processed_product_ids' );
|
227 |
$cursor = $this->get_attr( 'update_inventory_counts_cursor' );
|
228 |
|
229 |
+
$args = array(
|
230 |
+
'location_ids' => array( wc_square()->get_settings_handler()->get_location_id() ),
|
231 |
'cursor' => $cursor,
|
232 |
+
);
|
233 |
|
234 |
$last_synced_at = $this->get_attr( 'inventory_last_synced_at' );
|
235 |
|
268 |
}
|
269 |
}
|
270 |
|
271 |
+
$cursor = $response->get_data() instanceof BatchRetrieveInventoryCountsResponse ? $response->get_data()->getCursor() : null;
|
272 |
|
273 |
$this->set_attr( 'update_inventory_counts_cursor', $cursor );
|
274 |
$this->set_attr( 'processed_product_ids', array_unique( $products_updated ) );
|
includes/Sync/Job.php
CHANGED
@@ -25,7 +25,7 @@ namespace WooCommerce\Square\Sync;
|
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
-
defined( 'ABSPATH' )
|
29 |
|
30 |
/**
|
31 |
* Synchronization Job abstract.
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
+
defined( 'ABSPATH' ) || exit;
|
29 |
|
30 |
/**
|
31 |
* Synchronization Job abstract.
|
includes/Sync/Manual_Synchronization.php
CHANGED
@@ -33,7 +33,7 @@ use SquareConnect\ObjectSerializer;
|
|
33 |
use WooCommerce\Square\Handlers\Category;
|
34 |
use WooCommerce\Square\Handlers\Product;
|
35 |
|
36 |
-
defined( 'ABSPATH' )
|
37 |
|
38 |
/**
|
39 |
* Class to represent a single synchronization job triggered manually.
|
@@ -49,6 +49,10 @@ class Manual_Synchronization extends Stepped_Job {
|
|
49 |
/** @var int the limit for how many inventory changes can be made in a single request */
|
50 |
const BATCH_CHANGE_INVENTORY_LIMIT = 100;
|
51 |
|
|
|
|
|
|
|
|
|
52 |
|
53 |
/**
|
54 |
* Validates the products attached to this job.
|
@@ -59,22 +63,20 @@ class Manual_Synchronization extends Stepped_Job {
|
|
59 |
|
60 |
$product_ids = $this->get_attr( 'product_ids' );
|
61 |
|
62 |
-
$products_query =
|
63 |
'include' => $product_ids,
|
64 |
'limit' => -1,
|
65 |
-
'
|
66 |
-
|
67 |
-
|
68 |
-
$validated_products = wc_get_products( $products_query );
|
69 |
|
70 |
if ( 'delete' === $this->get_attr( 'action' ) ) {
|
71 |
|
72 |
-
$products_query['status'] = 'trash';
|
73 |
-
$trashed_products = wc_get_products( $products_query );
|
74 |
-
|
75 |
-
$validated_products = array_unique( array_merge( $validated_products, $trashed_products ), SORT_NUMERIC );
|
76 |
}
|
77 |
|
|
|
|
|
78 |
$this->set_attr( 'validated_product_ids', $validated_products );
|
79 |
|
80 |
$this->complete_step( 'validate_products' );
|
@@ -97,11 +99,11 @@ class Manual_Synchronization extends Stepped_Job {
|
|
97 |
$limits = $catalog_info->get_data()->getLimits();
|
98 |
|
99 |
$this->set_attr( 'max_objects_to_retrieve', $limits->getBatchRetrieveMaxObjectIds() );
|
100 |
-
$this->set_attr( 'max_objects_per_batch',
|
101 |
-
$this->set_attr( 'max_objects_total',
|
102 |
}
|
103 |
-
|
104 |
-
}
|
105 |
|
106 |
$this->complete_step( 'update_limits' );
|
107 |
}
|
@@ -133,9 +135,9 @@ class Manual_Synchronization extends Stepped_Job {
|
|
133 |
|
134 |
$map = Category::get_map();
|
135 |
$category_ids = $this->get_attr( 'refresh_mappings_category_ids', $this->get_attr( 'category_ids' ) );
|
136 |
-
$mapped_categories =
|
137 |
-
$unmapped_categories = $this->get_attr( 'unmapped_categories',
|
138 |
-
$unmapped_category_ids =
|
139 |
|
140 |
if ( empty( $category_ids ) ) {
|
141 |
$this->complete_step( 'refresh_category_mappings' );
|
@@ -152,7 +154,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
152 |
|
153 |
} else {
|
154 |
|
155 |
-
$this->set_attr( 'refresh_mappings_category_ids',
|
156 |
}
|
157 |
|
158 |
foreach ( $category_ids as $category_id ) {
|
@@ -169,14 +171,21 @@ class Manual_Synchronization extends Stepped_Job {
|
|
169 |
|
170 |
if ( ! empty( $mapped_categories ) ) {
|
171 |
|
172 |
-
$square_ids = array_values(
|
173 |
-
|
174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
|
176 |
$response = wc_square()->get_api()->batch_retrieve_catalog_objects( $square_ids );
|
177 |
|
178 |
// swap the square ID into the array key for quick lookup
|
179 |
-
$mapped_category_audit =
|
180 |
|
181 |
foreach ( $mapped_categories as $mapped_category_id => $mapped_category ) {
|
182 |
$mapped_category_audit[ $mapped_category['square_id'] ] = $mapped_category_id;
|
@@ -218,10 +227,12 @@ class Manual_Synchronization extends Stepped_Job {
|
|
218 |
|
219 |
if ( ! empty( $unmapped_category_ids ) ) {
|
220 |
|
221 |
-
$unmapped_category_terms = get_terms(
|
222 |
-
|
223 |
-
|
224 |
-
|
|
|
|
|
225 |
|
226 |
// make the 'name' attribute the array key, for more efficient searching later.
|
227 |
foreach ( $unmapped_category_terms as $unmapped_category_term ) {
|
@@ -246,8 +257,8 @@ class Manual_Synchronization extends Stepped_Job {
|
|
246 |
*/
|
247 |
protected function query_unmapped_categories() {
|
248 |
|
249 |
-
$unmapped_categories = $this->get_attr( 'unmapped_categories',
|
250 |
-
$mapped_categories = $this->get_attr( 'mapped_categories',
|
251 |
|
252 |
if ( empty( $unmapped_categories ) ) {
|
253 |
|
@@ -255,10 +266,12 @@ class Manual_Synchronization extends Stepped_Job {
|
|
255 |
|
256 |
} else {
|
257 |
|
258 |
-
$response = wc_square()->get_api()->search_catalog_objects(
|
259 |
-
|
260 |
-
|
261 |
-
|
|
|
|
|
262 |
|
263 |
$category_map = Category::get_map();
|
264 |
$categories = $response->get_data()->getObjects();
|
@@ -273,10 +286,10 @@ class Manual_Synchronization extends Stepped_Job {
|
|
273 |
|
274 |
$category_id = $unmapped_categories[ $unmapped_category_key ]['term_id'];
|
275 |
|
276 |
-
$category_map[ $category_id ] =
|
277 |
'square_id' => $category_object->getId(),
|
278 |
'square_version' => $category_object->getVersion(),
|
279 |
-
|
280 |
|
281 |
$mapped_categories[] = $category_id;
|
282 |
unset( $unmapped_categories[ $unmapped_category_key ] );
|
@@ -309,13 +322,15 @@ class Manual_Synchronization extends Stepped_Job {
|
|
309 |
protected function upsert_categories() {
|
310 |
|
311 |
$category_ids = $this->get_attr( 'category_ids' );
|
312 |
-
$categories = get_terms(
|
313 |
-
|
314 |
-
|
315 |
-
|
|
|
|
|
316 |
|
317 |
-
$batches =
|
318 |
-
$reverse_map =
|
319 |
|
320 |
// For now, keep it to one category per batch. Since we can still send 1000 batches per request, it's efficient,
|
321 |
// and insulates errors per category rather than a single category error breaking the entire batch it is in.
|
@@ -329,19 +344,19 @@ class Manual_Synchronization extends Stepped_Job {
|
|
329 |
|
330 |
$reverse_map[ $square_id ] = $category_id;
|
331 |
|
332 |
-
$catalog_object_data =
|
333 |
'type' => 'CATEGORY',
|
334 |
'id' => $square_id,
|
335 |
-
'category_data' =>
|
336 |
'name' => wp_specialchars_decode( $category->name ), // names are stored encoded in the database
|
337 |
-
|
338 |
-
|
339 |
|
340 |
if ( 0 < $square_version ) {
|
341 |
$catalog_object_data['version'] = $square_version;
|
342 |
}
|
343 |
|
344 |
-
$batches[] = new \SquareConnect\Model\CatalogObjectBatch(
|
345 |
}
|
346 |
|
347 |
$idempotency_key = wc_square()->get_idempotency_key( md5( serialize( $batches ) . $this->get_attr( 'id' ) ) . '_upsert_categories' );
|
@@ -389,8 +404,8 @@ class Manual_Synchronization extends Stepped_Job {
|
|
389 |
*/
|
390 |
protected function prepare_matched_products_for_upsert() {
|
391 |
|
392 |
-
$product_ids_to_prepare = $this->get_attr( 'product_ids_to_prepare', $this->get_attr( 'validated_product_ids',
|
393 |
-
$in_progress = $this->get_attr( 'in_progress_prepare_matched_products_for_upsert',
|
394 |
|
395 |
if ( empty( $product_ids_to_prepare ) ) {
|
396 |
$this->complete_step( 'prepare_matched_products_for_upsert' );
|
@@ -429,7 +444,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
429 |
|
430 |
try {
|
431 |
|
432 |
-
$objects =
|
433 |
$api_response = json_decode( $in_progress['api_response'], true );
|
434 |
|
435 |
if ( isset( $api_response['objects'] ) ) {
|
@@ -438,9 +453,10 @@ class Manual_Synchronization extends Stepped_Job {
|
|
438 |
}
|
439 |
}
|
440 |
|
441 |
-
$response = new \SquareConnect\Model\BatchRetrieveCatalogObjectsResponse(
|
442 |
|
443 |
-
} catch ( \Exception $e ) {
|
|
|
444 |
}
|
445 |
|
446 |
if ( null === $response ) {
|
@@ -460,7 +476,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
460 |
return;
|
461 |
}
|
462 |
|
463 |
-
$catalog_objects = isset( $in_progress['catalog_objects'] ) ? $in_progress['catalog_objects'] :
|
464 |
|
465 |
if ( $response && $response_objects = $response->getObjects() ) {
|
466 |
|
@@ -487,11 +503,11 @@ class Manual_Synchronization extends Stepped_Job {
|
|
487 |
}
|
488 |
}
|
489 |
|
490 |
-
$matched_products_to_upsert = $this->get_attr( 'matched_products_to_upsert',
|
491 |
|
492 |
$this->set_attr( 'matched_products_to_upsert', $matched_products_to_upsert + $catalog_objects );
|
493 |
$this->set_attr( 'product_ids_to_prepare', array_diff( $product_ids_to_prepare, $product_ids ) );
|
494 |
-
$this->set_attr( 'in_progress_prepare_matched_products_for_upsert',
|
495 |
}
|
496 |
|
497 |
|
@@ -504,7 +520,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
504 |
*/
|
505 |
protected function upsert_matched_products() {
|
506 |
|
507 |
-
$matched_products_to_upsert = $this->get_attr( 'matched_products_to_upsert',
|
508 |
|
509 |
if ( empty( $matched_products_to_upsert ) ) {
|
510 |
|
@@ -517,7 +533,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
517 |
|
518 |
if ( isset( $result['processed'] ) ) {
|
519 |
|
520 |
-
$processed_product_ids = $this->get_attr( 'processed_product_ids',
|
521 |
|
522 |
$this->set_attr( 'processed_product_ids', array_merge( $processed_product_ids, $result['processed'] ) );
|
523 |
|
@@ -536,8 +552,8 @@ class Manual_Synchronization extends Stepped_Job {
|
|
536 |
*/
|
537 |
protected function update_matched_products() {
|
538 |
|
539 |
-
$product_ids = $this->get_attr( 'matched_product_ids', $this->get_attr( 'validated_product_ids',
|
540 |
-
$processed_product_ids = $this->get_attr( 'processed_product_ids',
|
541 |
|
542 |
// remove IDs that have already been processed
|
543 |
$product_ids = array_diff( $product_ids, $processed_product_ids );
|
@@ -558,7 +574,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
558 |
|
559 |
} else {
|
560 |
|
561 |
-
$this->set_attr( 'matched_product_ids',
|
562 |
}
|
563 |
|
564 |
$products_map = Product::get_square_meta( $product_ids, 'square_item_id' );
|
@@ -574,7 +590,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
574 |
throw new Framework\SV_WC_API_Exception( 'Response data is missing' );
|
575 |
}
|
576 |
|
577 |
-
$catalog_objects =
|
578 |
|
579 |
if ( $response->get_data()->getObjects() ) {
|
580 |
|
@@ -596,7 +612,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
596 |
$this->set_attr( 'processed_product_ids', array_merge( $result['processed'], $processed_product_ids ) );
|
597 |
|
598 |
// any products that were staged but not processed, push to the matched array to try next time
|
599 |
-
$matched_product_ids = $this->get_attr( 'matched_product_ids',
|
600 |
$this->set_attr( 'matched_product_ids', array_merge( $result['unprocessed'], $matched_product_ids ) );
|
601 |
}
|
602 |
}
|
@@ -611,14 +627,17 @@ class Manual_Synchronization extends Stepped_Job {
|
|
611 |
*/
|
612 |
protected function search_matched_products() {
|
613 |
|
614 |
-
$product_ids = $this->get_attr( 'search_product_ids', $this->get_attr( 'validated_product_ids',
|
615 |
-
$processed_product_ids = $this->get_attr( 'processed_product_ids',
|
616 |
-
$in_progress = $this->get_attr(
|
617 |
-
'
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
|
|
|
|
|
|
622 |
|
623 |
// remove IDs that have already been processed
|
624 |
$product_ids = array_diff( $product_ids, $processed_product_ids );
|
@@ -643,11 +662,13 @@ class Manual_Synchronization extends Stepped_Job {
|
|
643 |
|
644 |
} else {
|
645 |
|
646 |
-
$response = wc_square()->get_api()->search_catalog_objects(
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
|
|
|
|
651 |
|
652 |
$search_response = $response->get_data();
|
653 |
|
@@ -658,7 +679,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
658 |
throw new Framework\SV_WC_API_Exception( 'Response data is missing' );
|
659 |
}
|
660 |
|
661 |
-
$catalog_objects = $search_response->getObjects() ?:
|
662 |
$cursor = $search_response->getCursor();
|
663 |
$catalog_objects_to_update = $in_progress['catalog_objects_to_update'];
|
664 |
|
@@ -764,8 +785,8 @@ class Manual_Synchronization extends Stepped_Job {
|
|
764 |
|
765 |
if ( ! empty( $result['unprocessed'] ) ) {
|
766 |
|
767 |
-
$catalog_processed
|
768 |
-
$remaining_product_ids
|
769 |
$in_progress['catalog_objects_to_update'] = array_diff_key( $catalog_objects_to_update, array_flip( $processed_product_ids ) );
|
770 |
|
771 |
} else {
|
@@ -779,7 +800,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
779 |
if ( ! $catalog_processed && ! empty( $remaining_product_ids ) ) {
|
780 |
|
781 |
$this->set_attr( 'search_products_cursor', $cursor );
|
782 |
-
$this->set_attr( 'search_product_ids',
|
783 |
|
784 |
} else {
|
785 |
|
@@ -794,8 +815,8 @@ class Manual_Synchronization extends Stepped_Job {
|
|
794 |
*/
|
795 |
protected function upsert_new_products() {
|
796 |
|
797 |
-
$product_ids = $this->get_attr( 'upsert_new_product_ids', $this->get_attr( 'validated_product_ids',
|
798 |
-
$processed_product_ids = $this->get_attr( 'processed_product_ids',
|
799 |
|
800 |
// remove IDs that have already been processed
|
801 |
$product_ids = array_diff( $product_ids, $processed_product_ids );
|
@@ -806,14 +827,16 @@ class Manual_Synchronization extends Stepped_Job {
|
|
806 |
return;
|
807 |
}
|
808 |
|
809 |
-
$catalog_objects =
|
810 |
|
811 |
foreach ( $product_ids as $product_id ) {
|
812 |
|
813 |
-
$catalog_objects[ $product_id ] = new CatalogObject(
|
814 |
-
|
815 |
-
|
816 |
-
|
|
|
|
|
817 |
}
|
818 |
|
819 |
$result = $this->upsert_catalog_objects( $catalog_objects );
|
@@ -856,24 +879,27 @@ class Manual_Synchronization extends Stepped_Job {
|
|
856 |
|
857 |
$is_delete_action = 'delete' === $this->get_attr( 'action' );
|
858 |
$product_ids = array_keys( $objects );
|
859 |
-
$original_square_image_ids =
|
860 |
-
$staged_product_ids =
|
861 |
-
$successful_product_ids =
|
862 |
$total_object_count = 0;
|
863 |
-
$batches =
|
864 |
-
$result =
|
865 |
-
'processed' =>
|
866 |
'unprocessed' => $product_ids,
|
867 |
-
|
868 |
-
|
869 |
-
$in_progress = $this->get_attr(
|
870 |
-
'
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
|
|
|
|
|
|
877 |
|
878 |
if ( null === $in_progress['unprocessed_upsert_response'] ) {
|
879 |
|
@@ -882,9 +908,12 @@ class Manual_Synchronization extends Stepped_Job {
|
|
882 |
|
883 |
$staged_product_ids = $in_progress['staged_product_ids'];
|
884 |
$total_object_count = $in_progress['total_object_count'];
|
885 |
-
$batches = array_map(
|
886 |
-
|
887 |
-
|
|
|
|
|
|
|
888 |
}
|
889 |
|
890 |
foreach ( $objects as $product_id => $object ) {
|
@@ -909,7 +938,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
909 |
$object = $this->convert_to_catalog_object( $object );
|
910 |
}
|
911 |
|
912 |
-
$product
|
913 |
$original_square_image_ids[ $product_id ] = $product->get_meta( '_square_item_image_id' );
|
914 |
|
915 |
$catalog_item = new Catalog_Item( $product, $is_delete_action );
|
@@ -918,7 +947,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
918 |
|
919 |
if ( $this->get_max_objects_total() >= $object_count + $total_object_count ) {
|
920 |
$batches[] = $batch;
|
921 |
-
$total_object_count
|
922 |
$staged_product_ids[] = $product_id;
|
923 |
} else {
|
924 |
break;
|
@@ -1002,7 +1031,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1002 |
wc_square()->log( 'Mapped ' . count( $in_progress['mapped_client_item_ids'] ) . ' Square IDs in ' . $duration . 's' );
|
1003 |
}
|
1004 |
|
1005 |
-
$pull_inventory_variation_ids = $this->get_attr( 'pull_inventory_variation_ids',
|
1006 |
|
1007 |
wc_square()->log( 'Storing Square item data to WooCommerce products' );
|
1008 |
|
@@ -1032,11 +1061,14 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1032 |
continue;
|
1033 |
}
|
1034 |
|
1035 |
-
Product::update_square_meta(
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
|
|
|
|
|
|
1040 |
|
1041 |
$successful_product_ids[] = $product->get_id();
|
1042 |
|
@@ -1048,10 +1080,13 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1048 |
|
1049 |
$pull_inventory_variation_ids[] = $catalog_item_variation->getId();
|
1050 |
|
1051 |
-
Product::update_square_meta(
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
|
|
|
|
|
|
1055 |
}
|
1056 |
}
|
1057 |
}
|
@@ -1069,7 +1104,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1069 |
|
1070 |
// If there is a local image which is different from the last uploaded image
|
1071 |
// Or if the remote square image id has changed
|
1072 |
-
if ( ( $local_image_id &&
|
1073 |
( ! ( $original_square_image_ids[ $product_id ] && $original_square_image_ids[ $product_id ] === $product->get_meta( '_square_item_image_id' ) ) ) ) {
|
1074 |
// there is no batch image endpoint
|
1075 |
$this->push_product_image( $product );
|
@@ -1091,15 +1126,17 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1091 |
// log any failed products
|
1092 |
foreach ( array_diff( $staged_product_ids, $successful_product_ids ) as $product_id ) {
|
1093 |
|
1094 |
-
Records::set_record(
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
|
|
|
|
1103 |
}
|
1104 |
|
1105 |
$this->set_attr( 'in_progress_upsert_catalog_objects', null );
|
@@ -1179,8 +1216,8 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1179 |
*/
|
1180 |
protected function push_inventory() {
|
1181 |
|
1182 |
-
$product_ids = $this->get_attr( 'inventory_push_product_ids',
|
1183 |
-
$inventory_changes =
|
1184 |
$inventory_change_count = 0;
|
1185 |
|
1186 |
foreach ( $product_ids as $key => $product_id ) {
|
@@ -1189,7 +1226,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1189 |
|
1190 |
if ( $product instanceof \WC_Product ) {
|
1191 |
|
1192 |
-
$product_inventory_changes =
|
1193 |
|
1194 |
if ( $product->is_type( 'variable' ) && $product->has_child() ) {
|
1195 |
|
@@ -1202,7 +1239,6 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1202 |
$product_inventory_changes[] = $inventory_change;
|
1203 |
}
|
1204 |
}
|
1205 |
-
|
1206 |
} elseif ( $square_variation_id = Product::get_square_item_variation_id( $product_id, false ) ) {
|
1207 |
|
1208 |
if ( $inventory_change = Product::get_inventory_change_physical_count_type( $product ) ) {
|
@@ -1221,7 +1257,6 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1221 |
|
1222 |
break;
|
1223 |
}
|
1224 |
-
|
1225 |
} else {
|
1226 |
|
1227 |
unset( $product_ids[ $key ] );
|
@@ -1251,8 +1286,8 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1251 |
*/
|
1252 |
protected function square_sor_sync() {
|
1253 |
|
1254 |
-
$synced_product_ids = $this->get_attr( 'validated_product_ids',
|
1255 |
-
$processed_product_ids = $this->get_attr( 'processed_product_ids',
|
1256 |
$unprocessed_product_ids = array_diff( $synced_product_ids, $processed_product_ids );
|
1257 |
$catalog_processed = $this->get_attr( 'catalog_processed', false );
|
1258 |
|
@@ -1278,12 +1313,14 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1278 |
|
1279 |
$cursor = $this->get_attr( 'square_sor_cursor' );
|
1280 |
|
1281 |
-
$response = wc_square()->get_api()->search_catalog_objects(
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
|
|
|
|
1287 |
|
1288 |
$response_data = $response->get_data();
|
1289 |
|
@@ -1304,14 +1341,13 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1304 |
$catalog_processed = ! $cursor;
|
1305 |
$this->set_attr( 'catalog_processed', $catalog_processed );
|
1306 |
|
1307 |
-
// bail early and fail for any API and plugin errors
|
1308 |
-
} catch ( \Exception $exception ) {
|
1309 |
|
1310 |
$this->fail( 'Product sync failed. ' . $exception->getMessage() );
|
1311 |
return;
|
1312 |
}
|
1313 |
|
1314 |
-
$related_objects = $
|
1315 |
|
1316 |
if ( $related_objects && is_array( $related_objects ) ) {
|
1317 |
// first import any related categories
|
@@ -1322,10 +1358,10 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1322 |
}
|
1323 |
}
|
1324 |
|
1325 |
-
$pull_inventory_variation_ids = $this->get_attr( 'pull_inventory_variation_ids',
|
1326 |
|
1327 |
/** @var \SquareConnect\Model\CatalogObject[] */
|
1328 |
-
$catalog_objects = $products_to_update =
|
1329 |
|
1330 |
wc_square()->log( 'Searching for products in ' . count( $response_data->getObjects() ) . ' Square objects' );
|
1331 |
|
@@ -1426,10 +1462,9 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1426 |
if ( ! $product->get_image_id() && $square_object->getImageId() ) {
|
1427 |
Product::update_image_from_square( $product, $square_object->getImageId() );
|
1428 |
}
|
1429 |
-
|
1430 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
1431 |
|
1432 |
-
$this->mark_failed_products(
|
1433 |
}
|
1434 |
|
1435 |
$processed_product_ids[] = $product->get_id();
|
@@ -1452,12 +1487,18 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1452 |
*/
|
1453 |
protected function pull_inventory() {
|
1454 |
|
1455 |
-
$processed_ids = $this->get_attr( 'processed_square_variation_ids',
|
1456 |
|
1457 |
-
$in_progress = wp_parse_args(
|
1458 |
-
|
1459 |
-
|
1460 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1461 |
|
1462 |
$response_data = null;
|
1463 |
|
@@ -1469,7 +1510,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1469 |
// if the saved response was somehow corrupted, start over
|
1470 |
if ( ! $response_data instanceof BatchRetrieveInventoryCountsResponse ) {
|
1471 |
|
1472 |
-
$square_variation_ids = $this->get_attr( 'pull_inventory_variation_ids',
|
1473 |
|
1474 |
// remove IDs that have already been processed
|
1475 |
$square_variation_ids = array_diff( $square_variation_ids, $processed_ids );
|
@@ -1480,37 +1521,53 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1480 |
return;
|
1481 |
}
|
1482 |
|
1483 |
-
if ( count( $square_variation_ids ) >
|
1484 |
|
1485 |
-
$variation_ids_batch = array_slice( $square_variation_ids, 0,
|
1486 |
|
1487 |
$this->set_attr( 'pull_inventory_variation_ids', array_diff( $square_variation_ids, $variation_ids_batch ) );
|
1488 |
|
1489 |
$square_variation_ids = $variation_ids_batch;
|
1490 |
}
|
1491 |
|
1492 |
-
$
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1496 |
|
1497 |
-
|
1498 |
-
throw new Framework\SV_WC_Plugin_Exception( 'Response data missing or invalid' );
|
1499 |
-
}
|
1500 |
|
1501 |
-
|
|
|
1502 |
|
1503 |
-
|
1504 |
-
|
|
|
1505 |
|
1506 |
-
$
|
1507 |
-
|
1508 |
-
|
|
|
|
|
1509 |
|
1510 |
-
|
1511 |
}
|
1512 |
|
1513 |
-
foreach ( $
|
1514 |
|
1515 |
if ( in_array( $count->getCatalogObjectId(), $in_progress['processed_variation_ids'], false ) ) {
|
1516 |
continue;
|
@@ -1544,7 +1601,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1544 |
$this->set_attr( 'processed_square_variation_ids', array_merge( $processed_ids, $in_progress['processed_variation_ids'] ) );
|
1545 |
|
1546 |
// clear any in-progress data
|
1547 |
-
$this->set_attr( 'in_progress_pull_inventory',
|
1548 |
}
|
1549 |
|
1550 |
/**
|
@@ -1554,7 +1611,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1554 |
*
|
1555 |
* @param \WC_Product[]|int[] $products products to mark as failed
|
1556 |
*/
|
1557 |
-
protected function mark_failed_products( $products =
|
1558 |
|
1559 |
foreach ( $products as $product ) {
|
1560 |
|
@@ -1564,10 +1621,10 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1564 |
continue;
|
1565 |
}
|
1566 |
|
1567 |
-
$record_data =
|
1568 |
'type' => 'alert',
|
1569 |
'product_id' => $product->get_id(),
|
1570 |
-
|
1571 |
|
1572 |
// optionally hide unmatched products from catalog
|
1573 |
if ( wc_square()->get_settings_handler()->is_system_of_record_square() && wc_square()->get_settings_handler()->hide_missing_square_products() ) {
|
@@ -1579,7 +1636,8 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1579 |
|
1580 |
$record_data['product_hidden'] = true;
|
1581 |
|
1582 |
-
} catch ( \Exception $e ) {
|
|
|
1583 |
}
|
1584 |
|
1585 |
Records::set_record( $record_data );
|
@@ -1599,15 +1657,15 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1599 |
|
1600 |
if ( ! empty( $product_ids ) ) {
|
1601 |
$category_ids = get_terms(
|
1602 |
-
|
1603 |
'taxonomy' => 'product_cat',
|
1604 |
'fields' => 'ids',
|
1605 |
'object_ids' => $product_ids,
|
1606 |
-
|
1607 |
);
|
1608 |
}
|
1609 |
|
1610 |
-
return ! empty( $category_ids ) && ! is_wp_error( $category_ids ) ? $category_ids :
|
1611 |
}
|
1612 |
|
1613 |
|
@@ -1618,21 +1676,21 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1618 |
*/
|
1619 |
protected function assign_next_steps() {
|
1620 |
|
1621 |
-
$next_steps =
|
1622 |
|
1623 |
if ( $this->is_system_of_record_woocommerce() ) {
|
1624 |
|
1625 |
if ( 'delete' === $this->get_attr( 'action' ) ) {
|
1626 |
|
1627 |
-
$next_steps =
|
1628 |
'validate_products',
|
1629 |
'update_matched_products',
|
1630 |
'search_matched_products',
|
1631 |
-
|
1632 |
|
1633 |
} else {
|
1634 |
|
1635 |
-
$next_steps =
|
1636 |
'validate_products',
|
1637 |
'extract_category_ids',
|
1638 |
'refresh_category_mappings',
|
@@ -1641,7 +1699,7 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1641 |
'update_matched_products',
|
1642 |
'search_matched_products',
|
1643 |
'upsert_new_products',
|
1644 |
-
|
1645 |
|
1646 |
// only handle product inventory if enabled
|
1647 |
if ( wc_square()->get_settings_handler()->is_inventory_sync_enabled() ) {
|
@@ -1649,13 +1707,12 @@ class Manual_Synchronization extends Stepped_Job {
|
|
1649 |
$next_steps[] = 'pull_inventory';
|
1650 |
}
|
1651 |
}
|
1652 |
-
|
1653 |
} elseif ( $this->is_system_of_record_square() ) {
|
1654 |
|
1655 |
-
$next_steps =
|
1656 |
'validate_products',
|
1657 |
'square_sor_sync',
|
1658 |
-
|
1659 |
|
1660 |
// only pull product inventory if enabled
|
1661 |
if ( wc_square()->get_settings_handler()->is_inventory_sync_enabled() ) {
|
33 |
use WooCommerce\Square\Handlers\Category;
|
34 |
use WooCommerce\Square\Handlers\Product;
|
35 |
|
36 |
+
defined( 'ABSPATH' ) || exit;
|
37 |
|
38 |
/**
|
39 |
* Class to represent a single synchronization job triggered manually.
|
49 |
/** @var int the limit for how many inventory changes can be made in a single request */
|
50 |
const BATCH_CHANGE_INVENTORY_LIMIT = 100;
|
51 |
|
52 |
+
/** @var int the limit for how many inventory counts can be requested per batch
|
53 |
+
* Square paginates responses in page size of 100.
|
54 |
+
* Consider some items can have more than one object returned with different states. */
|
55 |
+
const BATCH_INVENTORY_COUNTS_LIMIT = 125;
|
56 |
|
57 |
/**
|
58 |
* Validates the products attached to this job.
|
63 |
|
64 |
$product_ids = $this->get_attr( 'product_ids' );
|
65 |
|
66 |
+
$products_query = array(
|
67 |
'include' => $product_ids,
|
68 |
'limit' => -1,
|
69 |
+
'status' => array( 'private', 'publish' ),
|
70 |
+
'return' => 'ids',
|
71 |
+
);
|
|
|
72 |
|
73 |
if ( 'delete' === $this->get_attr( 'action' ) ) {
|
74 |
|
75 |
+
$products_query['status'] = array( 'trash', 'draft', 'pending', 'private', 'publish' );
|
|
|
|
|
|
|
76 |
}
|
77 |
|
78 |
+
$validated_products = wc_get_products( $products_query );
|
79 |
+
|
80 |
$this->set_attr( 'validated_product_ids', $validated_products );
|
81 |
|
82 |
$this->complete_step( 'validate_products' );
|
99 |
$limits = $catalog_info->get_data()->getLimits();
|
100 |
|
101 |
$this->set_attr( 'max_objects_to_retrieve', $limits->getBatchRetrieveMaxObjectIds() );
|
102 |
+
$this->set_attr( 'max_objects_per_batch', $limits->getBatchUpsertMaxObjectsPerBatch() );
|
103 |
+
$this->set_attr( 'max_objects_total', $limits->getBatchUpsertMaxTotalObjects() );
|
104 |
}
|
105 |
+
} catch ( Framework\SV_WC_Plugin_Exception $exception ) { // no need to handle errors here
|
106 |
+
}
|
107 |
|
108 |
$this->complete_step( 'update_limits' );
|
109 |
}
|
135 |
|
136 |
$map = Category::get_map();
|
137 |
$category_ids = $this->get_attr( 'refresh_mappings_category_ids', $this->get_attr( 'category_ids' ) );
|
138 |
+
$mapped_categories = array();
|
139 |
+
$unmapped_categories = $this->get_attr( 'unmapped_categories', array() );
|
140 |
+
$unmapped_category_ids = array();
|
141 |
|
142 |
if ( empty( $category_ids ) ) {
|
143 |
$this->complete_step( 'refresh_category_mappings' );
|
154 |
|
155 |
} else {
|
156 |
|
157 |
+
$this->set_attr( 'refresh_mappings_category_ids', array() );
|
158 |
}
|
159 |
|
160 |
foreach ( $category_ids as $category_id ) {
|
171 |
|
172 |
if ( ! empty( $mapped_categories ) ) {
|
173 |
|
174 |
+
$square_ids = array_values(
|
175 |
+
array_filter(
|
176 |
+
array_map(
|
177 |
+
function ( $mapped_category ) {
|
178 |
+
return isset( $mapped_category['square_id'] ) ? $mapped_category['square_id'] : null;
|
179 |
+
},
|
180 |
+
$mapped_categories
|
181 |
+
)
|
182 |
+
)
|
183 |
+
);
|
184 |
|
185 |
$response = wc_square()->get_api()->batch_retrieve_catalog_objects( $square_ids );
|
186 |
|
187 |
// swap the square ID into the array key for quick lookup
|
188 |
+
$mapped_category_audit = array();
|
189 |
|
190 |
foreach ( $mapped_categories as $mapped_category_id => $mapped_category ) {
|
191 |
$mapped_category_audit[ $mapped_category['square_id'] ] = $mapped_category_id;
|
227 |
|
228 |
if ( ! empty( $unmapped_category_ids ) ) {
|
229 |
|
230 |
+
$unmapped_category_terms = get_terms(
|
231 |
+
array(
|
232 |
+
'taxonomy' => 'product_cat',
|
233 |
+
'include' => $unmapped_category_ids,
|
234 |
+
)
|
235 |
+
);
|
236 |
|
237 |
// make the 'name' attribute the array key, for more efficient searching later.
|
238 |
foreach ( $unmapped_category_terms as $unmapped_category_term ) {
|
257 |
*/
|
258 |
protected function query_unmapped_categories() {
|
259 |
|
260 |
+
$unmapped_categories = $this->get_attr( 'unmapped_categories', array() );
|
261 |
+
$mapped_categories = $this->get_attr( 'mapped_categories', array() );
|
262 |
|
263 |
if ( empty( $unmapped_categories ) ) {
|
264 |
|
266 |
|
267 |
} else {
|
268 |
|
269 |
+
$response = wc_square()->get_api()->search_catalog_objects(
|
270 |
+
array(
|
271 |
+
'object_types' => array( 'CATEGORY' ),
|
272 |
+
'cursor' => $this->get_attr( 'unmapped_categories_cursor' ),
|
273 |
+
)
|
274 |
+
);
|
275 |
|
276 |
$category_map = Category::get_map();
|
277 |
$categories = $response->get_data()->getObjects();
|
286 |
|
287 |
$category_id = $unmapped_categories[ $unmapped_category_key ]['term_id'];
|
288 |
|
289 |
+
$category_map[ $category_id ] = array(
|
290 |
'square_id' => $category_object->getId(),
|
291 |
'square_version' => $category_object->getVersion(),
|
292 |
+
);
|
293 |
|
294 |
$mapped_categories[] = $category_id;
|
295 |
unset( $unmapped_categories[ $unmapped_category_key ] );
|
322 |
protected function upsert_categories() {
|
323 |
|
324 |
$category_ids = $this->get_attr( 'category_ids' );
|
325 |
+
$categories = get_terms(
|
326 |
+
array(
|
327 |
+
'taxonomy' => 'product_cat',
|
328 |
+
'include' => $category_ids,
|
329 |
+
)
|
330 |
+
);
|
331 |
|
332 |
+
$batches = array();
|
333 |
+
$reverse_map = array();
|
334 |
|
335 |
// For now, keep it to one category per batch. Since we can still send 1000 batches per request, it's efficient,
|
336 |
// and insulates errors per category rather than a single category error breaking the entire batch it is in.
|
344 |
|
345 |
$reverse_map[ $square_id ] = $category_id;
|
346 |
|
347 |
+
$catalog_object_data = array(
|
348 |
'type' => 'CATEGORY',
|
349 |
'id' => $square_id,
|
350 |
+
'category_data' => array(
|
351 |
'name' => wp_specialchars_decode( $category->name ), // names are stored encoded in the database
|
352 |
+
),
|
353 |
+
);
|
354 |
|
355 |
if ( 0 < $square_version ) {
|
356 |
$catalog_object_data['version'] = $square_version;
|
357 |
}
|
358 |
|
359 |
+
$batches[] = new \SquareConnect\Model\CatalogObjectBatch( array( 'objects' => array( new \SquareConnect\Model\CatalogObject( $catalog_object_data ) ) ) );
|
360 |
}
|
361 |
|
362 |
$idempotency_key = wc_square()->get_idempotency_key( md5( serialize( $batches ) . $this->get_attr( 'id' ) ) . '_upsert_categories' );
|
404 |
*/
|
405 |
protected function prepare_matched_products_for_upsert() {
|
406 |
|
407 |
+
$product_ids_to_prepare = $this->get_attr( 'product_ids_to_prepare', $this->get_attr( 'validated_product_ids', array() ) );
|
408 |
+
$in_progress = $this->get_attr( 'in_progress_prepare_matched_products_for_upsert', array() );
|
409 |
|
410 |
if ( empty( $product_ids_to_prepare ) ) {
|
411 |
$this->complete_step( 'prepare_matched_products_for_upsert' );
|
444 |
|
445 |
try {
|
446 |
|
447 |
+
$objects = array();
|
448 |
$api_response = json_decode( $in_progress['api_response'], true );
|
449 |
|
450 |
if ( isset( $api_response['objects'] ) ) {
|
453 |
}
|
454 |
}
|
455 |
|
456 |
+
$response = new \SquareConnect\Model\BatchRetrieveCatalogObjectsResponse( array( 'objects' => $objects ) );
|
457 |
|
458 |
+
} catch ( \Exception $e ) {
|
459 |
+
}
|
460 |
}
|
461 |
|
462 |
if ( null === $response ) {
|
476 |
return;
|
477 |
}
|
478 |
|
479 |
+
$catalog_objects = isset( $in_progress['catalog_objects'] ) ? $in_progress['catalog_objects'] : array();
|
480 |
|
481 |
if ( $response && $response_objects = $response->getObjects() ) {
|
482 |
|
503 |
}
|
504 |
}
|
505 |
|
506 |
+
$matched_products_to_upsert = $this->get_attr( 'matched_products_to_upsert', array() );
|
507 |
|
508 |
$this->set_attr( 'matched_products_to_upsert', $matched_products_to_upsert + $catalog_objects );
|
509 |
$this->set_attr( 'product_ids_to_prepare', array_diff( $product_ids_to_prepare, $product_ids ) );
|
510 |
+
$this->set_attr( 'in_progress_prepare_matched_products_for_upsert', array() );
|
511 |
}
|
512 |
|
513 |
|
520 |
*/
|
521 |
protected function upsert_matched_products() {
|
522 |
|
523 |
+
$matched_products_to_upsert = $this->get_attr( 'matched_products_to_upsert', array() );
|
524 |
|
525 |
if ( empty( $matched_products_to_upsert ) ) {
|
526 |
|
533 |
|
534 |
if ( isset( $result['processed'] ) ) {
|
535 |
|
536 |
+
$processed_product_ids = $this->get_attr( 'processed_product_ids', array() );
|
537 |
|
538 |
$this->set_attr( 'processed_product_ids', array_merge( $processed_product_ids, $result['processed'] ) );
|
539 |
|
552 |
*/
|
553 |
protected function update_matched_products() {
|
554 |
|
555 |
+
$product_ids = $this->get_attr( 'matched_product_ids', $this->get_attr( 'validated_product_ids', array() ) );
|
556 |
+
$processed_product_ids = $this->get_attr( 'processed_product_ids', array() );
|
557 |
|
558 |
// remove IDs that have already been processed
|
559 |
$product_ids = array_diff( $product_ids, $processed_product_ids );
|
574 |
|
575 |
} else {
|
576 |
|
577 |
+
$this->set_attr( 'matched_product_ids', array() );
|
578 |
}
|
579 |
|
580 |
$products_map = Product::get_square_meta( $product_ids, 'square_item_id' );
|
590 |
throw new Framework\SV_WC_API_Exception( 'Response data is missing' );
|
591 |
}
|
592 |
|
593 |
+
$catalog_objects = array();
|
594 |
|
595 |
if ( $response->get_data()->getObjects() ) {
|
596 |
|
612 |
$this->set_attr( 'processed_product_ids', array_merge( $result['processed'], $processed_product_ids ) );
|
613 |
|
614 |
// any products that were staged but not processed, push to the matched array to try next time
|
615 |
+
$matched_product_ids = $this->get_attr( 'matched_product_ids', array() );
|
616 |
$this->set_attr( 'matched_product_ids', array_merge( $result['unprocessed'], $matched_product_ids ) );
|
617 |
}
|
618 |
}
|
627 |
*/
|
628 |
protected function search_matched_products() {
|
629 |
|
630 |
+
$product_ids = $this->get_attr( 'search_product_ids', $this->get_attr( 'validated_product_ids', array() ) );
|
631 |
+
$processed_product_ids = $this->get_attr( 'processed_product_ids', array() );
|
632 |
+
$in_progress = $this->get_attr(
|
633 |
+
'in_progress_search_matched_products',
|
634 |
+
array(
|
635 |
+
'unprocessed_search_response' => null,
|
636 |
+
'processed_remote_object_ids' => array(),
|
637 |
+
'catalog_objects_to_update' => array(),
|
638 |
+
'upserting' => false,
|
639 |
+
)
|
640 |
+
);
|
641 |
|
642 |
// remove IDs that have already been processed
|
643 |
$product_ids = array_diff( $product_ids, $processed_product_ids );
|
662 |
|
663 |
} else {
|
664 |
|
665 |
+
$response = wc_square()->get_api()->search_catalog_objects(
|
666 |
+
array(
|
667 |
+
'cursor' => $this->get_attr( 'search_products_cursor' ),
|
668 |
+
'object_types' => array( 'ITEM' ),
|
669 |
+
'limit' => $this->get_max_objects_to_retrieve(),
|
670 |
+
)
|
671 |
+
);
|
672 |
|
673 |
$search_response = $response->get_data();
|
674 |
|
679 |
throw new Framework\SV_WC_API_Exception( 'Response data is missing' );
|
680 |
}
|
681 |
|
682 |
+
$catalog_objects = $search_response->getObjects() ?: array();
|
683 |
$cursor = $search_response->getCursor();
|
684 |
$catalog_objects_to_update = $in_progress['catalog_objects_to_update'];
|
685 |
|
785 |
|
786 |
if ( ! empty( $result['unprocessed'] ) ) {
|
787 |
|
788 |
+
$catalog_processed = false;
|
789 |
+
$remaining_product_ids = array_merge( $result['unprocessed'], $remaining_product_ids );
|
790 |
$in_progress['catalog_objects_to_update'] = array_diff_key( $catalog_objects_to_update, array_flip( $processed_product_ids ) );
|
791 |
|
792 |
} else {
|
800 |
if ( ! $catalog_processed && ! empty( $remaining_product_ids ) ) {
|
801 |
|
802 |
$this->set_attr( 'search_products_cursor', $cursor );
|
803 |
+
$this->set_attr( 'search_product_ids', $remaining_product_ids );
|
804 |
|
805 |
} else {
|
806 |
|
815 |
*/
|
816 |
protected function upsert_new_products() {
|
817 |
|
818 |
+
$product_ids = $this->get_attr( 'upsert_new_product_ids', $this->get_attr( 'validated_product_ids', array() ) );
|
819 |
+
$processed_product_ids = $this->get_attr( 'processed_product_ids', array() );
|
820 |
|
821 |
// remove IDs that have already been processed
|
822 |
$product_ids = array_diff( $product_ids, $processed_product_ids );
|
827 |
return;
|
828 |
}
|
829 |
|
830 |
+
$catalog_objects = array();
|
831 |
|
832 |
foreach ( $product_ids as $product_id ) {
|
833 |
|
834 |
+
$catalog_objects[ $product_id ] = new CatalogObject(
|
835 |
+
array(
|
836 |
+
'type' => 'ITEM',
|
837 |
+
'item_data' => new \SquareConnect\Model\CatalogItem(),
|
838 |
+
)
|
839 |
+
);
|
840 |
}
|
841 |
|
842 |
$result = $this->upsert_catalog_objects( $catalog_objects );
|
879 |
|
880 |
$is_delete_action = 'delete' === $this->get_attr( 'action' );
|
881 |
$product_ids = array_keys( $objects );
|
882 |
+
$original_square_image_ids = array();
|
883 |
+
$staged_product_ids = array();
|
884 |
+
$successful_product_ids = array();
|
885 |
$total_object_count = 0;
|
886 |
+
$batches = array();
|
887 |
+
$result = array(
|
888 |
+
'processed' => array(),
|
889 |
'unprocessed' => $product_ids,
|
890 |
+
);
|
891 |
+
|
892 |
+
$in_progress = $this->get_attr(
|
893 |
+
'in_progress_upsert_catalog_objects',
|
894 |
+
array(
|
895 |
+
'batches' => array(),
|
896 |
+
'staged_product_ids' => array(),
|
897 |
+
'total_object_count' => null,
|
898 |
+
'unprocessed_upsert_response' => null,
|
899 |
+
'mapped_client_item_ids' => array(),
|
900 |
+
'processed_remote_catalog_item_ids' => array(),
|
901 |
+
)
|
902 |
+
);
|
903 |
|
904 |
if ( null === $in_progress['unprocessed_upsert_response'] ) {
|
905 |
|
908 |
|
909 |
$staged_product_ids = $in_progress['staged_product_ids'];
|
910 |
$total_object_count = $in_progress['total_object_count'];
|
911 |
+
$batches = array_map(
|
912 |
+
static function ( $batch_data ) {
|
913 |
+
return ObjectSerializer::deserialize( json_decode( $batch_data, false ), CatalogObjectBatch::class );
|
914 |
+
},
|
915 |
+
$in_progress['batches']
|
916 |
+
);
|
917 |
}
|
918 |
|
919 |
foreach ( $objects as $product_id => $object ) {
|
938 |
$object = $this->convert_to_catalog_object( $object );
|
939 |
}
|
940 |
|
941 |
+
$product = wc_get_product( $product_id );
|
942 |
$original_square_image_ids[ $product_id ] = $product->get_meta( '_square_item_image_id' );
|
943 |
|
944 |
$catalog_item = new Catalog_Item( $product, $is_delete_action );
|
947 |
|
948 |
if ( $this->get_max_objects_total() >= $object_count + $total_object_count ) {
|
949 |
$batches[] = $batch;
|
950 |
+
$total_object_count += $object_count;
|
951 |
$staged_product_ids[] = $product_id;
|
952 |
} else {
|
953 |
break;
|
1031 |
wc_square()->log( 'Mapped ' . count( $in_progress['mapped_client_item_ids'] ) . ' Square IDs in ' . $duration . 's' );
|
1032 |
}
|
1033 |
|
1034 |
+
$pull_inventory_variation_ids = $this->get_attr( 'pull_inventory_variation_ids', array() );
|
1035 |
|
1036 |
wc_square()->log( 'Storing Square item data to WooCommerce products' );
|
1037 |
|
1061 |
continue;
|
1062 |
}
|
1063 |
|
1064 |
+
Product::update_square_meta(
|
1065 |
+
$product,
|
1066 |
+
array(
|
1067 |
+
'item_id' => $remote_item_id,
|
1068 |
+
'item_version' => $remote_catalog_item->getVersion(),
|
1069 |
+
'item_image_id' => $remote_catalog_item->getImageId(),
|
1070 |
+
)
|
1071 |
+
);
|
1072 |
|
1073 |
$successful_product_ids[] = $product->get_id();
|
1074 |
|
1080 |
|
1081 |
$pull_inventory_variation_ids[] = $catalog_item_variation->getId();
|
1082 |
|
1083 |
+
Product::update_square_meta(
|
1084 |
+
$product_variation,
|
1085 |
+
array(
|
1086 |
+
'item_variation_id' => $catalog_item_variation->getId(),
|
1087 |
+
'item_variation_version' => $catalog_item_variation->getVersion(),
|
1088 |
+
)
|
1089 |
+
);
|
1090 |
}
|
1091 |
}
|
1092 |
}
|
1104 |
|
1105 |
// If there is a local image which is different from the last uploaded image
|
1106 |
// Or if the remote square image id has changed
|
1107 |
+
if ( ( $local_image_id && $local_image_id !== $product->get_meta( '_square_uploaded_image_id' ) ) ||
|
1108 |
( ! ( $original_square_image_ids[ $product_id ] && $original_square_image_ids[ $product_id ] === $product->get_meta( '_square_item_image_id' ) ) ) ) {
|
1109 |
// there is no batch image endpoint
|
1110 |
$this->push_product_image( $product );
|
1126 |
// log any failed products
|
1127 |
foreach ( array_diff( $staged_product_ids, $successful_product_ids ) as $product_id ) {
|
1128 |
|
1129 |
+
Records::set_record(
|
1130 |
+
array(
|
1131 |
+
'type' => 'alert',
|
1132 |
+
'product_id' => $product_id,
|
1133 |
+
'message' => sprintf(
|
1134 |
+
/* translators: Placeholder: %s - product ID */
|
1135 |
+
esc_html__( 'Product %s could not be updated in Square.', 'woocommerce-square' ),
|
1136 |
+
'<a href="' . esc_url( get_edit_post_link( $product_id ) ) . '">' . $product_id . '</a>'
|
1137 |
+
),
|
1138 |
+
)
|
1139 |
+
);
|
1140 |
}
|
1141 |
|
1142 |
$this->set_attr( 'in_progress_upsert_catalog_objects', null );
|
1216 |
*/
|
1217 |
protected function push_inventory() {
|
1218 |
|
1219 |
+
$product_ids = $this->get_attr( 'inventory_push_product_ids', array() );
|
1220 |
+
$inventory_changes = array();
|
1221 |
$inventory_change_count = 0;
|
1222 |
|
1223 |
foreach ( $product_ids as $key => $product_id ) {
|
1226 |
|
1227 |
if ( $product instanceof \WC_Product ) {
|
1228 |
|
1229 |
+
$product_inventory_changes = array();
|
1230 |
|
1231 |
if ( $product->is_type( 'variable' ) && $product->has_child() ) {
|
1232 |
|
1239 |
$product_inventory_changes[] = $inventory_change;
|
1240 |
}
|
1241 |
}
|
|
|
1242 |
} elseif ( $square_variation_id = Product::get_square_item_variation_id( $product_id, false ) ) {
|
1243 |
|
1244 |
if ( $inventory_change = Product::get_inventory_change_physical_count_type( $product ) ) {
|
1257 |
|
1258 |
break;
|
1259 |
}
|
|
|
1260 |
} else {
|
1261 |
|
1262 |
unset( $product_ids[ $key ] );
|
1286 |
*/
|
1287 |
protected function square_sor_sync() {
|
1288 |
|
1289 |
+
$synced_product_ids = $this->get_attr( 'validated_product_ids', array() );
|
1290 |
+
$processed_product_ids = $this->get_attr( 'processed_product_ids', array() );
|
1291 |
$unprocessed_product_ids = array_diff( $synced_product_ids, $processed_product_ids );
|
1292 |
$catalog_processed = $this->get_attr( 'catalog_processed', false );
|
1293 |
|
1313 |
|
1314 |
$cursor = $this->get_attr( 'square_sor_cursor' );
|
1315 |
|
1316 |
+
$response = wc_square()->get_api()->search_catalog_objects(
|
1317 |
+
array(
|
1318 |
+
'cursor' => $cursor,
|
1319 |
+
'object_types' => array( 'ITEM' ),
|
1320 |
+
'include_related_objects' => true,
|
1321 |
+
'limit' => $this->get_max_objects_to_retrieve(),
|
1322 |
+
)
|
1323 |
+
);
|
1324 |
|
1325 |
$response_data = $response->get_data();
|
1326 |
|
1341 |
$catalog_processed = ! $cursor;
|
1342 |
$this->set_attr( 'catalog_processed', $catalog_processed );
|
1343 |
|
1344 |
+
} catch ( \Exception $exception ) { // bail early and fail for any API and plugin errors
|
|
|
1345 |
|
1346 |
$this->fail( 'Product sync failed. ' . $exception->getMessage() );
|
1347 |
return;
|
1348 |
}
|
1349 |
|
1350 |
+
$related_objects = $response_data->getRelatedObjects();
|
1351 |
|
1352 |
if ( $related_objects && is_array( $related_objects ) ) {
|
1353 |
// first import any related categories
|
1358 |
}
|
1359 |
}
|
1360 |
|
1361 |
+
$pull_inventory_variation_ids = $this->get_attr( 'pull_inventory_variation_ids', array() );
|
1362 |
|
1363 |
/** @var \SquareConnect\Model\CatalogObject[] */
|
1364 |
+
$catalog_objects = $products_to_update = array();
|
1365 |
|
1366 |
wc_square()->log( 'Searching for products in ' . count( $response_data->getObjects() ) . ' Square objects' );
|
1367 |
|
1462 |
if ( ! $product->get_image_id() && $square_object->getImageId() ) {
|
1463 |
Product::update_image_from_square( $product, $square_object->getImageId() );
|
1464 |
}
|
|
|
1465 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
1466 |
|
1467 |
+
$this->mark_failed_products( array( $product ) );
|
1468 |
}
|
1469 |
|
1470 |
$processed_product_ids[] = $product->get_id();
|
1487 |
*/
|
1488 |
protected function pull_inventory() {
|
1489 |
|
1490 |
+
$processed_ids = $this->get_attr( 'processed_square_variation_ids', array() );
|
1491 |
|
1492 |
+
$in_progress = wp_parse_args(
|
1493 |
+
$this->get_attr(
|
1494 |
+
'in_progress_pull_inventory',
|
1495 |
+
array()
|
1496 |
+
),
|
1497 |
+
array(
|
1498 |
+
'response_data' => null,
|
1499 |
+
'processed_variation_ids' => array(),
|
1500 |
+
)
|
1501 |
+
);
|
1502 |
|
1503 |
$response_data = null;
|
1504 |
|
1510 |
// if the saved response was somehow corrupted, start over
|
1511 |
if ( ! $response_data instanceof BatchRetrieveInventoryCountsResponse ) {
|
1512 |
|
1513 |
+
$square_variation_ids = $this->get_attr( 'pull_inventory_variation_ids', array() );
|
1514 |
|
1515 |
// remove IDs that have already been processed
|
1516 |
$square_variation_ids = array_diff( $square_variation_ids, $processed_ids );
|
1521 |
return;
|
1522 |
}
|
1523 |
|
1524 |
+
if ( count( $square_variation_ids ) > self::BATCH_INVENTORY_COUNTS_LIMIT ) {
|
1525 |
|
1526 |
+
$variation_ids_batch = array_slice( $square_variation_ids, 0, self::BATCH_INVENTORY_COUNTS_LIMIT );
|
1527 |
|
1528 |
$this->set_attr( 'pull_inventory_variation_ids', array_diff( $square_variation_ids, $variation_ids_batch ) );
|
1529 |
|
1530 |
$square_variation_ids = $variation_ids_batch;
|
1531 |
}
|
1532 |
|
1533 |
+
$cursor = '';
|
1534 |
+
$response_counts = array();
|
1535 |
+
$location_ids = array( wc_square()->get_settings_handler()->get_location_id() );
|
1536 |
+
$catalog_object_ids = array_values( $square_variation_ids );
|
1537 |
+
|
1538 |
+
// Repeat fetching objects using the cursor when the results are paginated.
|
1539 |
+
do {
|
1540 |
+
$response = wc_square()->get_api()->batch_retrieve_inventory_counts(
|
1541 |
+
array(
|
1542 |
+
'catalog_object_ids' => $catalog_object_ids,
|
1543 |
+
'location_ids' => $location_ids,
|
1544 |
+
'cursor' => $cursor,
|
1545 |
+
)
|
1546 |
+
);
|
1547 |
+
|
1548 |
+
if ( ! $response->get_data() instanceof BatchRetrieveInventoryCountsResponse ) {
|
1549 |
+
throw new Framework\SV_WC_Plugin_Exception( 'Response data missing or invalid' );
|
1550 |
+
}
|
1551 |
|
1552 |
+
$response_data = $response->get_data();
|
|
|
|
|
1553 |
|
1554 |
+
// if no counts were returned, there's nothing to process
|
1555 |
+
if ( ! is_array( $response_data->getCounts() ) ) {
|
1556 |
|
1557 |
+
$this->set_attr( 'processed_square_variation_ids', array_merge( $processed_ids, $square_variation_ids ) );
|
1558 |
+
return;
|
1559 |
+
}
|
1560 |
|
1561 |
+
$in_progress['response_data'] = $response_data . '';
|
1562 |
+
|
1563 |
+
// Store the response counts to be processed later.
|
1564 |
+
$response_counts = array_merge( $response_counts, $response_data->getCounts() );
|
1565 |
+
$cursor = $response->get_data()->getCursor();
|
1566 |
|
1567 |
+
} while ( ! empty( $cursor ) );
|
1568 |
}
|
1569 |
|
1570 |
+
foreach ( $response_counts as $count ) {
|
1571 |
|
1572 |
if ( in_array( $count->getCatalogObjectId(), $in_progress['processed_variation_ids'], false ) ) {
|
1573 |
continue;
|
1601 |
$this->set_attr( 'processed_square_variation_ids', array_merge( $processed_ids, $in_progress['processed_variation_ids'] ) );
|
1602 |
|
1603 |
// clear any in-progress data
|
1604 |
+
$this->set_attr( 'in_progress_pull_inventory', array() );
|
1605 |
}
|
1606 |
|
1607 |
/**
|
1611 |
*
|
1612 |
* @param \WC_Product[]|int[] $products products to mark as failed
|
1613 |
*/
|
1614 |
+
protected function mark_failed_products( $products = array() ) {
|
1615 |
|
1616 |
foreach ( $products as $product ) {
|
1617 |
|
1621 |
continue;
|
1622 |
}
|
1623 |
|
1624 |
+
$record_data = array(
|
1625 |
'type' => 'alert',
|
1626 |
'product_id' => $product->get_id(),
|
1627 |
+
);
|
1628 |
|
1629 |
// optionally hide unmatched products from catalog
|
1630 |
if ( wc_square()->get_settings_handler()->is_system_of_record_square() && wc_square()->get_settings_handler()->hide_missing_square_products() ) {
|
1636 |
|
1637 |
$record_data['product_hidden'] = true;
|
1638 |
|
1639 |
+
} catch ( \Exception $e ) {
|
1640 |
+
}
|
1641 |
}
|
1642 |
|
1643 |
Records::set_record( $record_data );
|
1657 |
|
1658 |
if ( ! empty( $product_ids ) ) {
|
1659 |
$category_ids = get_terms(
|
1660 |
+
array(
|
1661 |
'taxonomy' => 'product_cat',
|
1662 |
'fields' => 'ids',
|
1663 |
'object_ids' => $product_ids,
|
1664 |
+
)
|
1665 |
);
|
1666 |
}
|
1667 |
|
1668 |
+
return ! empty( $category_ids ) && ! is_wp_error( $category_ids ) ? $category_ids : array();
|
1669 |
}
|
1670 |
|
1671 |
|
1676 |
*/
|
1677 |
protected function assign_next_steps() {
|
1678 |
|
1679 |
+
$next_steps = array();
|
1680 |
|
1681 |
if ( $this->is_system_of_record_woocommerce() ) {
|
1682 |
|
1683 |
if ( 'delete' === $this->get_attr( 'action' ) ) {
|
1684 |
|
1685 |
+
$next_steps = array(
|
1686 |
'validate_products',
|
1687 |
'update_matched_products',
|
1688 |
'search_matched_products',
|
1689 |
+
);
|
1690 |
|
1691 |
} else {
|
1692 |
|
1693 |
+
$next_steps = array(
|
1694 |
'validate_products',
|
1695 |
'extract_category_ids',
|
1696 |
'refresh_category_mappings',
|
1699 |
'update_matched_products',
|
1700 |
'search_matched_products',
|
1701 |
'upsert_new_products',
|
1702 |
+
);
|
1703 |
|
1704 |
// only handle product inventory if enabled
|
1705 |
if ( wc_square()->get_settings_handler()->is_inventory_sync_enabled() ) {
|
1707 |
$next_steps[] = 'pull_inventory';
|
1708 |
}
|
1709 |
}
|
|
|
1710 |
} elseif ( $this->is_system_of_record_square() ) {
|
1711 |
|
1712 |
+
$next_steps = array(
|
1713 |
'validate_products',
|
1714 |
'square_sor_sync',
|
1715 |
+
);
|
1716 |
|
1717 |
// only pull product inventory if enabled
|
1718 |
if ( wc_square()->get_settings_handler()->is_inventory_sync_enabled() ) {
|
includes/Sync/Product_Import.php
CHANGED
@@ -30,7 +30,7 @@ use WooCommerce\Square\Handlers\Product;
|
|
30 |
use WooCommerce\Square\Sync\Records\Record;
|
31 |
use WooCommerce\Square\Utilities\Money_Utility;
|
32 |
|
33 |
-
defined( 'ABSPATH' )
|
34 |
|
35 |
/**
|
36 |
* Class to represent a synchronization job to import products from Square.
|
@@ -42,10 +42,13 @@ class Product_Import extends Stepped_Job {
|
|
42 |
|
43 |
protected function assign_next_steps() {
|
44 |
|
45 |
-
$this->set_attr(
|
46 |
-
'
|
47 |
-
|
48 |
-
|
|
|
|
|
|
|
49 |
}
|
50 |
|
51 |
|
@@ -83,27 +86,28 @@ class Product_Import extends Stepped_Job {
|
|
83 |
*/
|
84 |
protected function import_products() {
|
85 |
|
86 |
-
$
|
87 |
-
$
|
88 |
-
$
|
|
|
89 |
|
90 |
-
$response = wc_square()->get_api()->search_catalog_objects(
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
96 |
|
97 |
$related_objects = $response->get_data()->getRelatedObjects();
|
|
|
98 |
|
99 |
if ( $related_objects && is_array( $related_objects ) ) {
|
100 |
-
|
101 |
-
// first import any related categories
|
102 |
foreach ( $related_objects as $related_object ) {
|
103 |
|
104 |
if ( 'CATEGORY' === $related_object->getType() ) {
|
105 |
-
|
106 |
-
Category::import_or_update( $related_object );
|
107 |
}
|
108 |
}
|
109 |
}
|
@@ -119,44 +123,87 @@ class Product_Import extends Stepped_Job {
|
|
119 |
break;
|
120 |
}
|
121 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
$item_id = $catalog_object->getId();
|
123 |
|
124 |
-
// ignore items not available at our location
|
125 |
-
if ( ! $catalog_object->getPresentAtAllLocations() && ( ! is_array( $catalog_object->getPresentAtLocationIds() ) || ! in_array( wc_square()->get_settings_handler()->get_location_id(), $catalog_object->getPresentAtLocationIds(), true ) ) ) {
|
126 |
|
127 |
$skipped_products[ $item_id ] = null;
|
128 |
continue;
|
129 |
}
|
130 |
|
131 |
-
//
|
132 |
-
|
133 |
|
134 |
-
|
135 |
-
|
|
|
136 |
}
|
137 |
|
138 |
-
|
139 |
-
|
|
|
|
|
|
|
140 |
continue;
|
141 |
}
|
142 |
|
143 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
|
145 |
-
|
|
|
146 |
|
147 |
-
|
|
|
|
|
148 |
|
149 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
}
|
151 |
}
|
152 |
|
153 |
if ( $time_exceeded ) {
|
154 |
|
155 |
-
wc_square()->log( '[Time Exceeded] Imported Products Count: ' . count( $
|
156 |
|
157 |
} else {
|
158 |
|
159 |
-
wc_square()->log( 'Imported Products Count: ' . count( $
|
|
|
160 |
|
161 |
$cursor = $response->get_data()->getCursor();
|
162 |
$this->set_attr( 'fetch_products_cursor', $cursor );
|
@@ -168,7 +215,8 @@ class Product_Import extends Stepped_Job {
|
|
168 |
}
|
169 |
|
170 |
$this->set_attr( 'skipped_products', $skipped_products );
|
171 |
-
$this->set_attr( '
|
|
|
172 |
}
|
173 |
|
174 |
|
@@ -181,23 +229,28 @@ class Product_Import extends Stepped_Job {
|
|
181 |
*/
|
182 |
protected function import_inventory() {
|
183 |
|
184 |
-
$search_result = wc_square()->get_api()->search_catalog_objects(
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
|
|
|
|
189 |
|
190 |
$cursor = $search_result->get_data()->getCursor();
|
191 |
-
$variation_ids = array_map(
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
|
|
|
|
|
|
201 |
|
202 |
foreach ( $result->get_counts() as $inventory_count ) {
|
203 |
|
@@ -223,6 +276,30 @@ class Product_Import extends Stepped_Job {
|
|
223 |
}
|
224 |
|
225 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
/**
|
227 |
* Determines whether a SKU within a catalog item is found in WooCommerce.
|
228 |
*
|
@@ -246,88 +323,16 @@ class Product_Import extends Stepped_Job {
|
|
246 |
|
247 |
|
248 |
/**
|
249 |
-
* Creates a product from
|
250 |
*
|
251 |
* @since 2.0.0
|
252 |
*
|
253 |
-
* @param
|
254 |
* @return int|null
|
255 |
*/
|
256 |
-
private function import_product( $
|
257 |
-
|
258 |
-
$product_id = 0;
|
259 |
-
|
260 |
try {
|
261 |
-
|
262 |
-
// validate permissions
|
263 |
-
if ( ! current_user_can( 'publish_products' ) ) {
|
264 |
-
throw new Framework\SV_WC_Plugin_Exception( __( 'You do not have permission to create products', 'woocommerce-square' ) );
|
265 |
-
}
|
266 |
-
|
267 |
-
// sanity check for valid API data
|
268 |
-
if ( ! $catalog_object instanceof \SquareConnect\Model\CatalogObject || ! $catalog_object->getItemData() instanceof \SquareConnect\Model\CatalogItem ) {
|
269 |
-
throw new Framework\SV_WC_Plugin_Exception( __( 'Invalid data', 'woocommerce-square' ) );
|
270 |
-
}
|
271 |
-
|
272 |
-
$data = $this->extract_product_data( $catalog_object );
|
273 |
-
|
274 |
-
/**
|
275 |
-
* Filters the data that is used to create a new WooCommerce product during import.
|
276 |
-
*
|
277 |
-
* @since 2.0.0
|
278 |
-
*
|
279 |
-
* @param array $data product data
|
280 |
-
* @param \SquareConnect\Model\CatalogObject $catalog_object the catalog object from the Square API
|
281 |
-
* @param Product_Import $this import class instance
|
282 |
-
*/
|
283 |
-
$data = apply_filters( 'woocommerce_square_create_product_data', $data, $catalog_object, $this );
|
284 |
-
|
285 |
-
// validate title field
|
286 |
-
if ( ! isset( $data['title'] ) ) {
|
287 |
-
throw new Framework\SV_WC_Plugin_Exception( sprintf( __( 'Missing parameter %s', 'woocommerce-square' ), 'title' ) );
|
288 |
-
}
|
289 |
-
|
290 |
-
// set default type
|
291 |
-
if ( ! isset( $data['type'] ) ) {
|
292 |
-
$data['type'] = 'simple';
|
293 |
-
}
|
294 |
-
|
295 |
-
// set default catalog_visibility
|
296 |
-
if ( ! isset( $data['catalog_visibility'] ) ) {
|
297 |
-
$data['catalog_visibility'] = 'visible';
|
298 |
-
}
|
299 |
-
|
300 |
-
// validate type
|
301 |
-
if ( ! array_key_exists( wc_clean( $data['type'] ), wc_get_product_types() ) ) {
|
302 |
-
throw new Framework\SV_WC_Plugin_Exception( sprintf( __( 'Invalid product type - the product type must be any of these: %s', 'woocommerce-square' ), implode( ', ', array_keys( wc_get_product_types() ) ) ) );
|
303 |
-
}
|
304 |
-
|
305 |
-
// set description
|
306 |
-
$post_content = isset( $data['description'] ) ? wc_clean( $data['description'] ) : '';
|
307 |
-
if ( $post_content && isset( $data['enable_html_description'] ) && true === $data['enable_html_description'] ) {
|
308 |
-
|
309 |
-
$post_content = $data['description'];
|
310 |
-
}
|
311 |
-
|
312 |
-
$new_product = [
|
313 |
-
'post_title' => wc_clean( $data['title'] ),
|
314 |
-
'post_status' => isset( $data['status'] ) ? wc_clean( $data['status'] ) : 'publish',
|
315 |
-
'post_type' => 'product',
|
316 |
-
'post_content' => isset( $data['description'] ) ? $post_content : '',
|
317 |
-
'post_author' => get_current_user_id(),
|
318 |
-
'menu_order' => isset( $data['menu_order'] ) ? (int) $data['menu_order'] : 0,
|
319 |
-
];
|
320 |
-
|
321 |
-
if ( ! empty( $data['name'] ) ) {
|
322 |
-
$new_product = array_merge( $new_product, [ 'post_name' => sanitize_title( $data['name'] ) ] );
|
323 |
-
}
|
324 |
-
|
325 |
-
// attempt to create the new product
|
326 |
-
$product_id = wp_insert_post( $new_product, true );
|
327 |
-
|
328 |
-
if ( is_wp_error( $product_id ) ) {
|
329 |
-
throw new Framework\SV_WC_Plugin_Exception( $product_id->get_error_message() );
|
330 |
-
}
|
331 |
|
332 |
// save product meta fields
|
333 |
$this->save_product_meta( $product_id, $data );
|
@@ -355,44 +360,106 @@ class Product_Import extends Stepped_Job {
|
|
355 |
|
356 |
// clear cache/transients
|
357 |
wc_delete_product_transients( $product_id );
|
358 |
-
|
359 |
} catch ( Framework\SV_WC_Plugin_Exception $e ) {
|
|
|
|
|
|
|
360 |
|
361 |
-
|
|
|
362 |
|
363 |
-
|
364 |
-
|
365 |
-
__( 'Could not import "%1$s" from Square. %2$s', 'woocommerce-square' ),
|
366 |
-
$catalog_object->getItemData()->getName(),
|
367 |
-
$e->getMessage()
|
368 |
-
);
|
369 |
|
370 |
-
|
371 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
372 |
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
|
|
378 |
}
|
379 |
|
380 |
-
//
|
381 |
-
|
382 |
-
'type' => 'alert',
|
383 |
-
'message' => $message,
|
384 |
-
] );
|
385 |
|
386 |
-
|
|
|
|
|
|
|
387 |
|
388 |
-
//
|
389 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
390 |
$product_id = 0;
|
|
|
|
|
391 |
}
|
392 |
|
393 |
return $product_id;
|
394 |
}
|
395 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
396 |
|
397 |
/**
|
398 |
* Extracts product data from a CatalogObject to an array of data.
|
@@ -400,10 +467,11 @@ class Product_Import extends Stepped_Job {
|
|
400 |
* @since 2.0.0
|
401 |
*
|
402 |
* @param \SquareConnect\Model\CatalogObject $catalog_object the catalog object
|
|
|
403 |
* @return array|null
|
404 |
* @throws Framework\SV_WC_Plugin_Exception
|
405 |
*/
|
406 |
-
protected function extract_product_data( $catalog_object ) {
|
407 |
|
408 |
$variations = $catalog_object->getItemData()->getVariations();
|
409 |
|
@@ -414,23 +482,22 @@ class Product_Import extends Stepped_Job {
|
|
414 |
|
415 |
$category_id = Category::get_category_id_by_square_id( $catalog_object->getItemData()->getCategoryId() );
|
416 |
|
417 |
-
$data =
|
418 |
'title' => $catalog_object->getItemData()->getName(),
|
419 |
-
'type' => 1 === count( $variations ) ? 'simple' : 'variable',
|
|
|
420 |
'description' => $catalog_object->getItemData()->getDescription(),
|
421 |
'image_id' => $catalog_object->getImageId(),
|
422 |
-
'categories' =>
|
423 |
-
'square_meta' =>
|
424 |
'item_id' => $catalog_object->getId(),
|
425 |
'item_version' => $catalog_object->getVersion(),
|
426 |
-
|
427 |
-
|
428 |
|
429 |
// variable product
|
430 |
-
if (
|
431 |
-
|
432 |
-
$data['type'] = 'variable';
|
433 |
-
$data['variations'] = [];
|
434 |
|
435 |
foreach ( $variations as $variation ) {
|
436 |
|
@@ -446,41 +513,42 @@ class Product_Import extends Stepped_Job {
|
|
446 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
447 |
|
448 |
// alert for failed variation imports
|
449 |
-
Records::set_record(
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
|
|
|
|
459 |
}
|
460 |
}
|
461 |
|
462 |
-
$data['attributes'] =
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
} else {
|
473 |
-
|
474 |
$variation = $this->extract_square_item_variation_data( $variations[0] );
|
475 |
|
476 |
$data['type'] = 'simple';
|
477 |
-
$data['sku'] = $variation['sku']
|
478 |
-
$data['regular_price'] = $variation['regular_price']
|
479 |
-
$data['stock_quantity'] = $variation['stock_quantity']
|
480 |
-
$data['managing_stock'] = $variation['managing_stock']
|
481 |
|
482 |
-
$data['square_meta']['item_variation_id'] = $variation['square_meta']['item_variation_id']
|
483 |
-
$data['square_meta']['item_variation_version'] = $variation['square_meta']['item_variation_version']
|
484 |
}
|
485 |
|
486 |
return $data;
|
@@ -504,24 +572,24 @@ class Product_Import extends Stepped_Job {
|
|
504 |
throw new Framework\SV_WC_Plugin_Exception( __( 'Items with variable pricing cannot be imported.', 'woocommerce-square' ) );
|
505 |
}
|
506 |
|
507 |
-
$data =
|
508 |
-
'name' => $variation_data->getName()
|
509 |
-
'sku' => $variation_data->getSku()
|
510 |
'regular_price' => $variation_data->getPriceMoney() && $variation_data->getPriceMoney()->getAmount() ? Money_Utility::cents_to_float( $variation->getItemVariationData()->getPriceMoney()->getAmount() ) : null,
|
511 |
'stock_quantity' => null,
|
512 |
'managing_stock' => true,
|
513 |
-
'square_meta' =>
|
514 |
'item_variation_id' => $variation->getId(),
|
515 |
'item_variation_version' => $variation->getVersion(),
|
516 |
-
|
517 |
-
'attributes' =>
|
518 |
-
|
519 |
'name' => 'Attribute',
|
520 |
'is_variation' => true,
|
521 |
-
'option' => $variation_data->getName()
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
|
526 |
return $data;
|
527 |
}
|
@@ -556,9 +624,7 @@ class Product_Import extends Stepped_Job {
|
|
556 |
$product_type = wc_clean( $data['type'] );
|
557 |
|
558 |
wp_set_object_terms( $product_id, $product_type, 'product_type' );
|
559 |
-
|
560 |
} else {
|
561 |
-
|
562 |
$_product_type = get_the_terms( $product_id, 'product_type' );
|
563 |
|
564 |
if ( is_array( $_product_type ) ) {
|
@@ -572,10 +638,7 @@ class Product_Import extends Stepped_Job {
|
|
572 |
add_post_meta( $product_id, 'total_sales', '0', true );
|
573 |
|
574 |
// catalog visibility
|
575 |
-
|
576 |
-
|
577 |
-
update_post_meta( $product_id, '_visibility', wc_clean( $data['catalog_visibility'] ) );
|
578 |
-
}
|
579 |
|
580 |
// sku
|
581 |
if ( isset( $data['sku'] ) ) {
|
@@ -601,9 +664,7 @@ class Product_Import extends Stepped_Job {
|
|
601 |
|
602 |
throw new Framework\SV_WC_Plugin_Exception( __( 'The SKU already exists on another product', 'woocommerce-square' ) );
|
603 |
}
|
604 |
-
|
605 |
} else {
|
606 |
-
|
607 |
update_post_meta( $product_id, '_sku', '' );
|
608 |
}
|
609 |
}
|
@@ -612,7 +673,7 @@ class Product_Import extends Stepped_Job {
|
|
612 |
// attributes
|
613 |
if ( isset( $data['attributes'] ) ) {
|
614 |
|
615 |
-
$attributes =
|
616 |
|
617 |
foreach ( $data['attributes'] as $attribute ) {
|
618 |
|
@@ -653,7 +714,7 @@ class Product_Import extends Stepped_Job {
|
|
653 |
|
654 |
} else {
|
655 |
|
656 |
-
$values =
|
657 |
}
|
658 |
|
659 |
// update post terms
|
@@ -665,18 +726,16 @@ class Product_Import extends Stepped_Job {
|
|
665 |
if ( ! empty( $values ) ) {
|
666 |
|
667 |
// add attribute to array, but don't set values
|
668 |
-
$attributes[ $taxonomy ] =
|
669 |
'name' => $taxonomy,
|
670 |
'value' => '',
|
671 |
'position' => isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0',
|
672 |
'is_visible' => ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0,
|
673 |
'is_variation' => ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0,
|
674 |
'is_taxonomy' => $is_taxonomy,
|
675 |
-
|
676 |
}
|
677 |
-
|
678 |
} elseif ( isset( $attribute['options'] ) ) {
|
679 |
-
|
680 |
// array based
|
681 |
if ( is_array( $attribute['options'] ) ) {
|
682 |
|
@@ -688,14 +747,14 @@ class Product_Import extends Stepped_Job {
|
|
688 |
}
|
689 |
|
690 |
// custom attribute - add attribute to array and set the values
|
691 |
-
$attributes[ $attribute_slug ] =
|
692 |
'name' => wc_clean( $attribute['name'] ),
|
693 |
'value' => $values,
|
694 |
'position' => isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0',
|
695 |
'is_visible' => ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0,
|
696 |
'is_variation' => ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0,
|
697 |
'is_taxonomy' => $is_taxonomy,
|
698 |
-
|
699 |
}
|
700 |
}
|
701 |
|
@@ -705,7 +764,7 @@ class Product_Import extends Stepped_Job {
|
|
705 |
}
|
706 |
|
707 |
// sales and prices
|
708 |
-
if ( in_array( $product_type,
|
709 |
|
710 |
// variable and grouped products have no prices
|
711 |
update_post_meta( $product_id, '_regular_price', '' );
|
@@ -774,8 +833,10 @@ class Product_Import extends Stepped_Job {
|
|
774 |
protected function save_variations( $product_id, $data ) {
|
775 |
global $wpdb;
|
776 |
|
777 |
-
$variations
|
778 |
-
$attributes
|
|
|
|
|
779 |
|
780 |
foreach ( $variations as $menu_order => $variation ) {
|
781 |
|
@@ -787,13 +848,14 @@ class Product_Import extends Stepped_Job {
|
|
787 |
$variation_id = wc_get_product_id_by_sku( $variation_sku );
|
788 |
}
|
789 |
|
|
|
790 |
$variation_post_title = sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce-square' ), $variation_id, esc_html( get_the_title( $product_id ) ) );
|
791 |
|
792 |
// update or add post
|
793 |
if ( ! $variation_id ) {
|
794 |
|
795 |
$post_status = ( isset( $variation['visible'] ) && false === $variation['visible'] ) ? 'private' : 'publish';
|
796 |
-
$new_variation =
|
797 |
'post_title' => $variation_post_title,
|
798 |
'post_content' => '',
|
799 |
'post_status' => $post_status,
|
@@ -801,7 +863,7 @@ class Product_Import extends Stepped_Job {
|
|
801 |
'post_parent' => $product_id,
|
802 |
'post_type' => 'product_variation',
|
803 |
'menu_order' => $menu_order,
|
804 |
-
|
805 |
|
806 |
$variation_id = wp_insert_post( $new_variation );
|
807 |
|
@@ -816,7 +878,10 @@ class Product_Import extends Stepped_Job {
|
|
816 |
|
817 |
} else {
|
818 |
|
819 |
-
$update_variation =
|
|
|
|
|
|
|
820 |
|
821 |
if ( isset( $variation['visible'] ) ) {
|
822 |
|
@@ -825,7 +890,12 @@ class Product_Import extends Stepped_Job {
|
|
825 |
$update_variation['post_status'] = $post_status;
|
826 |
}
|
827 |
|
828 |
-
$wpdb->update( $wpdb->posts, $update_variation,
|
|
|
|
|
|
|
|
|
|
|
829 |
|
830 |
/**
|
831 |
* Fired after updating a product variation during an import from Square.
|
@@ -865,7 +935,6 @@ class Product_Import extends Stepped_Job {
|
|
865 |
|
866 |
throw new Framework\SV_WC_Plugin_Exception( __( 'The SKU already exists on another product', 'woocommerce-square' ) );
|
867 |
}
|
868 |
-
|
869 |
} else {
|
870 |
|
871 |
update_post_meta( $variation_id, '_sku', '' );
|
@@ -874,7 +943,7 @@ class Product_Import extends Stepped_Job {
|
|
874 |
}
|
875 |
|
876 |
update_post_meta( $variation_id, '_manage_stock', 'yes' );
|
877 |
-
update_post_meta( $variation_id, '_backorders', 'no');
|
878 |
|
879 |
$this->wc_save_product_price( $variation_id, $variation['regular_price'] );
|
880 |
|
@@ -890,7 +959,7 @@ class Product_Import extends Stepped_Job {
|
|
890 |
// update taxonomies
|
891 |
if ( isset( $variation['attributes'] ) ) {
|
892 |
|
893 |
-
$updated_attribute_keys =
|
894 |
|
895 |
foreach ( $variation['attributes'] as $attribute_key => $attribute ) {
|
896 |
|
@@ -899,7 +968,7 @@ class Product_Import extends Stepped_Job {
|
|
899 |
}
|
900 |
|
901 |
$taxonomy = 0;
|
902 |
-
$_attribute =
|
903 |
|
904 |
if ( isset( $attribute['slug'] ) ) {
|
905 |
|
@@ -936,7 +1005,7 @@ class Product_Import extends Stepped_Job {
|
|
936 |
}
|
937 |
|
938 |
// remove old taxonomies attributes so data is kept up to date - first get attribute key names
|
939 |
-
$delete_attribute_keys = $wpdb->get_col( $wpdb->prepare( "SELECT meta_key FROM {$wpdb->postmeta} WHERE meta_key LIKE 'attribute_%%' AND meta_key NOT IN ( '" . implode( "','", $updated_attribute_keys ) . "' ) AND post_id = %d;", $variation_id ) );
|
940 |
|
941 |
foreach ( $delete_attribute_keys as $key ) {
|
942 |
|
@@ -966,6 +1035,11 @@ class Product_Import extends Stepped_Job {
|
|
966 |
do_action( 'woocommerce_square_save_product_variation', $variation_id, $menu_order, $variation );
|
967 |
}
|
968 |
|
|
|
|
|
|
|
|
|
|
|
969 |
// update parent if variable so price sorting works and stays in sync with the cheapest child
|
970 |
\WC_Product_Variable::sync( $product_id );
|
971 |
|
@@ -977,7 +1051,7 @@ class Product_Import extends Stepped_Job {
|
|
977 |
|
978 |
if ( isset( $data['default_attributes'] ) && is_array( $data['default_attributes'] ) ) {
|
979 |
|
980 |
-
$default_attributes =
|
981 |
|
982 |
foreach ( $data['default_attributes'] as $default_attr_key => $default_attr ) {
|
983 |
|
@@ -1081,7 +1155,7 @@ class Product_Import extends Stepped_Job {
|
|
1081 |
|
1082 |
if ( $date_to && ! $date_from ) {
|
1083 |
|
1084 |
-
$date_from = strtotime( 'NOW', current_time( 'timestamp' ) );
|
1085 |
|
1086 |
update_post_meta( $product_id, '_sale_price_dates_from', $date_from );
|
1087 |
}
|
@@ -1096,12 +1170,12 @@ class Product_Import extends Stepped_Job {
|
|
1096 |
update_post_meta( $product_id, '_price', $regular_price );
|
1097 |
}
|
1098 |
|
1099 |
-
if ( '' !== $sale_price && $date_from && strtotime( $date_from ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ) {
|
1100 |
|
1101 |
update_post_meta( $product_id, '_price', $sale_price );
|
1102 |
}
|
1103 |
|
1104 |
-
if ( $date_to && strtotime( $date_to ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ) {
|
1105 |
|
1106 |
update_post_meta( $product_id, '_price', $regular_price );
|
1107 |
update_post_meta( $product_id, '_sale_price_dates_from', '' );
|
@@ -1124,11 +1198,13 @@ class Product_Import extends Stepped_Job {
|
|
1124 |
}
|
1125 |
|
1126 |
// Delete product attachments
|
1127 |
-
$attachments = get_children(
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
|
|
|
|
1132 |
|
1133 |
foreach ( $attachments as $attachment ) {
|
1134 |
wp_delete_attachment( $attachment->ID, true );
|
@@ -1138,5 +1214,90 @@ class Product_Import extends Stepped_Job {
|
|
1138 |
wp_delete_post( $product_id, true );
|
1139 |
}
|
1140 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1141 |
|
1142 |
}
|
30 |
use WooCommerce\Square\Sync\Records\Record;
|
31 |
use WooCommerce\Square\Utilities\Money_Utility;
|
32 |
|
33 |
+
defined( 'ABSPATH' ) || exit;
|
34 |
|
35 |
/**
|
36 |
* Class to represent a synchronization job to import products from Square.
|
42 |
|
43 |
protected function assign_next_steps() {
|
44 |
|
45 |
+
$this->set_attr(
|
46 |
+
'next_steps',
|
47 |
+
array(
|
48 |
+
'import_products',
|
49 |
+
'import_inventory',
|
50 |
+
)
|
51 |
+
);
|
52 |
}
|
53 |
|
54 |
|
86 |
*/
|
87 |
protected function import_products() {
|
88 |
|
89 |
+
$cursor = $this->get_attr( 'fetch_products_cursor' );
|
90 |
+
$imported_product_ids = $this->get_attr( 'processed_product_ids', array() );
|
91 |
+
$updated_product_ids = $this->get_attr( 'updated_product_ids', array() );
|
92 |
+
$skipped_products = $this->get_attr( 'skipped_products', array() );
|
93 |
|
94 |
+
$response = wc_square()->get_api()->search_catalog_objects(
|
95 |
+
array(
|
96 |
+
'cursor' => $cursor,
|
97 |
+
'object_types' => array( 'ITEM' ),
|
98 |
+
'include_related_objects' => true,
|
99 |
+
'limit' => $this->get_import_api_limit(),
|
100 |
+
)
|
101 |
+
);
|
102 |
|
103 |
$related_objects = $response->get_data()->getRelatedObjects();
|
104 |
+
$categories = array();
|
105 |
|
106 |
if ( $related_objects && is_array( $related_objects ) ) {
|
|
|
|
|
107 |
foreach ( $related_objects as $related_object ) {
|
108 |
|
109 |
if ( 'CATEGORY' === $related_object->getType() ) {
|
110 |
+
$categories[ $related_object->getId() ] = $related_object;
|
|
|
111 |
}
|
112 |
}
|
113 |
}
|
123 |
break;
|
124 |
}
|
125 |
|
126 |
+
// validate permissions
|
127 |
+
if ( ! current_user_can( 'publish_products' ) ) {
|
128 |
+
$this->record_error( 'You do not have permission to create products' );
|
129 |
+
break; // use a break so we don't continue trying to import products without permissions
|
130 |
+
}
|
131 |
+
|
132 |
+
// validate Square Catalog object (API data)
|
133 |
+
if ( ! $catalog_object instanceof \SquareConnect\Model\CatalogObject || ! $catalog_object->getItemData() instanceof \SquareConnect\Model\CatalogItem ) {
|
134 |
+
$this->record_error( 'Invalid data' );
|
135 |
+
continue;
|
136 |
+
}
|
137 |
+
|
138 |
$item_id = $catalog_object->getId();
|
139 |
|
140 |
+
// ignore items that have a missing SKU or are not available at our location
|
141 |
+
if ( ! $catalog_object->getPresentAtAllLocations() && ( ! is_array( $catalog_object->getPresentAtLocationIds() ) || ! in_array( wc_square()->get_settings_handler()->get_location_id(), $catalog_object->getPresentAtLocationIds(), true ) ) || $this->item_variation_has_missing_sku( $catalog_object ) ) {
|
142 |
|
143 |
$skipped_products[ $item_id ] = null;
|
144 |
continue;
|
145 |
}
|
146 |
|
147 |
+
// import or update categories related to the products that are being imported
|
148 |
+
$catelog_category_id = $catalog_object->getItemData()->getCategoryId();
|
149 |
|
150 |
+
if ( $catelog_category_id && isset( $categories[ $catelog_category_id ] ) ) {
|
151 |
+
Category::import_or_update( $categories[ $catelog_category_id ] );
|
152 |
+
unset( $categories[ $catelog_category_id ] ); // don't import/update the same category multiple times per batch
|
153 |
}
|
154 |
|
155 |
+
$product_id = Product::get_product_id_by_square_id( $item_id );
|
156 |
+
$product = ! empty( $product_id ) ? wc_get_product( $product_id ) : null;
|
157 |
+
|
158 |
+
if ( $product_id && ! $product ) {
|
159 |
+
$this->record_error( 'Product not found', $catalog_object, 'update' );
|
160 |
continue;
|
161 |
}
|
162 |
|
163 |
+
$data = $this->extract_product_data( $catalog_object, $product );
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Filters the data that is used to create update a WooCommerce product during import.
|
167 |
+
*
|
168 |
+
* @since 2.0.0
|
169 |
+
*
|
170 |
+
* @param array $data product data
|
171 |
+
* @param \SquareConnect\Model\CatalogObject $catalog_object the catalog object from the Square API
|
172 |
+
* @param Product_Import $this import class instance
|
173 |
+
*/
|
174 |
+
$data = apply_filters( 'woocommerce_square_create_product_data', $data, $catalog_object, $this );
|
175 |
|
176 |
+
// set default type
|
177 |
+
$data['type'] = ! empty( $data['type'] ) ? $data['type'] : 'simple';
|
178 |
|
179 |
+
// if an item matches an existing product, update the product using data from Square
|
180 |
+
if ( $product ) {
|
181 |
+
$product_id = $this->update_product( $product, $data );
|
182 |
|
183 |
+
if ( $product_id ) {
|
184 |
+
$updated_product_ids[] = $product_id;
|
185 |
+
}
|
186 |
+
} elseif ( $this->item_variation_has_matching_sku( $catalog_object ) ) {
|
187 |
+
// look in variation SKUs for a match - if so, skip the parent item, a normal sync should link it automatically
|
188 |
+
continue;
|
189 |
+
} else {
|
190 |
+
$product_id = $this->import_product( $data );
|
191 |
+
|
192 |
+
if ( $product_id ) {
|
193 |
+
Product::set_synced_with_square( $product_id );
|
194 |
+
$imported_product_ids[] = $product_id;
|
195 |
+
}
|
196 |
}
|
197 |
}
|
198 |
|
199 |
if ( $time_exceeded ) {
|
200 |
|
201 |
+
wc_square()->log( '[Time Exceeded] Imported New Products Count: ' . count( $imported_product_ids ) );
|
202 |
|
203 |
} else {
|
204 |
|
205 |
+
wc_square()->log( 'Imported New Products Count: ' . count( $imported_product_ids ) );
|
206 |
+
wc_square()->log( 'Updated Products Count: ' . count( $updated_product_ids ) );
|
207 |
|
208 |
$cursor = $response->get_data()->getCursor();
|
209 |
$this->set_attr( 'fetch_products_cursor', $cursor );
|
215 |
}
|
216 |
|
217 |
$this->set_attr( 'skipped_products', $skipped_products );
|
218 |
+
$this->set_attr( 'updated_product_ids', $updated_product_ids );
|
219 |
+
$this->set_attr( 'processed_product_ids', $imported_product_ids );
|
220 |
}
|
221 |
|
222 |
|
229 |
*/
|
230 |
protected function import_inventory() {
|
231 |
|
232 |
+
$search_result = wc_square()->get_api()->search_catalog_objects(
|
233 |
+
array(
|
234 |
+
'object_types' => array( 'ITEM_VARIATION' ),
|
235 |
+
'limit' => 100,
|
236 |
+
'cursor' => $this->get_attr( 'import_inventory_cursor', null ),
|
237 |
+
)
|
238 |
+
);
|
239 |
|
240 |
$cursor = $search_result->get_data()->getCursor();
|
241 |
+
$variation_ids = array_map(
|
242 |
+
static function( \SquareConnect\Model\CatalogObject $catalog_object ) {
|
243 |
+
return $catalog_object->getId();
|
244 |
+
},
|
245 |
+
$search_result->get_data()->getObjects()
|
246 |
+
);
|
247 |
+
|
248 |
+
$result = wc_square()->get_api()->batch_retrieve_inventory_counts(
|
249 |
+
array(
|
250 |
+
'catalog_object_ids' => $variation_ids,
|
251 |
+
'location_ids' => array( wc_square()->get_settings_handler()->get_location_id() ),
|
252 |
+
)
|
253 |
+
);
|
254 |
|
255 |
foreach ( $result->get_counts() as $inventory_count ) {
|
256 |
|
276 |
}
|
277 |
|
278 |
|
279 |
+
/**
|
280 |
+
* Determines whether any catalog item variation is missing a SKU
|
281 |
+
*
|
282 |
+
* @since 2.2.0
|
283 |
+
*
|
284 |
+
* @param \SquareConnect\Model\CatalogObject $catalog_object the catalog object
|
285 |
+
* @return bool
|
286 |
+
*/
|
287 |
+
private function item_variation_has_missing_sku( $catalog_object ) {
|
288 |
+
$missing_sku = true;
|
289 |
+
|
290 |
+
foreach ( $catalog_object->getItemData()->getVariations() as $variation ) {
|
291 |
+
if ( in_array( trim( $variation->getItemVariationData()->getSku() ), array( '', null ), true ) ) { // can't use empty() because a valid SKU could be '0' which returns true
|
292 |
+
$missing_sku = true;
|
293 |
+
break;
|
294 |
+
}
|
295 |
+
|
296 |
+
$missing_sku = false;
|
297 |
+
}
|
298 |
+
|
299 |
+
return $missing_sku;
|
300 |
+
}
|
301 |
+
|
302 |
+
|
303 |
/**
|
304 |
* Determines whether a SKU within a catalog item is found in WooCommerce.
|
305 |
*
|
323 |
|
324 |
|
325 |
/**
|
326 |
+
* Creates a product from catalog object data.
|
327 |
*
|
328 |
* @since 2.0.0
|
329 |
*
|
330 |
+
* @param array $data the catalog object data
|
331 |
* @return int|null
|
332 |
*/
|
333 |
+
private function import_product( $data ) {
|
|
|
|
|
|
|
334 |
try {
|
335 |
+
$product_id = $this->create_product_from_square_data( $data );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
336 |
|
337 |
// save product meta fields
|
338 |
$this->save_product_meta( $product_id, $data );
|
360 |
|
361 |
// clear cache/transients
|
362 |
wc_delete_product_transients( $product_id );
|
|
|
363 |
} catch ( Framework\SV_WC_Plugin_Exception $e ) {
|
364 |
+
// remove the product when creation fails
|
365 |
+
$this->clear_product( $product_id );
|
366 |
+
$product_id = 0;
|
367 |
|
368 |
+
$this->record_error( $e->getMessage(), $data );
|
369 |
+
}
|
370 |
|
371 |
+
return $product_id;
|
372 |
+
}
|
|
|
|
|
|
|
|
|
373 |
|
374 |
+
/**
|
375 |
+
* Updates a product from catalog object data
|
376 |
+
*
|
377 |
+
* @since 2.2.0
|
378 |
+
*
|
379 |
+
* @param WC_Product $product existing product in Woo that is being updated
|
380 |
+
* @param array $data the Square catalog object data
|
381 |
+
* @return int|null
|
382 |
+
*/
|
383 |
+
private function update_product( $product, $data ) {
|
384 |
+
global $wpdb;
|
385 |
+
$product_id = $product->get_id();
|
386 |
|
387 |
+
try {
|
388 |
+
$wpdb->query( 'START TRANSACTION' );
|
389 |
+
|
390 |
+
// update an existing product from a simple to a variable product if it has at least two variations
|
391 |
+
if ( ! $product instanceof \WC_Product_Variable && 'variable' === $data['type'] ) {
|
392 |
+
$product_id = $this->update_simple_product_to_variable( $product_id, $data );
|
393 |
}
|
394 |
|
395 |
+
// save product meta fields
|
396 |
+
$this->save_product_meta( $product_id, $data );
|
|
|
|
|
|
|
397 |
|
398 |
+
// save the image, if included
|
399 |
+
if ( ! empty( $data['image_id'] ) ) {
|
400 |
+
Product::update_image_from_square( $product_id, $data['image_id'] );
|
401 |
+
}
|
402 |
|
403 |
+
// save/update variations
|
404 |
+
if ( isset( $data['type'], $data['variations'] ) && 'variable' === $data['type'] && is_array( $data['variations'] ) ) {
|
405 |
+
$this->save_variations( $product_id, $data );
|
406 |
+
}
|
407 |
+
|
408 |
+
$wpdb->query( 'COMMIT' );
|
409 |
+
|
410 |
+
wc_delete_product_transients( $product_id );
|
411 |
+
} catch ( Framework\SV_WC_Plugin_Exception $e ) {
|
412 |
+
// undo any updated data when updating fails
|
413 |
+
$wpdb->query( 'ROLLBACK' );
|
414 |
$product_id = 0;
|
415 |
+
|
416 |
+
$this->record_error( $e->getMessage(), $data, 'update' );
|
417 |
}
|
418 |
|
419 |
return $product_id;
|
420 |
}
|
421 |
|
422 |
+
/**
|
423 |
+
* Convert an existing simple product to a variable when new variations are found.
|
424 |
+
* This function
|
425 |
+
*
|
426 |
+
* @since 2.2.0
|
427 |
+
*
|
428 |
+
* @param int $variation_id simple product ID being updated to a variation with new parent product
|
429 |
+
* @param array $data
|
430 |
+
* @return int|null
|
431 |
+
*/
|
432 |
+
protected function update_simple_product_to_variable( $variation_id, $data = array() ) {
|
433 |
+
// create a new parent product
|
434 |
+
$parent_product_id = $this->create_product_from_square_data( $data );
|
435 |
+
|
436 |
+
// convert the simple product to a variation
|
437 |
+
wp_set_object_terms( $variation_id, 'variation', 'product_type' );
|
438 |
+
wp_update_post(
|
439 |
+
array(
|
440 |
+
'ID' => $variation_id,
|
441 |
+
'post_content' => '',
|
442 |
+
'post_author' => get_current_user_id(),
|
443 |
+
'post_parent' => $parent_product_id,
|
444 |
+
'post_type' => 'product_variation',
|
445 |
+
)
|
446 |
+
);
|
447 |
+
|
448 |
+
// remove simple product meta that doesn't exist or needs be updated on the variation
|
449 |
+
delete_post_meta( $variation_id, Product::SQUARE_ID_META_KEY );
|
450 |
+
delete_post_meta( $variation_id, Product::SQUARE_VERSION_META_KEY );
|
451 |
+
delete_post_meta( $variation_id, Product::SQUARE_IMAGE_ID_META_KEY );
|
452 |
+
delete_post_meta( $variation_id, '_visibility' );
|
453 |
+
|
454 |
+
// copy total sales from previous simple product over to new parent variable product
|
455 |
+
$total_sales = get_post_meta( $variation_id, 'total_sales', true );
|
456 |
+
|
457 |
+
if ( $total_sales ) {
|
458 |
+
update_post_meta( $parent_product_id, 'total_sales', $total_sales );
|
459 |
+
}
|
460 |
+
|
461 |
+
return $parent_product_id;
|
462 |
+
}
|
463 |
|
464 |
/**
|
465 |
* Extracts product data from a CatalogObject to an array of data.
|
467 |
* @since 2.0.0
|
468 |
*
|
469 |
* @param \SquareConnect\Model\CatalogObject $catalog_object the catalog object
|
470 |
+
* @param WC_Product|null $product
|
471 |
* @return array|null
|
472 |
* @throws Framework\SV_WC_Plugin_Exception
|
473 |
*/
|
474 |
+
protected function extract_product_data( $catalog_object, $product = null ) {
|
475 |
|
476 |
$variations = $catalog_object->getItemData()->getVariations();
|
477 |
|
482 |
|
483 |
$category_id = Category::get_category_id_by_square_id( $catalog_object->getItemData()->getCategoryId() );
|
484 |
|
485 |
+
$data = array(
|
486 |
'title' => $catalog_object->getItemData()->getName(),
|
487 |
+
'type' => ( 1 === count( $variations ) && ! ( $product && $product instanceof \WC_Product_Variable ) ) ? 'simple' : 'variable',
|
488 |
+
'sku' => '', // make sure to reset SKU when simple product is updated to variable
|
489 |
'description' => $catalog_object->getItemData()->getDescription(),
|
490 |
'image_id' => $catalog_object->getImageId(),
|
491 |
+
'categories' => array( $category_id ),
|
492 |
+
'square_meta' => array(
|
493 |
'item_id' => $catalog_object->getId(),
|
494 |
'item_version' => $catalog_object->getVersion(),
|
495 |
+
),
|
496 |
+
);
|
497 |
|
498 |
// variable product
|
499 |
+
if ( 'variable' === $data['type'] ) {
|
500 |
+
$data['variations'] = array();
|
|
|
|
|
501 |
|
502 |
foreach ( $variations as $variation ) {
|
503 |
|
513 |
} catch ( Framework\SV_WC_Plugin_Exception $exception ) {
|
514 |
|
515 |
// alert for failed variation imports
|
516 |
+
Records::set_record(
|
517 |
+
array(
|
518 |
+
'type' => 'alert',
|
519 |
+
'message' => sprintf(
|
520 |
+
/* translators: Placeholders: %1$s - Square item name, %2$s - Square item variation name, %3$s - failure reason */
|
521 |
+
__( 'Could not import "%1$s - %2$s" from Square. %3$s', 'woocommerce-square' ),
|
522 |
+
$catalog_object->getItemData()->getName(),
|
523 |
+
$variation->getItemVariationData()->getName(),
|
524 |
+
$exception->getMessage()
|
525 |
+
),
|
526 |
+
)
|
527 |
+
);
|
528 |
}
|
529 |
}
|
530 |
|
531 |
+
$data['attributes'] = array(
|
532 |
+
array(
|
533 |
+
'name' => 'Attribute',
|
534 |
+
'slug' => 'attribute',
|
535 |
+
'position' => 0,
|
536 |
+
'visible' => true,
|
537 |
+
'variation' => true,
|
538 |
+
'options' => wp_list_pluck( $data['variations'], 'name' ),
|
539 |
+
),
|
540 |
+
);
|
541 |
+
} else { // simple product
|
|
|
542 |
$variation = $this->extract_square_item_variation_data( $variations[0] );
|
543 |
|
544 |
$data['type'] = 'simple';
|
545 |
+
$data['sku'] = ! empty( $variation['sku'] ) ? $variation['sku'] : null;
|
546 |
+
$data['regular_price'] = ! empty( $variation['regular_price'] ) ? $variation['regular_price'] : null;
|
547 |
+
$data['stock_quantity'] = ! empty( $variation['stock_quantity'] ) ? $variation['stock_quantity'] : null;
|
548 |
+
$data['managing_stock'] = ! empty( $variation['managing_stock'] ) ? $variation['managing_stock'] : null;
|
549 |
|
550 |
+
$data['square_meta']['item_variation_id'] = ! empty( $variation['square_meta']['item_variation_id'] ) ? $variation['square_meta']['item_variation_id'] : null;
|
551 |
+
$data['square_meta']['item_variation_version'] = ! empty( $variation['square_meta']['item_variation_version'] ) ? $variation['square_meta']['item_variation_version'] : null;
|
552 |
}
|
553 |
|
554 |
return $data;
|
572 |
throw new Framework\SV_WC_Plugin_Exception( __( 'Items with variable pricing cannot be imported.', 'woocommerce-square' ) );
|
573 |
}
|
574 |
|
575 |
+
$data = array(
|
576 |
+
'name' => $variation_data->getName(),
|
577 |
+
'sku' => $variation_data->getSku(),
|
578 |
'regular_price' => $variation_data->getPriceMoney() && $variation_data->getPriceMoney()->getAmount() ? Money_Utility::cents_to_float( $variation->getItemVariationData()->getPriceMoney()->getAmount() ) : null,
|
579 |
'stock_quantity' => null,
|
580 |
'managing_stock' => true,
|
581 |
+
'square_meta' => array(
|
582 |
'item_variation_id' => $variation->getId(),
|
583 |
'item_variation_version' => $variation->getVersion(),
|
584 |
+
),
|
585 |
+
'attributes' => array(
|
586 |
+
array(
|
587 |
'name' => 'Attribute',
|
588 |
'is_variation' => true,
|
589 |
+
'option' => $variation_data->getName(),
|
590 |
+
),
|
591 |
+
),
|
592 |
+
);
|
593 |
|
594 |
return $data;
|
595 |
}
|
624 |
$product_type = wc_clean( $data['type'] );
|
625 |
|
626 |
wp_set_object_terms( $product_id, $product_type, 'product_type' );
|
|
|
627 |
} else {
|
|
|
628 |
$_product_type = get_the_terms( $product_id, 'product_type' );
|
629 |
|
630 |
if ( is_array( $_product_type ) ) {
|
638 |
add_post_meta( $product_id, 'total_sales', '0', true );
|
639 |
|
640 |
// catalog visibility
|
641 |
+
update_post_meta( $product_id, '_visibility', ! empty( $data['catalog_visibility'] ) ? wc_clean( $data['catalog_visibility'] ) : 'visible' );
|
|
|
|
|
|
|
642 |
|
643 |
// sku
|
644 |
if ( isset( $data['sku'] ) ) {
|
664 |
|
665 |
throw new Framework\SV_WC_Plugin_Exception( __( 'The SKU already exists on another product', 'woocommerce-square' ) );
|
666 |
}
|
|
|
667 |
} else {
|
|
|
668 |
update_post_meta( $product_id, '_sku', '' );
|
669 |
}
|
670 |
}
|
673 |
// attributes
|
674 |
if ( isset( $data['attributes'] ) ) {
|
675 |
|
676 |
+
$attributes = array();
|
677 |
|
678 |
foreach ( $data['attributes'] as $attribute ) {
|
679 |
|
714 |
|
715 |
} else {
|
716 |
|
717 |
+
$values = array();
|
718 |
}
|
719 |
|
720 |
// update post terms
|
726 |
if ( ! empty( $values ) ) {
|
727 |
|
728 |
// add attribute to array, but don't set values
|
729 |
+
$attributes[ $taxonomy ] = array(
|
730 |
'name' => $taxonomy,
|
731 |
'value' => '',
|
732 |
'position' => isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0',
|
733 |
'is_visible' => ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0,
|
734 |
'is_variation' => ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0,
|
735 |
'is_taxonomy' => $is_taxonomy,
|
736 |
+
);
|
737 |
}
|
|
|
738 |
} elseif ( isset( $attribute['options'] ) ) {
|
|
|
739 |
// array based
|
740 |
if ( is_array( $attribute['options'] ) ) {
|
741 |
|
747 |
}
|
748 |
|
749 |
// custom attribute - add attribute to array and set the values
|
750 |
+
$attributes[ $attribute_slug ] = array(
|
751 |
'name' => wc_clean( $attribute['name'] ),
|
752 |
'value' => $values,
|
753 |
'position' => isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0',
|
754 |
'is_visible' => ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0,
|
755 |
'is_variation' => ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0,
|
756 |
'is_taxonomy' => $is_taxonomy,
|
757 |
+
);
|
758 |
}
|
759 |
}
|
760 |
|
764 |
}
|
765 |
|
766 |
// sales and prices
|
767 |
+
if ( in_array( $product_type, array( 'variable', 'grouped' ), true ) ) {
|
768 |
|
769 |
// variable and grouped products have no prices
|
770 |
update_post_meta( $product_id, '_regular_price', '' );
|
833 |
protected function save_variations( $product_id, $data ) {
|
834 |
global $wpdb;
|
835 |
|
836 |
+
$variations = $data['variations'];
|
837 |
+
$attributes = (array) maybe_unserialize( get_post_meta( $product_id, '_product_attributes', true ) );
|
838 |
+
$variable_product = wc_get_product( $product_id );
|
839 |
+
$variations_to_remove = $variable_product ? $variable_product->get_children() : array();
|
840 |
|
841 |
foreach ( $variations as $menu_order => $variation ) {
|
842 |
|
848 |
$variation_id = wc_get_product_id_by_sku( $variation_sku );
|
849 |
}
|
850 |
|
851 |
+
/* translators: Placeholders: %1$s - variation ID, %2$s - product name */
|
852 |
$variation_post_title = sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce-square' ), $variation_id, esc_html( get_the_title( $product_id ) ) );
|
853 |
|
854 |
// update or add post
|
855 |
if ( ! $variation_id ) {
|
856 |
|
857 |
$post_status = ( isset( $variation['visible'] ) && false === $variation['visible'] ) ? 'private' : 'publish';
|
858 |
+
$new_variation = array(
|
859 |
'post_title' => $variation_post_title,
|
860 |
'post_content' => '',
|
861 |
'post_status' => $post_status,
|
863 |
'post_parent' => $product_id,
|
864 |
'post_type' => 'product_variation',
|
865 |
'menu_order' => $menu_order,
|
866 |
+
);
|
867 |
|
868 |
$variation_id = wp_insert_post( $new_variation );
|
869 |
|
878 |
|
879 |
} else {
|
880 |
|
881 |
+
$update_variation = array(
|
882 |
+
'post_title' => $variation_post_title,
|
883 |
+
'menu_order' => $menu_order,
|
884 |
+
);
|
885 |
|
886 |
if ( isset( $variation['visible'] ) ) {
|
887 |
|
890 |
$update_variation['post_status'] = $post_status;
|
891 |
}
|
892 |
|
893 |
+
$wpdb->update( $wpdb->posts, $update_variation, array( 'ID' => $variation_id ) );
|
894 |
+
|
895 |
+
// remove any variation from $variations_to_remove that is found in Sqaure and also matches a variation in Woo
|
896 |
+
if ( ( $key = array_search( $variation_id, $variations_to_remove, true ) ) !== false ) { //phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.Found, Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
|
897 |
+
unset( $variations_to_remove[ $key ] );
|
898 |
+
}
|
899 |
|
900 |
/**
|
901 |
* Fired after updating a product variation during an import from Square.
|
935 |
|
936 |
throw new Framework\SV_WC_Plugin_Exception( __( 'The SKU already exists on another product', 'woocommerce-square' ) );
|
937 |
}
|
|
|
938 |
} else {
|
939 |
|
940 |
update_post_meta( $variation_id, '_sku', '' );
|
943 |
}
|
944 |
|
945 |
update_post_meta( $variation_id, '_manage_stock', 'yes' );
|
946 |
+
update_post_meta( $variation_id, '_backorders', 'no' );
|
947 |
|
948 |
$this->wc_save_product_price( $variation_id, $variation['regular_price'] );
|
949 |
|
959 |
// update taxonomies
|
960 |
if ( isset( $variation['attributes'] ) ) {
|
961 |
|
962 |
+
$updated_attribute_keys = array();
|
963 |
|
964 |
foreach ( $variation['attributes'] as $attribute_key => $attribute ) {
|
965 |
|
968 |
}
|
969 |
|
970 |
$taxonomy = 0;
|
971 |
+
$_attribute = array();
|
972 |
|
973 |
if ( isset( $attribute['slug'] ) ) {
|
974 |
|
1005 |
}
|
1006 |
|
1007 |
// remove old taxonomies attributes so data is kept up to date - first get attribute key names
|
1008 |
+
$delete_attribute_keys = $wpdb->get_col( $wpdb->prepare( "SELECT meta_key FROM {$wpdb->postmeta} WHERE meta_key LIKE 'attribute_%%' AND meta_key NOT IN ( '" . implode( "','", $updated_attribute_keys ) . "' ) AND post_id = %d;", $variation_id ) ); //phpcs:ignore WordPress.DB.PreparedSQLPlaceholders, WordPress.DB.PreparedSQL.NotPrepared
|
1009 |
|
1010 |
foreach ( $delete_attribute_keys as $key ) {
|
1011 |
|
1035 |
do_action( 'woocommerce_square_save_product_variation', $variation_id, $menu_order, $variation );
|
1036 |
}
|
1037 |
|
1038 |
+
// remove any existing variations on the product that no longer exist in Square
|
1039 |
+
foreach ( $variations_to_remove as $variation_id ) {
|
1040 |
+
wp_delete_post( $variation_id, true );
|
1041 |
+
}
|
1042 |
+
|
1043 |
// update parent if variable so price sorting works and stays in sync with the cheapest child
|
1044 |
\WC_Product_Variable::sync( $product_id );
|
1045 |
|
1051 |
|
1052 |
if ( isset( $data['default_attributes'] ) && is_array( $data['default_attributes'] ) ) {
|
1053 |
|
1054 |
+
$default_attributes = array();
|
1055 |
|
1056 |
foreach ( $data['default_attributes'] as $default_attr_key => $default_attr ) {
|
1057 |
|
1155 |
|
1156 |
if ( $date_to && ! $date_from ) {
|
1157 |
|
1158 |
+
$date_from = strtotime( 'NOW', current_time( 'timestamp' ) ); //phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested
|
1159 |
|
1160 |
update_post_meta( $product_id, '_sale_price_dates_from', $date_from );
|
1161 |
}
|
1170 |
update_post_meta( $product_id, '_price', $regular_price );
|
1171 |
}
|
1172 |
|
1173 |
+
if ( '' !== $sale_price && $date_from && strtotime( $date_from ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ) { //phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested
|
1174 |
|
1175 |
update_post_meta( $product_id, '_price', $sale_price );
|
1176 |
}
|
1177 |
|
1178 |
+
if ( $date_to && strtotime( $date_to ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ) { //phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested
|
1179 |
|
1180 |
update_post_meta( $product_id, '_price', $regular_price );
|
1181 |
update_post_meta( $product_id, '_sale_price_dates_from', '' );
|
1198 |
}
|
1199 |
|
1200 |
// Delete product attachments
|
1201 |
+
$attachments = get_children(
|
1202 |
+
array(
|
1203 |
+
'post_parent' => $product_id,
|
1204 |
+
'post_status' => 'any',
|
1205 |
+
'post_type' => 'attachment',
|
1206 |
+
)
|
1207 |
+
);
|
1208 |
|
1209 |
foreach ( $attachments as $attachment ) {
|
1210 |
wp_delete_attachment( $attachment->ID, true );
|
1214 |
wp_delete_post( $product_id, true );
|
1215 |
}
|
1216 |
|
1217 |
+
/**
|
1218 |
+
* Creates a product in WooCommerce using the data from Square
|
1219 |
+
*
|
1220 |
+
* @since 2.2.0
|
1221 |
+
*
|
1222 |
+
* @param array $data New product data
|
1223 |
+
* @return int
|
1224 |
+
* @throws Framework\SV_WC_Plugin_Exception
|
1225 |
+
*/
|
1226 |
+
protected function create_product_from_square_data( $data = array() ) {
|
1227 |
+
// validate title field
|
1228 |
+
if ( ! isset( $data['title'] ) ) {
|
1229 |
+
/* translators: Placeholders: %s - missing parameter name */
|
1230 |
+
throw new Framework\SV_WC_Plugin_Exception( sprintf( __( 'Missing parameter %s', 'woocommerce-square' ), 'title' ) );
|
1231 |
+
}
|
1232 |
+
|
1233 |
+
// validate type
|
1234 |
+
if ( ! array_key_exists( wc_clean( $data['type'] ), wc_get_product_types() ) ) {
|
1235 |
+
/* translators: Placeholders: %s - comma separated list of valid product types */
|
1236 |
+
throw new Framework\SV_WC_Plugin_Exception( sprintf( __( 'Invalid product type - the product type must be any of these: %s', 'woocommerce-square' ), implode( ', ', array_keys( wc_get_product_types() ) ) ) );
|
1237 |
+
}
|
1238 |
+
|
1239 |
+
// set description
|
1240 |
+
$post_content = isset( $data['description'] ) ? wc_clean( $data['description'] ) : '';
|
1241 |
+
|
1242 |
+
if ( $post_content && isset( $data['enable_html_description'] ) && true === $data['enable_html_description'] ) {
|
1243 |
+
$post_content = $data['description'];
|
1244 |
+
}
|
1245 |
+
|
1246 |
+
$new_product = array(
|
1247 |
+
'post_title' => wc_clean( $data['title'] ),
|
1248 |
+
'post_status' => isset( $data['status'] ) ? wc_clean( $data['status'] ) : 'publish',
|
1249 |
+
'post_type' => 'product',
|
1250 |
+
'post_content' => isset( $data['description'] ) ? $post_content : '',
|
1251 |
+
'post_author' => get_current_user_id(),
|
1252 |
+
'menu_order' => isset( $data['menu_order'] ) ? (int) $data['menu_order'] : 0,
|
1253 |
+
);
|
1254 |
+
|
1255 |
+
if ( ! empty( $data['name'] ) ) {
|
1256 |
+
$new_product = array_merge( $new_product, array( 'post_name' => sanitize_title( $data['name'] ) ) );
|
1257 |
+
}
|
1258 |
+
|
1259 |
+
// attempt to create the new product
|
1260 |
+
$product_id = wp_insert_post( $new_product, true );
|
1261 |
+
|
1262 |
+
if ( is_wp_error( $product_id ) ) {
|
1263 |
+
throw new Framework\SV_WC_Plugin_Exception( $product_id->get_error_message() );
|
1264 |
+
}
|
1265 |
+
|
1266 |
+
return $product_id;
|
1267 |
+
}
|
1268 |
+
|
1269 |
+
/**
|
1270 |
+
* Record an error made during import or update by creating a new Sync Record and Square log
|
1271 |
+
*
|
1272 |
+
* @since 2.2.0
|
1273 |
+
*
|
1274 |
+
* @param string $error Error message to record
|
1275 |
+
* @param \SquareConnect\Model\CatalogObject|array|null $catalog_item the catalog object or data
|
1276 |
+
* @param string $context Context for whether the error occurred during import or update
|
1277 |
+
*/
|
1278 |
+
protected function record_error( $error, $catalog_item = null, $context = 'import' ) {
|
1279 |
+
if ( $catalog_item && $catalog_item instanceof \SquareConnect\Model\CatalogObject && $catalog_item->getItemData() instanceof \SquareConnect\Model\CatalogItem ) {
|
1280 |
+
$item_name = $catalog_item->getItemData()->getName();
|
1281 |
+
} elseif ( is_array( $catalog_item ) && ! empty( $catalog_item['title'] ) ) {
|
1282 |
+
$item_name = $catalog_item['title'];
|
1283 |
+
}
|
1284 |
+
|
1285 |
+
if ( 'update' === $context ) {
|
1286 |
+
/* translators: Placeholders: %1$s - Square item name, %2$s - Failure reason */
|
1287 |
+
$message = sprintf( __( 'Could not update %1$s from Square. %2$s', 'woocommerce-square' ), ! empty( $item_name ) ? '"' . $item_name . '"' : 'item', $error );
|
1288 |
+
} else {
|
1289 |
+
/* translators: Placeholders: %1$s - Square item name, %2$s - Failure reason */
|
1290 |
+
$message = sprintf( __( 'Could not import %1$s from Square. %2$s', 'woocommerce-square' ), ! empty( $item_name ) ? '"' . $item_name . '"' : 'item', $error );
|
1291 |
+
}
|
1292 |
+
|
1293 |
+
Records::set_record(
|
1294 |
+
array(
|
1295 |
+
'type' => 'alert',
|
1296 |
+
'message' => $message,
|
1297 |
+
)
|
1298 |
+
);
|
1299 |
+
|
1300 |
+
wc_square()->log( sprintf( 'Error %s product during import: %s', 'import' === $context ? 'creating' : 'updating', $error ) );
|
1301 |
+
}
|
1302 |
|
1303 |
}
|
includes/Sync/Records.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Sync;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Sync\Records\Record;
|
@@ -63,7 +63,7 @@ class Records {
|
|
63 |
*/
|
64 |
public static function get_record( $id ) {
|
65 |
|
66 |
-
$records = self::get_records(
|
67 |
|
68 |
return ! empty( $records ) ? current( $records ) : null;
|
69 |
}
|
@@ -77,19 +77,22 @@ class Records {
|
|
77 |
* @param array $args associative array of arguments to query records
|
78 |
* @return Record[]
|
79 |
*/
|
80 |
-
public static function get_records( array $args =
|
81 |
-
|
82 |
-
$args = wp_parse_args(
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
|
|
|
|
|
|
93 |
|
94 |
foreach ( $raw_records as $raw_record_data ) {
|
95 |
|
@@ -128,12 +131,12 @@ class Records {
|
|
128 |
if ( ! empty( $records ) ) {
|
129 |
|
130 |
switch ( $args['orderby'] ) {
|
131 |
-
case 'date'
|
132 |
-
uasort( $records,
|
133 |
-
|
134 |
-
case 'type'
|
135 |
-
uasort( $records,
|
136 |
-
|
137 |
}
|
138 |
|
139 |
if ( 'DESC' === $args['sort'] ) {
|
@@ -240,8 +243,8 @@ class Records {
|
|
240 |
if ( $new_record instanceof Record ) {
|
241 |
|
242 |
// ensures there are never more than 50 records, leaving behind the older ones
|
243 |
-
$existing_records = self::get_records(
|
244 |
-
$raw_records =
|
245 |
|
246 |
foreach ( $existing_records as $existing_record ) {
|
247 |
$raw_records[ $existing_record->get_id() ] = $existing_record->get_data();
|
@@ -251,7 +254,7 @@ class Records {
|
|
251 |
|
252 |
$success = update_option( self::$records_option_key, $raw_records );
|
253 |
|
254 |
-
|
255 |
|
256 |
$success = false;
|
257 |
}
|
@@ -271,7 +274,7 @@ class Records {
|
|
271 |
public static function set_records( array $data ) {
|
272 |
|
273 |
$success = false;
|
274 |
-
$raw_records =
|
275 |
|
276 |
foreach ( $data as $record ) {
|
277 |
|
@@ -286,7 +289,7 @@ class Records {
|
|
286 |
|
287 |
if ( ! empty( $raw_records ) ) {
|
288 |
|
289 |
-
$records = self::get_records(
|
290 |
|
291 |
foreach ( $records as $record ) {
|
292 |
$raw_records[ $record->get_id() ] = $record->get_data();
|
@@ -310,7 +313,7 @@ class Records {
|
|
310 |
public static function delete_record( $id ) {
|
311 |
|
312 |
$success = false;
|
313 |
-
$raw_records = get_option( self::$records_option_key,
|
314 |
|
315 |
if ( array_key_exists( $id, $raw_records ) ) {
|
316 |
|
@@ -334,9 +337,9 @@ class Records {
|
|
334 |
public static function delete_records( array $args ) {
|
335 |
|
336 |
$removed = 0;
|
337 |
-
$raw_records = get_option( self::$records_option_key,
|
338 |
|
339 |
-
foreach( $raw_records as $raw_record ) {
|
340 |
|
341 |
$record = new Record( $raw_record );
|
342 |
|
@@ -383,7 +386,7 @@ class Records {
|
|
383 |
*/
|
384 |
public static function clean_records() {
|
385 |
|
386 |
-
return update_option( self::$records_option_key,
|
387 |
}
|
388 |
|
389 |
|
23 |
|
24 |
namespace WooCommerce\Square\Sync;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Sync\Records\Record;
|
63 |
*/
|
64 |
public static function get_record( $id ) {
|
65 |
|
66 |
+
$records = self::get_records( array( 'id' => $id ) );
|
67 |
|
68 |
return ! empty( $records ) ? current( $records ) : null;
|
69 |
}
|
77 |
* @param array $args associative array of arguments to query records
|
78 |
* @return Record[]
|
79 |
*/
|
80 |
+
public static function get_records( array $args = array() ) {
|
81 |
+
|
82 |
+
$args = wp_parse_args(
|
83 |
+
$args,
|
84 |
+
array(
|
85 |
+
'id' => null,
|
86 |
+
'type' => null,
|
87 |
+
'product' => null,
|
88 |
+
'orderby' => 'date',
|
89 |
+
'sort' => 'DESC',
|
90 |
+
'limit' => 50,
|
91 |
+
)
|
92 |
+
);
|
93 |
+
|
94 |
+
$records = array();
|
95 |
+
$raw_records = get_option( self::$records_option_key, array() );
|
96 |
|
97 |
foreach ( $raw_records as $raw_record_data ) {
|
98 |
|
131 |
if ( ! empty( $records ) ) {
|
132 |
|
133 |
switch ( $args['orderby'] ) {
|
134 |
+
case 'date':
|
135 |
+
uasort( $records, array( 'self', 'sort_records_by_date' ) );
|
136 |
+
break;
|
137 |
+
case 'type':
|
138 |
+
uasort( $records, array( 'self', 'sort_records_by_type' ) );
|
139 |
+
break;
|
140 |
}
|
141 |
|
142 |
if ( 'DESC' === $args['sort'] ) {
|
243 |
if ( $new_record instanceof Record ) {
|
244 |
|
245 |
// ensures there are never more than 50 records, leaving behind the older ones
|
246 |
+
$existing_records = self::get_records( array( 'limit' => 49 ) );
|
247 |
+
$raw_records = array();
|
248 |
|
249 |
foreach ( $existing_records as $existing_record ) {
|
250 |
$raw_records[ $existing_record->get_id() ] = $existing_record->get_data();
|
254 |
|
255 |
$success = update_option( self::$records_option_key, $raw_records );
|
256 |
|
257 |
+
} else {
|
258 |
|
259 |
$success = false;
|
260 |
}
|
274 |
public static function set_records( array $data ) {
|
275 |
|
276 |
$success = false;
|
277 |
+
$raw_records = array();
|
278 |
|
279 |
foreach ( $data as $record ) {
|
280 |
|
289 |
|
290 |
if ( ! empty( $raw_records ) ) {
|
291 |
|
292 |
+
$records = self::get_records( array( 'limit' => 50 - count( $raw_records ) ) );
|
293 |
|
294 |
foreach ( $records as $record ) {
|
295 |
$raw_records[ $record->get_id() ] = $record->get_data();
|
313 |
public static function delete_record( $id ) {
|
314 |
|
315 |
$success = false;
|
316 |
+
$raw_records = get_option( self::$records_option_key, array() );
|
317 |
|
318 |
if ( array_key_exists( $id, $raw_records ) ) {
|
319 |
|
337 |
public static function delete_records( array $args ) {
|
338 |
|
339 |
$removed = 0;
|
340 |
+
$raw_records = get_option( self::$records_option_key, array() );
|
341 |
|
342 |
+
foreach ( $raw_records as $raw_record ) {
|
343 |
|
344 |
$record = new Record( $raw_record );
|
345 |
|
386 |
*/
|
387 |
public static function clean_records() {
|
388 |
|
389 |
+
return update_option( self::$records_option_key, array() );
|
390 |
}
|
391 |
|
392 |
|
includes/Sync/Records/Record.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Sync\Records;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Sync\Records;
|
@@ -81,20 +81,23 @@ class Record {
|
|
81 |
private function parse_data( $data ) {
|
82 |
|
83 |
if ( is_numeric( $data ) ) {
|
84 |
-
$data =
|
85 |
'type' => 'alert',
|
86 |
'product_id' => absint( $data ),
|
87 |
-
|
88 |
}
|
89 |
|
90 |
$date = date( 'Y-m-d H:i:s', current_time( 'timestamp', true ) );
|
91 |
-
$data = wp_parse_args(
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
98 |
|
99 |
if ( empty( $data['id'] ) ) {
|
100 |
$data['id'] = uniqid( 'wc_square_sync_record_', false );
|
@@ -129,14 +132,14 @@ class Record {
|
|
129 |
*/
|
130 |
public function get_data() {
|
131 |
|
132 |
-
return
|
133 |
'id' => (string) $this->id,
|
134 |
'type' => (string) $this->type,
|
135 |
'date' => (string) $this->date,
|
136 |
'message' => (string) $this->message,
|
137 |
'product_id' => (int) $this->product_id,
|
138 |
'product_hidden' => (bool) $this->product_hidden,
|
139 |
-
|
140 |
}
|
141 |
|
142 |
|
@@ -199,12 +202,12 @@ class Record {
|
|
199 |
*/
|
200 |
private function get_valid_types() {
|
201 |
|
202 |
-
return
|
203 |
'info' => __( 'Info', 'woocommerce-square' ),
|
204 |
'notice' => __( 'Notice', 'woocommerce-square' ),
|
205 |
'alert' => __( 'Alert', 'woocommerce-square' ),
|
206 |
'resolved' => __( 'Resolved', 'woocommerce-square' ),
|
207 |
-
|
208 |
}
|
209 |
|
210 |
|
@@ -502,7 +505,7 @@ class Record {
|
|
502 |
|
503 |
if ( is_bool( $was_hidden ) ) {
|
504 |
$this->product_hidden = $was_hidden;
|
505 |
-
$set
|
506 |
}
|
507 |
|
508 |
return $set;
|
@@ -533,32 +536,32 @@ class Record {
|
|
533 |
*/
|
534 |
public function get_actions() {
|
535 |
|
536 |
-
$actions =
|
537 |
|
538 |
if ( ! $this->is_resolved() ) {
|
539 |
|
540 |
-
$actions['delete'] = (object)
|
541 |
'name' => 'delete',
|
542 |
'label' => __( 'Delete', 'woocommerce-square' ),
|
543 |
'icon' => '<span class="dashicons dashicons-trash"></span>',
|
544 |
-
|
545 |
|
546 |
if ( ! $this->is_type( 'info' ) ) {
|
547 |
|
548 |
-
$actions['resolve'] = (object)
|
549 |
'name' => 'resolve',
|
550 |
'label' => __( 'Ignore', 'woocommerce-square' ),
|
551 |
'icon' => '<span class="dashicons dashicons-hidden"></span>',
|
552 |
-
|
553 |
}
|
554 |
|
555 |
if ( $this->has_product() ) {
|
556 |
|
557 |
-
$actions['unsync'] = (object)
|
558 |
'name' => 'unsync',
|
559 |
'label' => __( 'Unlink', 'woocommerce-square' ),
|
560 |
'icon' => '<span class="dashicons dashicons-editor-unlink"></span>',
|
561 |
-
|
562 |
}
|
563 |
}
|
564 |
|
23 |
|
24 |
namespace WooCommerce\Square\Sync\Records;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Sync\Records;
|
81 |
private function parse_data( $data ) {
|
82 |
|
83 |
if ( is_numeric( $data ) ) {
|
84 |
+
$data = array(
|
85 |
'type' => 'alert',
|
86 |
'product_id' => absint( $data ),
|
87 |
+
);
|
88 |
}
|
89 |
|
90 |
$date = date( 'Y-m-d H:i:s', current_time( 'timestamp', true ) );
|
91 |
+
$data = wp_parse_args(
|
92 |
+
(array) $data,
|
93 |
+
array(
|
94 |
+
'type' => $this->get_default_type(),
|
95 |
+
'date' => $date,
|
96 |
+
'message' => '',
|
97 |
+
'product_id' => 0,
|
98 |
+
'product_hidden' => false,
|
99 |
+
)
|
100 |
+
);
|
101 |
|
102 |
if ( empty( $data['id'] ) ) {
|
103 |
$data['id'] = uniqid( 'wc_square_sync_record_', false );
|
132 |
*/
|
133 |
public function get_data() {
|
134 |
|
135 |
+
return array(
|
136 |
'id' => (string) $this->id,
|
137 |
'type' => (string) $this->type,
|
138 |
'date' => (string) $this->date,
|
139 |
'message' => (string) $this->message,
|
140 |
'product_id' => (int) $this->product_id,
|
141 |
'product_hidden' => (bool) $this->product_hidden,
|
142 |
+
);
|
143 |
}
|
144 |
|
145 |
|
202 |
*/
|
203 |
private function get_valid_types() {
|
204 |
|
205 |
+
return array(
|
206 |
'info' => __( 'Info', 'woocommerce-square' ),
|
207 |
'notice' => __( 'Notice', 'woocommerce-square' ),
|
208 |
'alert' => __( 'Alert', 'woocommerce-square' ),
|
209 |
'resolved' => __( 'Resolved', 'woocommerce-square' ),
|
210 |
+
);
|
211 |
}
|
212 |
|
213 |
|
505 |
|
506 |
if ( is_bool( $was_hidden ) ) {
|
507 |
$this->product_hidden = $was_hidden;
|
508 |
+
$set = true;
|
509 |
}
|
510 |
|
511 |
return $set;
|
536 |
*/
|
537 |
public function get_actions() {
|
538 |
|
539 |
+
$actions = array();
|
540 |
|
541 |
if ( ! $this->is_resolved() ) {
|
542 |
|
543 |
+
$actions['delete'] = (object) array(
|
544 |
'name' => 'delete',
|
545 |
'label' => __( 'Delete', 'woocommerce-square' ),
|
546 |
'icon' => '<span class="dashicons dashicons-trash"></span>',
|
547 |
+
);
|
548 |
|
549 |
if ( ! $this->is_type( 'info' ) ) {
|
550 |
|
551 |
+
$actions['resolve'] = (object) array(
|
552 |
'name' => 'resolve',
|
553 |
'label' => __( 'Ignore', 'woocommerce-square' ),
|
554 |
'icon' => '<span class="dashicons dashicons-hidden"></span>',
|
555 |
+
);
|
556 |
}
|
557 |
|
558 |
if ( $this->has_product() ) {
|
559 |
|
560 |
+
$actions['unsync'] = (object) array(
|
561 |
'name' => 'unsync',
|
562 |
'label' => __( 'Unlink', 'woocommerce-square' ),
|
563 |
'icon' => '<span class="dashicons dashicons-editor-unlink"></span>',
|
564 |
+
);
|
565 |
}
|
566 |
}
|
567 |
|
includes/Sync/Stepped_Job.php
CHANGED
@@ -25,7 +25,7 @@ namespace WooCommerce\Square\Sync;
|
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
-
defined( 'ABSPATH' )
|
29 |
|
30 |
/**
|
31 |
* Stepped Job abstract.
|
@@ -105,7 +105,7 @@ abstract class Stepped_Job extends Job {
|
|
105 |
|
106 |
$next_step = $this->get_next_step();
|
107 |
|
108 |
-
if ( is_callable(
|
109 |
|
110 |
$this->start_step_cycle( $next_step );
|
111 |
|
@@ -138,10 +138,10 @@ abstract class Stepped_Job extends Job {
|
|
138 |
*/
|
139 |
protected function start_step_cycle( $step_name ) {
|
140 |
|
141 |
-
$current_step_cycle =
|
142 |
'step_name' => $step_name,
|
143 |
'start_time' => microtime( true ),
|
144 |
-
|
145 |
|
146 |
wc_square()->log( "Starting step cycle: $step_name" );
|
147 |
|
@@ -160,7 +160,7 @@ abstract class Stepped_Job extends Job {
|
|
160 |
*/
|
161 |
protected function complete_step_cycle( $step_name, $is_successful = true, $error_message = '' ) {
|
162 |
|
163 |
-
$current_step_cycle = $this->get_attr( 'current_step_cycle',
|
164 |
|
165 |
if ( ! empty( $current_step_cycle ) ) {
|
166 |
|
@@ -177,7 +177,7 @@ abstract class Stepped_Job extends Job {
|
|
177 |
wc_square()->log( "Failed step cycle: $step_name (${current_step_cycle['runtime']}) - $error_message" );
|
178 |
}
|
179 |
|
180 |
-
$completed_cycles = $this->get_attr( 'completed_step_cycles',
|
181 |
$completed_cycles[] = $current_step_cycle;
|
182 |
$this->set_attr( 'completed_step_cycles', $completed_cycles );
|
183 |
}
|
@@ -217,12 +217,12 @@ abstract class Stepped_Job extends Job {
|
|
217 |
return;
|
218 |
}
|
219 |
|
220 |
-
$completed_steps = $this->get_attr( 'completed_steps',
|
221 |
|
222 |
-
$completed_steps[] =
|
223 |
'name' => $step_name,
|
224 |
'completion_time' => current_time( 'mysql' ),
|
225 |
-
|
226 |
|
227 |
$this->set_attr( 'completed_steps', $completed_steps );
|
228 |
|
25 |
|
26 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
+
defined( 'ABSPATH' ) || exit;
|
29 |
|
30 |
/**
|
31 |
* Stepped Job abstract.
|
105 |
|
106 |
$next_step = $this->get_next_step();
|
107 |
|
108 |
+
if ( is_callable( array( $this, $next_step ) ) ) {
|
109 |
|
110 |
$this->start_step_cycle( $next_step );
|
111 |
|
138 |
*/
|
139 |
protected function start_step_cycle( $step_name ) {
|
140 |
|
141 |
+
$current_step_cycle = array(
|
142 |
'step_name' => $step_name,
|
143 |
'start_time' => microtime( true ),
|
144 |
+
);
|
145 |
|
146 |
wc_square()->log( "Starting step cycle: $step_name" );
|
147 |
|
160 |
*/
|
161 |
protected function complete_step_cycle( $step_name, $is_successful = true, $error_message = '' ) {
|
162 |
|
163 |
+
$current_step_cycle = $this->get_attr( 'current_step_cycle', array() );
|
164 |
|
165 |
if ( ! empty( $current_step_cycle ) ) {
|
166 |
|
177 |
wc_square()->log( "Failed step cycle: $step_name (${current_step_cycle['runtime']}) - $error_message" );
|
178 |
}
|
179 |
|
180 |
+
$completed_cycles = $this->get_attr( 'completed_step_cycles', array() );
|
181 |
$completed_cycles[] = $current_step_cycle;
|
182 |
$this->set_attr( 'completed_step_cycles', $completed_cycles );
|
183 |
}
|
217 |
return;
|
218 |
}
|
219 |
|
220 |
+
$completed_steps = $this->get_attr( 'completed_steps', array() );
|
221 |
|
222 |
+
$completed_steps[] = array(
|
223 |
'name' => $step_name,
|
224 |
'completion_time' => current_time( 'mysql' ),
|
225 |
+
);
|
226 |
|
227 |
$this->set_attr( 'completed_steps', $completed_steps );
|
228 |
|
includes/Utilities/Encryption_Utility.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Utilities;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
@@ -67,8 +67,7 @@ class Encryption_Utility {
|
|
67 |
|
68 |
$this->cipher_method = $preferred_cipher_method;
|
69 |
|
70 |
-
// otherwise, throw a notice and continue with the default
|
71 |
-
} else {
|
72 |
|
73 |
$message = sprintf(
|
74 |
__( '%1$s encryption is not available on this site. %2$s will be used instead.', 'woocommerce-square' ),
|
23 |
|
24 |
namespace WooCommerce\Square\Utilities;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
67 |
|
68 |
$this->cipher_method = $preferred_cipher_method;
|
69 |
|
70 |
+
} else { // otherwise, throw a notice and continue with the default
|
|
|
71 |
|
72 |
$message = sprintf(
|
73 |
__( '%1$s encryption is not available on this site. %2$s will be used instead.', 'woocommerce-square' ),
|
includes/Utilities/Money_Utility.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Utilities;
|
25 |
|
26 |
-
defined( 'ABSPATH' )
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
@@ -49,10 +49,12 @@ class Money_Utility {
|
|
49 |
*/
|
50 |
public static function amount_to_money( $amount, $currency ) {
|
51 |
|
52 |
-
return new \SquareConnect\Model\Money(
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
56 |
}
|
57 |
|
58 |
|
@@ -106,7 +108,7 @@ class Money_Utility {
|
|
106 |
*/
|
107 |
public static function get_currency_decimals( $currency ) {
|
108 |
|
109 |
-
$other_currencies =
|
110 |
'BIF' => 0,
|
111 |
'CLP' => 0,
|
112 |
'DJF' => 0,
|
@@ -123,7 +125,7 @@ class Money_Utility {
|
|
123 |
'XAF' => 0,
|
124 |
'XOF' => 0,
|
125 |
'XPF' => 0,
|
126 |
-
|
127 |
|
128 |
if ( Framework\SV_WC_Plugin_Compatibility::is_wc_version_gte( '3.5' ) ) {
|
129 |
|
@@ -136,7 +138,7 @@ class Money_Utility {
|
|
136 |
|
137 |
} else {
|
138 |
|
139 |
-
$currencies =
|
140 |
$currency_codes = get_woocommerce_currencies();
|
141 |
|
142 |
foreach ( $currency_codes as $code => $name ) {
|
23 |
|
24 |
namespace WooCommerce\Square\Utilities;
|
25 |
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
|
49 |
*/
|
50 |
public static function amount_to_money( $amount, $currency ) {
|
51 |
|
52 |
+
return new \SquareConnect\Model\Money(
|
53 |
+
array(
|
54 |
+
'amount' => self::amount_to_cents( $amount, $currency ),
|
55 |
+
'currency' => $currency,
|
56 |
+
)
|
57 |
+
);
|
58 |
}
|
59 |
|
60 |
|
108 |
*/
|
109 |
public static function get_currency_decimals( $currency ) {
|
110 |
|
111 |
+
$other_currencies = array(
|
112 |
'BIF' => 0,
|
113 |
'CLP' => 0,
|
114 |
'DJF' => 0,
|
125 |
'XAF' => 0,
|
126 |
'XOF' => 0,
|
127 |
'XPF' => 0,
|
128 |
+
);
|
129 |
|
130 |
if ( Framework\SV_WC_Plugin_Compatibility::is_wc_version_gte( '3.5' ) ) {
|
131 |
|
138 |
|
139 |
} else {
|
140 |
|
141 |
+
$currencies = array();
|
142 |
$currency_codes = get_woocommerce_currencies();
|
143 |
|
144 |
foreach ( $currency_codes as $code => $name ) {
|
includes/Utilities/String_Utility.php
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WooCommerce Square
|
4 |
+
*
|
5 |
+
* This source file is subject to the GNU General Public License v3.0
|
6 |
+
* that is bundled with this package in the file license.txt.
|
7 |
+
* It is also available through the world-wide-web at this URL:
|
8 |
+
* http://www.gnu.org/licenses/gpl-3.0.html
|
9 |
+
* If you did not receive a copy of the license and are unable to
|
10 |
+
* obtain it through the world-wide-web, please send an email
|
11 |
+
* to license@woocommerce.com so we can send you a copy immediately.
|
12 |
+
*
|
13 |
+
* DISCLAIMER
|
14 |
+
*
|
15 |
+
* Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
|
16 |
+
* versions in the future. If you wish to customize WooCommerce Square for your
|
17 |
+
* needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
|
18 |
+
*
|
19 |
+
* @author WooCommerce
|
20 |
+
* @copyright Copyright: (c) 2019, Automattic, Inc.
|
21 |
+
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
22 |
+
*/
|
23 |
+
|
24 |
+
namespace WooCommerce\Square\Utilities;
|
25 |
+
|
26 |
+
defined( 'ABSPATH' ) || exit;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Helper for dealing with String values.
|
30 |
+
*
|
31 |
+
* @since 2.2.0
|
32 |
+
*/
|
33 |
+
class String_Utility {
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Truncates $string after a given $length if string is longer than
|
37 |
+
* $length.
|
38 |
+
*
|
39 |
+
* The last characters will be replaced with the $omission string
|
40 |
+
* for a total length not exceeding $length
|
41 |
+
*
|
42 |
+
* See SV_WC_Helper::str_truncate()
|
43 |
+
*
|
44 |
+
* @since 2.2.0
|
45 |
+
* @param string $string text to truncate
|
46 |
+
* @param int $length total desired length of string, including omission
|
47 |
+
* @param string $omission omission text, defaults to '...'
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
public static function truncate( $string, $length, $omission = '...' ) {
|
51 |
+
$string = self::to_ascii( $string );
|
52 |
+
|
53 |
+
// bail if string doesn't need to be truncated
|
54 |
+
if ( strlen( $string ) <= $length ) {
|
55 |
+
return $string;
|
56 |
+
}
|
57 |
+
|
58 |
+
$length -= strlen( $omission );
|
59 |
+
|
60 |
+
return substr( $string, 0, $length ) . $omission;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Returns a string with all non-ASCII characters removed. This is useful
|
65 |
+
* for any string functions that expect only ASCII chars and can't
|
66 |
+
* safely handle UTF-8. Note this only allows ASCII chars in the range
|
67 |
+
* 33-126 (newlines/carriage returns are stripped)
|
68 |
+
*
|
69 |
+
* See SV_WC_Helper::str_to_ascii()
|
70 |
+
*
|
71 |
+
* @since 2.2.0
|
72 |
+
* @param string $string string to make ASCII
|
73 |
+
* @return string
|
74 |
+
*/
|
75 |
+
public static function to_ascii( $string ) {
|
76 |
+
// strip ASCII chars 32 and under
|
77 |
+
$string = filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW );
|
78 |
+
|
79 |
+
// strip ASCII chars 127 and higher
|
80 |
+
return filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH );
|
81 |
+
}
|
82 |
+
}
|
readme.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
=== WooCommerce Square ===
|
2 |
-
Contributors: automattic, royho, woothemes, bor0
|
3 |
Tags: credit card, square, woocommerce, inventory sync
|
4 |
Requires at least: 4.6
|
5 |
-
Tested up to: 5.
|
6 |
Requires PHP: 5.6
|
7 |
-
Stable tag: 2.
|
8 |
License: GPLv3
|
9 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
10 |
|
@@ -72,6 +72,26 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o
|
|
72 |
|
73 |
== Changelog ==
|
74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
= 2.1.6 - 2020.07.15 =
|
76 |
* Fix - Make the "Sync Now" button disabled when no business location is set in Square settings.
|
77 |
* Fix - Enable checking/unchecking the Manage Stock setting for all variations.
|
1 |
=== WooCommerce Square ===
|
2 |
+
Contributors: woocommerce, automattic, royho, woothemes, bor0, mattdallan, menakas, chickenn00dle
|
3 |
Tags: credit card, square, woocommerce, inventory sync
|
4 |
Requires at least: 4.6
|
5 |
+
Tested up to: 5.5
|
6 |
Requires PHP: 5.6
|
7 |
+
Stable tag: 2.2.0
|
8 |
License: GPLv3
|
9 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
10 |
|
72 |
|
73 |
== Changelog ==
|
74 |
|
75 |
+
= 2.2.0 - 2020.08.31 =
|
76 |
+
* Feature - Import new product variations from square to existing products in WooCommerce. PR#475
|
77 |
+
* Feature - Variations that are removed from Square will now be removed from products in WooCommerce during import. PR#475
|
78 |
+
* Feature - Upgrade to the Square Payments and Refunds API. PR#408
|
79 |
+
* Feature - New orders can be refunded up to one year after payment (up from 120 days). PR#408
|
80 |
+
* Fix - Only import products from Square that have non-empty SKUs. PR#475
|
81 |
+
* Fix - Empty product categories imported from Square into WooCommerce. PR#475
|
82 |
+
* Fix - Assign existing products to new categories imported from Square. PR#475
|
83 |
+
* Fix - Prevents loading of Square Assets on all pages except My Account -> Payment Methods & Checkout. PR#469
|
84 |
+
* Fix - Square Product Import & Product Manual Sync not triggering on mobile browsers. PR#472
|
85 |
+
* Fix - 3D Secure Verification Token is missing, Intent mismatch and other checkout errors related to SCA for merchants outside of the EU. PR#471
|
86 |
+
* Fix - Updated some of our documentation and support links in admin notices so they no longer redirect to an old URL or a 404 page. PR#474
|
87 |
+
* Fix - Use pagination to fetch inventory counts from Square. PR#478
|
88 |
+
* Fix - Display WooCommerce checkout validation errors along with Square payment form errors. PR#476
|
89 |
+
* Fix - Switching between sandbox and production environments will now show correct business locations. PR#462
|
90 |
+
* Fix - Don't wipe a customer's saved cards on when we receive an API error. PR#460
|
91 |
+
* Fix - Exclude draft and pending products from syncing from WooCommerce to Square. PR#484
|
92 |
+
* Fix - DevTools errors caused by missing minified JS files.
|
93 |
+
* Fix - PHP errors when syncing large amounts of products (`get_data() on null` and `getCursor() on a string`). PR#497
|
94 |
+
|
95 |
= 2.1.6 - 2020.07.15 =
|
96 |
* Fix - Make the "Sync Now" button disabled when no business location is set in Square settings.
|
97 |
* Fix - Enable checking/unchecking the Manage Stock setting for all variations.
|
templates/emails/plain/square-email.php
CHANGED
@@ -21,7 +21,7 @@
|
|
21 |
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
22 |
*/
|
23 |
|
24 |
-
defined( 'ABSPATH' )
|
25 |
|
26 |
/**
|
27 |
* Square plain email template.
|
21 |
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
22 |
*/
|
23 |
|
24 |
+
defined( 'ABSPATH' ) || exit;
|
25 |
|
26 |
/**
|
27 |
* Square plain email template.
|
templates/emails/square-email.php
CHANGED
@@ -21,7 +21,7 @@
|
|
21 |
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
22 |
*/
|
23 |
|
24 |
-
defined( 'ABSPATH' )
|
25 |
|
26 |
/**
|
27 |
* Square html email template.
|
21 |
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
22 |
*/
|
23 |
|
24 |
+
defined( 'ABSPATH' ) || exit;
|
25 |
|
26 |
/**
|
27 |
* Square html email template.
|
vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets/js/frontend/sv-wc-payment-gateway-apple-pay.min.js.map
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"version": 3,
|
3 |
+
"file": "sv-wc-payment-gateway-apple-pay.min.js",
|
4 |
+
"sourceRoot": "",
|
5 |
+
"sources": [
|
6 |
+
"sv-wc-payment-gateway-apple-pay.coffee"
|
7 |
+
],
|
8 |
+
"names": [],
|
9 |
+
"mappings": "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"
|
10 |
+
}
|
vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets/js/frontend/sv-wc-payment-gateway-my-payment-methods.min.js.map
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"version": 3,
|
3 |
+
"file": "sv-wc-payment-gateway-my-payment-methods.min.js",
|
4 |
+
"sourceRoot": "",
|
5 |
+
"sources": [
|
6 |
+
"sv-wc-payment-gateway-my-payment-methods.coffee"
|
7 |
+
],
|
8 |
+
"names": [],
|
9 |
+
"mappings": ";AAAA;;;;;;;;;AAAA;AAAA,MAAA;;EAQA,MAAA,CAAQ,QAAR,CAAkB,CAAC,KAAnB,CAAyB,SAAC,CAAD;IACxB;WAKM,MAAM,CAAC;MAaC,uCAAE,IAAF;;;;QAEZ,IAAC,CAAA,EAAD,GAAc,IAAI,CAAC;QACnB,IAAC,CAAA,IAAD,GAAc,IAAI,CAAC;QACnB,IAAC,CAAA,IAAD,GAAc,IAAI,CAAC;QACnB,IAAC,CAAA,QAAD,GAAc,IAAI,CAAC;QACnB,IAAC,CAAA,UAAD,GAAc,IAAI,CAAC;QAGnB,IAAA,CAA8G,IAAI,CAAC,eAAnH;UAAA,CAAA,CAAG,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,qBAAhB,CAAsC,CAAC,IAAvC,CAA6C,gDAA7C,CAA+F,CAAC,IAAhG,CAAA,EAAA;;QAGA,CAAA,CAAG,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,qCAAhB,CAAsD,CAAC,MAAvD,CAAA;QAGA,CAAA,CAAG,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,qBAAhB,CAAsC,CAAC,EAAvC,CAA2C,OAA3C,EAAoD,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,8CAAjE,EAAgH,CAAA,SAAA,KAAA;iBAAA,SAAE,KAAF;mBAAa,KAAI,CAAC,WAAL,CAAkB,KAAlB;UAAb;QAAA,CAAA,CAAA,CAAA,IAAA,CAAhH;QAGA,CAAA,CAAG,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,qBAAhB,CAAsC,CAAC,EAAvC,CAA2C,OAA3C,EAAoD,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,8CAAjE,EAAgH,CAAA,SAAA,KAAA;iBAAA,SAAE,KAAF;mBAAa,KAAI,CAAC,WAAL,CAAkB,KAAlB;UAAb;QAAA,CAAA,CAAA,CAAA,IAAA,CAAhH;QAGA,CAAA,CAAG,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,qBAAhB,CAAsC,CAAC,EAAvC,CAA2C,OAA3C,EAAoD,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,qDAAjE,EAAuH,CAAA,SAAA,KAAA;iBAAA,SAAE,KAAF;mBAAa,KAAI,CAAC,WAAL,CAAkB,KAAlB;UAAb;QAAA,CAAA,CAAA,CAAA,IAAA,CAAvH;QAGA,CAAA,CAAG,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,qBAAhB,CAAsC,CAAC,EAAvC,CAA2C,OAA3C,EAAoD,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,gDAAjE,EAAkH,CAAA,SAAA,KAAA;iBAAA,SAAE,KAAF;YAEjH,IAAG,CAAA,CAAG,KAAK,CAAC,aAAT,CAAwB,CAAC,QAAzB,CAAmC,UAAnC,CAAA,IAAmD,CAAI,OAAA,CAAS,KAAC,CAAA,IAAI,CAAC,UAAf,CAA1D;qBACC,KAAK,CAAC,cAAN,CAAA,EADD;;UAFiH;QAAA,CAAA,CAAA,CAAA,IAAA,CAAlH;QAQA,CAAA,CAAG,qCAAH,CAA0C,CAAC,KAA3C,CAAiD,SAAE,KAAF;UAChD,IAA0B,CAAA,CAAG,IAAH,CAAS,CAAC,QAAV,CAAoB,UAApB,CAA1B;mBAAA,KAAK,CAAC,cAAN,CAAA,EAAA;;QADgD,CAAjD;MAhCY;;8CAyCb,WAAA,GAAa,SAAE,KAAF;AAEZ,YAAA;QAAA,KAAK,CAAC,cAAN,CAAA;QAEA,MAAA,GAAS,CAAA,CAAG,KAAK,CAAC,aAAT;QACT,GAAA,GAAS,MAAM,CAAC,OAAP,CAAgB,IAAhB;QAET,GAAG,CAAC,IAAJ,CAAU,OAAV,CAAmB,CAAC,IAApB,CAAA;QACA,GAAG,CAAC,IAAJ,CAAU,OAAV,CAAmB,CAAC,IAApB,CAAA;QACA,GAAG,CAAC,QAAJ,CAAc,SAAd;QAGA,MAAM,CAAC,IAAP,CAAa,IAAC,CAAA,IAAI,CAAC,aAAnB,CAAkC,CAAC,WAAnC,CAAgD,qBAAhD,CAAuE,CAAC,QAAxE,CAAkF,4BAAlF,CAAgH,CAAC,WAAjH,CAA8H,QAA9H;QAEA,MAAM,CAAC,QAAP,CAAiB,sBAAjB,CAAyC,CAAC,IAA1C,CAAA;QACA,MAAM,CAAC,QAAP,CAAiB,wBAAjB,CAA2C,CAAC,IAA5C,CAAA;eAEA,IAAI,CAAC,iBAAL,CAAA;MAjBY;;8CAyBb,WAAA,GAAa,SAAE,KAAF;AAEZ,YAAA;QAAA,KAAK,CAAC,cAAN,CAAA;QAEA,MAAA,GAAS,CAAA,CAAG,KAAK,CAAC,aAAT;QACT,GAAA,GAAS,MAAM,CAAC,OAAP,CAAgB,IAAhB;QAET,IAAI,CAAC,QAAL,CAAA;QAGA,GAAG,CAAC,IAAJ,CAAU,QAAV,CAAoB,CAAC,MAArB,CAAA;QAEA,IAAA,GACC;UAAA,MAAA,EAAU,KAAA,GAAM,IAAC,CAAA,EAAP,GAAU,sBAApB;UACA,KAAA,EAAU,IAAC,CAAA,UADX;UAEA,QAAA,EAAU,GAAG,CAAC,IAAJ,CAAU,UAAV,CAFV;UAGA,IAAA,EAAU,GAAG,CAAC,IAAJ,CAAU,aAAV,CAAyB,CAAC,SAA1B,CAAA,CAHV;;eAKD,CAAC,CAAC,IAAF,CAAQ,IAAC,CAAA,QAAT,EAAmB,IAAnB,CAEC,CAAC,IAFF,CAEO,CAAA,SAAA,KAAA;iBAAA,SAAE,QAAF;YAEL,IAAA,CAAuD,QAAQ,CAAC,OAAhE;AAAA,qBAAO,KAAI,CAAC,aAAL,CAAoB,GAApB,EAAyB,QAAQ,CAAC,IAAlC,EAAP;;YAGA,IAAG,QAAQ,CAAC,IAAI,CAAC,UAAjB;cACC,GAAG,CAAC,QAAJ,CAAA,CAAc,CAAC,IAAf,CAAqB,MAAA,GAAO,KAAC,CAAA,IAAR,GAAa,+BAAlC,CAAkE,CAAC,KAAnE,CAAA,CAA0E,CAAC,QAA3E,CAAqF,OAArF,CAA8F,CAAC,IAA/F,CAAqG,OAArG,CAA8G,CAAC,IAA/G,CAAqH,SAArH,EAAgI,KAAhI,EADD;;YAGA,IAAG,0BAAH;cACC,GAAG,CAAC,WAAJ,CAAiB,QAAQ,CAAC,IAAI,CAAC,IAA/B,EADD;;YAGA,IAAG,2BAAH;cACC,KAAC,CAAA,UAAD,GAAc,QAAQ,CAAC,IAAI,CAAC,MAD7B;;mBAGA,KAAI,CAAC,kBAAL,CAAA;UAdK;QAAA,CAAA,CAAA,CAAA,IAAA,CAFP,CAkBC,CAAC,IAlBF,CAkBO,CAAA,SAAA,KAAA;iBAAA,SAAE,KAAF,EAAS,UAAT,EAAqB,KAArB;mBAEL,KAAI,CAAC,aAAL,CAAoB,GAApB,EAAyB,KAAzB;UAFK;QAAA,CAAA,CAAA,CAAA,IAAA,CAlBP,CAsBC,CAAC,MAtBF,CAsBS,CAAA,SAAA,KAAA;iBAAA,SAAA;mBAEP,KAAI,CAAC,UAAL,CAAA;UAFO;QAAA,CAAA,CAAA,CAAA,IAAA,CAtBT;MAlBY;;8CAkDb,WAAA,GAAa,SAAE,KAAF;AAEZ,YAAA;QAAA,KAAK,CAAC,cAAN,CAAA;QAEA,MAAA,GAAS,CAAA,CAAG,KAAK,CAAC,aAAT;QACT,GAAA,GAAS,MAAM,CAAC,OAAP,CAAgB,IAAhB;QAET,GAAG,CAAC,IAAJ,CAAU,OAAV,CAAmB,CAAC,IAApB,CAAA;QACA,GAAG,CAAC,IAAJ,CAAU,OAAV,CAAmB,CAAC,IAApB,CAAA;QACA,GAAG,CAAC,WAAJ,CAAiB,SAAjB;QAGA,MAAM,CAAC,WAAP,CAAoB,4BAApB,CAAkD,CAAC,QAAnD,CAA6D,qBAA7D,CAAoF,CAAC,IAArF,CAA2F,IAAC,CAAA,IAAI,CAAC,WAAjG,CAA8G,CAAC,QAA/G,CAAyH,QAAzH;QAEA,MAAM,CAAC,QAAP,CAAiB,sBAAjB,CAAyC,CAAC,IAA1C,CAAA;QACA,MAAM,CAAC,QAAP,CAAiB,wBAAjB,CAA2C,CAAC,IAA5C,CAAA;eAEA,IAAI,CAAC,kBAAL,CAAA;MAjBY;;8CA0Bb,iBAAA,GAAmB,SAAA;QAGlB,CAAA,CAAG,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,qBAAhB,CAAsC,CAAC,QAAvC,CAAiD,SAAjD;eAGA,CAAA,CAAG,qCAAH,CAA0C,CAAC,QAA3C,CAAqD,UAArD;MANkB;;8CAYnB,kBAAA,GAAoB,SAAA;QAGnB,CAAA,CAAG,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,qBAAhB,CAAsC,CAAC,WAAvC,CAAoD,SAApD;eAGA,CAAA,CAAG,qCAAH,CAA0C,CAAC,WAA3C,CAAwD,UAAxD;MANmB;;8CAYpB,QAAA,GAAU,SAAA;eAAG,CAAA,CAAG,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,qBAAhB,CAAsC,CAAC,MAAvC,CAA+C,KAA/C,CAAsD,CAAC,KAAvD,CAA8D;UAAA,OAAA,EAAS,IAAT;UAAe,UAAA,EAAY;YAAA,UAAA,EAAY,MAAZ;YAAoB,OAAA,EAAS,GAA7B;WAA3B;SAA9D;MAAH;;8CAMV,UAAA,GAAY,SAAA;eAAG,CAAA,CAAG,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,qBAAhB,CAAsC,CAAC,MAAvC,CAA+C,KAA/C,CAAsD,CAAC,OAAvD,CAAA;MAAH;;8CAUZ,aAAA,GAAe,SAAE,GAAF,EAAO,KAAP,EAAc,OAAd;AAEd,YAAA;;UAF4B,UAAU;;QAEtC,OAAO,CAAC,KAAR,CAAe,KAAf;QAEA,IAAA,CAAkC,OAAlC;UAAA,OAAA,GAAU,IAAC,CAAA,IAAI,CAAC,WAAhB;;QAEA,OAAA,GAAU,CAAA,CAAG,MAAA,GAAO,IAAC,CAAA,IAAR,GAAa,iCAAhB,CAAkD,CAAC,IAAnD,CAAA;eAEV,CAAA,CAAG,iCAAA,GAAoC,OAApC,GAA8C,IAA9C,GAAqD,OAArD,GAA+D,YAAlE,CAAgF,CAAC,WAAjF,CAA8F,GAA9F,CAAmG,CAAC,IAApG,CAA0G,IAA1G,CAAgH,CAAC,KAAjH,CAAwH,IAAxH,CAA8H,CAAC,OAA/H,CAAwI,GAAxI;MARc;;;;;EAzMQ,CAAzB;AARA"
|
10 |
+
}
|
vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets/js/frontend/sv-wc-payment-gateway-payment-form.min.js.map
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"version": 3,
|
3 |
+
"file": "sv-wc-payment-gateway-payment-form.min.js",
|
4 |
+
"sourceRoot": "",
|
5 |
+
"sources": [
|
6 |
+
"sv-wc-payment-gateway-payment-form.coffee"
|
7 |
+
],
|
8 |
+
"names": [],
|
9 |
+
"mappings": "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"
|
10 |
+
}
|
woocommerce-square.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
* Plugin Name: WooCommerce Square
|
4 |
-
* Version: 2.
|
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
|
@@ -19,10 +19,10 @@
|
|
19 |
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
20 |
*
|
21 |
* WC requires at least: 3.0
|
22 |
-
* WC tested up to: 4.
|
23 |
*/
|
24 |
|
25 |
-
defined( 'ABSPATH' )
|
26 |
|
27 |
require_once( plugin_dir_path( __FILE__ ) . 'vendor/prospress/action-scheduler/action-scheduler.php' );
|
28 |
|
@@ -211,23 +211,35 @@ class WooCommerce_Square_Loader {
|
|
211 |
|
212 |
if ( ! $this->is_wp_compatible() ) {
|
213 |
|
214 |
-
$this->add_admin_notice(
|
215 |
-
'
|
216 |
-
'
|
217 |
-
|
218 |
-
|
219 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
}
|
221 |
|
222 |
if ( ! $this->is_wc_compatible() ) {
|
223 |
|
224 |
-
$this->add_admin_notice(
|
225 |
-
'
|
226 |
-
'
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
}
|
232 |
}
|
233 |
|
@@ -307,7 +319,7 @@ class WooCommerce_Square_Loader {
|
|
307 |
|
308 |
$this->notices[ $slug ] = array(
|
309 |
'class' => $class,
|
310 |
-
'message' => $message
|
311 |
);
|
312 |
}
|
313 |
|
1 |
<?php
|
2 |
/**
|
3 |
* Plugin Name: WooCommerce Square
|
4 |
+
* Version: 2.2.0
|
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
|
19 |
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
20 |
*
|
21 |
* WC requires at least: 3.0
|
22 |
+
* WC tested up to: 4.4
|
23 |
*/
|
24 |
|
25 |
+
defined( 'ABSPATH' ) || exit;
|
26 |
|
27 |
require_once( plugin_dir_path( __FILE__ ) . 'vendor/prospress/action-scheduler/action-scheduler.php' );
|
28 |
|
211 |
|
212 |
if ( ! $this->is_wp_compatible() ) {
|
213 |
|
214 |
+
$this->add_admin_notice(
|
215 |
+
'update_wordpress',
|
216 |
+
'error',
|
217 |
+
sprintf(
|
218 |
+
'%s requires WordPress version %s or higher. Please %supdate WordPress »%s',
|
219 |
+
'<strong>' . self::PLUGIN_NAME .
|
220 |
+
'</strong>',
|
221 |
+
self::MINIMUM_WP_VERSION,
|
222 |
+
'<a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">',
|
223 |
+
'</a>'
|
224 |
+
)
|
225 |
+
);
|
226 |
}
|
227 |
|
228 |
if ( ! $this->is_wc_compatible() ) {
|
229 |
|
230 |
+
$this->add_admin_notice(
|
231 |
+
'update_woocommerce',
|
232 |
+
'error',
|
233 |
+
sprintf(
|
234 |
+
'%1$s requires WooCommerce version %2$s or higher. Please %3$supdate WooCommerce%4$s to the latest version, or %5$sdownload the minimum required version »%6$s',
|
235 |
+
'<strong>' . self::PLUGIN_NAME . '</strong>',
|
236 |
+
self::MINIMUM_WC_VERSION,
|
237 |
+
'<a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">',
|
238 |
+
'</a>',
|
239 |
+
'<a href="' . esc_url( 'https://downloads.wordpress.org/plugin/woocommerce.' . self::MINIMUM_WC_VERSION . '.zip' ) . '">',
|
240 |
+
'</a>'
|
241 |
+
)
|
242 |
+
);
|
243 |
}
|
244 |
}
|
245 |
|
319 |
|
320 |
$this->notices[ $slug ] = array(
|
321 |
'class' => $class,
|
322 |
+
'message' => $message,
|
323 |
);
|
324 |
}
|
325 |
|