PluginProbe ʕ •ᴥ•ʔ
WooCommerce Square / 2.2.2
WooCommerce Square v2.2.2
5.5.0 5.4.3 5.4.2 5.4.1 5.4.0 trunk 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.7.0 2.8.0 2.9.0 2.9.1 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.2.0 3.3.0 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.7.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 4.0.0 4.1.0 4.2.0 4.2.1 4.2.2 4.2.3 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.8.4 4.8.5 4.8.6 4.8.7 4.8.8 4.9.0 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.6 4.9.7 4.9.8 4.9.9 5.0.0 5.0.1 5.1.0 5.1.1 5.1.2 5.2.0 5.3.0 5.3.1 5.3.2 5.3.3
woocommerce-square / includes / AJAX.php
woocommerce-square / includes Last commit date
API 6 years ago Admin 5 years ago Emails 6 years ago Gateway 6 years ago Handlers 5 years ago Sync 5 years ago Utilities 6 years ago AJAX.php 5 years ago API.php 6 years ago Admin.php 6 years ago Functions.php 6 years ago Gateway.php 5 years ago Lifecycle.php 6 years ago Plugin.php 5 years ago Settings.php 6 years ago
AJAX.php
332 lines
1 <?php
2 /**
3 * WooCommerce Square
4 *
5 * This source file is subject to the GNU General Public License v3.0
6 * that is bundled with this package in the file license.txt.
7 * It is also available through the world-wide-web at this URL:
8 * http://www.gnu.org/licenses/gpl-3.0.html
9 * If you did not receive a copy of the license and are unable to
10 * obtain it through the world-wide-web, please send an email
11 * to license@woocommerce.com so we can send you a copy immediately.
12 *
13 * DISCLAIMER
14 *
15 * Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
16 * versions in the future. If you wish to customize WooCommerce Square for your
17 * needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
18 *
19 * @author WooCommerce
20 * @copyright Copyright: (c) 2019, Automattic, Inc.
21 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
22 */
23
24 namespace WooCommerce\Square;
25
26 defined( 'ABSPATH' ) || exit;
27
28 use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
29 use WooCommerce\Square\Handlers\Product;
30 use WooCommerce\Square\Handlers\Sync;
31 use WooCommerce\Square\Sync\Records;
32
33 /**
34 * AJAX handler.
35 *
36 * @since 2.0.0
37 */
38 class AJAX {
39
40
41 /**
42 * Adds AJAX action callbacks.
43 *
44 * @since 2.0.0
45 */
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
67 /**
68 * Checks if a product is set to be synced with Square.
69 *
70 * @internal
71 *
72 * @since 2.0.0
73 *
74 * @deprecated 2.1.6
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'] ) ) ) {
82
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 {
90 if ( ! Product::has_sku( $product ) ) {
91 wp_send_json_error( 'missing_sku' );
92 }
93 }
94 wp_send_json_success( Product::is_synced_with_square( $product ) ? 'yes' : 'no' );
95 }
96
97 wp_send_json_error( 'invalid_product' );
98 }
99
100
101 /**
102 * Fetches product stock data from Square.
103 *
104 * @internal
105 *
106 * @since 2.0.0
107 */
108 public function fetch_product_stock_with_square() {
109
110 check_ajax_referer( 'fetch-product-stock-with-square', 'security' );
111
112 $fix_error = __( 'Please mark product as un-synced and save, then synced again.', 'woocommerce-square' );
113
114 if ( isset( $_REQUEST['product_id'] ) && ( $product = wc_get_product( $_REQUEST['product_id'] ) ) ) {
115
116 try {
117
118 $product = Product::update_stock_from_square( $product );
119
120 wp_send_json_success( $product->get_stock_quantity() );
121
122 } catch ( Framework\SV_WC_Plugin_Exception $exception ) {
123
124 /* translators: Placeholders: %1$s = error message, %2$s = help text */
125 wp_send_json_error( sprintf( __( 'Unable to fetch inventory: %1$s. %2$s', 'woocommerce-square' ), $exception->getMessage(), $fix_error ) );
126 }
127 }
128
129 /* translators: Placeholders: %s = help text */
130 wp_send_json_error( sprintf( __( 'Error finding item in Square. %s', 'woocommerce-square' ), $fix_error ) );
131 }
132
133
134 /**
135 * Starts importing products from Square.
136 *
137 * @internal
138 *
139 * @since 2.0.0
140 */
141 public function import_products_from_square() {
142
143 check_ajax_referer( 'import-products-from-square', 'security' );
144
145 $started = wc_square()->get_sync_handler()->start_product_import( ! empty( $_POST['dispatch'] ), ( ! empty( $_POST['update_during_import'] ) && 'true' === $_POST['update_during_import'] ) );
146
147 if ( ! $started ) {
148 wp_send_json_error( __( 'Could not start import. Please try again.', 'woocommerce-square' ) );
149 }
150
151 wp_send_json_success( __( 'Your products are being imported in the background! This may take some time to complete.', 'woocommerce-square' ) );
152 }
153
154
155 /**
156 * Starts syncing products with Square.
157 *
158 * @internal
159 *
160 * @since 2.0.0
161 */
162 public function sync_products_with_square() {
163
164 check_ajax_referer( 'sync-products-with-square', 'security' );
165
166 $started = wc_square()->get_sync_handler()->start_manual_sync( ! empty( $_POST['dispatch'] ) );
167
168 if ( ! $started ) {
169 wp_send_json_error();
170 }
171
172 wp_send_json_success();
173 }
174
175
176 /**
177 * Handles sync records actions.
178 *
179 * @internal
180 *
181 * @since 2.0.0
182 */
183 public function handle_sync_records() {
184
185 check_ajax_referer( 'handle-sync-with-square-records', 'security' );
186
187 $error = '';
188
189 if ( isset( $_POST['id'], $_POST['handle'] ) ) {
190
191 $id = $_POST['id'];
192 $action = $_POST['handle'];
193
194 if ( 'all' === $id && 'delete' === $action ) {
195
196 $outcome = Records::clean_records();
197 $error = esc_html__( 'Could not delete records.', 'woocommerce-square' );
198
199 } elseif ( is_string( $id ) && '' !== $id ) {
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() ) ) {
223 $record->resolve();
224 $outcome = Product::unset_synced_with_square( $product ) && $record->save();
225 }
226
227 $error = esc_html__( 'Could not unsync product.', 'woocommerce-square' );
228
229 break;
230 }
231 }
232
233 if ( ! empty( $outcome ) ) {
234 wp_send_json_success( $outcome );
235 }
236 }
237
238 /* translators: Placeholder: %s - error message */
239 wp_send_json_error( sprintf( __( 'An error occurred. %s', 'woocommerce-square' ), $error ) );
240 }
241
242
243 /**
244 * Gets a sync job status.
245 *
246 * Also bumps the job progression (useful for when background processing isn't available).
247 *
248 * @internal
249 *
250 * @since 2.0.0
251 */
252 public function get_sync_with_square_job_status() {
253
254 check_ajax_referer( 'get-sync-with-square-status', 'security' );
255
256 $job_id = isset( $_POST['job_id'] ) ? $_POST['job_id'] : null;
257
258 if ( $job_id && ( $handler = wc_square()->get_background_job_handler() ) ) {
259
260 try {
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() );
280 }
281 }
282
283 /* translators: Placeholder: %s - sync job ID */
284 wp_send_json_error( sprintf( esc_html__( 'No sync job in progress found %s', 'woocommerce-square' ), is_string( $job_id ) ? $job_id : null ) );
285 }
286
287 /**
288 * Get sync status, variable status, and edit url for product
289 *
290 * Used to manipulate quick edit menu for product
291 *
292 * @since 2.1.6
293 */
294 public function get_quick_edit_product_details() {
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
302 if ( $is_variable && $product->has_child() ) {
303 if ( Product::has_multiple_variation_attributes( $product ) ) {
304 wp_send_json_error( 'multiple_attributes' );
305 }
306
307 if ( ! Product::has_sku( $product ) ) {
308 wp_send_json_error( 'missing_variation_sku' );
309 }
310 } else {
311 if ( ! Product::has_sku( $product ) ) {
312 wp_send_json_error( 'missing_sku' );
313 }
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 }
330
331 }
332