PluginProbe ʕ •ᴥ•ʔ
WooCommerce Square / 4.5.0
WooCommerce Square v4.5.0
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 3 years ago Admin 2 years ago Emails 2 years ago Framework 2 years ago Gateway 2 years ago Handlers 2 years ago Sync 2 years ago Utilities 3 years ago AJAX.php 3 years ago API.php 3 years ago Admin.php 3 years ago Functions.php 3 years ago Gateway.php 2 years ago Lifecycle.php 3 years ago Plugin.php 2 years ago Settings.php 2 years ago WC_Order_Square.php 2 years ago
AJAX.php
319 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 GNU General Public License v3.0 or later
9 * If you did not receive a copy of the license and are unable to
10 * obtain it through the world-wide-web, please send an email
11 * to license@woocommerce.com so we can send you a copy immediately.
12 *
13 * DISCLAIMER
14 *
15 * Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
16 * versions in the future. If you wish to customize WooCommerce Square for your
17 * needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
18 *
19 * @author WooCommerce
20 * @copyright Copyright: (c) 2019, Automattic, Inc.
21 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
22 */
23
24 namespace WooCommerce\Square;
25
26 defined( 'ABSPATH' ) || exit;
27
28 use WooCommerce\Square\Handlers\Product;
29 use WooCommerce\Square\Sync\Records;
30
31 /**
32 * AJAX handler.
33 *
34 * @since 2.0.0
35 */
36 class AJAX {
37
38
39 /**
40 * Adds AJAX action callbacks.
41 *
42 * @since 2.0.0
43 */
44 public function __construct() {
45
46 // check an individual product sync status
47 add_action( 'wp_ajax_wc_square_get_quick_edit_product_details', array( $this, 'get_quick_edit_product_details' ) );
48
49 // fetch product stock from Square
50 add_action( 'wp_ajax_wc_square_fetch_product_stock_with_square', array( $this, 'fetch_product_stock_with_square' ) );
51
52 add_action( 'wp_ajax_wc_square_import_products_from_square', array( $this, 'import_products_from_square' ) );
53
54 // sync all products with Square
55 add_action( 'wp_ajax_wc_square_sync_products_with_square', array( $this, 'sync_products_with_square' ) );
56
57 // handle sync records
58 add_action( 'wp_ajax_wc_square_handle_sync_records', array( $this, 'handle_sync_records' ) );
59
60 // get the status of a sync job
61 add_action( 'wp_ajax_wc_square_get_sync_with_square_status', array( $this, 'get_sync_with_square_job_status' ) );
62 }
63
64 /**
65 * Fetches product stock data from Square.
66 *
67 * @internal
68 *
69 * @since 2.0.0
70 */
71 public function fetch_product_stock_with_square() {
72 check_ajax_referer( 'fetch-product-stock-with-square', 'security' );
73
74 if ( ! current_user_can( 'edit_products' ) ) {
75 wp_send_json_error( __( 'Invalid permissions.', 'woocommerce-square' ) );
76 }
77
78 $fix_error = __( 'Please mark product as un-synced and save, then synced again.', 'woocommerce-square' );
79 $product = isset( $_REQUEST['product_id'] ) ? wc_get_product( (int) $_REQUEST['product_id'] ) : false;
80
81 if ( $product ) {
82
83 try {
84 $product = Product::update_stock_from_square( $product );
85 $response = array(
86 'quantity' => $product->get_stock_quantity(),
87 'manage_stock' => $product->get_manage_stock(),
88 );
89
90 wp_send_json_success( $response );
91
92 } catch ( \Exception $exception ) {
93
94 /* translators: Placeholders: %1$s = error message, %2$s = help text */
95 wp_send_json_error( sprintf( __( 'Unable to fetch inventory: %1$s. %2$s', 'woocommerce-square' ), $exception->getMessage(), $fix_error ) );
96 }
97 }
98
99 /* translators: Placeholders: %s = help text */
100 wp_send_json_error( sprintf( __( 'Error finding item in Square. %s', 'woocommerce-square' ), $fix_error ) );
101 }
102
103
104 /**
105 * Starts importing products from Square.
106 *
107 * @internal
108 *
109 * @since 2.0.0
110 */
111 public function import_products_from_square() {
112
113 check_ajax_referer( 'import-products-from-square', 'security' );
114
115 // The edit_others_shop_orders capability is used to determine if the user can access these settings.
116 if ( ! current_user_can( 'edit_others_shop_orders' ) ) {
117 wp_send_json_error( __( 'Could not start import. Invalid permissions.', 'woocommerce-square' ) );
118 }
119
120 $started = wc_square()->get_sync_handler()->start_product_import( ( ! empty( $_POST['update_during_import'] ) && 'true' === $_POST['update_during_import'] ) );
121
122 if ( ! $started ) {
123 wp_send_json_error( __( 'Could not start import. Please try again.', 'woocommerce-square' ) );
124 }
125
126 wp_send_json_success( __( 'Your products are being imported in the background! This may take some time to complete.', 'woocommerce-square' ) );
127 }
128
129
130 /**
131 * Starts syncing products with Square.
132 *
133 * @internal
134 *
135 * @since 2.0.0
136 */
137 public function sync_products_with_square() {
138
139 check_ajax_referer( 'sync-products-with-square', 'security' );
140
141 // The edit_others_shop_orders capability is used to determine if the user can access these settings.
142 if ( ! current_user_can( 'edit_others_shop_orders' ) ) {
143 wp_send_json_error();
144 }
145
146 $started = wc_square()->get_sync_handler()->start_manual_sync();
147
148 if ( ! $started ) {
149 wp_send_json_error();
150 }
151
152 wp_send_json_success();
153 }
154
155
156 /**
157 * Handles sync records actions.
158 *
159 * @internal
160 *
161 * @since 2.0.0
162 */
163 public function handle_sync_records() {
164
165 check_ajax_referer( 'handle-sync-with-square-records', 'security' );
166
167 if ( ! current_user_can( 'edit_others_shop_orders' ) ) {
168 wp_send_json_error( __( 'An error occurred. Invalid permissions.', 'woocommerce-square' ) );
169 }
170
171 $error = '';
172
173 if ( isset( $_POST['id'], $_POST['handle'] ) ) {
174
175 $id = sanitize_key( $_POST['id'] );
176 $action = sanitize_key( $_POST['handle'] );
177
178 if ( 'all' === $id && 'delete' === $action ) {
179
180 $outcome = Records::clean_records();
181 $error = esc_html__( 'Could not delete records.', 'woocommerce-square' );
182
183 } elseif ( is_string( $id ) && '' !== $id ) {
184
185 switch ( $action ) {
186
187 case 'delete':
188 $outcome = Records::delete_record( $id );
189 $error = esc_html__( 'Could not delete record.', 'woocommerce-square' );
190
191 break;
192
193 case 'resolve':
194 $record = Records::get_record( $id );
195 if ( $record ) {
196 $record->resolve();
197 $outcome = $record->save();
198 }
199
200 $error = esc_html__( 'Could not resolve record.', 'woocommerce-square' );
201
202 break;
203
204 case 'unsync':
205 $record = Records::get_record( $id );
206 $product = $record ? $record->get_product() : null;
207 if ( $product ) {
208 $record->resolve();
209 $outcome = Product::unset_synced_with_square( $product ) && $record->save();
210 }
211
212 $error = esc_html__( 'Could not unsync product.', 'woocommerce-square' );
213
214 break;
215 }
216 }
217
218 if ( ! empty( $outcome ) ) {
219 wp_send_json_success( $outcome );
220 }
221 }
222
223 /* translators: Placeholder: %s - error message */
224 wp_send_json_error( sprintf( __( 'An error occurred. %s', 'woocommerce-square' ), $error ) );
225 }
226
227
228 /**
229 * Gets a sync job status.
230 *
231 * Also bumps the job progression (useful for when background processing isn't available).
232 *
233 * @internal
234 *
235 * @since 2.0.0
236 */
237 public function get_sync_with_square_job_status() {
238 check_ajax_referer( 'get-sync-with-square-status', 'security' );
239
240 if ( ! current_user_can( 'edit_others_shop_orders' ) ) {
241 wp_send_json_error( __( 'An error occurred. Invalid permissions.', 'woocommerce-square' ) );
242 }
243
244 $job_id = isset( $_POST['job_id'] ) ? sanitize_key( $_POST['job_id'] ) : null;
245
246 if ( $job_id ) {
247 try {
248 $handler = wc_square()->get_background_job_handler();
249 $job_in_progress = $handler ? $handler->get_job( $job_id ) : false;
250 if ( $job_in_progress ) {
251
252 $result = array(
253 'action' => $job_in_progress->action,
254 'id' => $job_in_progress->id,
255 'job_products_count' => count( $job_in_progress->product_ids ),
256 'percentage' => ( (float) count( $job_in_progress->processed_product_ids ) / max( 1, count( $job_in_progress->product_ids ) ) ) * 100,
257 'imported_products_count' => count( $job_in_progress->processed_product_ids ),
258 'updated_products_count' => count( $job_in_progress->updated_product_ids ),
259 'skipped_products_count' => count( $job_in_progress->skipped_products ),
260 'status' => $job_in_progress->status,
261 );
262
263 wp_send_json_success( $result );
264 }
265 } catch ( \Exception $e ) {
266
267 wp_send_json_error( $e->getMessage() );
268 }
269 }
270
271 /* translators: Placeholder: %s - sync job ID */
272 wp_send_json_error( sprintf( esc_html__( 'No sync job in progress found %s', 'woocommerce-square' ), is_string( $job_id ) ? $job_id : null ) );
273 }
274
275 /**
276 * Get sync status, variable status, and edit url for product
277 *
278 * Used to manipulate quick edit menu for product
279 *
280 * @since 2.1.6
281 */
282 public function get_quick_edit_product_details() {
283
284 check_ajax_referer( 'get-quick-edit-product-details', 'security' );
285
286 if ( ! current_user_can( 'edit_products' ) ) {
287 wp_send_json_error( 'invalid_permission' );
288 }
289
290 $product = isset( $_POST['product_id'] ) ? wc_get_product( (int) $_POST['product_id'] ) : false;
291
292 if ( $product ) {
293 $is_variable = $product->is_type( 'variable' );
294
295 if ( ! Product::has_sku( $product ) ) {
296 if ( $is_variable ) {
297 wp_send_json_error( 'missing_variation_sku' );
298 } else {
299 wp_send_json_error( 'missing_sku' );
300 }
301 }
302
303 $is_synced_with_square = Product::is_synced_with_square( $product ) ? 'yes' : 'no';
304 $is_woocommerce_sor = wc_square()->get_settings_handler()->is_system_of_record_woocommerce();
305
306 wp_send_json_success(
307 array(
308 'edit_url' => $is_woocommerce_sor ? get_edit_post_link( (int) $_POST['product_id'] ) : null,
309 'i18n' => $is_woocommerce_sor ? __( 'Stock must be fetched from Square before editing stock quantity', 'woocommerce-square' ) : null,
310 'is_synced_with_square' => $is_synced_with_square,
311 'is_variable' => $is_variable,
312 )
313 );
314 }
315 wp_send_json_error( 'invalid_product' );
316 }
317
318 }
319