These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * WooCommerce WC_AJAX. AJAX Event Handlers. |
||
4 | * |
||
5 | * @class WC_AJAX |
||
6 | * @package WooCommerce/Classes |
||
7 | */ |
||
8 | |||
9 | defined( 'ABSPATH' ) || exit; |
||
10 | |||
11 | /** |
||
12 | * WC_Ajax class. |
||
13 | */ |
||
14 | class WC_AJAX { |
||
15 | |||
16 | /** |
||
17 | * Hook in ajax handlers. |
||
18 | */ |
||
19 | public static function init() { |
||
20 | add_action( 'init', array( __CLASS__, 'define_ajax' ), 0 ); |
||
21 | add_action( 'template_redirect', array( __CLASS__, 'do_wc_ajax' ), 0 ); |
||
22 | self::add_ajax_events(); |
||
23 | } |
||
24 | |||
25 | /** |
||
26 | * Get WC Ajax Endpoint. |
||
27 | * |
||
28 | * @param string $request Optional. |
||
29 | * |
||
30 | * @return string |
||
31 | */ |
||
32 | public static function get_endpoint( $request = '' ) { |
||
33 | return esc_url_raw( apply_filters( 'woocommerce_ajax_get_endpoint', add_query_arg( 'wc-ajax', $request, remove_query_arg( array( 'remove_item', 'add-to-cart', 'added-to-cart', 'order_again', '_wpnonce' ), home_url( '/', 'relative' ) ) ), $request ) ); |
||
34 | } |
||
35 | |||
36 | /** |
||
37 | * Set WC AJAX constant and headers. |
||
38 | */ |
||
39 | public static function define_ajax() { |
||
40 | // phpcs:disable |
||
41 | if ( ! empty( $_GET['wc-ajax'] ) ) { |
||
42 | wc_maybe_define_constant( 'DOING_AJAX', true ); |
||
43 | wc_maybe_define_constant( 'WC_DOING_AJAX', true ); |
||
44 | if ( ! WP_DEBUG || ( WP_DEBUG && ! WP_DEBUG_DISPLAY ) ) { |
||
45 | @ini_set( 'display_errors', 0 ); // Turn off display_errors during AJAX events to prevent malformed JSON. |
||
46 | } |
||
47 | $GLOBALS['wpdb']->hide_errors(); |
||
48 | } |
||
49 | // phpcs:enable |
||
50 | } |
||
51 | |||
52 | /** |
||
53 | * Send headers for WC Ajax Requests. |
||
54 | * |
||
55 | * @since 2.5.0 |
||
56 | */ |
||
57 | private static function wc_ajax_headers() { |
||
58 | if ( ! headers_sent() ) { |
||
59 | send_origin_headers(); |
||
60 | send_nosniff_header(); |
||
61 | wc_nocache_headers(); |
||
62 | header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) ); |
||
63 | header( 'X-Robots-Tag: noindex' ); |
||
64 | status_header( 200 ); |
||
65 | View Code Duplication | } elseif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { |
|
66 | headers_sent( $file, $line ); |
||
67 | trigger_error( "wc_ajax_headers cannot set headers - headers already sent by {$file} on line {$line}", E_USER_NOTICE ); // @codingStandardsIgnoreLine |
||
68 | } |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * Check for WC Ajax request and fire action. |
||
73 | */ |
||
74 | public static function do_wc_ajax() { |
||
75 | global $wp_query; |
||
76 | |||
77 | // phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification |
||
78 | if ( ! empty( $_GET['wc-ajax'] ) ) { |
||
79 | $wp_query->set( 'wc-ajax', sanitize_text_field( wp_unslash( $_GET['wc-ajax'] ) ) ); |
||
80 | } |
||
81 | |||
82 | $action = $wp_query->get( 'wc-ajax' ); |
||
83 | |||
84 | if ( $action ) { |
||
85 | self::wc_ajax_headers(); |
||
86 | $action = sanitize_text_field( $action ); |
||
87 | do_action( 'wc_ajax_' . $action ); |
||
88 | wp_die(); |
||
89 | } |
||
90 | // phpcs:enable |
||
91 | } |
||
92 | |||
93 | /** |
||
94 | * Hook in methods - uses WordPress ajax handlers (admin-ajax). |
||
95 | */ |
||
96 | public static function add_ajax_events() { |
||
97 | $ajax_events_nopriv = array( |
||
98 | 'get_refreshed_fragments', |
||
99 | 'apply_coupon', |
||
100 | 'remove_coupon', |
||
101 | 'update_shipping_method', |
||
102 | 'get_cart_totals', |
||
103 | 'update_order_review', |
||
104 | 'add_to_cart', |
||
105 | 'remove_from_cart', |
||
106 | 'checkout', |
||
107 | 'get_variation', |
||
108 | 'get_customer_location', |
||
109 | ); |
||
110 | |||
111 | foreach ( $ajax_events_nopriv as $ajax_event ) { |
||
112 | add_action( 'wp_ajax_woocommerce_' . $ajax_event, array( __CLASS__, $ajax_event ) ); |
||
113 | add_action( 'wp_ajax_nopriv_woocommerce_' . $ajax_event, array( __CLASS__, $ajax_event ) ); |
||
114 | |||
115 | // WC AJAX can be used for frontend ajax requests. |
||
116 | add_action( 'wc_ajax_' . $ajax_event, array( __CLASS__, $ajax_event ) ); |
||
117 | } |
||
118 | |||
119 | $ajax_events = array( |
||
120 | 'feature_product', |
||
121 | 'mark_order_status', |
||
122 | 'get_order_details', |
||
123 | 'add_attribute', |
||
124 | 'add_new_attribute', |
||
125 | 'remove_variation', |
||
126 | 'remove_variations', |
||
127 | 'save_attributes', |
||
128 | 'add_variation', |
||
129 | 'link_all_variations', |
||
130 | 'revoke_access_to_download', |
||
131 | 'grant_access_to_download', |
||
132 | 'get_customer_details', |
||
133 | 'add_order_item', |
||
134 | 'add_order_fee', |
||
135 | 'add_order_shipping', |
||
136 | 'add_order_tax', |
||
137 | 'add_coupon_discount', |
||
138 | 'remove_order_coupon', |
||
139 | 'remove_order_item', |
||
140 | 'remove_order_tax', |
||
141 | 'reduce_order_item_stock', |
||
142 | 'increase_order_item_stock', |
||
143 | 'add_order_item_meta', |
||
144 | 'remove_order_item_meta', |
||
145 | 'calc_line_taxes', |
||
146 | 'save_order_items', |
||
147 | 'load_order_items', |
||
148 | 'add_order_note', |
||
149 | 'delete_order_note', |
||
150 | 'json_search_products', |
||
151 | 'json_search_products_and_variations', |
||
152 | 'json_search_downloadable_products_and_variations', |
||
153 | 'json_search_customers', |
||
154 | 'json_search_categories', |
||
155 | 'term_ordering', |
||
156 | 'product_ordering', |
||
157 | 'refund_line_items', |
||
158 | 'delete_refund', |
||
159 | 'rated', |
||
160 | 'update_api_key', |
||
161 | 'load_variations', |
||
162 | 'save_variations', |
||
163 | 'bulk_edit_variations', |
||
164 | 'tax_rates_save_changes', |
||
165 | 'shipping_zones_save_changes', |
||
166 | 'shipping_zone_add_method', |
||
167 | 'shipping_zone_methods_save_changes', |
||
168 | 'shipping_zone_methods_save_settings', |
||
169 | 'shipping_classes_save_changes', |
||
170 | 'toggle_gateway_enabled', |
||
171 | ); |
||
172 | |||
173 | foreach ( $ajax_events as $ajax_event ) { |
||
174 | add_action( 'wp_ajax_woocommerce_' . $ajax_event, array( __CLASS__, $ajax_event ) ); |
||
175 | } |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * Get a refreshed cart fragment, including the mini cart HTML. |
||
180 | */ |
||
181 | public static function get_refreshed_fragments() { |
||
182 | ob_start(); |
||
183 | |||
184 | woocommerce_mini_cart(); |
||
185 | |||
186 | $mini_cart = ob_get_clean(); |
||
187 | |||
188 | $data = array( |
||
189 | 'fragments' => apply_filters( |
||
190 | 'woocommerce_add_to_cart_fragments', |
||
191 | array( |
||
192 | 'div.widget_shopping_cart_content' => '<div class="widget_shopping_cart_content">' . $mini_cart . '</div>', |
||
193 | ) |
||
194 | ), |
||
195 | 'cart_hash' => WC()->cart->get_cart_hash(), |
||
196 | ); |
||
197 | |||
198 | wp_send_json( $data ); |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * AJAX apply coupon on checkout page. |
||
203 | */ |
||
204 | public static function apply_coupon() { |
||
205 | |||
206 | check_ajax_referer( 'apply-coupon', 'security' ); |
||
207 | |||
208 | if ( ! empty( $_POST['coupon_code'] ) ) { |
||
209 | WC()->cart->add_discount( wc_format_coupon_code( wp_unslash( $_POST['coupon_code'] ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
210 | } else { |
||
211 | wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' ); |
||
212 | } |
||
213 | |||
214 | wc_print_notices(); |
||
215 | wp_die(); |
||
216 | } |
||
217 | |||
218 | /** |
||
219 | * AJAX remove coupon on cart and checkout page. |
||
220 | */ |
||
221 | public static function remove_coupon() { |
||
222 | check_ajax_referer( 'remove-coupon', 'security' ); |
||
223 | |||
224 | $coupon = isset( $_POST['coupon'] ) ? wc_format_coupon_code( wp_unslash( $_POST['coupon'] ) ) : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
225 | |||
226 | if ( empty( $coupon ) ) { |
||
227 | wc_add_notice( __( 'Sorry there was a problem removing this coupon.', 'woocommerce' ), 'error' ); |
||
228 | } else { |
||
229 | WC()->cart->remove_coupon( $coupon ); |
||
230 | wc_add_notice( __( 'Coupon has been removed.', 'woocommerce' ) ); |
||
231 | } |
||
232 | |||
233 | wc_print_notices(); |
||
234 | wp_die(); |
||
235 | } |
||
236 | |||
237 | /** |
||
238 | * AJAX update shipping method on cart page. |
||
239 | */ |
||
240 | public static function update_shipping_method() { |
||
241 | check_ajax_referer( 'update-shipping-method', 'security' ); |
||
242 | |||
243 | wc_maybe_define_constant( 'WOOCOMMERCE_CART', true ); |
||
244 | |||
245 | $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' ); |
||
246 | $posted_shipping_methods = isset( $_POST['shipping_method'] ) ? wc_clean( wp_unslash( $_POST['shipping_method'] ) ) : array(); |
||
247 | |||
248 | if ( is_array( $posted_shipping_methods ) ) { |
||
249 | foreach ( $posted_shipping_methods as $i => $value ) { |
||
250 | $chosen_shipping_methods[ $i ] = $value; |
||
251 | } |
||
252 | } |
||
253 | |||
254 | WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods ); |
||
255 | |||
256 | self::get_cart_totals(); |
||
257 | } |
||
258 | |||
259 | /** |
||
260 | * AJAX receive updated cart_totals div. |
||
261 | */ |
||
262 | public static function get_cart_totals() { |
||
263 | wc_maybe_define_constant( 'WOOCOMMERCE_CART', true ); |
||
264 | WC()->cart->calculate_totals(); |
||
265 | woocommerce_cart_totals(); |
||
266 | wp_die(); |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * Session has expired. |
||
271 | */ |
||
272 | private static function update_order_review_expired() { |
||
273 | wp_send_json( |
||
274 | array( |
||
275 | 'fragments' => apply_filters( |
||
276 | 'woocommerce_update_order_review_fragments', |
||
277 | array( |
||
278 | 'form.woocommerce-checkout' => '<div class="woocommerce-error">' . __( 'Sorry, your session has expired.', 'woocommerce' ) . ' <a href="' . esc_url( wc_get_page_permalink( 'shop' ) ) . '" class="wc-backward">' . __( 'Return to shop', 'woocommerce' ) . '</a></div>', |
||
279 | ) |
||
280 | ), |
||
281 | ) |
||
282 | ); |
||
283 | } |
||
284 | |||
285 | /** |
||
286 | * AJAX update order review on checkout. |
||
287 | */ |
||
288 | public static function update_order_review() { |
||
289 | check_ajax_referer( 'update-order-review', 'security' ); |
||
290 | |||
291 | wc_maybe_define_constant( 'WOOCOMMERCE_CHECKOUT', true ); |
||
292 | |||
293 | View Code Duplication | if ( WC()->cart->is_empty() && ! is_customize_preview() && apply_filters( 'woocommerce_checkout_update_order_review_expired', true ) ) { |
|
294 | self::update_order_review_expired(); |
||
295 | } |
||
296 | |||
297 | do_action( 'woocommerce_checkout_update_order_review', isset( $_POST['post_data'] ) ? wp_unslash( $_POST['post_data'] ) : '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
298 | |||
299 | $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' ); |
||
300 | $posted_shipping_methods = isset( $_POST['shipping_method'] ) ? wc_clean( wp_unslash( $_POST['shipping_method'] ) ) : array(); |
||
301 | |||
302 | if ( is_array( $posted_shipping_methods ) ) { |
||
303 | foreach ( $posted_shipping_methods as $i => $value ) { |
||
304 | $chosen_shipping_methods[ $i ] = $value; |
||
305 | } |
||
306 | } |
||
307 | |||
308 | WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods ); |
||
309 | WC()->session->set( 'chosen_payment_method', empty( $_POST['payment_method'] ) ? '' : wc_clean( wp_unslash( $_POST['payment_method'] ) ) ); |
||
310 | WC()->customer->set_props( |
||
311 | array( |
||
312 | 'billing_country' => isset( $_POST['country'] ) ? wc_clean( wp_unslash( $_POST['country'] ) ) : null, |
||
313 | 'billing_state' => isset( $_POST['state'] ) ? wc_clean( wp_unslash( $_POST['state'] ) ) : null, |
||
314 | 'billing_postcode' => isset( $_POST['postcode'] ) ? wc_clean( wp_unslash( $_POST['postcode'] ) ) : null, |
||
315 | 'billing_city' => isset( $_POST['city'] ) ? wc_clean( wp_unslash( $_POST['city'] ) ) : null, |
||
316 | 'billing_address_1' => isset( $_POST['address'] ) ? wc_clean( wp_unslash( $_POST['address'] ) ) : null, |
||
317 | 'billing_address_2' => isset( $_POST['address_2'] ) ? wc_clean( wp_unslash( $_POST['address_2'] ) ) : null, |
||
318 | ) |
||
319 | ); |
||
320 | |||
321 | if ( wc_ship_to_billing_address_only() ) { |
||
322 | WC()->customer->set_props( |
||
323 | array( |
||
324 | 'shipping_country' => isset( $_POST['country'] ) ? wc_clean( wp_unslash( $_POST['country'] ) ) : null, |
||
325 | 'shipping_state' => isset( $_POST['state'] ) ? wc_clean( wp_unslash( $_POST['state'] ) ) : null, |
||
326 | 'shipping_postcode' => isset( $_POST['postcode'] ) ? wc_clean( wp_unslash( $_POST['postcode'] ) ) : null, |
||
327 | 'shipping_city' => isset( $_POST['city'] ) ? wc_clean( wp_unslash( $_POST['city'] ) ) : null, |
||
328 | 'shipping_address_1' => isset( $_POST['address'] ) ? wc_clean( wp_unslash( $_POST['address'] ) ) : null, |
||
329 | 'shipping_address_2' => isset( $_POST['address_2'] ) ? wc_clean( wp_unslash( $_POST['address_2'] ) ) : null, |
||
330 | ) |
||
331 | ); |
||
332 | } else { |
||
333 | WC()->customer->set_props( |
||
334 | array( |
||
335 | 'shipping_country' => isset( $_POST['s_country'] ) ? wc_clean( wp_unslash( $_POST['s_country'] ) ) : null, |
||
336 | 'shipping_state' => isset( $_POST['s_state'] ) ? wc_clean( wp_unslash( $_POST['s_state'] ) ) : null, |
||
337 | 'shipping_postcode' => isset( $_POST['s_postcode'] ) ? wc_clean( wp_unslash( $_POST['s_postcode'] ) ) : null, |
||
338 | 'shipping_city' => isset( $_POST['s_city'] ) ? wc_clean( wp_unslash( $_POST['s_city'] ) ) : null, |
||
339 | 'shipping_address_1' => isset( $_POST['s_address'] ) ? wc_clean( wp_unslash( $_POST['s_address'] ) ) : null, |
||
340 | 'shipping_address_2' => isset( $_POST['s_address_2'] ) ? wc_clean( wp_unslash( $_POST['s_address_2'] ) ) : null, |
||
341 | ) |
||
342 | ); |
||
343 | } |
||
344 | |||
345 | if ( isset( $_POST['has_full_address'] ) && wc_string_to_bool( wc_clean( wp_unslash( $_POST['has_full_address'] ) ) ) ) { |
||
346 | WC()->customer->set_calculated_shipping( true ); |
||
347 | } else { |
||
348 | WC()->customer->set_calculated_shipping( false ); |
||
349 | } |
||
350 | |||
351 | WC()->customer->save(); |
||
352 | |||
353 | // Calculate shipping before totals. This will ensure any shipping methods that affect things like taxes are chosen prior to final totals being calculated. Ref: #22708. |
||
354 | WC()->cart->calculate_shipping(); |
||
355 | WC()->cart->calculate_totals(); |
||
356 | |||
357 | // Get order review fragment. |
||
358 | ob_start(); |
||
359 | woocommerce_order_review(); |
||
360 | $woocommerce_order_review = ob_get_clean(); |
||
361 | |||
362 | // Get checkout payment fragment. |
||
363 | ob_start(); |
||
364 | woocommerce_checkout_payment(); |
||
365 | $woocommerce_checkout_payment = ob_get_clean(); |
||
366 | |||
367 | // Get messages if reload checkout is not true. |
||
368 | $reload_checkout = isset( WC()->session->reload_checkout ) ? true : false; |
||
369 | if ( ! $reload_checkout ) { |
||
370 | $messages = wc_print_notices( true ); |
||
371 | } else { |
||
372 | $messages = ''; |
||
373 | } |
||
374 | |||
375 | unset( WC()->session->refresh_totals, WC()->session->reload_checkout ); |
||
376 | |||
377 | wp_send_json( |
||
378 | array( |
||
379 | 'result' => empty( $messages ) ? 'success' : 'failure', |
||
380 | 'messages' => $messages, |
||
381 | 'reload' => $reload_checkout ? 'true' : 'false', |
||
382 | 'fragments' => apply_filters( |
||
383 | 'woocommerce_update_order_review_fragments', |
||
384 | array( |
||
385 | '.woocommerce-checkout-review-order-table' => $woocommerce_order_review, |
||
386 | '.woocommerce-checkout-payment' => $woocommerce_checkout_payment, |
||
387 | ) |
||
388 | ), |
||
389 | ) |
||
390 | ); |
||
391 | } |
||
392 | |||
393 | /** |
||
394 | * AJAX add to cart. |
||
395 | */ |
||
396 | public static function add_to_cart() { |
||
397 | ob_start(); |
||
398 | |||
399 | // phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification |
||
400 | if ( ! isset( $_POST['product_id'] ) ) { |
||
401 | return; |
||
402 | } |
||
403 | |||
404 | $product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) ); |
||
405 | $product = wc_get_product( $product_id ); |
||
406 | $quantity = empty( $_POST['quantity'] ) ? 1 : wc_stock_amount( wp_unslash( $_POST['quantity'] ) ); |
||
407 | $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity ); |
||
408 | $product_status = get_post_status( $product_id ); |
||
409 | $variation_id = 0; |
||
410 | $variation = array(); |
||
411 | |||
412 | if ( $product && 'variation' === $product->get_type() ) { |
||
413 | $variation_id = $product_id; |
||
414 | $product_id = $product->get_parent_id(); |
||
415 | $variation = $product->get_variation_attributes(); |
||
416 | } |
||
417 | |||
418 | if ( $passed_validation && false !== WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation ) && 'publish' === $product_status ) { |
||
419 | |||
420 | do_action( 'woocommerce_ajax_added_to_cart', $product_id ); |
||
421 | |||
422 | if ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) { |
||
423 | wc_add_to_cart_message( array( $product_id => $quantity ), true ); |
||
424 | } |
||
425 | |||
426 | self::get_refreshed_fragments(); |
||
427 | |||
428 | } else { |
||
429 | |||
430 | // If there was an error adding to the cart, redirect to the product page to show any errors. |
||
431 | $data = array( |
||
432 | 'error' => true, |
||
433 | 'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id ), |
||
434 | ); |
||
435 | |||
436 | wp_send_json( $data ); |
||
437 | } |
||
438 | // phpcs:enable |
||
439 | } |
||
440 | |||
441 | /** |
||
442 | * AJAX remove from cart. |
||
443 | */ |
||
444 | public static function remove_from_cart() { |
||
445 | ob_start(); |
||
446 | |||
447 | // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification |
||
448 | $cart_item_key = wc_clean( isset( $_POST['cart_item_key'] ) ? wp_unslash( $_POST['cart_item_key'] ) : '' ); |
||
449 | |||
450 | if ( $cart_item_key && false !== WC()->cart->remove_cart_item( $cart_item_key ) ) { |
||
451 | self::get_refreshed_fragments(); |
||
452 | } else { |
||
453 | wp_send_json_error(); |
||
454 | } |
||
455 | } |
||
456 | |||
457 | /** |
||
458 | * Process ajax checkout form. |
||
459 | */ |
||
460 | public static function checkout() { |
||
461 | wc_maybe_define_constant( 'WOOCOMMERCE_CHECKOUT', true ); |
||
462 | WC()->checkout()->process_checkout(); |
||
463 | wp_die( 0 ); |
||
464 | } |
||
465 | |||
466 | /** |
||
467 | * Get a matching variation based on posted attributes. |
||
468 | */ |
||
469 | public static function get_variation() { |
||
470 | ob_start(); |
||
471 | |||
472 | // phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification |
||
473 | if ( empty( $_POST['product_id'] ) ) { |
||
474 | wp_die(); |
||
475 | } |
||
476 | |||
477 | $variable_product = wc_get_product( absint( $_POST['product_id'] ) ); |
||
478 | |||
479 | if ( ! $variable_product ) { |
||
480 | wp_die(); |
||
481 | } |
||
482 | |||
483 | $data_store = WC_Data_Store::load( 'product' ); |
||
484 | $variation_id = $data_store->find_matching_product_variation( $variable_product, wp_unslash( $_POST ) ); |
||
485 | $variation = $variation_id ? $variable_product->get_available_variation( $variation_id ) : false; |
||
486 | wp_send_json( $variation ); |
||
487 | // phpcs:enable |
||
488 | } |
||
489 | |||
490 | /** |
||
491 | * Locate user via AJAX. |
||
492 | */ |
||
493 | public static function get_customer_location() { |
||
494 | $location_hash = WC_Cache_Helper::geolocation_ajax_get_location_hash(); |
||
495 | wp_send_json_success( array( 'hash' => $location_hash ) ); |
||
496 | } |
||
497 | |||
498 | /** |
||
499 | * Toggle Featured status of a product from admin. |
||
500 | */ |
||
501 | public static function feature_product() { |
||
502 | if ( current_user_can( 'edit_products' ) && check_admin_referer( 'woocommerce-feature-product' ) && isset( $_GET['product_id'] ) ) { |
||
503 | $product = wc_get_product( absint( $_GET['product_id'] ) ); |
||
504 | |||
505 | if ( $product ) { |
||
506 | $product->set_featured( ! $product->get_featured() ); |
||
507 | $product->save(); |
||
508 | } |
||
509 | } |
||
510 | |||
511 | wp_safe_redirect( wp_get_referer() ? remove_query_arg( array( 'trashed', 'untrashed', 'deleted', 'ids' ), wp_get_referer() ) : admin_url( 'edit.php?post_type=product' ) ); |
||
512 | exit; |
||
513 | } |
||
514 | |||
515 | /** |
||
516 | * Mark an order with a status. |
||
517 | */ |
||
518 | public static function mark_order_status() { |
||
519 | if ( current_user_can( 'edit_shop_orders' ) && check_admin_referer( 'woocommerce-mark-order-status' ) && isset( $_GET['status'], $_GET['order_id'] ) ) { |
||
520 | $status = sanitize_text_field( wp_unslash( $_GET['status'] ) ); |
||
521 | $order = wc_get_order( absint( wp_unslash( $_GET['order_id'] ) ) ); |
||
522 | |||
523 | if ( wc_is_order_status( 'wc-' . $status ) && $order ) { |
||
524 | // Initialize payment gateways in case order has hooked status transition actions. |
||
525 | WC()->payment_gateways(); |
||
526 | |||
527 | $order->update_status( $status, '', true ); |
||
528 | do_action( 'woocommerce_order_edit_status', $order->get_id(), $status ); |
||
529 | } |
||
530 | } |
||
531 | |||
532 | wp_safe_redirect( wp_get_referer() ? wp_get_referer() : admin_url( 'edit.php?post_type=shop_order' ) ); |
||
533 | exit; |
||
534 | } |
||
535 | |||
536 | /** |
||
537 | * Get order details. |
||
538 | */ |
||
539 | public static function get_order_details() { |
||
540 | check_admin_referer( 'woocommerce-preview-order', 'security' ); |
||
541 | |||
542 | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_GET['order_id'] ) ) { |
||
543 | wp_die( -1 ); |
||
544 | } |
||
545 | |||
546 | $order = wc_get_order( absint( $_GET['order_id'] ) ); // WPCS: sanitization ok. |
||
547 | |||
548 | if ( $order ) { |
||
549 | include_once 'admin/list-tables/class-wc-admin-list-table-orders.php'; |
||
550 | |||
551 | wp_send_json_success( WC_Admin_List_Table_Orders::order_preview_get_order_details( $order ) ); |
||
552 | } |
||
553 | wp_die(); |
||
554 | } |
||
555 | |||
556 | /** |
||
557 | * Add an attribute row. |
||
558 | */ |
||
559 | public static function add_attribute() { |
||
560 | ob_start(); |
||
561 | |||
562 | check_ajax_referer( 'add-attribute', 'security' ); |
||
563 | |||
564 | if ( ! current_user_can( 'edit_products' ) || ! isset( $_POST['taxonomy'], $_POST['i'] ) ) { |
||
565 | wp_die( -1 ); |
||
566 | } |
||
567 | |||
568 | $i = absint( $_POST['i'] ); |
||
569 | $metabox_class = array(); |
||
570 | $attribute = new WC_Product_Attribute(); |
||
571 | |||
572 | $attribute->set_id( wc_attribute_taxonomy_id_by_name( sanitize_text_field( wp_unslash( $_POST['taxonomy'] ) ) ) ); |
||
573 | $attribute->set_name( sanitize_text_field( wp_unslash( $_POST['taxonomy'] ) ) ); |
||
574 | $attribute->set_visible( apply_filters( 'woocommerce_attribute_default_visibility', 1 ) ); |
||
575 | $attribute->set_variation( apply_filters( 'woocommerce_attribute_default_is_variation', 0 ) ); |
||
576 | |||
577 | if ( $attribute->is_taxonomy() ) { |
||
578 | $metabox_class[] = 'taxonomy'; |
||
579 | $metabox_class[] = $attribute->get_name(); |
||
580 | } |
||
581 | |||
582 | include 'admin/meta-boxes/views/html-product-attribute.php'; |
||
583 | wp_die(); |
||
584 | } |
||
585 | |||
586 | /** |
||
587 | * Add a new attribute via ajax function. |
||
588 | */ |
||
589 | public static function add_new_attribute() { |
||
590 | check_ajax_referer( 'add-attribute', 'security' ); |
||
591 | |||
592 | if ( current_user_can( 'manage_product_terms' ) && isset( $_POST['taxonomy'], $_POST['term'] ) ) { |
||
593 | $taxonomy = esc_attr( wp_unslash( $_POST['taxonomy'] ) ); // phpcs:ignore |
||
594 | $term = wc_clean( wp_unslash( $_POST['term'] ) ); |
||
595 | |||
596 | if ( taxonomy_exists( $taxonomy ) ) { |
||
597 | |||
598 | $result = wp_insert_term( $term, $taxonomy ); |
||
599 | |||
600 | if ( is_wp_error( $result ) ) { |
||
601 | wp_send_json( |
||
602 | array( |
||
603 | 'error' => $result->get_error_message(), |
||
604 | ) |
||
605 | ); |
||
606 | } else { |
||
607 | $term = get_term_by( 'id', $result['term_id'], $taxonomy ); |
||
608 | wp_send_json( |
||
609 | array( |
||
610 | 'term_id' => $term->term_id, |
||
611 | 'name' => $term->name, |
||
612 | 'slug' => $term->slug, |
||
613 | ) |
||
614 | ); |
||
615 | } |
||
616 | } |
||
617 | } |
||
618 | wp_die( -1 ); |
||
619 | } |
||
620 | |||
621 | /** |
||
622 | * Delete variations via ajax function. |
||
623 | */ |
||
624 | public static function remove_variations() { |
||
625 | check_ajax_referer( 'delete-variations', 'security' ); |
||
626 | |||
627 | if ( current_user_can( 'edit_products' ) && isset( $_POST['variation_ids'] ) ) { |
||
628 | $variation_ids = array_map( 'absint', (array) wp_unslash( $_POST['variation_ids'] ) ); |
||
629 | |||
630 | foreach ( $variation_ids as $variation_id ) { |
||
631 | if ( 'product_variation' === get_post_type( $variation_id ) ) { |
||
632 | $variation = wc_get_product( $variation_id ); |
||
633 | $variation->delete( true ); |
||
634 | } |
||
635 | } |
||
636 | } |
||
637 | |||
638 | wp_die( -1 ); |
||
639 | } |
||
640 | |||
641 | /** |
||
642 | * Save attributes via ajax. |
||
643 | */ |
||
644 | public static function save_attributes() { |
||
645 | check_ajax_referer( 'save-attributes', 'security' ); |
||
646 | |||
647 | View Code Duplication | if ( ! current_user_can( 'edit_products' ) || ! isset( $_POST['data'], $_POST['post_id'] ) ) { |
|
648 | wp_die( -1 ); |
||
649 | } |
||
650 | |||
651 | $response = array(); |
||
652 | |||
653 | try { |
||
654 | parse_str( wp_unslash( $_POST['data'] ), $data ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
655 | |||
656 | $attributes = WC_Meta_Box_Product_Data::prepare_attributes( $data ); |
||
657 | $product_id = absint( wp_unslash( $_POST['post_id'] ) ); |
||
658 | $product_type = ! empty( $_POST['product_type'] ) ? wc_clean( wp_unslash( $_POST['product_type'] ) ) : 'simple'; |
||
659 | $classname = WC_Product_Factory::get_product_classname( $product_id, $product_type ); |
||
660 | $product = new $classname( $product_id ); |
||
661 | |||
662 | $product->set_attributes( $attributes ); |
||
663 | $product->save(); |
||
664 | |||
665 | ob_start(); |
||
666 | $attributes = $product->get_attributes( 'edit' ); |
||
667 | $i = -1; |
||
668 | if ( ! empty( $data['attribute_names'] ) ) { |
||
669 | foreach ( $data['attribute_names'] as $attribute_name ) { |
||
670 | $attribute = isset( $attributes[ sanitize_title( $attribute_name ) ] ) ? $attributes[ sanitize_title( $attribute_name ) ] : false; |
||
671 | if ( ! $attribute ) { |
||
672 | continue; |
||
673 | } |
||
674 | $i++; |
||
675 | $metabox_class = array(); |
||
676 | |||
677 | if ( $attribute->is_taxonomy() ) { |
||
678 | $metabox_class[] = 'taxonomy'; |
||
679 | $metabox_class[] = $attribute->get_name(); |
||
680 | } |
||
681 | |||
682 | include 'admin/meta-boxes/views/html-product-attribute.php'; |
||
683 | } |
||
684 | } |
||
685 | |||
686 | $response['html'] = ob_get_clean(); |
||
687 | } catch ( Exception $e ) { |
||
688 | wp_send_json_error( array( 'error' => $e->getMessage() ) ); |
||
689 | } |
||
690 | |||
691 | // wp_send_json_success must be outside the try block not to break phpunit tests. |
||
692 | wp_send_json_success( $response ); |
||
693 | } |
||
694 | |||
695 | /** |
||
696 | * Add variation via ajax function. |
||
697 | */ |
||
698 | public static function add_variation() { |
||
699 | check_ajax_referer( 'add-variation', 'security' ); |
||
700 | |||
701 | View Code Duplication | if ( ! current_user_can( 'edit_products' ) || ! isset( $_POST['post_id'], $_POST['loop'] ) ) { |
|
702 | wp_die( -1 ); |
||
703 | } |
||
704 | |||
705 | global $post; // Set $post global so its available, like within the admin screens. |
||
706 | |||
707 | $product_id = intval( $_POST['post_id'] ); |
||
708 | $post = get_post( $product_id ); // phpcs:ignore |
||
709 | $loop = intval( $_POST['loop'] ); |
||
710 | $product_object = new WC_Product_Variable( $product_id ); // Forces type to variable in case product is unsaved. |
||
711 | $variation_object = new WC_Product_Variation(); |
||
712 | $variation_object->set_parent_id( $product_id ); |
||
713 | $variation_object->set_attributes( array_fill_keys( array_map( 'sanitize_title', array_keys( $product_object->get_variation_attributes() ) ), '' ) ); |
||
714 | $variation_id = $variation_object->save(); |
||
715 | $variation = get_post( $variation_id ); |
||
716 | $variation_data = array_merge( get_post_custom( $variation_id ), wc_get_product_variation_attributes( $variation_id ) ); // kept for BW compatibility. |
||
717 | include 'admin/meta-boxes/views/html-variation-admin.php'; |
||
718 | wp_die(); |
||
719 | } |
||
720 | |||
721 | /** |
||
722 | * Link all variations via ajax function. |
||
723 | */ |
||
724 | public static function link_all_variations() { |
||
725 | check_ajax_referer( 'link-variations', 'security' ); |
||
726 | |||
727 | if ( ! current_user_can( 'edit_products' ) ) { |
||
728 | wp_die( -1 ); |
||
729 | } |
||
730 | |||
731 | wc_maybe_define_constant( 'WC_MAX_LINKED_VARIATIONS', 50 ); |
||
732 | wc_set_time_limit( 0 ); |
||
733 | |||
734 | $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0; |
||
735 | |||
736 | if ( ! $post_id ) { |
||
737 | wp_die(); |
||
738 | } |
||
739 | |||
740 | $product = wc_get_product( $post_id ); |
||
741 | $data_store = $product->get_data_store(); |
||
742 | |||
743 | if ( ! is_callable( array( $data_store, 'create_all_product_variations' ) ) ) { |
||
744 | wp_die(); |
||
745 | } |
||
746 | |||
747 | echo esc_html( $data_store->create_all_product_variations( $product, WC_MAX_LINKED_VARIATIONS ) ); |
||
748 | |||
749 | $data_store->sort_all_product_variations( $product->get_id() ); |
||
750 | wp_die(); |
||
751 | } |
||
752 | |||
753 | /** |
||
754 | * Delete download permissions via ajax function. |
||
755 | */ |
||
756 | public static function revoke_access_to_download() { |
||
757 | check_ajax_referer( 'revoke-access', 'security' ); |
||
758 | |||
759 | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['download_id'], $_POST['product_id'], $_POST['order_id'], $_POST['permission_id'] ) ) { |
||
760 | wp_die( -1 ); |
||
761 | } |
||
762 | $download_id = wc_clean( wp_unslash( $_POST['download_id'] ) ); |
||
763 | $product_id = intval( $_POST['product_id'] ); |
||
764 | $order_id = intval( $_POST['order_id'] ); |
||
765 | $permission_id = absint( $_POST['permission_id'] ); |
||
766 | $data_store = WC_Data_Store::load( 'customer-download' ); |
||
767 | $data_store->delete_by_id( $permission_id ); |
||
768 | |||
769 | do_action( 'woocommerce_ajax_revoke_access_to_product_download', $download_id, $product_id, $order_id, $permission_id ); |
||
770 | |||
771 | wp_die(); |
||
772 | } |
||
773 | |||
774 | /** |
||
775 | * Grant download permissions via ajax function. |
||
776 | */ |
||
777 | public static function grant_access_to_download() { |
||
778 | |||
779 | check_ajax_referer( 'grant-access', 'security' ); |
||
780 | |||
781 | View Code Duplication | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['loop'], $_POST['order_id'], $_POST['product_ids'] ) ) { |
|
782 | wp_die( -1 ); |
||
783 | } |
||
784 | |||
785 | global $wpdb; |
||
786 | |||
787 | $wpdb->hide_errors(); |
||
788 | |||
789 | $order_id = intval( $_POST['order_id'] ); |
||
790 | $product_ids = array_filter( array_map( 'absint', (array) wp_unslash( $_POST['product_ids'] ) ) ); |
||
791 | $loop = intval( $_POST['loop'] ); |
||
792 | $file_counter = 0; |
||
793 | $order = wc_get_order( $order_id ); |
||
794 | |||
795 | foreach ( $product_ids as $product_id ) { |
||
796 | $product = wc_get_product( $product_id ); |
||
797 | $files = $product->get_downloads(); |
||
798 | |||
799 | if ( ! $order->get_billing_email() ) { |
||
800 | wp_die(); |
||
801 | } |
||
802 | |||
803 | if ( ! empty( $files ) ) { |
||
804 | foreach ( $files as $download_id => $file ) { |
||
805 | $inserted_id = wc_downloadable_file_permission( $download_id, $product_id, $order ); |
||
806 | if ( $inserted_id ) { |
||
807 | $download = new WC_Customer_Download( $inserted_id ); |
||
808 | $loop ++; |
||
809 | $file_counter ++; |
||
810 | |||
811 | if ( $file->get_name() ) { |
||
812 | $file_count = $file->get_name(); |
||
813 | } else { |
||
814 | /* translators: %d file count */ |
||
815 | $file_count = sprintf( __( 'File %d', 'woocommerce' ), $file_counter ); |
||
816 | } |
||
817 | include 'admin/meta-boxes/views/html-order-download-permission.php'; |
||
818 | } |
||
819 | } |
||
820 | } |
||
821 | } |
||
822 | wp_die(); |
||
823 | } |
||
824 | |||
825 | /** |
||
826 | * Get customer details via ajax. |
||
827 | */ |
||
828 | public static function get_customer_details() { |
||
829 | check_ajax_referer( 'get-customer-details', 'security' ); |
||
830 | |||
831 | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['user_id'] ) ) { |
||
832 | wp_die( -1 ); |
||
833 | } |
||
834 | |||
835 | $user_id = absint( $_POST['user_id'] ); |
||
836 | $customer = new WC_Customer( $user_id ); |
||
837 | |||
838 | if ( has_filter( 'woocommerce_found_customer_details' ) ) { |
||
839 | wc_deprecated_function( 'The woocommerce_found_customer_details filter', '3.0', 'woocommerce_ajax_get_customer_details' ); |
||
840 | } |
||
841 | |||
842 | $data = $customer->get_data(); |
||
843 | $data['date_created'] = $data['date_created'] ? $data['date_created']->getTimestamp() : null; |
||
844 | $data['date_modified'] = $data['date_modified'] ? $data['date_modified']->getTimestamp() : null; |
||
845 | |||
846 | $customer_data = apply_filters( 'woocommerce_ajax_get_customer_details', $data, $customer, $user_id ); |
||
847 | wp_send_json( $customer_data ); |
||
848 | } |
||
849 | |||
850 | /** |
||
851 | * Add order item via ajax. Used on the edit order screen in WP Admin. |
||
852 | * |
||
853 | * @throws Exception If order is invalid. |
||
854 | */ |
||
855 | public static function add_order_item() { |
||
856 | check_ajax_referer( 'order-item', 'security' ); |
||
857 | |||
858 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
859 | wp_die( -1 ); |
||
860 | } |
||
861 | |||
862 | $response = array(); |
||
863 | |||
864 | try { |
||
865 | if ( ! isset( $_POST['order_id'] ) ) { |
||
866 | throw new Exception( __( 'Invalid order', 'woocommerce' ) ); |
||
867 | } |
||
868 | |||
869 | $order_id = absint( wp_unslash( $_POST['order_id'] ) ); // WPCS: input var ok. |
||
870 | $order = wc_get_order( $order_id ); |
||
871 | |||
872 | if ( ! $order ) { |
||
873 | throw new Exception( __( 'Invalid order', 'woocommerce' ) ); |
||
874 | } |
||
875 | |||
876 | // If we passed through items it means we need to save first before adding a new one. |
||
877 | $items = ( ! empty( $_POST['items'] ) ) ? wp_unslash( $_POST['items'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
878 | |||
879 | View Code Duplication | if ( ! empty( $items ) ) { |
|
880 | $save_items = array(); |
||
881 | parse_str( $items, $save_items ); |
||
882 | wc_save_order_items( $order->get_id(), $save_items ); |
||
883 | } |
||
884 | |||
885 | $items_to_add = isset( $_POST['data'] ) ? array_filter( wp_unslash( (array) $_POST['data'] ) ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
886 | |||
887 | // Add items to order. |
||
888 | $order_notes = array(); |
||
889 | |||
890 | foreach ( $items_to_add as $item ) { |
||
891 | if ( ! isset( $item['id'], $item['qty'] ) || empty( $item['id'] ) ) { |
||
892 | continue; |
||
893 | } |
||
894 | $product_id = absint( $item['id'] ); |
||
895 | $qty = wc_stock_amount( $item['qty'] ); |
||
896 | $product = wc_get_product( $product_id ); |
||
897 | |||
898 | if ( ! $product ) { |
||
899 | throw new Exception( __( 'Invalid product ID', 'woocommerce' ) . ' ' . $product_id ); |
||
900 | } |
||
901 | |||
902 | $item_id = $order->add_product( $product, $qty ); |
||
903 | $item = apply_filters( 'woocommerce_ajax_order_item', $order->get_item( $item_id ), $item_id ); |
||
904 | $added_items[ $item_id ] = $item; |
||
905 | $order_notes[ $item_id ] = $product->get_formatted_name(); |
||
906 | |||
907 | if ( $product->managing_stock() ) { |
||
908 | $new_stock = wc_update_product_stock( $product, $qty, 'decrease' ); |
||
909 | $order_notes[ $item_id ] = $product->get_formatted_name() . ' – ' . ( $new_stock + $qty ) . '→' . $new_stock; |
||
910 | $item->add_meta_data( '_reduced_stock', $qty, true ); |
||
911 | $item->save(); |
||
912 | } |
||
913 | |||
914 | do_action( 'woocommerce_ajax_add_order_item_meta', $item_id, $item, $order ); |
||
915 | } |
||
916 | |||
917 | /* translators: %s item name. */ |
||
918 | $order->add_order_note( sprintf( __( 'Added line items: %s', 'woocommerce' ), implode( ', ', $order_notes ) ), false, true ); |
||
919 | |||
920 | do_action( 'woocommerce_ajax_order_items_added', $added_items, $order ); |
||
921 | |||
922 | $data = get_post_meta( $order_id ); |
||
923 | |||
924 | // Get HTML to return. |
||
925 | ob_start(); |
||
926 | include 'admin/meta-boxes/views/html-order-items.php'; |
||
927 | $items_html = ob_get_clean(); |
||
928 | |||
929 | ob_start(); |
||
930 | $notes = wc_get_order_notes( array( 'order_id' => $order_id ) ); |
||
931 | include 'admin/meta-boxes/views/html-order-notes.php'; |
||
932 | $notes_html = ob_get_clean(); |
||
933 | |||
934 | wp_send_json_success( |
||
935 | array( |
||
936 | 'html' => $items_html, |
||
937 | 'notes_html' => $notes_html, |
||
938 | ) |
||
939 | ); |
||
940 | } catch ( Exception $e ) { |
||
941 | wp_send_json_error( array( 'error' => $e->getMessage() ) ); |
||
942 | } |
||
943 | |||
944 | // wp_send_json_success must be outside the try block not to break phpunit tests. |
||
945 | wp_send_json_success( $response ); |
||
946 | } |
||
947 | |||
948 | /** |
||
949 | * Add order fee via ajax. |
||
950 | * |
||
951 | * @throws Exception If order is invalid. |
||
952 | */ |
||
953 | public static function add_order_fee() { |
||
954 | check_ajax_referer( 'order-item', 'security' ); |
||
955 | |||
956 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
957 | wp_die( -1 ); |
||
958 | } |
||
959 | |||
960 | $response = array(); |
||
961 | |||
962 | try { |
||
963 | $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0; |
||
964 | $order = wc_get_order( $order_id ); |
||
965 | |||
966 | if ( ! $order ) { |
||
967 | throw new Exception( __( 'Invalid order', 'woocommerce' ) ); |
||
968 | } |
||
969 | |||
970 | $amount = isset( $_POST['amount'] ) ? wc_clean( wp_unslash( $_POST['amount'] ) ) : 0; |
||
971 | |||
972 | $calculate_tax_args = array( |
||
973 | 'country' => isset( $_POST['country'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['country'] ) ) ) : '', |
||
974 | 'state' => isset( $_POST['state'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['state'] ) ) ) : '', |
||
975 | 'postcode' => isset( $_POST['postcode'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['postcode'] ) ) ) : '', |
||
976 | 'city' => isset( $_POST['city'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['city'] ) ) ) : '', |
||
977 | ); |
||
978 | |||
979 | if ( strstr( $amount, '%' ) ) { |
||
980 | $formatted_amount = $amount; |
||
981 | $percent = floatval( trim( $amount, '%' ) ); |
||
982 | $amount = $order->get_total() * ( $percent / 100 ); |
||
983 | } else { |
||
984 | $amount = floatval( $amount ); |
||
985 | $formatted_amount = wc_price( $amount, array( 'currency' => $order->get_currency() ) ); |
||
986 | } |
||
987 | |||
988 | $fee = new WC_Order_Item_Fee(); |
||
989 | $fee->set_amount( $amount ); |
||
990 | $fee->set_total( $amount ); |
||
991 | /* translators: %s fee amount */ |
||
992 | $fee->set_name( sprintf( __( '%s fee', 'woocommerce' ), wc_clean( $formatted_amount ) ) ); |
||
993 | |||
994 | $order->add_item( $fee ); |
||
995 | $order->calculate_taxes( $calculate_tax_args ); |
||
996 | $order->calculate_totals( false ); |
||
997 | $order->save(); |
||
998 | |||
999 | ob_start(); |
||
1000 | include 'admin/meta-boxes/views/html-order-items.php'; |
||
1001 | $response['html'] = ob_get_clean(); |
||
1002 | } catch ( Exception $e ) { |
||
1003 | wp_send_json_error( array( 'error' => $e->getMessage() ) ); |
||
1004 | } |
||
1005 | |||
1006 | // wp_send_json_success must be outside the try block not to break phpunit tests. |
||
1007 | wp_send_json_success( $response ); |
||
1008 | } |
||
1009 | |||
1010 | /** |
||
1011 | * Add order shipping cost via ajax. |
||
1012 | * |
||
1013 | * @throws Exception If order is invalid. |
||
1014 | */ |
||
1015 | public static function add_order_shipping() { |
||
1016 | check_ajax_referer( 'order-item', 'security' ); |
||
1017 | |||
1018 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1019 | wp_die( -1 ); |
||
1020 | } |
||
1021 | |||
1022 | $response = array(); |
||
1023 | |||
1024 | try { |
||
1025 | $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0; |
||
1026 | $order = wc_get_order( $order_id ); |
||
1027 | |||
1028 | if ( ! $order ) { |
||
1029 | throw new Exception( __( 'Invalid order', 'woocommerce' ) ); |
||
1030 | } |
||
1031 | |||
1032 | $order_taxes = $order->get_taxes(); |
||
1033 | $shipping_methods = WC()->shipping() ? WC()->shipping()->load_shipping_methods() : array(); |
||
1034 | |||
1035 | // Add new shipping. |
||
1036 | $item = new WC_Order_Item_Shipping(); |
||
1037 | $item->set_shipping_rate( new WC_Shipping_Rate() ); |
||
1038 | $item->set_order_id( $order_id ); |
||
1039 | $item_id = $item->save(); |
||
1040 | |||
1041 | ob_start(); |
||
1042 | include 'admin/meta-boxes/views/html-order-shipping.php'; |
||
1043 | $response['html'] = ob_get_clean(); |
||
1044 | } catch ( Exception $e ) { |
||
1045 | wp_send_json_error( array( 'error' => $e->getMessage() ) ); |
||
1046 | } |
||
1047 | |||
1048 | // wp_send_json_success must be outside the try block not to break phpunit tests. |
||
1049 | wp_send_json_success( $response ); |
||
1050 | } |
||
1051 | |||
1052 | /** |
||
1053 | * Add order tax column via ajax. |
||
1054 | * |
||
1055 | * @throws Exception If order or tax rate is invalid. |
||
1056 | */ |
||
1057 | public static function add_order_tax() { |
||
1058 | check_ajax_referer( 'order-item', 'security' ); |
||
1059 | |||
1060 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1061 | wp_die( -1 ); |
||
1062 | } |
||
1063 | |||
1064 | $response = array(); |
||
1065 | |||
1066 | try { |
||
1067 | $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0; |
||
1068 | $order = wc_get_order( $order_id ); |
||
1069 | |||
1070 | if ( ! $order ) { |
||
1071 | throw new Exception( __( 'Invalid order', 'woocommerce' ) ); |
||
1072 | } |
||
1073 | |||
1074 | $rate_id = isset( $_POST['rate_id'] ) ? absint( $_POST['rate_id'] ) : ''; |
||
1075 | |||
1076 | if ( ! $rate_id ) { |
||
1077 | throw new Exception( __( 'Invalid rate', 'woocommerce' ) ); |
||
1078 | } |
||
1079 | |||
1080 | $data = get_post_meta( $order_id ); |
||
1081 | |||
1082 | // Add new tax. |
||
1083 | $item = new WC_Order_Item_Tax(); |
||
1084 | $item->set_rate( $rate_id ); |
||
1085 | $item->set_order_id( $order_id ); |
||
1086 | $item->save(); |
||
1087 | |||
1088 | ob_start(); |
||
1089 | include 'admin/meta-boxes/views/html-order-items.php'; |
||
1090 | $response['html'] = ob_get_clean(); |
||
1091 | } catch ( Exception $e ) { |
||
1092 | wp_send_json_error( array( 'error' => $e->getMessage() ) ); |
||
1093 | } |
||
1094 | |||
1095 | // wp_send_json_success must be outside the try block not to break phpunit tests. |
||
1096 | wp_send_json_success( $response ); |
||
1097 | } |
||
1098 | |||
1099 | /** |
||
1100 | * Add order discount via ajax. |
||
1101 | * |
||
1102 | * @throws Exception If order or coupon is invalid. |
||
1103 | */ |
||
1104 | public static function add_coupon_discount() { |
||
1105 | check_ajax_referer( 'order-item', 'security' ); |
||
1106 | |||
1107 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1108 | wp_die( -1 ); |
||
1109 | } |
||
1110 | |||
1111 | $response = array(); |
||
1112 | |||
1113 | try { |
||
1114 | $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0; |
||
1115 | $order = wc_get_order( $order_id ); |
||
1116 | $calculate_tax_args = array( |
||
1117 | 'country' => isset( $_POST['country'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['country'] ) ) ) : '', |
||
1118 | 'state' => isset( $_POST['state'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['state'] ) ) ) : '', |
||
1119 | 'postcode' => isset( $_POST['postcode'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['postcode'] ) ) ) : '', |
||
1120 | 'city' => isset( $_POST['city'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['city'] ) ) ) : '', |
||
1121 | ); |
||
1122 | |||
1123 | if ( ! $order ) { |
||
1124 | throw new Exception( __( 'Invalid order', 'woocommerce' ) ); |
||
1125 | } |
||
1126 | |||
1127 | if ( empty( $_POST['coupon'] ) ) { |
||
1128 | throw new Exception( __( 'Invalid coupon', 'woocommerce' ) ); |
||
1129 | } |
||
1130 | |||
1131 | // Add user ID and/or email so validation for coupon limits works. |
||
1132 | $user_id_arg = isset( $_POST['user_id'] ) ? absint( $_POST['user_id'] ) : 0; |
||
1133 | $user_email_arg = isset( $_POST['user_email'] ) ? sanitize_email( wp_unslash( $_POST['user_email'] ) ) : ''; |
||
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
1134 | |||
1135 | if ( $user_id_arg ) { |
||
1136 | $order->set_customer_id( $user_id_arg ); |
||
1137 | } |
||
1138 | if ( $user_email_arg ) { |
||
1139 | $order->set_billing_email( $user_email_arg ); |
||
1140 | } |
||
1141 | |||
1142 | $result = $order->apply_coupon( wc_format_coupon_code( wp_unslash( $_POST['coupon'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
1143 | |||
1144 | if ( is_wp_error( $result ) ) { |
||
1145 | throw new Exception( html_entity_decode( wp_strip_all_tags( $result->get_error_message() ) ) ); |
||
1146 | } |
||
1147 | |||
1148 | $order->calculate_taxes( $calculate_tax_args ); |
||
1149 | $order->calculate_totals( false ); |
||
1150 | |||
1151 | ob_start(); |
||
1152 | include 'admin/meta-boxes/views/html-order-items.php'; |
||
1153 | $response['html'] = ob_get_clean(); |
||
1154 | } catch ( Exception $e ) { |
||
1155 | wp_send_json_error( array( 'error' => $e->getMessage() ) ); |
||
1156 | } |
||
1157 | |||
1158 | // wp_send_json_success must be outside the try block not to break phpunit tests. |
||
1159 | wp_send_json_success( $response ); |
||
1160 | } |
||
1161 | |||
1162 | /** |
||
1163 | * Remove coupon from an order via ajax. |
||
1164 | * |
||
1165 | * @throws Exception If order or coupon is invalid. |
||
1166 | */ |
||
1167 | public static function remove_order_coupon() { |
||
1168 | check_ajax_referer( 'order-item', 'security' ); |
||
1169 | |||
1170 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1171 | wp_die( -1 ); |
||
1172 | } |
||
1173 | |||
1174 | $response = array(); |
||
1175 | |||
1176 | try { |
||
1177 | $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0; |
||
1178 | $order = wc_get_order( $order_id ); |
||
1179 | $calculate_tax_args = array( |
||
1180 | 'country' => isset( $_POST['country'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['country'] ) ) ) : '', |
||
1181 | 'state' => isset( $_POST['state'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['state'] ) ) ) : '', |
||
1182 | 'postcode' => isset( $_POST['postcode'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['postcode'] ) ) ) : '', |
||
1183 | 'city' => isset( $_POST['city'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['city'] ) ) ) : '', |
||
1184 | ); |
||
1185 | |||
1186 | if ( ! $order ) { |
||
1187 | throw new Exception( __( 'Invalid order', 'woocommerce' ) ); |
||
1188 | } |
||
1189 | |||
1190 | if ( empty( $_POST['coupon'] ) ) { |
||
1191 | throw new Exception( __( 'Invalid coupon', 'woocommerce' ) ); |
||
1192 | } |
||
1193 | |||
1194 | $order->remove_coupon( wc_format_coupon_code( wp_unslash( $_POST['coupon'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
1195 | $order->calculate_taxes( $calculate_tax_args ); |
||
1196 | $order->calculate_totals( false ); |
||
1197 | |||
1198 | ob_start(); |
||
1199 | include 'admin/meta-boxes/views/html-order-items.php'; |
||
1200 | $response['html'] = ob_get_clean(); |
||
1201 | } catch ( Exception $e ) { |
||
1202 | wp_send_json_error( array( 'error' => $e->getMessage() ) ); |
||
1203 | } |
||
1204 | |||
1205 | // wp_send_json_success must be outside the try block not to break phpunit tests. |
||
1206 | wp_send_json_success( $response ); |
||
1207 | } |
||
1208 | |||
1209 | /** |
||
1210 | * Remove an order item. |
||
1211 | * |
||
1212 | * @throws Exception If order is invalid. |
||
1213 | */ |
||
1214 | public static function remove_order_item() { |
||
1215 | check_ajax_referer( 'order-item', 'security' ); |
||
1216 | |||
1217 | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['order_id'], $_POST['order_item_ids'] ) ) { |
||
1218 | wp_die( -1 ); |
||
1219 | } |
||
1220 | |||
1221 | $response = array(); |
||
1222 | |||
1223 | try { |
||
1224 | $order_id = absint( $_POST['order_id'] ); |
||
1225 | $order = wc_get_order( $order_id ); |
||
1226 | |||
1227 | if ( ! $order ) { |
||
1228 | throw new Exception( __( 'Invalid order', 'woocommerce' ) ); |
||
1229 | } |
||
1230 | |||
1231 | if ( ! isset( $_POST['order_item_ids'] ) ) { |
||
1232 | throw new Exception( __( 'Invalid items', 'woocommerce' ) ); |
||
1233 | } |
||
1234 | |||
1235 | $order_item_ids = wp_unslash( $_POST['order_item_ids'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
1236 | $items = ( ! empty( $_POST['items'] ) ) ? wp_unslash( $_POST['items'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
1237 | $calculate_tax_args = array( |
||
1238 | 'country' => isset( $_POST['country'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['country'] ) ) ) : '', |
||
1239 | 'state' => isset( $_POST['state'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['state'] ) ) ) : '', |
||
1240 | 'postcode' => isset( $_POST['postcode'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['postcode'] ) ) ) : '', |
||
1241 | 'city' => isset( $_POST['city'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['city'] ) ) ) : '', |
||
1242 | ); |
||
1243 | |||
1244 | if ( ! is_array( $order_item_ids ) && is_numeric( $order_item_ids ) ) { |
||
1245 | $order_item_ids = array( $order_item_ids ); |
||
1246 | } |
||
1247 | |||
1248 | // If we passed through items it means we need to save first before deleting. |
||
1249 | View Code Duplication | if ( ! empty( $items ) ) { |
|
1250 | $save_items = array(); |
||
1251 | parse_str( $items, $save_items ); |
||
1252 | wc_save_order_items( $order->get_id(), $save_items ); |
||
1253 | } |
||
1254 | |||
1255 | if ( ! empty( $order_item_ids ) ) { |
||
1256 | $order_notes = array(); |
||
1257 | |||
1258 | foreach ( $order_item_ids as $item_id ) { |
||
1259 | $item_id = absint( $item_id ); |
||
1260 | $item = $order->get_item( $item_id ); |
||
1261 | |||
1262 | // Before deleting the item, adjust any stock values already reduced. |
||
1263 | if ( $item->is_type( 'line_item' ) ) { |
||
1264 | $changed_stock = wc_maybe_adjust_line_item_product_stock( $item, 0 ); |
||
1265 | |||
1266 | if ( $changed_stock && ! is_wp_error( $changed_stock ) ) { |
||
1267 | /* translators: %1$s: item name %2$s: stock change */ |
||
1268 | $order->add_order_note( sprintf( __( 'Deleted %1$s and adjusted stock (%2$s)', 'woocommerce' ), $item->get_name(), $changed_stock['from'] . '→' . $changed_stock['to'] ), false, true ); |
||
1269 | } else { |
||
1270 | /* translators: %s item name. */ |
||
1271 | $order->add_order_note( sprintf( __( 'Deleted %s', 'woocommerce' ), $item->get_name() ), false, true ); |
||
1272 | } |
||
1273 | } |
||
1274 | |||
1275 | wc_delete_order_item( $item_id ); |
||
1276 | } |
||
1277 | } |
||
1278 | |||
1279 | $order = wc_get_order( $order_id ); |
||
1280 | $order->calculate_taxes( $calculate_tax_args ); |
||
1281 | $order->calculate_totals( false ); |
||
1282 | |||
1283 | // Get HTML to return. |
||
1284 | ob_start(); |
||
1285 | include 'admin/meta-boxes/views/html-order-items.php'; |
||
1286 | $items_html = ob_get_clean(); |
||
1287 | |||
1288 | ob_start(); |
||
1289 | $notes = wc_get_order_notes( array( 'order_id' => $order_id ) ); |
||
1290 | include 'admin/meta-boxes/views/html-order-notes.php'; |
||
1291 | $notes_html = ob_get_clean(); |
||
1292 | |||
1293 | wp_send_json_success( |
||
1294 | array( |
||
1295 | 'html' => $items_html, |
||
1296 | 'notes_html' => $notes_html, |
||
1297 | ) |
||
1298 | ); |
||
1299 | } catch ( Exception $e ) { |
||
1300 | wp_send_json_error( array( 'error' => $e->getMessage() ) ); |
||
1301 | } |
||
1302 | |||
1303 | // wp_send_json_success must be outside the try block not to break phpunit tests. |
||
1304 | wp_send_json_success( $response ); |
||
1305 | } |
||
1306 | |||
1307 | /** |
||
1308 | * Remove an order tax. |
||
1309 | * |
||
1310 | * @throws Exception If there is an error whilst deleting the rate. |
||
1311 | */ |
||
1312 | public static function remove_order_tax() { |
||
1313 | check_ajax_referer( 'order-item', 'security' ); |
||
1314 | |||
1315 | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['order_id'], $_POST['rate_id'] ) ) { |
||
1316 | wp_die( -1 ); |
||
1317 | } |
||
1318 | |||
1319 | $response = array(); |
||
1320 | |||
1321 | try { |
||
1322 | $order_id = absint( $_POST['order_id'] ); |
||
1323 | $rate_id = absint( $_POST['rate_id'] ); |
||
1324 | |||
1325 | wc_delete_order_item( $rate_id ); |
||
1326 | |||
1327 | $order = wc_get_order( $order_id ); |
||
1328 | $order->calculate_totals( false ); |
||
1329 | |||
1330 | ob_start(); |
||
1331 | include 'admin/meta-boxes/views/html-order-items.php'; |
||
1332 | $response['html'] = ob_get_clean(); |
||
1333 | } catch ( Exception $e ) { |
||
1334 | wp_send_json_error( array( 'error' => $e->getMessage() ) ); |
||
1335 | } |
||
1336 | |||
1337 | // wp_send_json_success must be outside the try block not to break phpunit tests. |
||
1338 | wp_send_json_success( $response ); |
||
1339 | } |
||
1340 | |||
1341 | /** |
||
1342 | * Calc line tax. |
||
1343 | */ |
||
1344 | public static function calc_line_taxes() { |
||
1345 | check_ajax_referer( 'calc-totals', 'security' ); |
||
1346 | |||
1347 | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['order_id'], $_POST['items'] ) ) { |
||
1348 | wp_die( -1 ); |
||
1349 | } |
||
1350 | |||
1351 | $order_id = absint( $_POST['order_id'] ); |
||
1352 | $calculate_tax_args = array( |
||
1353 | 'country' => isset( $_POST['country'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['country'] ) ) ) : '', |
||
1354 | 'state' => isset( $_POST['state'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['state'] ) ) ) : '', |
||
1355 | 'postcode' => isset( $_POST['postcode'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['postcode'] ) ) ) : '', |
||
1356 | 'city' => isset( $_POST['city'] ) ? wc_strtoupper( wc_clean( wp_unslash( $_POST['city'] ) ) ) : '', |
||
1357 | ); |
||
1358 | |||
1359 | // Parse the jQuery serialized items. |
||
1360 | $items = array(); |
||
1361 | parse_str( wp_unslash( $_POST['items'] ), $items ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
1362 | |||
1363 | // Save order items first. |
||
1364 | wc_save_order_items( $order_id, $items ); |
||
1365 | |||
1366 | // Grab the order and recalculate taxes. |
||
1367 | $order = wc_get_order( $order_id ); |
||
1368 | $order->calculate_taxes( $calculate_tax_args ); |
||
1369 | $order->calculate_totals( false ); |
||
1370 | include 'admin/meta-boxes/views/html-order-items.php'; |
||
1371 | wp_die(); |
||
1372 | } |
||
1373 | |||
1374 | /** |
||
1375 | * Save order items via ajax. |
||
1376 | */ |
||
1377 | public static function save_order_items() { |
||
1378 | check_ajax_referer( 'order-item', 'security' ); |
||
1379 | |||
1380 | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['order_id'], $_POST['items'] ) ) { |
||
1381 | wp_die( -1 ); |
||
1382 | } |
||
1383 | |||
1384 | if ( isset( $_POST['order_id'], $_POST['items'] ) ) { |
||
1385 | $order_id = absint( $_POST['order_id'] ); |
||
1386 | |||
1387 | // Parse the jQuery serialized items. |
||
1388 | $items = array(); |
||
1389 | parse_str( wp_unslash( $_POST['items'] ), $items ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
1390 | |||
1391 | // Save order items. |
||
1392 | wc_save_order_items( $order_id, $items ); |
||
1393 | |||
1394 | // Return HTML items. |
||
1395 | $order = wc_get_order( $order_id ); |
||
1396 | |||
1397 | // Get HTML to return. |
||
1398 | ob_start(); |
||
1399 | include 'admin/meta-boxes/views/html-order-items.php'; |
||
1400 | $items_html = ob_get_clean(); |
||
1401 | |||
1402 | ob_start(); |
||
1403 | $notes = wc_get_order_notes( array( 'order_id' => $order_id ) ); |
||
1404 | include 'admin/meta-boxes/views/html-order-notes.php'; |
||
1405 | $notes_html = ob_get_clean(); |
||
1406 | |||
1407 | wp_send_json_success( |
||
1408 | array( |
||
1409 | 'html' => $items_html, |
||
1410 | 'notes_html' => $notes_html, |
||
1411 | ) |
||
1412 | ); |
||
1413 | } |
||
1414 | wp_die(); |
||
1415 | } |
||
1416 | |||
1417 | /** |
||
1418 | * Load order items via ajax. |
||
1419 | */ |
||
1420 | View Code Duplication | public static function load_order_items() { |
|
1421 | check_ajax_referer( 'order-item', 'security' ); |
||
1422 | |||
1423 | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['order_id'] ) ) { |
||
1424 | wp_die( -1 ); |
||
1425 | } |
||
1426 | |||
1427 | // Return HTML items. |
||
1428 | $order_id = absint( $_POST['order_id'] ); |
||
1429 | $order = wc_get_order( $order_id ); |
||
1430 | include 'admin/meta-boxes/views/html-order-items.php'; |
||
1431 | wp_die(); |
||
1432 | } |
||
1433 | |||
1434 | /** |
||
1435 | * Add order note via ajax. |
||
1436 | */ |
||
1437 | public static function add_order_note() { |
||
1438 | check_ajax_referer( 'add-order-note', 'security' ); |
||
1439 | |||
1440 | View Code Duplication | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['post_id'], $_POST['note'], $_POST['note_type'] ) ) { |
|
1441 | wp_die( -1 ); |
||
1442 | } |
||
1443 | |||
1444 | $post_id = absint( $_POST['post_id'] ); |
||
1445 | $note = wp_kses_post( trim( wp_unslash( $_POST['note'] ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
1446 | $note_type = wc_clean( wp_unslash( $_POST['note_type'] ) ); |
||
1447 | |||
1448 | $is_customer_note = ( 'customer' === $note_type ) ? 1 : 0; |
||
1449 | |||
1450 | if ( $post_id > 0 ) { |
||
1451 | $order = wc_get_order( $post_id ); |
||
1452 | $comment_id = $order->add_order_note( $note, $is_customer_note, true ); |
||
1453 | $note = wc_get_order_note( $comment_id ); |
||
1454 | |||
1455 | $note_classes = array( 'note' ); |
||
1456 | $note_classes[] = $is_customer_note ? 'customer-note' : ''; |
||
1457 | $note_classes = apply_filters( 'woocommerce_order_note_class', array_filter( $note_classes ), $note ); |
||
1458 | ?> |
||
1459 | <li rel="<?php echo absint( $note->id ); ?>" class="<?php echo esc_attr( implode( ' ', $note_classes ) ); ?>"> |
||
1460 | <div class="note_content"> |
||
1461 | <?php echo wp_kses_post( wpautop( wptexturize( make_clickable( $note->content ) ) ) ); ?> |
||
1462 | </div> |
||
1463 | <p class="meta"> |
||
1464 | <abbr class="exact-date" title="<?php echo esc_attr( $note->date_created->date( 'y-m-d h:i:s' ) ); ?>"> |
||
1465 | <?php |
||
1466 | /* translators: $1: Date created, $2 Time created */ |
||
1467 | printf( esc_html__( 'added on %1$s at %2$s', 'woocommerce' ), esc_html( $note->date_created->date_i18n( wc_date_format() ) ), esc_html( $note->date_created->date_i18n( wc_time_format() ) ) ); |
||
1468 | ?> |
||
1469 | </abbr> |
||
1470 | <?php |
||
1471 | if ( 'system' !== $note->added_by ) : |
||
1472 | /* translators: %s: note author */ |
||
1473 | printf( ' ' . esc_html__( 'by %s', 'woocommerce' ), esc_html( $note->added_by ) ); |
||
1474 | endif; |
||
1475 | ?> |
||
1476 | <a href="#" class="delete_note" role="button"><?php esc_html_e( 'Delete note', 'woocommerce' ); ?></a> |
||
1477 | </p> |
||
1478 | </li> |
||
1479 | <?php |
||
1480 | } |
||
1481 | wp_die(); |
||
1482 | } |
||
1483 | |||
1484 | /** |
||
1485 | * Delete order note via ajax. |
||
1486 | */ |
||
1487 | View Code Duplication | public static function delete_order_note() { |
|
1488 | check_ajax_referer( 'delete-order-note', 'security' ); |
||
1489 | |||
1490 | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['note_id'] ) ) { |
||
1491 | wp_die( -1 ); |
||
1492 | } |
||
1493 | |||
1494 | $note_id = (int) $_POST['note_id']; |
||
1495 | |||
1496 | if ( $note_id > 0 ) { |
||
1497 | wc_delete_order_note( $note_id ); |
||
1498 | } |
||
1499 | wp_die(); |
||
1500 | } |
||
1501 | |||
1502 | /** |
||
1503 | * Search for products and echo json. |
||
1504 | * |
||
1505 | * @param string $term (default: '') Term to search for. |
||
1506 | * @param bool $include_variations in search or not. |
||
1507 | */ |
||
1508 | public static function json_search_products( $term = '', $include_variations = false ) { |
||
1509 | check_ajax_referer( 'search-products', 'security' ); |
||
1510 | |||
1511 | View Code Duplication | if ( empty( $term ) && isset( $_GET['term'] ) ) { |
|
1512 | $term = (string) wc_clean( wp_unslash( $_GET['term'] ) ); |
||
1513 | } |
||
1514 | |||
1515 | if ( empty( $term ) ) { |
||
1516 | wp_die(); |
||
1517 | } |
||
1518 | |||
1519 | View Code Duplication | if ( ! empty( $_GET['limit'] ) ) { |
|
1520 | $limit = absint( $_GET['limit'] ); |
||
1521 | } else { |
||
1522 | $limit = absint( apply_filters( 'woocommerce_json_search_limit', 30 ) ); |
||
1523 | } |
||
1524 | |||
1525 | $include_ids = ! empty( $_GET['include'] ) ? array_map( 'absint', (array) wp_unslash( $_GET['include'] ) ) : array(); |
||
1526 | $exclude_ids = ! empty( $_GET['exclude'] ) ? array_map( 'absint', (array) wp_unslash( $_GET['exclude'] ) ) : array(); |
||
1527 | |||
1528 | $data_store = WC_Data_Store::load( 'product' ); |
||
1529 | $ids = $data_store->search_products( $term, '', (bool) $include_variations, false, $limit, $include_ids, $exclude_ids ); |
||
1530 | |||
1531 | $product_objects = array_filter( array_map( 'wc_get_product', $ids ), 'wc_products_array_filter_readable' ); |
||
1532 | $products = array(); |
||
1533 | |||
1534 | foreach ( $product_objects as $product_object ) { |
||
1535 | $formatted_name = $product_object->get_formatted_name(); |
||
1536 | $managing_stock = $product_object->managing_stock(); |
||
1537 | |||
1538 | if ( $managing_stock && ! empty( $_GET['display_stock'] ) ) { |
||
1539 | $stock_amount = $product_object->get_stock_quantity(); |
||
1540 | /* Translators: %d stock amount */ |
||
1541 | $formatted_name .= ' – ' . sprintf( __( 'Stock: %d', 'woocommerce' ), wc_format_stock_quantity_for_display( $stock_amount, $product_object ) ); |
||
1542 | } |
||
1543 | |||
1544 | $products[ $product_object->get_id() ] = rawurldecode( $formatted_name ); |
||
1545 | } |
||
1546 | |||
1547 | wp_send_json( apply_filters( 'woocommerce_json_search_found_products', $products ) ); |
||
1548 | } |
||
1549 | |||
1550 | /** |
||
1551 | * Search for product variations and return json. |
||
1552 | * |
||
1553 | * @see WC_AJAX::json_search_products() |
||
1554 | */ |
||
1555 | public static function json_search_products_and_variations() { |
||
1556 | self::json_search_products( '', true ); |
||
1557 | } |
||
1558 | |||
1559 | /** |
||
1560 | * Search for downloadable product variations and return json. |
||
1561 | * |
||
1562 | * @see WC_AJAX::json_search_products() |
||
1563 | */ |
||
1564 | public static function json_search_downloadable_products_and_variations() { |
||
1565 | check_ajax_referer( 'search-products', 'security' ); |
||
1566 | |||
1567 | View Code Duplication | if ( ! empty( $_GET['limit'] ) ) { |
|
1568 | $limit = absint( $_GET['limit'] ); |
||
1569 | } else { |
||
1570 | $limit = absint( apply_filters( 'woocommerce_json_search_limit', 30 ) ); |
||
1571 | } |
||
1572 | |||
1573 | $include_ids = ! empty( $_GET['include'] ) ? array_map( 'absint', (array) wp_unslash( $_GET['include'] ) ) : array(); |
||
1574 | $exclude_ids = ! empty( $_GET['exclude'] ) ? array_map( 'absint', (array) wp_unslash( $_GET['exclude'] ) ) : array(); |
||
1575 | |||
1576 | $term = isset( $_GET['term'] ) ? (string) wc_clean( wp_unslash( $_GET['term'] ) ) : ''; |
||
1577 | $data_store = WC_Data_Store::load( 'product' ); |
||
1578 | $ids = $data_store->search_products( $term, 'downloadable', true, false, $limit ); |
||
1579 | |||
1580 | $product_objects = array_filter( array_map( 'wc_get_product', $ids ), 'wc_products_array_filter_readable' ); |
||
1581 | $products = array(); |
||
1582 | |||
1583 | foreach ( $product_objects as $product_object ) { |
||
1584 | $products[ $product_object->get_id() ] = rawurldecode( $product_object->get_formatted_name() ); |
||
1585 | } |
||
1586 | |||
1587 | wp_send_json( $products ); |
||
1588 | } |
||
1589 | |||
1590 | /** |
||
1591 | * Search for customers and return json. |
||
1592 | */ |
||
1593 | public static function json_search_customers() { |
||
1594 | ob_start(); |
||
1595 | |||
1596 | check_ajax_referer( 'search-customers', 'security' ); |
||
1597 | |||
1598 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1599 | wp_die( -1 ); |
||
1600 | } |
||
1601 | |||
1602 | $term = isset( $_GET['term'] ) ? (string) wc_clean( wp_unslash( $_GET['term'] ) ) : ''; |
||
1603 | $limit = 0; |
||
1604 | |||
1605 | if ( empty( $term ) ) { |
||
1606 | wp_die(); |
||
1607 | } |
||
1608 | |||
1609 | $ids = array(); |
||
1610 | // Search by ID. |
||
1611 | if ( is_numeric( $term ) ) { |
||
1612 | $customer = new WC_Customer( intval( $term ) ); |
||
1613 | |||
1614 | // Customer does not exists. |
||
1615 | if ( 0 !== $customer->get_id() ) { |
||
1616 | $ids = array( $customer->get_id() ); |
||
1617 | } |
||
1618 | } |
||
1619 | |||
1620 | // Usernames can be numeric so we first check that no users was found by ID before searching for numeric username, this prevents performance issues with ID lookups. |
||
1621 | if ( empty( $ids ) ) { |
||
1622 | $data_store = WC_Data_Store::load( 'customer' ); |
||
1623 | |||
1624 | // If search is smaller than 3 characters, limit result set to avoid |
||
1625 | // too many rows being returned. |
||
1626 | if ( 3 > strlen( $term ) ) { |
||
1627 | $limit = 20; |
||
1628 | } |
||
1629 | $ids = $data_store->search_customers( $term, $limit ); |
||
1630 | } |
||
1631 | |||
1632 | $found_customers = array(); |
||
1633 | |||
1634 | if ( ! empty( $_GET['exclude'] ) ) { |
||
1635 | $ids = array_diff( $ids, array_map( 'absint', (array) wp_unslash( $_GET['exclude'] ) ) ); |
||
1636 | } |
||
1637 | |||
1638 | foreach ( $ids as $id ) { |
||
1639 | $customer = new WC_Customer( $id ); |
||
1640 | /* translators: 1: user display name 2: user ID 3: user email */ |
||
1641 | $found_customers[ $id ] = sprintf( |
||
1642 | /* translators: $1: customer name, $2 customer id, $3: customer email */ |
||
1643 | esc_html__( '%1$s (#%2$s – %3$s)', 'woocommerce' ), |
||
1644 | $customer->get_first_name() . ' ' . $customer->get_last_name(), |
||
1645 | $customer->get_id(), |
||
1646 | $customer->get_email() |
||
1647 | ); |
||
1648 | } |
||
1649 | |||
1650 | wp_send_json( apply_filters( 'woocommerce_json_search_found_customers', $found_customers ) ); |
||
1651 | } |
||
1652 | |||
1653 | /** |
||
1654 | * Search for categories and return json. |
||
1655 | */ |
||
1656 | public static function json_search_categories() { |
||
1657 | ob_start(); |
||
1658 | |||
1659 | check_ajax_referer( 'search-categories', 'security' ); |
||
1660 | |||
1661 | if ( ! current_user_can( 'edit_products' ) ) { |
||
1662 | wp_die( -1 ); |
||
1663 | } |
||
1664 | |||
1665 | $search_text = isset( $_GET['term'] ) ? wc_clean( wp_unslash( $_GET['term'] ) ) : ''; |
||
1666 | |||
1667 | if ( ! $search_text ) { |
||
1668 | wp_die(); |
||
1669 | } |
||
1670 | |||
1671 | $found_categories = array(); |
||
1672 | $args = array( |
||
1673 | 'taxonomy' => array( 'product_cat' ), |
||
1674 | 'orderby' => 'id', |
||
1675 | 'order' => 'ASC', |
||
1676 | 'hide_empty' => true, |
||
1677 | 'fields' => 'all', |
||
1678 | 'name__like' => $search_text, |
||
1679 | ); |
||
1680 | |||
1681 | $terms = get_terms( $args ); |
||
1682 | |||
1683 | if ( $terms ) { |
||
1684 | foreach ( $terms as $term ) { |
||
1685 | $term->formatted_name = ''; |
||
1686 | |||
1687 | if ( $term->parent ) { |
||
1688 | $ancestors = array_reverse( get_ancestors( $term->term_id, 'product_cat' ) ); |
||
1689 | foreach ( $ancestors as $ancestor ) { |
||
1690 | $ancestor_term = get_term( $ancestor, 'product_cat' ); |
||
1691 | if ( $ancestor_term ) { |
||
1692 | $term->formatted_name .= $ancestor_term->name . ' > '; |
||
1693 | } |
||
1694 | } |
||
1695 | } |
||
1696 | |||
1697 | $term->formatted_name .= $term->name . ' (' . $term->count . ')'; |
||
1698 | $found_categories[ $term->term_id ] = $term; |
||
1699 | } |
||
1700 | } |
||
1701 | |||
1702 | wp_send_json( apply_filters( 'woocommerce_json_search_found_categories', $found_categories ) ); |
||
1703 | } |
||
1704 | |||
1705 | /** |
||
1706 | * Ajax request handling for categories ordering. |
||
1707 | */ |
||
1708 | public static function term_ordering() { |
||
1709 | // phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification |
||
1710 | if ( ! current_user_can( 'edit_products' ) || empty( $_POST['id'] ) ) { |
||
1711 | wp_die( -1 ); |
||
1712 | } |
||
1713 | |||
1714 | $id = (int) $_POST['id']; |
||
1715 | $next_id = isset( $_POST['nextid'] ) && (int) $_POST['nextid'] ? (int) $_POST['nextid'] : null; |
||
1716 | $taxonomy = isset( $_POST['thetaxonomy'] ) ? esc_attr( wp_unslash( $_POST['thetaxonomy'] ) ) : null; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
1717 | $term = get_term_by( 'id', $id, $taxonomy ); |
||
1718 | |||
1719 | if ( ! $id || ! $term || ! $taxonomy ) { |
||
1720 | wp_die( 0 ); |
||
1721 | } |
||
1722 | |||
1723 | wc_reorder_terms( $term, $next_id, $taxonomy ); |
||
1724 | |||
1725 | $children = get_terms( $taxonomy, "child_of=$id&menu_order=ASC&hide_empty=0" ); |
||
1726 | |||
1727 | if ( $term && count( $children ) ) { |
||
1728 | echo 'children'; |
||
1729 | wp_die(); |
||
1730 | } |
||
1731 | // phpcs:enable |
||
1732 | } |
||
1733 | |||
1734 | /** |
||
1735 | * Ajax request handling for product ordering. |
||
1736 | * |
||
1737 | * Based on Simple Page Ordering by 10up (https://wordpress.org/plugins/simple-page-ordering/). |
||
1738 | */ |
||
1739 | public static function product_ordering() { |
||
1740 | global $wpdb; |
||
1741 | |||
1742 | // phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification |
||
1743 | if ( ! current_user_can( 'edit_products' ) || empty( $_POST['id'] ) ) { |
||
1744 | wp_die( -1 ); |
||
1745 | } |
||
1746 | |||
1747 | $sorting_id = absint( $_POST['id'] ); |
||
1748 | $previd = absint( isset( $_POST['previd'] ) ? $_POST['previd'] : 0 ); |
||
1749 | $nextid = absint( isset( $_POST['nextid'] ) ? $_POST['nextid'] : 0 ); |
||
1750 | $menu_orders = wp_list_pluck( $wpdb->get_results( "SELECT ID, menu_order FROM {$wpdb->posts} WHERE post_type = 'product' ORDER BY menu_order ASC, post_title ASC" ), 'menu_order', 'ID' ); |
||
1751 | $index = 0; |
||
1752 | |||
1753 | foreach ( $menu_orders as $id => $menu_order ) { |
||
1754 | $id = absint( $id ); |
||
1755 | |||
1756 | if ( $sorting_id === $id ) { |
||
1757 | continue; |
||
1758 | } |
||
1759 | if ( $nextid === $id ) { |
||
1760 | $index ++; |
||
1761 | } |
||
1762 | $index ++; |
||
1763 | $menu_orders[ $id ] = $index; |
||
1764 | $wpdb->update( $wpdb->posts, array( 'menu_order' => $index ), array( 'ID' => $id ) ); |
||
1765 | |||
1766 | /** |
||
1767 | * When a single product has gotten it's ordering updated. |
||
1768 | * $id The product ID |
||
1769 | * $index The new menu order |
||
1770 | */ |
||
1771 | do_action( 'woocommerce_after_single_product_ordering', $id, $index ); |
||
1772 | } |
||
1773 | |||
1774 | if ( isset( $menu_orders[ $previd ] ) ) { |
||
1775 | $menu_orders[ $sorting_id ] = $menu_orders[ $previd ] + 1; |
||
1776 | } elseif ( isset( $menu_orders[ $nextid ] ) ) { |
||
1777 | $menu_orders[ $sorting_id ] = $menu_orders[ $nextid ] - 1; |
||
1778 | } else { |
||
1779 | $menu_orders[ $sorting_id ] = 0; |
||
1780 | } |
||
1781 | |||
1782 | $wpdb->update( $wpdb->posts, array( 'menu_order' => $menu_orders[ $sorting_id ] ), array( 'ID' => $sorting_id ) ); |
||
1783 | |||
1784 | do_action( 'woocommerce_after_product_ordering', $sorting_id, $menu_orders ); |
||
1785 | wp_send_json( $menu_orders ); |
||
1786 | // phpcs:enable |
||
1787 | } |
||
1788 | |||
1789 | /** |
||
1790 | * Handle a refund via the edit order screen. |
||
1791 | * |
||
1792 | * @throws Exception To return errors. |
||
1793 | */ |
||
1794 | public static function refund_line_items() { |
||
1795 | ob_start(); |
||
1796 | |||
1797 | check_ajax_referer( 'order-item', 'security' ); |
||
1798 | |||
1799 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1800 | wp_die( -1 ); |
||
1801 | } |
||
1802 | |||
1803 | $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0; |
||
1804 | $refund_amount = isset( $_POST['refund_amount'] ) ? wc_format_decimal( sanitize_text_field( wp_unslash( $_POST['refund_amount'] ) ), wc_get_price_decimals() ) : 0; |
||
1805 | $refunded_amount = isset( $_POST['refunded_amount'] ) ? wc_format_decimal( sanitize_text_field( wp_unslash( $_POST['refunded_amount'] ) ), wc_get_price_decimals() ) : 0; |
||
1806 | $refund_reason = isset( $_POST['refund_reason'] ) ? sanitize_text_field( wp_unslash( $_POST['refund_reason'] ) ) : ''; |
||
1807 | $line_item_qtys = isset( $_POST['line_item_qtys'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['line_item_qtys'] ) ), true ) : array(); |
||
1808 | $line_item_totals = isset( $_POST['line_item_totals'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['line_item_totals'] ) ), true ) : array(); |
||
1809 | $line_item_tax_totals = isset( $_POST['line_item_tax_totals'] ) ? json_decode( sanitize_text_field( wp_unslash( $_POST['line_item_tax_totals'] ) ), true ) : array(); |
||
1810 | $api_refund = isset( $_POST['api_refund'] ) && 'true' === $_POST['api_refund']; |
||
1811 | $restock_refunded_items = isset( $_POST['restock_refunded_items'] ) && 'true' === $_POST['restock_refunded_items']; |
||
1812 | $refund = false; |
||
1813 | $response = array(); |
||
1814 | |||
1815 | try { |
||
1816 | $order = wc_get_order( $order_id ); |
||
1817 | $order_items = $order->get_items(); |
||
1818 | $max_refund = wc_format_decimal( $order->get_total() - $order->get_total_refunded(), wc_get_price_decimals() ); |
||
1819 | |||
1820 | if ( ! $refund_amount || $max_refund < $refund_amount || 0 > $refund_amount ) { |
||
1821 | throw new Exception( __( 'Invalid refund amount', 'woocommerce' ) ); |
||
1822 | } |
||
1823 | |||
1824 | if ( wc_format_decimal( $order->get_total_refunded(), wc_get_price_decimals() ) !== $refunded_amount ) { |
||
1825 | throw new Exception( __( 'Error processing refund. Please try again.', 'woocommerce' ) ); |
||
1826 | } |
||
1827 | |||
1828 | // Prepare line items which we are refunding. |
||
1829 | $line_items = array(); |
||
1830 | $item_ids = array_unique( array_merge( array_keys( $line_item_qtys ), array_keys( $line_item_totals ) ) ); |
||
1831 | |||
1832 | foreach ( $item_ids as $item_id ) { |
||
1833 | $line_items[ $item_id ] = array( |
||
1834 | 'qty' => 0, |
||
1835 | 'refund_total' => 0, |
||
1836 | 'refund_tax' => array(), |
||
1837 | ); |
||
1838 | } |
||
1839 | foreach ( $line_item_qtys as $item_id => $qty ) { |
||
1840 | $line_items[ $item_id ]['qty'] = max( $qty, 0 ); |
||
1841 | } |
||
1842 | foreach ( $line_item_totals as $item_id => $total ) { |
||
1843 | $line_items[ $item_id ]['refund_total'] = wc_format_decimal( $total ); |
||
1844 | } |
||
1845 | foreach ( $line_item_tax_totals as $item_id => $tax_totals ) { |
||
1846 | $line_items[ $item_id ]['refund_tax'] = array_filter( array_map( 'wc_format_decimal', $tax_totals ) ); |
||
1847 | } |
||
1848 | |||
1849 | // Create the refund object. |
||
1850 | $refund = wc_create_refund( |
||
1851 | array( |
||
1852 | 'amount' => $refund_amount, |
||
1853 | 'reason' => $refund_reason, |
||
1854 | 'order_id' => $order_id, |
||
1855 | 'line_items' => $line_items, |
||
1856 | 'refund_payment' => $api_refund, |
||
1857 | 'restock_items' => $restock_refunded_items, |
||
1858 | ) |
||
1859 | ); |
||
1860 | |||
1861 | if ( is_wp_error( $refund ) ) { |
||
1862 | throw new Exception( $refund->get_error_message() ); |
||
1863 | } |
||
1864 | |||
1865 | if ( did_action( 'woocommerce_order_fully_refunded' ) ) { |
||
1866 | $response['status'] = 'fully_refunded'; |
||
1867 | } |
||
1868 | } catch ( Exception $e ) { |
||
1869 | wp_send_json_error( array( 'error' => $e->getMessage() ) ); |
||
1870 | } |
||
1871 | |||
1872 | // wp_send_json_success must be outside the try block not to break phpunit tests. |
||
1873 | wp_send_json_success( $response ); |
||
1874 | } |
||
1875 | |||
1876 | /** |
||
1877 | * Delete a refund. |
||
1878 | */ |
||
1879 | public static function delete_refund() { |
||
1880 | check_ajax_referer( 'order-item', 'security' ); |
||
1881 | |||
1882 | if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['refund_id'] ) ) { |
||
1883 | wp_die( -1 ); |
||
1884 | } |
||
1885 | |||
1886 | $refund_ids = array_map( 'absint', is_array( $_POST['refund_id'] ) ? wp_unslash( $_POST['refund_id'] ) : array( wp_unslash( $_POST['refund_id'] ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
1887 | foreach ( $refund_ids as $refund_id ) { |
||
1888 | if ( $refund_id && 'shop_order_refund' === get_post_type( $refund_id ) ) { |
||
1889 | $refund = wc_get_order( $refund_id ); |
||
1890 | $order_id = $refund->get_parent_id(); |
||
1891 | $refund->delete( true ); |
||
1892 | do_action( 'woocommerce_refund_deleted', $refund_id, $order_id ); |
||
1893 | } |
||
1894 | } |
||
1895 | wp_die(); |
||
1896 | } |
||
1897 | |||
1898 | /** |
||
1899 | * Triggered when clicking the rating footer. |
||
1900 | */ |
||
1901 | public static function rated() { |
||
1902 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
1903 | wp_die( -1 ); |
||
1904 | } |
||
1905 | update_option( 'woocommerce_admin_footer_text_rated', 1 ); |
||
1906 | wp_die(); |
||
1907 | } |
||
1908 | |||
1909 | /** |
||
1910 | * Create/Update API key. |
||
1911 | * |
||
1912 | * @throws Exception On invalid or empty description, user, or permissions. |
||
1913 | */ |
||
1914 | public static function update_api_key() { |
||
1915 | ob_start(); |
||
1916 | |||
1917 | global $wpdb; |
||
1918 | |||
1919 | check_ajax_referer( 'update-api-key', 'security' ); |
||
1920 | |||
1921 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
1922 | wp_die( -1 ); |
||
1923 | } |
||
1924 | |||
1925 | $response = array(); |
||
1926 | |||
1927 | try { |
||
1928 | if ( empty( $_POST['description'] ) ) { |
||
1929 | throw new Exception( __( 'Description is missing.', 'woocommerce' ) ); |
||
1930 | } |
||
1931 | if ( empty( $_POST['user'] ) ) { |
||
1932 | throw new Exception( __( 'User is missing.', 'woocommerce' ) ); |
||
1933 | } |
||
1934 | if ( empty( $_POST['permissions'] ) ) { |
||
1935 | throw new Exception( __( 'Permissions is missing.', 'woocommerce' ) ); |
||
1936 | } |
||
1937 | |||
1938 | $key_id = isset( $_POST['key_id'] ) ? absint( $_POST['key_id'] ) : 0; |
||
1939 | $description = sanitize_text_field( wp_unslash( $_POST['description'] ) ); |
||
1940 | $permissions = ( in_array( wp_unslash( $_POST['permissions'] ), array( 'read', 'write', 'read_write' ), true ) ) ? sanitize_text_field( wp_unslash( $_POST['permissions'] ) ) : 'read'; |
||
1941 | $user_id = absint( $_POST['user'] ); |
||
1942 | |||
1943 | // Check if current user can edit other users. |
||
1944 | if ( $user_id && ! current_user_can( 'edit_user', $user_id ) ) { |
||
1945 | if ( get_current_user_id() !== $user_id ) { |
||
1946 | throw new Exception( __( 'You do not have permission to assign API Keys to the selected user.', 'woocommerce' ) ); |
||
1947 | } |
||
1948 | } |
||
1949 | |||
1950 | if ( 0 < $key_id ) { |
||
1951 | $data = array( |
||
1952 | 'user_id' => $user_id, |
||
1953 | 'description' => $description, |
||
1954 | 'permissions' => $permissions, |
||
1955 | ); |
||
1956 | |||
1957 | $wpdb->update( |
||
1958 | $wpdb->prefix . 'woocommerce_api_keys', |
||
1959 | $data, |
||
1960 | array( 'key_id' => $key_id ), |
||
1961 | array( |
||
1962 | '%d', |
||
1963 | '%s', |
||
1964 | '%s', |
||
1965 | ), |
||
1966 | array( '%d' ) |
||
1967 | ); |
||
1968 | |||
1969 | $response = $data; |
||
1970 | $response['consumer_key'] = ''; |
||
1971 | $response['consumer_secret'] = ''; |
||
1972 | $response['message'] = __( 'API Key updated successfully.', 'woocommerce' ); |
||
1973 | } else { |
||
1974 | $consumer_key = 'ck_' . wc_rand_hash(); |
||
1975 | $consumer_secret = 'cs_' . wc_rand_hash(); |
||
1976 | |||
1977 | $data = array( |
||
1978 | 'user_id' => $user_id, |
||
1979 | 'description' => $description, |
||
1980 | 'permissions' => $permissions, |
||
1981 | 'consumer_key' => wc_api_hash( $consumer_key ), |
||
1982 | 'consumer_secret' => $consumer_secret, |
||
1983 | 'truncated_key' => substr( $consumer_key, -7 ), |
||
1984 | ); |
||
1985 | |||
1986 | $wpdb->insert( |
||
1987 | $wpdb->prefix . 'woocommerce_api_keys', |
||
1988 | $data, |
||
1989 | array( |
||
1990 | '%d', |
||
1991 | '%s', |
||
1992 | '%s', |
||
1993 | '%s', |
||
1994 | '%s', |
||
1995 | '%s', |
||
1996 | ) |
||
1997 | ); |
||
1998 | |||
1999 | $key_id = $wpdb->insert_id; |
||
2000 | $response = $data; |
||
2001 | $response['consumer_key'] = $consumer_key; |
||
2002 | $response['consumer_secret'] = $consumer_secret; |
||
2003 | $response['message'] = __( 'API Key generated successfully. Make sure to copy your new keys now as the secret key will be hidden once you leave this page.', 'woocommerce' ); |
||
2004 | $response['revoke_url'] = '<a style="color: #a00; text-decoration: none;" href="' . esc_url( wp_nonce_url( add_query_arg( array( 'revoke-key' => $key_id ), admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=keys' ) ), 'revoke' ) ) . '">' . __( 'Revoke key', 'woocommerce' ) . '</a>'; |
||
2005 | } |
||
2006 | } catch ( Exception $e ) { |
||
2007 | wp_send_json_error( array( 'message' => $e->getMessage() ) ); |
||
2008 | } |
||
2009 | |||
2010 | // wp_send_json_success must be outside the try block not to break phpunit tests. |
||
2011 | wp_send_json_success( $response ); |
||
2012 | } |
||
2013 | |||
2014 | /** |
||
2015 | * Load variations via AJAX. |
||
2016 | */ |
||
2017 | public static function load_variations() { |
||
2018 | ob_start(); |
||
2019 | |||
2020 | check_ajax_referer( 'load-variations', 'security' ); |
||
2021 | |||
2022 | if ( ! current_user_can( 'edit_products' ) || empty( $_POST['product_id'] ) ) { |
||
2023 | wp_die( -1 ); |
||
2024 | } |
||
2025 | |||
2026 | // Set $post global so its available, like within the admin screens. |
||
2027 | global $post; |
||
2028 | |||
2029 | $loop = 0; |
||
2030 | $product_id = absint( $_POST['product_id'] ); |
||
2031 | $post = get_post( $product_id ); // phpcs:ignore |
||
2032 | $product_object = wc_get_product( $product_id ); |
||
2033 | $per_page = ! empty( $_POST['per_page'] ) ? absint( $_POST['per_page'] ) : 10; |
||
2034 | $page = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1; |
||
2035 | $variations = wc_get_products( |
||
2036 | array( |
||
2037 | 'status' => array( 'private', 'publish' ), |
||
2038 | 'type' => 'variation', |
||
2039 | 'parent' => $product_id, |
||
2040 | 'limit' => $per_page, |
||
2041 | 'page' => $page, |
||
2042 | 'orderby' => array( |
||
2043 | 'menu_order' => 'ASC', |
||
2044 | 'ID' => 'DESC', |
||
2045 | ), |
||
2046 | 'return' => 'objects', |
||
2047 | ) |
||
2048 | ); |
||
2049 | |||
2050 | if ( $variations ) { |
||
2051 | foreach ( $variations as $variation_object ) { |
||
2052 | $variation_id = $variation_object->get_id(); |
||
2053 | $variation = get_post( $variation_id ); |
||
2054 | $variation_data = array_merge( get_post_custom( $variation_id ), wc_get_product_variation_attributes( $variation_id ) ); // kept for BW compatibility. |
||
2055 | include 'admin/meta-boxes/views/html-variation-admin.php'; |
||
2056 | $loop++; |
||
2057 | } |
||
2058 | } |
||
2059 | wp_die(); |
||
2060 | } |
||
2061 | |||
2062 | /** |
||
2063 | * Save variations via AJAX. |
||
2064 | */ |
||
2065 | public static function save_variations() { |
||
2066 | ob_start(); |
||
2067 | |||
2068 | check_ajax_referer( 'save-variations', 'security' ); |
||
2069 | |||
2070 | // Check permissions again and make sure we have what we need. |
||
2071 | View Code Duplication | if ( ! current_user_can( 'edit_products' ) || empty( $_POST ) || empty( $_POST['product_id'] ) ) { |
|
2072 | wp_die( -1 ); |
||
2073 | } |
||
2074 | |||
2075 | $product_id = absint( $_POST['product_id'] ); |
||
2076 | WC_Admin_Meta_Boxes::$meta_box_errors = array(); |
||
2077 | WC_Meta_Box_Product_Data::save_variations( $product_id, get_post( $product_id ) ); |
||
2078 | |||
2079 | do_action( 'woocommerce_ajax_save_product_variations', $product_id ); |
||
2080 | |||
2081 | $errors = WC_Admin_Meta_Boxes::$meta_box_errors; |
||
2082 | |||
2083 | if ( $errors ) { |
||
2084 | echo '<div class="error notice is-dismissible">'; |
||
2085 | |||
2086 | foreach ( $errors as $error ) { |
||
2087 | echo '<p>' . wp_kses_post( $error ) . '</p>'; |
||
2088 | } |
||
2089 | |||
2090 | echo '<button type="button" class="notice-dismiss"><span class="screen-reader-text">' . esc_html__( 'Dismiss this notice.', 'woocommerce' ) . '</span></button>'; |
||
2091 | echo '</div>'; |
||
2092 | |||
2093 | delete_option( 'woocommerce_meta_box_errors' ); |
||
2094 | } |
||
2095 | |||
2096 | wp_die(); |
||
2097 | } |
||
2098 | |||
2099 | /** |
||
2100 | * Bulk action - Toggle Enabled. |
||
2101 | * |
||
2102 | * @param array $variations List of variations. |
||
2103 | * @param array $data Data to set. |
||
2104 | * |
||
2105 | * @used-by bulk_edit_variations |
||
2106 | */ |
||
2107 | private static function variation_bulk_action_toggle_enabled( $variations, $data ) { |
||
2108 | foreach ( $variations as $variation_id ) { |
||
2109 | $variation = wc_get_product( $variation_id ); |
||
2110 | $variation->set_status( 'private' === $variation->get_status( 'edit' ) ? 'publish' : 'private' ); |
||
2111 | $variation->save(); |
||
2112 | } |
||
2113 | } |
||
2114 | |||
2115 | /** |
||
2116 | * Bulk action - Toggle Downloadable Checkbox. |
||
2117 | * |
||
2118 | * @param array $variations List of variations. |
||
2119 | * @param array $data Data to set. |
||
2120 | * |
||
2121 | * @used-by bulk_edit_variations |
||
2122 | */ |
||
2123 | private static function variation_bulk_action_toggle_downloadable( $variations, $data ) { |
||
2124 | self::variation_bulk_toggle( $variations, 'downloadable' ); |
||
2125 | } |
||
2126 | |||
2127 | /** |
||
2128 | * Bulk action - Toggle Virtual Checkbox. |
||
2129 | * |
||
2130 | * @param array $variations List of variations. |
||
2131 | * @param array $data Data to set. |
||
2132 | * |
||
2133 | * @used-by bulk_edit_variations |
||
2134 | */ |
||
2135 | private static function variation_bulk_action_toggle_virtual( $variations, $data ) { |
||
2136 | self::variation_bulk_toggle( $variations, 'virtual' ); |
||
2137 | } |
||
2138 | |||
2139 | /** |
||
2140 | * Bulk action - Toggle Manage Stock Checkbox. |
||
2141 | * |
||
2142 | * @param array $variations List of variations. |
||
2143 | * @param array $data Data to set. |
||
2144 | * |
||
2145 | * @used-by bulk_edit_variations |
||
2146 | */ |
||
2147 | private static function variation_bulk_action_toggle_manage_stock( $variations, $data ) { |
||
2148 | self::variation_bulk_toggle( $variations, 'manage_stock' ); |
||
2149 | } |
||
2150 | |||
2151 | /** |
||
2152 | * Bulk action - Set Regular Prices. |
||
2153 | * |
||
2154 | * @param array $variations List of variations. |
||
2155 | * @param array $data Data to set. |
||
2156 | * |
||
2157 | * @used-by bulk_edit_variations |
||
2158 | */ |
||
2159 | private static function variation_bulk_action_variable_regular_price( $variations, $data ) { |
||
2160 | self::variation_bulk_set( $variations, 'regular_price', $data['value'] ); |
||
2161 | } |
||
2162 | |||
2163 | /** |
||
2164 | * Bulk action - Set Sale Prices. |
||
2165 | * |
||
2166 | * @param array $variations List of variations. |
||
2167 | * @param array $data Data to set. |
||
2168 | * |
||
2169 | * @used-by bulk_edit_variations |
||
2170 | */ |
||
2171 | private static function variation_bulk_action_variable_sale_price( $variations, $data ) { |
||
2172 | self::variation_bulk_set( $variations, 'sale_price', $data['value'] ); |
||
2173 | } |
||
2174 | |||
2175 | /** |
||
2176 | * Bulk action - Set Stock Status as In Stock. |
||
2177 | * |
||
2178 | * @param array $variations List of variations. |
||
2179 | * @param array $data Data to set. |
||
2180 | * |
||
2181 | * @used-by bulk_edit_variations |
||
2182 | */ |
||
2183 | private static function variation_bulk_action_variable_stock_status_instock( $variations, $data ) { |
||
2184 | self::variation_bulk_set( $variations, 'stock_status', 'instock' ); |
||
2185 | } |
||
2186 | |||
2187 | /** |
||
2188 | * Bulk action - Set Stock Status as Out of Stock. |
||
2189 | * |
||
2190 | * @param array $variations List of variations. |
||
2191 | * @param array $data Data to set. |
||
2192 | * |
||
2193 | * @used-by bulk_edit_variations |
||
2194 | */ |
||
2195 | private static function variation_bulk_action_variable_stock_status_outofstock( $variations, $data ) { |
||
2196 | self::variation_bulk_set( $variations, 'stock_status', 'outofstock' ); |
||
2197 | } |
||
2198 | |||
2199 | /** |
||
2200 | * Bulk action - Set Stock Status as On Backorder. |
||
2201 | * |
||
2202 | * @param array $variations List of variations. |
||
2203 | * @param array $data Data to set. |
||
2204 | * |
||
2205 | * @used-by bulk_edit_variations |
||
2206 | */ |
||
2207 | private static function variation_bulk_action_variable_stock_status_onbackorder( $variations, $data ) { |
||
2208 | self::variation_bulk_set( $variations, 'stock_status', 'onbackorder' ); |
||
2209 | } |
||
2210 | |||
2211 | /** |
||
2212 | * Bulk action - Set Stock. |
||
2213 | * |
||
2214 | * @param array $variations List of variations. |
||
2215 | * @param array $data Data to set. |
||
2216 | * |
||
2217 | * @used-by bulk_edit_variations |
||
2218 | */ |
||
2219 | private static function variation_bulk_action_variable_stock( $variations, $data ) { |
||
2220 | if ( ! isset( $data['value'] ) ) { |
||
2221 | return; |
||
2222 | } |
||
2223 | |||
2224 | $quantity = wc_stock_amount( wc_clean( $data['value'] ) ); |
||
2225 | |||
2226 | foreach ( $variations as $variation_id ) { |
||
2227 | $variation = wc_get_product( $variation_id ); |
||
2228 | if ( $variation->managing_stock() ) { |
||
2229 | $variation->set_stock_quantity( $quantity ); |
||
2230 | } else { |
||
2231 | $variation->set_stock_quantity( null ); |
||
2232 | } |
||
2233 | $variation->save(); |
||
2234 | } |
||
2235 | } |
||
2236 | |||
2237 | /** |
||
2238 | * Bulk action - Set Weight. |
||
2239 | * |
||
2240 | * @param array $variations List of variations. |
||
2241 | * @param array $data Data to set. |
||
2242 | * |
||
2243 | * @used-by bulk_edit_variations |
||
2244 | */ |
||
2245 | private static function variation_bulk_action_variable_weight( $variations, $data ) { |
||
2246 | self::variation_bulk_set( $variations, 'weight', $data['value'] ); |
||
2247 | } |
||
2248 | |||
2249 | /** |
||
2250 | * Bulk action - Set Length. |
||
2251 | * |
||
2252 | * @param array $variations List of variations. |
||
2253 | * @param array $data Data to set. |
||
2254 | * |
||
2255 | * @used-by bulk_edit_variations |
||
2256 | */ |
||
2257 | private static function variation_bulk_action_variable_length( $variations, $data ) { |
||
2258 | self::variation_bulk_set( $variations, 'length', $data['value'] ); |
||
2259 | } |
||
2260 | |||
2261 | /** |
||
2262 | * Bulk action - Set Width. |
||
2263 | * |
||
2264 | * @param array $variations List of variations. |
||
2265 | * @param array $data Data to set. |
||
2266 | * |
||
2267 | * @used-by bulk_edit_variations |
||
2268 | */ |
||
2269 | private static function variation_bulk_action_variable_width( $variations, $data ) { |
||
2270 | self::variation_bulk_set( $variations, 'width', $data['value'] ); |
||
2271 | } |
||
2272 | |||
2273 | /** |
||
2274 | * Bulk action - Set Height. |
||
2275 | * |
||
2276 | * @param array $variations List of variations. |
||
2277 | * @param array $data Data to set. |
||
2278 | * |
||
2279 | * @used-by bulk_edit_variations |
||
2280 | */ |
||
2281 | private static function variation_bulk_action_variable_height( $variations, $data ) { |
||
2282 | self::variation_bulk_set( $variations, 'height', $data['value'] ); |
||
2283 | } |
||
2284 | |||
2285 | /** |
||
2286 | * Bulk action - Set Download Limit. |
||
2287 | * |
||
2288 | * @param array $variations List of variations. |
||
2289 | * @param array $data Data to set. |
||
2290 | * |
||
2291 | * @used-by bulk_edit_variations |
||
2292 | */ |
||
2293 | private static function variation_bulk_action_variable_download_limit( $variations, $data ) { |
||
2294 | self::variation_bulk_set( $variations, 'download_limit', $data['value'] ); |
||
2295 | } |
||
2296 | |||
2297 | /** |
||
2298 | * Bulk action - Set Download Expiry. |
||
2299 | * |
||
2300 | * @param array $variations List of variations. |
||
2301 | * @param array $data Data to set. |
||
2302 | * |
||
2303 | * @used-by bulk_edit_variations |
||
2304 | */ |
||
2305 | private static function variation_bulk_action_variable_download_expiry( $variations, $data ) { |
||
2306 | self::variation_bulk_set( $variations, 'download_expiry', $data['value'] ); |
||
2307 | } |
||
2308 | |||
2309 | /** |
||
2310 | * Bulk action - Delete all. |
||
2311 | * |
||
2312 | * @param array $variations List of variations. |
||
2313 | * @param array $data Data to set. |
||
2314 | * |
||
2315 | * @used-by bulk_edit_variations |
||
2316 | */ |
||
2317 | private static function variation_bulk_action_delete_all( $variations, $data ) { |
||
2318 | if ( isset( $data['allowed'] ) && 'true' === $data['allowed'] ) { |
||
2319 | foreach ( $variations as $variation_id ) { |
||
2320 | $variation = wc_get_product( $variation_id ); |
||
2321 | $variation->delete( true ); |
||
2322 | } |
||
2323 | } |
||
2324 | } |
||
2325 | |||
2326 | /** |
||
2327 | * Bulk action - Sale Schedule. |
||
2328 | * |
||
2329 | * @param array $variations List of variations. |
||
2330 | * @param array $data Data to set. |
||
2331 | * |
||
2332 | * @used-by bulk_edit_variations |
||
2333 | */ |
||
2334 | private static function variation_bulk_action_variable_sale_schedule( $variations, $data ) { |
||
2335 | if ( ! isset( $data['date_from'] ) && ! isset( $data['date_to'] ) ) { |
||
2336 | return; |
||
2337 | } |
||
2338 | |||
2339 | foreach ( $variations as $variation_id ) { |
||
2340 | $variation = wc_get_product( $variation_id ); |
||
2341 | |||
2342 | if ( 'false' !== $data['date_from'] ) { |
||
2343 | $variation->set_date_on_sale_from( wc_clean( $data['date_from'] ) ); |
||
2344 | } |
||
2345 | |||
2346 | if ( 'false' !== $data['date_to'] ) { |
||
2347 | $variation->set_date_on_sale_to( wc_clean( $data['date_to'] ) ); |
||
2348 | } |
||
2349 | |||
2350 | $variation->save(); |
||
2351 | } |
||
2352 | } |
||
2353 | |||
2354 | /** |
||
2355 | * Bulk action - Increase Regular Prices. |
||
2356 | * |
||
2357 | * @param array $variations List of variations. |
||
2358 | * @param array $data Data to set. |
||
2359 | * |
||
2360 | * @used-by bulk_edit_variations |
||
2361 | */ |
||
2362 | private static function variation_bulk_action_variable_regular_price_increase( $variations, $data ) { |
||
2363 | self::variation_bulk_adjust_price( $variations, 'regular_price', '+', wc_clean( $data['value'] ) ); |
||
2364 | } |
||
2365 | |||
2366 | /** |
||
2367 | * Bulk action - Decrease Regular Prices. |
||
2368 | * |
||
2369 | * @param array $variations List of variations. |
||
2370 | * @param array $data Data to set. |
||
2371 | * |
||
2372 | * @used-by bulk_edit_variations |
||
2373 | */ |
||
2374 | private static function variation_bulk_action_variable_regular_price_decrease( $variations, $data ) { |
||
2375 | self::variation_bulk_adjust_price( $variations, 'regular_price', '-', wc_clean( $data['value'] ) ); |
||
2376 | } |
||
2377 | |||
2378 | /** |
||
2379 | * Bulk action - Increase Sale Prices. |
||
2380 | * |
||
2381 | * @param array $variations List of variations. |
||
2382 | * @param array $data Data to set. |
||
2383 | * |
||
2384 | * @used-by bulk_edit_variations |
||
2385 | */ |
||
2386 | private static function variation_bulk_action_variable_sale_price_increase( $variations, $data ) { |
||
2387 | self::variation_bulk_adjust_price( $variations, 'sale_price', '+', wc_clean( $data['value'] ) ); |
||
2388 | } |
||
2389 | |||
2390 | /** |
||
2391 | * Bulk action - Decrease Sale Prices. |
||
2392 | * |
||
2393 | * @param array $variations List of variations. |
||
2394 | * @param array $data Data to set. |
||
2395 | * |
||
2396 | * @used-by bulk_edit_variations |
||
2397 | */ |
||
2398 | private static function variation_bulk_action_variable_sale_price_decrease( $variations, $data ) { |
||
2399 | self::variation_bulk_adjust_price( $variations, 'sale_price', '-', wc_clean( $data['value'] ) ); |
||
2400 | } |
||
2401 | |||
2402 | /** |
||
2403 | * Bulk action - Set Price. |
||
2404 | * |
||
2405 | * @param array $variations List of variations. |
||
2406 | * @param string $field price being adjusted _regular_price or _sale_price. |
||
2407 | * @param string $operator + or -. |
||
2408 | * @param string $value Price or Percent. |
||
2409 | * |
||
2410 | * @used-by bulk_edit_variations |
||
2411 | */ |
||
2412 | private static function variation_bulk_adjust_price( $variations, $field, $operator, $value ) { |
||
2413 | foreach ( $variations as $variation_id ) { |
||
2414 | $variation = wc_get_product( $variation_id ); |
||
2415 | $field_value = $variation->{"get_$field"}( 'edit' ); |
||
2416 | |||
2417 | if ( '%' === substr( $value, -1 ) ) { |
||
2418 | $percent = wc_format_decimal( substr( $value, 0, -1 ) ); |
||
2419 | $field_value += round( ( $field_value / 100 ) * $percent, wc_get_price_decimals() ) * "{$operator}1"; |
||
2420 | } else { |
||
2421 | $field_value += $value * "{$operator}1"; |
||
2422 | } |
||
2423 | |||
2424 | $variation->{"set_$field"}( $field_value ); |
||
2425 | $variation->save(); |
||
2426 | } |
||
2427 | } |
||
2428 | |||
2429 | /** |
||
2430 | * Bulk set convenience function. |
||
2431 | * |
||
2432 | * @param array $variations List of variations. |
||
2433 | * @param string $field Field to set. |
||
2434 | * @param string $value to set. |
||
2435 | */ |
||
2436 | private static function variation_bulk_set( $variations, $field, $value ) { |
||
2437 | foreach ( $variations as $variation_id ) { |
||
2438 | $variation = wc_get_product( $variation_id ); |
||
2439 | $variation->{ "set_$field" }( wc_clean( $value ) ); |
||
2440 | $variation->save(); |
||
2441 | } |
||
2442 | } |
||
2443 | |||
2444 | /** |
||
2445 | * Bulk toggle convenience function. |
||
2446 | * |
||
2447 | * @param array $variations List of variations. |
||
2448 | * @param string $field Field to toggle. |
||
2449 | */ |
||
2450 | private static function variation_bulk_toggle( $variations, $field ) { |
||
2451 | foreach ( $variations as $variation_id ) { |
||
2452 | $variation = wc_get_product( $variation_id ); |
||
2453 | $prev_value = $variation->{ "get_$field" }( 'edit' ); |
||
2454 | $variation->{ "set_$field" }( ! $prev_value ); |
||
2455 | $variation->save(); |
||
2456 | } |
||
2457 | } |
||
2458 | |||
2459 | /** |
||
2460 | * Bulk edit variations via AJAX. |
||
2461 | * |
||
2462 | * @uses WC_AJAX::variation_bulk_set() |
||
2463 | * @uses WC_AJAX::variation_bulk_adjust_price() |
||
2464 | * @uses WC_AJAX::variation_bulk_action_variable_sale_price_decrease() |
||
2465 | * @uses WC_AJAX::variation_bulk_action_variable_sale_price_increase() |
||
2466 | * @uses WC_AJAX::variation_bulk_action_variable_regular_price_decrease() |
||
2467 | * @uses WC_AJAX::variation_bulk_action_variable_regular_price_increase() |
||
2468 | * @uses WC_AJAX::variation_bulk_action_variable_sale_schedule() |
||
2469 | * @uses WC_AJAX::variation_bulk_action_delete_all() |
||
2470 | * @uses WC_AJAX::variation_bulk_action_variable_download_expiry() |
||
2471 | * @uses WC_AJAX::variation_bulk_action_variable_download_limit() |
||
2472 | * @uses WC_AJAX::variation_bulk_action_variable_height() |
||
2473 | * @uses WC_AJAX::variation_bulk_action_variable_width() |
||
2474 | * @uses WC_AJAX::variation_bulk_action_variable_length() |
||
2475 | * @uses WC_AJAX::variation_bulk_action_variable_weight() |
||
2476 | * @uses WC_AJAX::variation_bulk_action_variable_stock() |
||
2477 | * @uses WC_AJAX::variation_bulk_action_variable_sale_price() |
||
2478 | * @uses WC_AJAX::variation_bulk_action_variable_regular_price() |
||
2479 | * @uses WC_AJAX::variation_bulk_action_toggle_manage_stock() |
||
2480 | * @uses WC_AJAX::variation_bulk_action_toggle_virtual() |
||
2481 | * @uses WC_AJAX::variation_bulk_action_toggle_downloadable() |
||
2482 | * @uses WC_AJAX::variation_bulk_action_toggle_enabled |
||
2483 | */ |
||
2484 | public static function bulk_edit_variations() { |
||
2485 | ob_start(); |
||
2486 | |||
2487 | check_ajax_referer( 'bulk-edit-variations', 'security' ); |
||
2488 | |||
2489 | // Check permissions again and make sure we have what we need. |
||
2490 | View Code Duplication | if ( ! current_user_can( 'edit_products' ) || empty( $_POST['product_id'] ) || empty( $_POST['bulk_action'] ) ) { |
|
2491 | wp_die( -1 ); |
||
2492 | } |
||
2493 | |||
2494 | $product_id = absint( $_POST['product_id'] ); |
||
2495 | $bulk_action = wc_clean( wp_unslash( $_POST['bulk_action'] ) ); |
||
2496 | $data = ! empty( $_POST['data'] ) ? wc_clean( wp_unslash( $_POST['data'] ) ) : array(); |
||
2497 | $variations = array(); |
||
2498 | |||
2499 | if ( apply_filters( 'woocommerce_bulk_edit_variations_need_children', true ) ) { |
||
2500 | $variations = get_posts( |
||
2501 | array( |
||
2502 | 'post_parent' => $product_id, |
||
2503 | 'posts_per_page' => -1, |
||
2504 | 'post_type' => 'product_variation', |
||
2505 | 'fields' => 'ids', |
||
2506 | 'post_status' => array( 'publish', 'private' ), |
||
2507 | ) |
||
2508 | ); |
||
2509 | } |
||
2510 | |||
2511 | if ( method_exists( __CLASS__, "variation_bulk_action_$bulk_action" ) ) { |
||
2512 | call_user_func( array( __CLASS__, "variation_bulk_action_$bulk_action" ), $variations, $data ); |
||
2513 | } else { |
||
2514 | do_action( 'woocommerce_bulk_edit_variations_default', $bulk_action, $data, $product_id, $variations ); |
||
2515 | } |
||
2516 | |||
2517 | do_action( 'woocommerce_bulk_edit_variations', $bulk_action, $data, $product_id, $variations ); |
||
2518 | WC_Product_Variable::sync( $product_id ); |
||
2519 | wc_delete_product_transients( $product_id ); |
||
2520 | wp_die(); |
||
2521 | } |
||
2522 | |||
2523 | /** |
||
2524 | * Handle submissions from assets/js/settings-views-html-settings-tax.js Backbone model. |
||
2525 | */ |
||
2526 | public static function tax_rates_save_changes() { |
||
2527 | // phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification |
||
2528 | if ( ! isset( $_POST['wc_tax_nonce'], $_POST['changes'] ) ) { |
||
2529 | wp_send_json_error( 'missing_fields' ); |
||
2530 | wp_die(); |
||
2531 | } |
||
2532 | |||
2533 | $current_class = ! empty( $_POST['current_class'] ) ? wp_unslash( $_POST['current_class'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2534 | |||
2535 | if ( ! wp_verify_nonce( wp_unslash( $_POST['wc_tax_nonce'] ), 'wc_tax_nonce-class:' . $current_class ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2536 | wp_send_json_error( 'bad_nonce' ); |
||
2537 | wp_die(); |
||
2538 | } |
||
2539 | |||
2540 | $current_class = WC_Tax::format_tax_rate_class( $current_class ); |
||
2541 | |||
2542 | // Check User Caps. |
||
2543 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
2544 | wp_send_json_error( 'missing_capabilities' ); |
||
2545 | wp_die(); |
||
2546 | } |
||
2547 | |||
2548 | $changes = wp_unslash( $_POST['changes'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2549 | foreach ( $changes as $tax_rate_id => $data ) { |
||
2550 | if ( isset( $data['deleted'] ) ) { |
||
2551 | if ( isset( $data['newRow'] ) ) { |
||
2552 | // So the user added and deleted a new row. |
||
2553 | // That's fine, it's not in the database anyways. NEXT! |
||
2554 | continue; |
||
2555 | } |
||
2556 | WC_Tax::_delete_tax_rate( $tax_rate_id ); |
||
2557 | } |
||
2558 | |||
2559 | $tax_rate = array_intersect_key( |
||
2560 | $data, |
||
2561 | array( |
||
2562 | 'tax_rate_country' => 1, |
||
2563 | 'tax_rate_state' => 1, |
||
2564 | 'tax_rate' => 1, |
||
2565 | 'tax_rate_name' => 1, |
||
2566 | 'tax_rate_priority' => 1, |
||
2567 | 'tax_rate_compound' => 1, |
||
2568 | 'tax_rate_shipping' => 1, |
||
2569 | 'tax_rate_order' => 1, |
||
2570 | ) |
||
2571 | ); |
||
2572 | |||
2573 | if ( isset( $tax_rate['tax_rate'] ) ) { |
||
2574 | $tax_rate['tax_rate'] = wc_format_decimal( $tax_rate['tax_rate'] ); |
||
2575 | } |
||
2576 | |||
2577 | if ( isset( $data['newRow'] ) ) { |
||
2578 | $tax_rate['tax_rate_class'] = $current_class; |
||
2579 | $tax_rate_id = WC_Tax::_insert_tax_rate( $tax_rate ); |
||
2580 | } elseif ( ! empty( $tax_rate ) ) { |
||
2581 | WC_Tax::_update_tax_rate( $tax_rate_id, $tax_rate ); |
||
2582 | } |
||
2583 | |||
2584 | if ( isset( $data['postcode'] ) ) { |
||
2585 | $postcode = array_map( 'wc_clean', $data['postcode'] ); |
||
2586 | $postcode = array_map( 'wc_normalize_postcode', $postcode ); |
||
2587 | WC_Tax::_update_tax_rate_postcodes( $tax_rate_id, $postcode ); |
||
2588 | } |
||
2589 | if ( isset( $data['city'] ) ) { |
||
2590 | WC_Tax::_update_tax_rate_cities( $tax_rate_id, array_map( 'wc_clean', array_map( 'wp_unslash', $data['city'] ) ) ); |
||
2591 | } |
||
2592 | } |
||
2593 | |||
2594 | WC_Cache_Helper::incr_cache_prefix( 'taxes' ); |
||
2595 | WC_Cache_Helper::get_transient_version( 'shipping', true ); |
||
2596 | |||
2597 | wp_send_json_success( |
||
2598 | array( |
||
2599 | 'rates' => WC_Tax::get_rates_for_tax_class( $current_class ), |
||
2600 | ) |
||
2601 | ); |
||
2602 | // phpcs:enable |
||
2603 | } |
||
2604 | |||
2605 | /** |
||
2606 | * Handle submissions from assets/js/wc-shipping-zones.js Backbone model. |
||
2607 | */ |
||
2608 | public static function shipping_zones_save_changes() { |
||
2609 | if ( ! isset( $_POST['wc_shipping_zones_nonce'], $_POST['changes'] ) ) { |
||
2610 | wp_send_json_error( 'missing_fields' ); |
||
2611 | wp_die(); |
||
2612 | } |
||
2613 | |||
2614 | if ( ! wp_verify_nonce( wp_unslash( $_POST['wc_shipping_zones_nonce'] ), 'wc_shipping_zones_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2615 | wp_send_json_error( 'bad_nonce' ); |
||
2616 | wp_die(); |
||
2617 | } |
||
2618 | |||
2619 | // Check User Caps. |
||
2620 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
2621 | wp_send_json_error( 'missing_capabilities' ); |
||
2622 | wp_die(); |
||
2623 | } |
||
2624 | |||
2625 | $changes = wp_unslash( $_POST['changes'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2626 | foreach ( $changes as $zone_id => $data ) { |
||
2627 | if ( isset( $data['deleted'] ) ) { |
||
2628 | if ( isset( $data['newRow'] ) ) { |
||
2629 | // So the user added and deleted a new row. |
||
2630 | // That's fine, it's not in the database anyways. NEXT! |
||
2631 | continue; |
||
2632 | } |
||
2633 | WC_Shipping_Zones::delete_zone( $zone_id ); |
||
2634 | continue; |
||
2635 | } |
||
2636 | |||
2637 | $zone_data = array_intersect_key( |
||
2638 | $data, |
||
2639 | array( |
||
2640 | 'zone_id' => 1, |
||
2641 | 'zone_order' => 1, |
||
2642 | ) |
||
2643 | ); |
||
2644 | |||
2645 | if ( isset( $zone_data['zone_id'] ) ) { |
||
2646 | $zone = new WC_Shipping_Zone( $zone_data['zone_id'] ); |
||
2647 | |||
2648 | if ( isset( $zone_data['zone_order'] ) ) { |
||
2649 | $zone->set_zone_order( $zone_data['zone_order'] ); |
||
2650 | } |
||
2651 | |||
2652 | $zone->save(); |
||
2653 | } |
||
2654 | } |
||
2655 | |||
2656 | wp_send_json_success( |
||
2657 | array( |
||
2658 | 'zones' => WC_Shipping_Zones::get_zones( 'json' ), |
||
2659 | ) |
||
2660 | ); |
||
2661 | } |
||
2662 | |||
2663 | /** |
||
2664 | * Handle submissions from assets/js/wc-shipping-zone-methods.js Backbone model. |
||
2665 | */ |
||
2666 | public static function shipping_zone_add_method() { |
||
2667 | View Code Duplication | if ( ! isset( $_POST['wc_shipping_zones_nonce'], $_POST['zone_id'], $_POST['method_id'] ) ) { |
|
2668 | wp_send_json_error( 'missing_fields' ); |
||
2669 | wp_die(); |
||
2670 | } |
||
2671 | |||
2672 | if ( ! wp_verify_nonce( wp_unslash( $_POST['wc_shipping_zones_nonce'] ), 'wc_shipping_zones_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2673 | wp_send_json_error( 'bad_nonce' ); |
||
2674 | wp_die(); |
||
2675 | } |
||
2676 | |||
2677 | // Check User Caps. |
||
2678 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
2679 | wp_send_json_error( 'missing_capabilities' ); |
||
2680 | wp_die(); |
||
2681 | } |
||
2682 | |||
2683 | $zone_id = wc_clean( wp_unslash( $_POST['zone_id'] ) ); |
||
2684 | $zone = new WC_Shipping_Zone( $zone_id ); |
||
2685 | $instance_id = $zone->add_shipping_method( wc_clean( wp_unslash( $_POST['method_id'] ) ) ); |
||
2686 | |||
2687 | wp_send_json_success( |
||
2688 | array( |
||
2689 | 'instance_id' => $instance_id, |
||
2690 | 'zone_id' => $zone->get_id(), |
||
2691 | 'zone_name' => $zone->get_zone_name(), |
||
2692 | 'methods' => $zone->get_shipping_methods( false, 'json' ), |
||
2693 | ) |
||
2694 | ); |
||
2695 | } |
||
2696 | |||
2697 | /** |
||
2698 | * Handle submissions from assets/js/wc-shipping-zone-methods.js Backbone model. |
||
2699 | */ |
||
2700 | public static function shipping_zone_methods_save_changes() { |
||
2701 | View Code Duplication | if ( ! isset( $_POST['wc_shipping_zones_nonce'], $_POST['zone_id'], $_POST['changes'] ) ) { |
|
2702 | wp_send_json_error( 'missing_fields' ); |
||
2703 | wp_die(); |
||
2704 | } |
||
2705 | |||
2706 | if ( ! wp_verify_nonce( wp_unslash( $_POST['wc_shipping_zones_nonce'] ), 'wc_shipping_zones_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2707 | wp_send_json_error( 'bad_nonce' ); |
||
2708 | wp_die(); |
||
2709 | } |
||
2710 | |||
2711 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
2712 | wp_send_json_error( 'missing_capabilities' ); |
||
2713 | wp_die(); |
||
2714 | } |
||
2715 | |||
2716 | global $wpdb; |
||
2717 | |||
2718 | $zone_id = wc_clean( wp_unslash( $_POST['zone_id'] ) ); |
||
2719 | $zone = new WC_Shipping_Zone( $zone_id ); |
||
2720 | $changes = wp_unslash( $_POST['changes'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2721 | |||
2722 | if ( isset( $changes['zone_name'] ) ) { |
||
2723 | $zone->set_zone_name( wc_clean( $changes['zone_name'] ) ); |
||
2724 | } |
||
2725 | |||
2726 | if ( isset( $changes['zone_locations'] ) ) { |
||
2727 | $zone->clear_locations( array( 'state', 'country', 'continent' ) ); |
||
2728 | $locations = array_filter( array_map( 'wc_clean', (array) $changes['zone_locations'] ) ); |
||
2729 | foreach ( $locations as $location ) { |
||
2730 | // Each posted location will be in the format type:code. |
||
2731 | $location_parts = explode( ':', $location ); |
||
2732 | switch ( $location_parts[0] ) { |
||
2733 | case 'state': |
||
2734 | $zone->add_location( $location_parts[1] . ':' . $location_parts[2], 'state' ); |
||
2735 | break; |
||
2736 | case 'country': |
||
2737 | $zone->add_location( $location_parts[1], 'country' ); |
||
2738 | break; |
||
2739 | case 'continent': |
||
2740 | $zone->add_location( $location_parts[1], 'continent' ); |
||
2741 | break; |
||
2742 | } |
||
2743 | } |
||
2744 | } |
||
2745 | |||
2746 | if ( isset( $changes['zone_postcodes'] ) ) { |
||
2747 | $zone->clear_locations( 'postcode' ); |
||
2748 | $postcodes = array_filter( array_map( 'strtoupper', array_map( 'wc_clean', explode( "\n", $changes['zone_postcodes'] ) ) ) ); |
||
2749 | foreach ( $postcodes as $postcode ) { |
||
2750 | $zone->add_location( $postcode, 'postcode' ); |
||
2751 | } |
||
2752 | } |
||
2753 | |||
2754 | if ( isset( $changes['methods'] ) ) { |
||
2755 | foreach ( $changes['methods'] as $instance_id => $data ) { |
||
2756 | $method_id = $wpdb->get_var( $wpdb->prepare( "SELECT method_id FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE instance_id = %d", $instance_id ) ); |
||
2757 | |||
2758 | if ( isset( $data['deleted'] ) ) { |
||
2759 | $shipping_method = WC_Shipping_Zones::get_shipping_method( $instance_id ); |
||
2760 | $option_key = $shipping_method->get_instance_option_key(); |
||
2761 | if ( $wpdb->delete( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'instance_id' => $instance_id ) ) ) { |
||
2762 | delete_option( $option_key ); |
||
2763 | do_action( 'woocommerce_shipping_zone_method_deleted', $instance_id, $method_id, $zone_id ); |
||
2764 | } |
||
2765 | continue; |
||
2766 | } |
||
2767 | |||
2768 | $method_data = array_intersect_key( |
||
2769 | $data, |
||
2770 | array( |
||
2771 | 'method_order' => 1, |
||
2772 | 'enabled' => 1, |
||
2773 | ) |
||
2774 | ); |
||
2775 | |||
2776 | if ( isset( $method_data['method_order'] ) ) { |
||
2777 | $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'method_order' => absint( $method_data['method_order'] ) ), array( 'instance_id' => absint( $instance_id ) ) ); |
||
2778 | } |
||
2779 | |||
2780 | if ( isset( $method_data['enabled'] ) ) { |
||
2781 | $is_enabled = absint( 'yes' === $method_data['enabled'] ); |
||
2782 | if ( $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'is_enabled' => $is_enabled ), array( 'instance_id' => absint( $instance_id ) ) ) ) { |
||
2783 | do_action( 'woocommerce_shipping_zone_method_status_toggled', $instance_id, $method_id, $zone_id, $is_enabled ); |
||
2784 | } |
||
2785 | } |
||
2786 | } |
||
2787 | } |
||
2788 | |||
2789 | $zone->save(); |
||
2790 | |||
2791 | wp_send_json_success( |
||
2792 | array( |
||
2793 | 'zone_id' => $zone->get_id(), |
||
2794 | 'zone_name' => $zone->get_zone_name(), |
||
2795 | 'methods' => $zone->get_shipping_methods( false, 'json' ), |
||
2796 | ) |
||
2797 | ); |
||
2798 | } |
||
2799 | |||
2800 | /** |
||
2801 | * Save method settings |
||
2802 | */ |
||
2803 | public static function shipping_zone_methods_save_settings() { |
||
2804 | if ( ! isset( $_POST['wc_shipping_zones_nonce'], $_POST['instance_id'], $_POST['data'] ) ) { |
||
2805 | wp_send_json_error( 'missing_fields' ); |
||
2806 | wp_die(); |
||
2807 | } |
||
2808 | |||
2809 | if ( ! wp_verify_nonce( wp_unslash( $_POST['wc_shipping_zones_nonce'] ), 'wc_shipping_zones_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2810 | wp_send_json_error( 'bad_nonce' ); |
||
2811 | wp_die(); |
||
2812 | } |
||
2813 | |||
2814 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
2815 | wp_send_json_error( 'missing_capabilities' ); |
||
2816 | wp_die(); |
||
2817 | } |
||
2818 | |||
2819 | $instance_id = absint( $_POST['instance_id'] ); |
||
2820 | $zone = WC_Shipping_Zones::get_zone_by( 'instance_id', $instance_id ); |
||
2821 | $shipping_method = WC_Shipping_Zones::get_shipping_method( $instance_id ); |
||
2822 | $shipping_method->set_post_data( wp_unslash( $_POST['data'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2823 | $shipping_method->process_admin_options(); |
||
2824 | |||
2825 | WC_Cache_Helper::get_transient_version( 'shipping', true ); |
||
2826 | |||
2827 | wp_send_json_success( |
||
2828 | array( |
||
2829 | 'zone_id' => $zone->get_id(), |
||
2830 | 'zone_name' => $zone->get_zone_name(), |
||
2831 | 'methods' => $zone->get_shipping_methods( false, 'json' ), |
||
2832 | 'errors' => $shipping_method->get_errors(), |
||
2833 | ) |
||
2834 | ); |
||
2835 | } |
||
2836 | |||
2837 | /** |
||
2838 | * Handle submissions from assets/js/wc-shipping-classes.js Backbone model. |
||
2839 | */ |
||
2840 | public static function shipping_classes_save_changes() { |
||
2841 | if ( ! isset( $_POST['wc_shipping_classes_nonce'], $_POST['changes'] ) ) { |
||
2842 | wp_send_json_error( 'missing_fields' ); |
||
2843 | wp_die(); |
||
2844 | } |
||
2845 | |||
2846 | if ( ! wp_verify_nonce( wp_unslash( $_POST['wc_shipping_classes_nonce'] ), 'wc_shipping_classes_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2847 | wp_send_json_error( 'bad_nonce' ); |
||
2848 | wp_die(); |
||
2849 | } |
||
2850 | |||
2851 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
2852 | wp_send_json_error( 'missing_capabilities' ); |
||
2853 | wp_die(); |
||
2854 | } |
||
2855 | |||
2856 | $changes = wp_unslash( $_POST['changes'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
||
2857 | |||
2858 | foreach ( $changes as $term_id => $data ) { |
||
2859 | $term_id = absint( $term_id ); |
||
2860 | |||
2861 | if ( isset( $data['deleted'] ) ) { |
||
2862 | if ( isset( $data['newRow'] ) ) { |
||
2863 | // So the user added and deleted a new row. |
||
2864 | // That's fine, it's not in the database anyways. NEXT! |
||
2865 | continue; |
||
2866 | } |
||
2867 | wp_delete_term( $term_id, 'product_shipping_class' ); |
||
2868 | continue; |
||
2869 | } |
||
2870 | |||
2871 | $update_args = array(); |
||
2872 | |||
2873 | if ( isset( $data['name'] ) ) { |
||
2874 | $update_args['name'] = wc_clean( $data['name'] ); |
||
2875 | } |
||
2876 | |||
2877 | if ( isset( $data['slug'] ) ) { |
||
2878 | $update_args['slug'] = wc_clean( $data['slug'] ); |
||
2879 | } |
||
2880 | |||
2881 | if ( isset( $data['description'] ) ) { |
||
2882 | $update_args['description'] = wc_clean( $data['description'] ); |
||
2883 | } |
||
2884 | |||
2885 | if ( isset( $data['newRow'] ) ) { |
||
2886 | $update_args = array_filter( $update_args ); |
||
2887 | if ( empty( $update_args['name'] ) ) { |
||
2888 | continue; |
||
2889 | } |
||
2890 | $inserted_term = wp_insert_term( $update_args['name'], 'product_shipping_class', $update_args ); |
||
2891 | $term_id = is_wp_error( $inserted_term ) ? 0 : $inserted_term['term_id']; |
||
2892 | } else { |
||
2893 | wp_update_term( $term_id, 'product_shipping_class', $update_args ); |
||
2894 | } |
||
2895 | |||
2896 | do_action( 'woocommerce_shipping_classes_save_class', $term_id, $data ); |
||
2897 | } |
||
2898 | |||
2899 | $wc_shipping = WC_Shipping::instance(); |
||
2900 | |||
2901 | wp_send_json_success( |
||
2902 | array( |
||
2903 | 'shipping_classes' => $wc_shipping->get_shipping_classes(), |
||
2904 | ) |
||
2905 | ); |
||
2906 | } |
||
2907 | |||
2908 | /** |
||
2909 | * Toggle payment gateway on or off via AJAX. |
||
2910 | * |
||
2911 | * @since 3.4.0 |
||
2912 | */ |
||
2913 | public static function toggle_gateway_enabled() { |
||
2914 | if ( current_user_can( 'manage_woocommerce' ) && check_ajax_referer( 'woocommerce-toggle-payment-gateway-enabled', 'security' ) && isset( $_POST['gateway_id'] ) ) { |
||
2915 | // Load gateways. |
||
2916 | $payment_gateways = WC()->payment_gateways->payment_gateways(); |
||
2917 | |||
2918 | // Get posted gateway. |
||
2919 | $gateway_id = wc_clean( wp_unslash( $_POST['gateway_id'] ) ); |
||
2920 | |||
2921 | foreach ( $payment_gateways as $gateway ) { |
||
2922 | if ( ! in_array( $gateway_id, array( $gateway->id, sanitize_title( get_class( $gateway ) ) ), true ) ) { |
||
2923 | continue; |
||
2924 | } |
||
2925 | $enabled = $gateway->get_option( 'enabled', 'no' ); |
||
2926 | |||
2927 | if ( ! wc_string_to_bool( $enabled ) ) { |
||
2928 | if ( $gateway->needs_setup() ) { |
||
2929 | wp_send_json_error( 'needs_setup' ); |
||
2930 | wp_die(); |
||
2931 | } else { |
||
2932 | $gateway->update_option( 'enabled', 'yes' ); |
||
2933 | } |
||
2934 | } else { |
||
2935 | // Disable the gateway. |
||
2936 | $gateway->update_option( 'enabled', 'no' ); |
||
2937 | } |
||
2938 | |||
2939 | wp_send_json_success( ! wc_string_to_bool( $enabled ) ); |
||
2940 | wp_die(); |
||
2941 | } |
||
2942 | } |
||
2943 | |||
2944 | wp_send_json_error( 'invalid_gateway_id' ); |
||
2945 | wp_die(); |
||
2946 | } |
||
2947 | } |
||
2948 | |||
2949 | WC_AJAX::init(); |
||
2950 |