This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | if ( ! defined( 'ABSPATH' ) ) { |
||
4 | exit; // Exit if accessed directly |
||
5 | } |
||
6 | |||
7 | /** |
||
8 | * WooCommerce WC_AJAX. |
||
9 | * |
||
10 | * AJAX Event Handler. |
||
11 | * |
||
12 | * @class WC_AJAX |
||
13 | * @version 2.4.0 |
||
14 | * @package WooCommerce/Classes |
||
15 | * @category Class |
||
16 | * @author WooThemes |
||
17 | */ |
||
18 | class WC_AJAX { |
||
19 | |||
20 | /** |
||
21 | * Hook in ajax handlers. |
||
22 | */ |
||
23 | public static function init() { |
||
24 | add_action( 'init', array( __CLASS__, 'define_ajax' ), 0 ); |
||
25 | add_action( 'template_redirect', array( __CLASS__, 'do_wc_ajax' ), 0 ); |
||
26 | self::add_ajax_events(); |
||
27 | } |
||
28 | |||
29 | /** |
||
30 | * Get WC Ajax Endpoint. |
||
31 | * @param string $request Optional |
||
32 | * @return string |
||
33 | */ |
||
34 | public static function get_endpoint( $request = '' ) { |
||
35 | return esc_url_raw( add_query_arg( 'wc-ajax', $request, remove_query_arg( array( 'remove_item', 'add-to-cart', 'added-to-cart' ) ) ) ); |
||
36 | } |
||
37 | |||
38 | /** |
||
39 | * Set WC AJAX constant and headers. |
||
40 | */ |
||
41 | public static function define_ajax() { |
||
42 | if ( ! empty( $_GET['wc-ajax'] ) ) { |
||
43 | if ( ! defined( 'DOING_AJAX' ) ) { |
||
44 | define( 'DOING_AJAX', true ); |
||
45 | } |
||
46 | if ( ! defined( 'WC_DOING_AJAX' ) ) { |
||
47 | define( 'WC_DOING_AJAX', true ); |
||
48 | } |
||
49 | // Turn off display_errors during AJAX events to prevent malformed JSON |
||
50 | if ( ! WP_DEBUG || ( WP_DEBUG && ! WP_DEBUG_DISPLAY ) ) { |
||
51 | @ini_set( 'display_errors', 0 ); |
||
52 | } |
||
53 | $GLOBALS['wpdb']->hide_errors(); |
||
54 | } |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * Send headers for WC Ajax Requests |
||
59 | * @since 2.5.0 |
||
60 | */ |
||
61 | private static function wc_ajax_headers() { |
||
62 | send_origin_headers(); |
||
63 | @header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) ); |
||
64 | @header( 'X-Robots-Tag: noindex' ); |
||
65 | send_nosniff_header(); |
||
66 | nocache_headers(); |
||
67 | status_header( 200 ); |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * Check for WC Ajax request and fire action. |
||
72 | */ |
||
73 | public static function do_wc_ajax() { |
||
74 | global $wp_query; |
||
75 | |||
76 | if ( ! empty( $_GET['wc-ajax'] ) ) { |
||
77 | $wp_query->set( 'wc-ajax', sanitize_text_field( $_GET['wc-ajax'] ) ); |
||
78 | } |
||
79 | |||
80 | if ( $action = $wp_query->get( 'wc-ajax' ) ) { |
||
81 | self::wc_ajax_headers(); |
||
82 | do_action( 'wc_ajax_' . sanitize_text_field( $action ) ); |
||
83 | die(); |
||
84 | } |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * Hook in methods - uses WordPress ajax handlers (admin-ajax). |
||
89 | */ |
||
90 | public static function add_ajax_events() { |
||
91 | // woocommerce_EVENT => nopriv |
||
92 | $ajax_events = array( |
||
93 | 'get_refreshed_fragments' => true, |
||
94 | 'apply_coupon' => true, |
||
95 | 'remove_coupon' => true, |
||
96 | 'update_shipping_method' => true, |
||
97 | 'get_cart_totals' => true, |
||
98 | 'update_order_review' => true, |
||
99 | 'add_to_cart' => true, |
||
100 | 'checkout' => true, |
||
101 | 'get_variation' => true, |
||
102 | 'feature_product' => false, |
||
103 | 'mark_order_status' => false, |
||
104 | 'add_attribute' => false, |
||
105 | 'add_new_attribute' => false, |
||
106 | 'remove_variation' => false, |
||
107 | 'remove_variations' => false, |
||
108 | 'save_attributes' => false, |
||
109 | 'add_variation' => false, |
||
110 | 'link_all_variations' => false, |
||
111 | 'revoke_access_to_download' => false, |
||
112 | 'grant_access_to_download' => false, |
||
113 | 'get_customer_details' => false, |
||
114 | 'add_order_item' => false, |
||
115 | 'add_order_fee' => false, |
||
116 | 'add_order_shipping' => false, |
||
117 | 'add_order_tax' => false, |
||
118 | 'remove_order_item' => false, |
||
119 | 'remove_order_tax' => false, |
||
120 | 'reduce_order_item_stock' => false, |
||
121 | 'increase_order_item_stock' => false, |
||
122 | 'add_order_item_meta' => false, |
||
123 | 'remove_order_item_meta' => false, |
||
124 | 'calc_line_taxes' => false, |
||
125 | 'save_order_items' => false, |
||
126 | 'load_order_items' => false, |
||
127 | 'add_order_note' => false, |
||
128 | 'delete_order_note' => false, |
||
129 | 'json_search_products' => false, |
||
130 | 'json_search_products_and_variations' => false, |
||
131 | 'json_search_grouped_products' => false, |
||
132 | 'json_search_downloadable_products_and_variations' => false, |
||
133 | 'json_search_customers' => false, |
||
134 | 'term_ordering' => false, |
||
135 | 'product_ordering' => false, |
||
136 | 'refund_line_items' => false, |
||
137 | 'delete_refund' => false, |
||
138 | 'rated' => false, |
||
139 | 'update_api_key' => false, |
||
140 | 'get_customer_location' => true, |
||
141 | 'load_variations' => false, |
||
142 | 'save_variations' => false, |
||
143 | 'bulk_edit_variations' => false, |
||
144 | 'tax_rates_save_changes' => false, |
||
145 | 'shipping_zones_save_changes' => false, |
||
146 | 'shipping_zone_add_method' => false, |
||
147 | 'shipping_zone_methods_save_changes' => false, |
||
148 | 'shipping_zone_methods_save_settings' => false, |
||
149 | 'shipping_classes_save_changes' => false, |
||
150 | ); |
||
151 | |||
152 | foreach ( $ajax_events as $ajax_event => $nopriv ) { |
||
153 | add_action( 'wp_ajax_woocommerce_' . $ajax_event, array( __CLASS__, $ajax_event ) ); |
||
154 | |||
155 | if ( $nopriv ) { |
||
156 | add_action( 'wp_ajax_nopriv_woocommerce_' . $ajax_event, array( __CLASS__, $ajax_event ) ); |
||
157 | |||
158 | // WC AJAX can be used for frontend ajax requests |
||
159 | add_action( 'wc_ajax_' . $ajax_event, array( __CLASS__, $ajax_event ) ); |
||
160 | } |
||
161 | } |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * Get a refreshed cart fragment. |
||
166 | */ |
||
167 | public static function get_refreshed_fragments() { |
||
168 | |||
169 | // Get mini cart |
||
170 | ob_start(); |
||
171 | |||
172 | woocommerce_mini_cart(); |
||
173 | |||
174 | $mini_cart = ob_get_clean(); |
||
175 | |||
176 | // Fragments and mini cart are returned |
||
177 | $data = array( |
||
178 | 'fragments' => apply_filters( 'woocommerce_add_to_cart_fragments', array( |
||
179 | 'div.widget_shopping_cart_content' => '<div class="widget_shopping_cart_content">' . $mini_cart . '</div>' |
||
180 | ) |
||
181 | ), |
||
182 | 'cart_hash' => apply_filters( 'woocommerce_add_to_cart_hash', WC()->cart->get_cart_for_session() ? md5( json_encode( WC()->cart->get_cart_for_session() ) ) : '', WC()->cart->get_cart_for_session() ) |
||
183 | ); |
||
184 | |||
185 | wp_send_json( $data ); |
||
186 | |||
187 | } |
||
188 | |||
189 | /** |
||
190 | * AJAX apply coupon on checkout page. |
||
191 | */ |
||
192 | public static function apply_coupon() { |
||
193 | |||
194 | check_ajax_referer( 'apply-coupon', 'security' ); |
||
195 | |||
196 | if ( ! empty( $_POST['coupon_code'] ) ) { |
||
197 | WC()->cart->add_discount( sanitize_text_field( $_POST['coupon_code'] ) ); |
||
198 | } else { |
||
199 | wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' ); |
||
200 | } |
||
201 | |||
202 | wc_print_notices(); |
||
203 | |||
204 | die(); |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * AJAX remove coupon on cart and checkout page. |
||
209 | */ |
||
210 | public static function remove_coupon() { |
||
211 | |||
212 | check_ajax_referer( 'remove-coupon', 'security' ); |
||
213 | |||
214 | $coupon = wc_clean( $_POST['coupon'] ); |
||
215 | |||
216 | if ( ! isset( $coupon ) || empty( $coupon ) ) { |
||
217 | wc_add_notice( __( 'Sorry there was a problem removing this coupon.', 'woocommerce' ), 'error' ); |
||
218 | |||
219 | } else { |
||
220 | |||
221 | WC()->cart->remove_coupon( $coupon ); |
||
222 | |||
223 | wc_add_notice( __( 'Coupon has been removed.', 'woocommerce' ) ); |
||
224 | } |
||
225 | |||
226 | wc_print_notices(); |
||
227 | |||
228 | die(); |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * AJAX update shipping method on cart page. |
||
233 | */ |
||
234 | public static function update_shipping_method() { |
||
235 | |||
236 | check_ajax_referer( 'update-shipping-method', 'security' ); |
||
237 | |||
238 | if ( ! defined('WOOCOMMERCE_CART') ) { |
||
239 | define( 'WOOCOMMERCE_CART', true ); |
||
240 | } |
||
241 | |||
242 | $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' ); |
||
243 | |||
244 | View Code Duplication | if ( isset( $_POST['shipping_method'] ) && is_array( $_POST['shipping_method'] ) ) { |
|
245 | foreach ( $_POST['shipping_method'] as $i => $value ) { |
||
246 | $chosen_shipping_methods[ $i ] = wc_clean( $value ); |
||
247 | } |
||
248 | } |
||
249 | |||
250 | WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods ); |
||
251 | |||
252 | WC()->cart->calculate_totals(); |
||
253 | |||
254 | woocommerce_cart_totals(); |
||
255 | |||
256 | die(); |
||
257 | } |
||
258 | |||
259 | /** |
||
260 | * AJAX receive updated cart_totals div. |
||
261 | */ |
||
262 | public static function get_cart_totals() { |
||
263 | |||
264 | if ( ! defined( 'WOOCOMMERCE_CART' ) ) { |
||
265 | define( 'WOOCOMMERCE_CART', true ); |
||
266 | } |
||
267 | |||
268 | WC()->cart->calculate_totals(); |
||
269 | |||
270 | woocommerce_cart_totals(); |
||
271 | |||
272 | die(); |
||
273 | } |
||
274 | |||
275 | /** |
||
276 | * AJAX update order review on checkout. |
||
277 | */ |
||
278 | public static function update_order_review() { |
||
279 | ob_start(); |
||
280 | |||
281 | check_ajax_referer( 'update-order-review', 'security' ); |
||
282 | |||
283 | if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) { |
||
284 | define( 'WOOCOMMERCE_CHECKOUT', true ); |
||
285 | } |
||
286 | |||
287 | if ( WC()->cart->is_empty() ) { |
||
288 | $data = array( |
||
289 | 'fragments' => apply_filters( 'woocommerce_update_order_review_fragments', array( |
||
290 | '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>' |
||
291 | ) ) |
||
292 | ); |
||
293 | |||
294 | wp_send_json( $data ); |
||
295 | |||
296 | die(); |
||
297 | } |
||
298 | |||
299 | do_action( 'woocommerce_checkout_update_order_review', $_POST['post_data'] ); |
||
300 | |||
301 | $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' ); |
||
302 | |||
303 | View Code Duplication | if ( isset( $_POST['shipping_method'] ) && is_array( $_POST['shipping_method'] ) ) { |
|
304 | foreach ( $_POST['shipping_method'] as $i => $value ) { |
||
305 | $chosen_shipping_methods[ $i ] = wc_clean( $value ); |
||
306 | } |
||
307 | } |
||
308 | |||
309 | WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods ); |
||
310 | WC()->session->set( 'chosen_payment_method', empty( $_POST['payment_method'] ) ? '' : $_POST['payment_method'] ); |
||
311 | |||
312 | if ( isset( $_POST['country'] ) ) { |
||
313 | WC()->customer->set_country( $_POST['country'] ); |
||
314 | } |
||
315 | |||
316 | if ( isset( $_POST['state'] ) ) { |
||
317 | WC()->customer->set_state( $_POST['state'] ); |
||
318 | } |
||
319 | |||
320 | if ( isset( $_POST['postcode'] ) ) { |
||
321 | WC()->customer->set_postcode( $_POST['postcode'] ); |
||
322 | } |
||
323 | |||
324 | if ( isset( $_POST['city'] ) ) { |
||
325 | WC()->customer->set_city( $_POST['city'] ); |
||
326 | } |
||
327 | |||
328 | if ( isset( $_POST['address'] ) ) { |
||
329 | WC()->customer->set_address( $_POST['address'] ); |
||
330 | } |
||
331 | |||
332 | if ( isset( $_POST['address_2'] ) ) { |
||
333 | WC()->customer->set_address_2( $_POST['address_2'] ); |
||
334 | } |
||
335 | |||
336 | if ( wc_ship_to_billing_address_only() ) { |
||
337 | |||
338 | View Code Duplication | if ( ! empty( $_POST['country'] ) ) { |
|
339 | WC()->customer->set_shipping_country( $_POST['country'] ); |
||
340 | WC()->customer->calculated_shipping( true ); |
||
341 | } |
||
342 | |||
343 | if ( isset( $_POST['state'] ) ) { |
||
344 | WC()->customer->set_shipping_state( $_POST['state'] ); |
||
345 | } |
||
346 | |||
347 | if ( isset( $_POST['postcode'] ) ) { |
||
348 | WC()->customer->set_shipping_postcode( $_POST['postcode'] ); |
||
349 | } |
||
350 | |||
351 | if ( isset( $_POST['city'] ) ) { |
||
352 | WC()->customer->set_shipping_city( $_POST['city'] ); |
||
353 | } |
||
354 | |||
355 | if ( isset( $_POST['address'] ) ) { |
||
356 | WC()->customer->set_shipping_address( $_POST['address'] ); |
||
357 | } |
||
358 | |||
359 | if ( isset( $_POST['address_2'] ) ) { |
||
360 | WC()->customer->set_shipping_address_2( $_POST['address_2'] ); |
||
361 | } |
||
362 | } else { |
||
363 | |||
364 | View Code Duplication | if ( ! empty( $_POST['s_country'] ) ) { |
|
365 | WC()->customer->set_shipping_country( $_POST['s_country'] ); |
||
366 | WC()->customer->calculated_shipping( true ); |
||
367 | } |
||
368 | |||
369 | if ( isset( $_POST['s_state'] ) ) { |
||
370 | WC()->customer->set_shipping_state( $_POST['s_state'] ); |
||
371 | } |
||
372 | |||
373 | if ( isset( $_POST['s_postcode'] ) ) { |
||
374 | WC()->customer->set_shipping_postcode( $_POST['s_postcode'] ); |
||
375 | } |
||
376 | |||
377 | if ( isset( $_POST['s_city'] ) ) { |
||
378 | WC()->customer->set_shipping_city( $_POST['s_city'] ); |
||
379 | } |
||
380 | |||
381 | if ( isset( $_POST['s_address'] ) ) { |
||
382 | WC()->customer->set_shipping_address( $_POST['s_address'] ); |
||
383 | } |
||
384 | |||
385 | if ( isset( $_POST['s_address_2'] ) ) { |
||
386 | WC()->customer->set_shipping_address_2( $_POST['s_address_2'] ); |
||
387 | } |
||
388 | } |
||
389 | |||
390 | WC()->cart->calculate_totals(); |
||
391 | |||
392 | // Get order review fragment |
||
393 | ob_start(); |
||
394 | woocommerce_order_review(); |
||
395 | $woocommerce_order_review = ob_get_clean(); |
||
396 | |||
397 | // Get checkout payment fragment |
||
398 | ob_start(); |
||
399 | woocommerce_checkout_payment(); |
||
400 | $woocommerce_checkout_payment = ob_get_clean(); |
||
401 | |||
402 | // Get messages if reload checkout is not true |
||
403 | $messages = ''; |
||
404 | if ( ! isset( WC()->session->reload_checkout ) ) { |
||
405 | ob_start(); |
||
406 | wc_print_notices(); |
||
407 | $messages = ob_get_clean(); |
||
408 | } |
||
409 | |||
410 | $data = array( |
||
411 | 'result' => empty( $messages ) ? 'success' : 'failure', |
||
412 | 'messages' => $messages, |
||
413 | 'reload' => isset( WC()->session->reload_checkout ) ? 'true' : 'false', |
||
414 | 'fragments' => apply_filters( 'woocommerce_update_order_review_fragments', array( |
||
415 | '.woocommerce-checkout-review-order-table' => $woocommerce_order_review, |
||
416 | '.woocommerce-checkout-payment' => $woocommerce_checkout_payment |
||
417 | ) ) |
||
418 | ); |
||
419 | |||
420 | unset( WC()->session->refresh_totals, WC()->session->reload_checkout ); |
||
421 | |||
422 | wp_send_json( $data ); |
||
423 | |||
424 | die(); |
||
425 | } |
||
426 | |||
427 | /** |
||
428 | * AJAX add to cart. |
||
429 | */ |
||
430 | public static function add_to_cart() { |
||
431 | ob_start(); |
||
432 | |||
433 | $product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) ); |
||
434 | $quantity = empty( $_POST['quantity'] ) ? 1 : wc_stock_amount( $_POST['quantity'] ); |
||
435 | $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity ); |
||
436 | $product_status = get_post_status( $product_id ); |
||
437 | |||
438 | if ( $passed_validation && false !== WC()->cart->add_to_cart( $product_id, $quantity ) && 'publish' === $product_status ) { |
||
439 | |||
440 | do_action( 'woocommerce_ajax_added_to_cart', $product_id ); |
||
441 | |||
442 | if ( get_option( 'woocommerce_cart_redirect_after_add' ) == 'yes' ) { |
||
443 | wc_add_to_cart_message( array( $product_id => $quantity ), true ); |
||
444 | } |
||
445 | |||
446 | // Return fragments |
||
447 | self::get_refreshed_fragments(); |
||
448 | |||
449 | } else { |
||
450 | |||
451 | // If there was an error adding to the cart, redirect to the product page to show any errors |
||
452 | $data = array( |
||
453 | 'error' => true, |
||
454 | 'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id ) |
||
455 | ); |
||
456 | |||
457 | wp_send_json( $data ); |
||
458 | |||
459 | } |
||
460 | |||
461 | die(); |
||
462 | } |
||
463 | |||
464 | /** |
||
465 | * Process ajax checkout form. |
||
466 | */ |
||
467 | public static function checkout() { |
||
468 | if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) { |
||
469 | define( 'WOOCOMMERCE_CHECKOUT', true ); |
||
470 | } |
||
471 | |||
472 | WC()->checkout()->process_checkout(); |
||
473 | |||
474 | die(0); |
||
475 | } |
||
476 | |||
477 | /** |
||
478 | * Get a matching variation based on posted attributes. |
||
479 | */ |
||
480 | public static function get_variation() { |
||
481 | ob_start(); |
||
482 | |||
483 | if ( empty( $_POST['product_id'] ) || ! ( $variable_product = wc_get_product( absint( $_POST['product_id'] ), array( 'product_type' => 'variable' ) ) ) ) { |
||
484 | die(); |
||
485 | } |
||
486 | |||
487 | $variation_id = $variable_product->get_matching_variation( wp_unslash( $_POST ) ); |
||
488 | |||
489 | if ( $variation_id ) { |
||
490 | $variation = $variable_product->get_available_variation( $variation_id ); |
||
491 | } else { |
||
492 | $variation = false; |
||
493 | } |
||
494 | |||
495 | wp_send_json( $variation ); |
||
496 | |||
497 | die(); |
||
498 | } |
||
499 | |||
500 | /** |
||
501 | * Feature a product from admin. |
||
502 | */ |
||
503 | public static function feature_product() { |
||
504 | if ( current_user_can( 'edit_products' ) && check_admin_referer( 'woocommerce-feature-product' ) ) { |
||
505 | $product_id = absint( $_GET['product_id'] ); |
||
506 | |||
507 | if ( 'product' === get_post_type( $product_id ) ) { |
||
508 | update_post_meta( $product_id, '_featured', get_post_meta( $product_id, '_featured', true ) === 'yes' ? 'no' : 'yes' ); |
||
509 | |||
510 | delete_transient( 'wc_featured_products' ); |
||
511 | } |
||
512 | } |
||
513 | |||
514 | wp_safe_redirect( wp_get_referer() ? remove_query_arg( array( 'trashed', 'untrashed', 'deleted', 'ids' ), wp_get_referer() ) : admin_url( 'edit.php?post_type=product' ) ); |
||
515 | die(); |
||
516 | } |
||
517 | |||
518 | /** |
||
519 | * Mark an order with a status. |
||
520 | */ |
||
521 | public static function mark_order_status() { |
||
522 | if ( current_user_can( 'edit_shop_orders' ) && check_admin_referer( 'woocommerce-mark-order-status' ) ) { |
||
523 | $status = sanitize_text_field( $_GET['status'] ); |
||
524 | $order_id = absint( $_GET['order_id'] ); |
||
525 | |||
526 | if ( wc_is_order_status( 'wc-' . $status ) && $order_id ) { |
||
527 | $order = wc_get_order( $order_id ); |
||
528 | $order->update_status( $status, '', true ); |
||
529 | do_action( 'woocommerce_order_edit_status', $order_id, $status ); |
||
530 | } |
||
531 | } |
||
532 | |||
533 | wp_safe_redirect( wp_get_referer() ? wp_get_referer() : admin_url( 'edit.php?post_type=shop_order' ) ); |
||
534 | die(); |
||
535 | } |
||
536 | |||
537 | /** |
||
538 | * Add an attribute row. |
||
539 | */ |
||
540 | public static function add_attribute() { |
||
541 | ob_start(); |
||
542 | |||
543 | check_ajax_referer( 'add-attribute', 'security' ); |
||
544 | |||
545 | if ( ! current_user_can( 'edit_products' ) ) { |
||
546 | die(-1); |
||
547 | } |
||
548 | |||
549 | global $wc_product_attributes; |
||
550 | |||
551 | $thepostid = 0; |
||
552 | $taxonomy = sanitize_text_field( $_POST['taxonomy'] ); |
||
553 | $i = absint( $_POST['i'] ); |
||
554 | $position = 0; |
||
555 | $metabox_class = array(); |
||
556 | $attribute = array( |
||
557 | 'name' => $taxonomy, |
||
558 | 'value' => '', |
||
559 | 'is_visible' => apply_filters( 'woocommerce_attribute_default_visibility', 1 ), |
||
560 | 'is_variation' => apply_filters( 'woocommerce_attribute_default_is_variation', 0 ), |
||
561 | 'is_taxonomy' => $taxonomy ? 1 : 0 |
||
562 | ); |
||
563 | |||
564 | if ( $taxonomy ) { |
||
565 | $attribute_taxonomy = $wc_product_attributes[ $taxonomy ]; |
||
566 | $metabox_class[] = 'taxonomy'; |
||
567 | $metabox_class[] = $taxonomy; |
||
568 | $attribute_label = wc_attribute_label( $taxonomy ); |
||
569 | } else { |
||
570 | $attribute_label = ''; |
||
571 | } |
||
572 | |||
573 | include( 'admin/meta-boxes/views/html-product-attribute.php' ); |
||
574 | die(); |
||
575 | } |
||
576 | |||
577 | /** |
||
578 | * Add a new attribute via ajax function. |
||
579 | */ |
||
580 | public static function add_new_attribute() { |
||
581 | ob_start(); |
||
582 | |||
583 | check_ajax_referer( 'add-attribute', 'security' ); |
||
584 | |||
585 | if ( ! current_user_can( 'manage_product_terms' ) ) { |
||
586 | die(-1); |
||
587 | } |
||
588 | |||
589 | $taxonomy = esc_attr( $_POST['taxonomy'] ); |
||
590 | $term = wc_clean( $_POST['term'] ); |
||
591 | |||
592 | if ( taxonomy_exists( $taxonomy ) ) { |
||
593 | |||
594 | $result = wp_insert_term( $term, $taxonomy ); |
||
595 | |||
596 | if ( is_wp_error( $result ) ) { |
||
597 | wp_send_json( array( |
||
598 | 'error' => $result->get_error_message() |
||
599 | ) ); |
||
600 | } else { |
||
601 | $term = get_term_by( 'id', $result['term_id'], $taxonomy ); |
||
602 | wp_send_json( array( |
||
603 | 'term_id' => $term->term_id, |
||
604 | 'name' => $term->name, |
||
605 | 'slug' => $term->slug |
||
606 | ) ); |
||
607 | } |
||
608 | } |
||
609 | |||
610 | die(); |
||
611 | } |
||
612 | |||
613 | /** |
||
614 | * Delete variations via ajax function. |
||
615 | */ |
||
616 | public static function remove_variations() { |
||
617 | check_ajax_referer( 'delete-variations', 'security' ); |
||
618 | |||
619 | if ( ! current_user_can( 'edit_products' ) ) { |
||
620 | die(-1); |
||
621 | } |
||
622 | |||
623 | $variation_ids = (array) $_POST['variation_ids']; |
||
624 | |||
625 | foreach ( $variation_ids as $variation_id ) { |
||
626 | $variation = get_post( $variation_id ); |
||
627 | |||
628 | if ( $variation && 'product_variation' == $variation->post_type ) { |
||
629 | wp_delete_post( $variation_id ); |
||
630 | } |
||
631 | } |
||
632 | |||
633 | die(); |
||
634 | } |
||
635 | |||
636 | /** |
||
637 | * Save attributes via ajax. |
||
638 | */ |
||
639 | public static function save_attributes() { |
||
640 | |||
641 | check_ajax_referer( 'save-attributes', 'security' ); |
||
642 | |||
643 | if ( ! current_user_can( 'edit_products' ) ) { |
||
644 | die(-1); |
||
645 | } |
||
646 | |||
647 | // Get post data |
||
648 | parse_str( $_POST['data'], $data ); |
||
649 | $post_id = absint( $_POST['post_id'] ); |
||
650 | |||
651 | // Save Attributes |
||
652 | $attributes = array(); |
||
653 | |||
654 | if ( isset( $data['attribute_names'] ) ) { |
||
655 | |||
656 | $attribute_names = array_map( 'stripslashes', $data['attribute_names'] ); |
||
657 | $attribute_values = isset( $data['attribute_values'] ) ? $data['attribute_values'] : array(); |
||
658 | |||
659 | if ( isset( $data['attribute_visibility'] ) ) { |
||
660 | $attribute_visibility = $data['attribute_visibility']; |
||
661 | } |
||
662 | |||
663 | if ( isset( $data['attribute_variation'] ) ) { |
||
664 | $attribute_variation = $data['attribute_variation']; |
||
665 | } |
||
666 | |||
667 | $attribute_is_taxonomy = $data['attribute_is_taxonomy']; |
||
668 | $attribute_position = $data['attribute_position']; |
||
669 | $attribute_names_max_key = max( array_keys( $attribute_names ) ); |
||
670 | |||
671 | for ( $i = 0; $i <= $attribute_names_max_key; $i++ ) { |
||
672 | if ( empty( $attribute_names[ $i ] ) ) { |
||
673 | continue; |
||
674 | } |
||
675 | |||
676 | $is_visible = isset( $attribute_visibility[ $i ] ) ? 1 : 0; |
||
677 | $is_variation = isset( $attribute_variation[ $i ] ) ? 1 : 0; |
||
678 | $is_taxonomy = $attribute_is_taxonomy[ $i ] ? 1 : 0; |
||
679 | |||
680 | if ( $is_taxonomy ) { |
||
681 | |||
682 | if ( isset( $attribute_values[ $i ] ) ) { |
||
683 | |||
684 | // Select based attributes - Format values (posted values are slugs) |
||
685 | if ( is_array( $attribute_values[ $i ] ) ) { |
||
686 | $values = array_map( 'sanitize_title', $attribute_values[ $i ] ); |
||
687 | |||
688 | // Text based attributes - Posted values are term names, wp_set_object_terms wants ids or slugs. |
||
689 | } else { |
||
690 | $values = array(); |
||
691 | $raw_values = array_map( 'wc_sanitize_term_text_based', explode( WC_DELIMITER, $attribute_values[ $i ] ) ); |
||
692 | |||
693 | foreach ( $raw_values as $value ) { |
||
694 | $term = get_term_by( 'name', $value, $attribute_names[ $i ] ); |
||
695 | if ( ! $term ) { |
||
696 | $term = wp_insert_term( $value, $attribute_names[ $i ] ); |
||
697 | |||
698 | if ( $term && ! is_wp_error( $term ) ) { |
||
699 | $values[] = $term['term_id']; |
||
700 | } |
||
701 | } else { |
||
702 | $values[] = $term->term_id; |
||
703 | } |
||
704 | } |
||
705 | } |
||
706 | |||
707 | // Remove empty items in the array |
||
708 | $values = array_filter( $values, 'strlen' ); |
||
709 | |||
710 | } else { |
||
711 | $values = array(); |
||
712 | } |
||
713 | |||
714 | // Update post terms |
||
715 | if ( taxonomy_exists( $attribute_names[ $i ] ) ) { |
||
716 | wp_set_object_terms( $post_id, $values, $attribute_names[ $i ] ); |
||
717 | } |
||
718 | |||
719 | View Code Duplication | if ( $values ) { |
|
720 | // Add attribute to array, but don't set values |
||
721 | $attributes[ sanitize_title( $attribute_names[ $i ] ) ] = array( |
||
722 | 'name' => wc_clean( $attribute_names[ $i ] ), |
||
723 | 'value' => '', |
||
724 | 'position' => $attribute_position[ $i ], |
||
725 | 'is_visible' => $is_visible, |
||
726 | 'is_variation' => $is_variation, |
||
727 | 'is_taxonomy' => $is_taxonomy |
||
728 | ); |
||
729 | } |
||
730 | |||
731 | View Code Duplication | } elseif ( isset( $attribute_values[ $i ] ) ) { |
|
732 | |||
733 | // Text based, possibly separated by pipes (WC_DELIMITER). Preserve line breaks in non-variation attributes. |
||
734 | $values = $is_variation ? wc_clean( $attribute_values[ $i ] ) : implode( "\n", array_map( 'wc_clean', explode( "\n", $attribute_values[ $i ] ) ) ); |
||
735 | $values = implode( ' ' . WC_DELIMITER . ' ', wc_get_text_attributes( $values ) ); |
||
736 | |||
737 | // Custom attribute - Add attribute to array and set the values |
||
738 | $attributes[ sanitize_title( $attribute_names[ $i ] ) ] = array( |
||
739 | 'name' => wc_clean( $attribute_names[ $i ] ), |
||
740 | 'value' => $values, |
||
741 | 'position' => $attribute_position[ $i ], |
||
742 | 'is_visible' => $is_visible, |
||
743 | 'is_variation' => $is_variation, |
||
744 | 'is_taxonomy' => $is_taxonomy |
||
745 | ); |
||
746 | } |
||
747 | |||
748 | } |
||
749 | } |
||
750 | |||
751 | uasort( $attributes, 'wc_product_attribute_uasort_comparison' ); |
||
752 | |||
753 | update_post_meta( $post_id, '_product_attributes', $attributes ); |
||
754 | |||
755 | die(); |
||
756 | } |
||
757 | |||
758 | /** |
||
759 | * Add variation via ajax function. |
||
760 | */ |
||
761 | public static function add_variation() { |
||
762 | |||
763 | check_ajax_referer( 'add-variation', 'security' ); |
||
764 | |||
765 | if ( ! current_user_can( 'edit_products' ) ) { |
||
766 | die(-1); |
||
767 | } |
||
768 | |||
769 | global $post; |
||
770 | |||
771 | $post_id = intval( $_POST['post_id'] ); |
||
772 | $post = get_post( $post_id ); // Set $post global so its available like within the admin screens |
||
773 | $loop = intval( $_POST['loop'] ); |
||
774 | |||
775 | $variation = array( |
||
776 | 'post_title' => 'Product #' . $post_id . ' Variation', |
||
777 | 'post_content' => '', |
||
778 | 'post_status' => 'publish', |
||
779 | 'post_author' => get_current_user_id(), |
||
780 | 'post_parent' => $post_id, |
||
781 | 'post_type' => 'product_variation', |
||
782 | 'menu_order' => -1 |
||
783 | ); |
||
784 | |||
785 | $variation_id = wp_insert_post( $variation ); |
||
786 | |||
787 | do_action( 'woocommerce_create_product_variation', $variation_id ); |
||
788 | |||
789 | if ( $variation_id ) { |
||
790 | $variation = get_post( $variation_id ); |
||
791 | $variation_meta = get_post_meta( $variation_id ); |
||
792 | $variation_data = array(); |
||
793 | $shipping_classes = get_the_terms( $variation_id, 'product_shipping_class' ); |
||
794 | $variation_fields = array( |
||
795 | '_sku' => '', |
||
796 | '_stock' => '', |
||
797 | '_regular_price' => '', |
||
798 | '_sale_price' => '', |
||
799 | '_weight' => '', |
||
800 | '_length' => '', |
||
801 | '_width' => '', |
||
802 | '_height' => '', |
||
803 | '_download_limit' => '', |
||
804 | '_download_expiry' => '', |
||
805 | '_downloadable_files' => '', |
||
806 | '_downloadable' => '', |
||
807 | '_virtual' => '', |
||
808 | '_thumbnail_id' => '', |
||
809 | '_sale_price_dates_from' => '', |
||
810 | '_sale_price_dates_to' => '', |
||
811 | '_manage_stock' => '', |
||
812 | '_stock_status' => '', |
||
813 | '_backorders' => null, |
||
814 | '_tax_class' => null, |
||
815 | '_variation_description' => '' |
||
816 | ); |
||
817 | |||
818 | View Code Duplication | foreach ( $variation_fields as $field => $value ) { |
|
819 | $variation_data[ $field ] = isset( $variation_meta[ $field ][0] ) ? maybe_unserialize( $variation_meta[ $field ][0] ) : $value; |
||
820 | } |
||
821 | |||
822 | // Add the variation attributes |
||
823 | $variation_data = array_merge( $variation_data, wc_get_product_variation_attributes( $variation_id ) ); |
||
824 | |||
825 | // Formatting |
||
826 | $variation_data['_regular_price'] = wc_format_localized_price( $variation_data['_regular_price'] ); |
||
827 | $variation_data['_sale_price'] = wc_format_localized_price( $variation_data['_sale_price'] ); |
||
828 | $variation_data['_weight'] = wc_format_localized_decimal( $variation_data['_weight'] ); |
||
829 | $variation_data['_length'] = wc_format_localized_decimal( $variation_data['_length'] ); |
||
830 | $variation_data['_width'] = wc_format_localized_decimal( $variation_data['_width'] ); |
||
831 | $variation_data['_height'] = wc_format_localized_decimal( $variation_data['_height'] ); |
||
832 | $variation_data['_thumbnail_id'] = absint( $variation_data['_thumbnail_id'] ); |
||
833 | $variation_data['image'] = $variation_data['_thumbnail_id'] ? wp_get_attachment_thumb_url( $variation_data['_thumbnail_id'] ) : ''; |
||
834 | $variation_data['shipping_class'] = $shipping_classes && ! is_wp_error( $shipping_classes ) ? current( $shipping_classes )->term_id : ''; |
||
835 | $variation_data['menu_order'] = $variation->menu_order; |
||
836 | $variation_data['_stock'] = wc_stock_amount( $variation_data['_stock'] ); |
||
837 | |||
838 | // Get tax classes |
||
839 | $tax_classes = WC_Tax::get_tax_classes(); |
||
840 | $tax_class_options = array(); |
||
841 | $tax_class_options[''] = __( 'Standard', 'woocommerce' ); |
||
842 | |||
843 | View Code Duplication | if ( ! empty( $tax_classes ) ) { |
|
844 | foreach ( $tax_classes as $class ) { |
||
845 | $tax_class_options[ sanitize_title( $class ) ] = esc_attr( $class ); |
||
846 | } |
||
847 | } |
||
848 | |||
849 | // Set backorder options |
||
850 | $backorder_options = array( |
||
851 | 'no' => __( 'Do not allow', 'woocommerce' ), |
||
852 | 'notify' => __( 'Allow, but notify customer', 'woocommerce' ), |
||
853 | 'yes' => __( 'Allow', 'woocommerce' ) |
||
854 | ); |
||
855 | |||
856 | // set stock status options |
||
857 | $stock_status_options = array( |
||
858 | 'instock' => __( 'In stock', 'woocommerce' ), |
||
859 | 'outofstock' => __( 'Out of stock', 'woocommerce' ) |
||
860 | ); |
||
861 | |||
862 | // Get attributes |
||
863 | $attributes = (array) maybe_unserialize( get_post_meta( $post_id, '_product_attributes', true ) ); |
||
864 | |||
865 | $parent_data = array( |
||
866 | 'id' => $post_id, |
||
867 | 'attributes' => $attributes, |
||
868 | 'tax_class_options' => $tax_class_options, |
||
869 | 'sku' => get_post_meta( $post_id, '_sku', true ), |
||
870 | 'weight' => wc_format_localized_decimal( get_post_meta( $post_id, '_weight', true ) ), |
||
871 | 'length' => wc_format_localized_decimal( get_post_meta( $post_id, '_length', true ) ), |
||
872 | 'width' => wc_format_localized_decimal( get_post_meta( $post_id, '_width', true ) ), |
||
873 | 'height' => wc_format_localized_decimal( get_post_meta( $post_id, '_height', true ) ), |
||
874 | 'tax_class' => get_post_meta( $post_id, '_tax_class', true ), |
||
875 | 'backorder_options' => $backorder_options, |
||
876 | 'stock_status_options' => $stock_status_options |
||
877 | ); |
||
878 | |||
879 | if ( ! $parent_data['weight'] ) { |
||
880 | $parent_data['weight'] = wc_format_localized_decimal( 0 ); |
||
881 | } |
||
882 | |||
883 | if ( ! $parent_data['length'] ) { |
||
884 | $parent_data['length'] = wc_format_localized_decimal( 0 ); |
||
885 | } |
||
886 | |||
887 | if ( ! $parent_data['width'] ) { |
||
888 | $parent_data['width'] = wc_format_localized_decimal( 0 ); |
||
889 | } |
||
890 | |||
891 | if ( ! $parent_data['height'] ) { |
||
892 | $parent_data['height'] = wc_format_localized_decimal( 0 ); |
||
893 | } |
||
894 | |||
895 | include( 'admin/meta-boxes/views/html-variation-admin.php' ); |
||
896 | } |
||
897 | |||
898 | die(); |
||
899 | } |
||
900 | |||
901 | /** |
||
902 | * Link all variations via ajax function. |
||
903 | */ |
||
904 | public static function link_all_variations() { |
||
905 | |||
906 | if ( ! defined( 'WC_MAX_LINKED_VARIATIONS' ) ) { |
||
907 | define( 'WC_MAX_LINKED_VARIATIONS', 49 ); |
||
908 | } |
||
909 | |||
910 | check_ajax_referer( 'link-variations', 'security' ); |
||
911 | |||
912 | if ( ! current_user_can( 'edit_products' ) ) { |
||
913 | die(-1); |
||
914 | } |
||
915 | |||
916 | wc_set_time_limit( 0 ); |
||
917 | |||
918 | $post_id = intval( $_POST['post_id'] ); |
||
919 | |||
920 | if ( ! $post_id ) { |
||
921 | die(); |
||
922 | } |
||
923 | |||
924 | $variations = array(); |
||
925 | $_product = wc_get_product( $post_id, array( 'product_type' => 'variable' ) ); |
||
926 | |||
927 | // Put variation attributes into an array |
||
928 | foreach ( $_product->get_attributes() as $attribute ) { |
||
929 | |||
930 | if ( ! $attribute['is_variation'] ) { |
||
931 | continue; |
||
932 | } |
||
933 | |||
934 | $attribute_field_name = 'attribute_' . sanitize_title( $attribute['name'] ); |
||
935 | |||
936 | if ( $attribute['is_taxonomy'] ) { |
||
937 | $options = wc_get_product_terms( $post_id, $attribute['name'], array( 'fields' => 'slugs' ) ); |
||
938 | } else { |
||
939 | $options = explode( WC_DELIMITER, $attribute['value'] ); |
||
940 | } |
||
941 | |||
942 | $options = array_map( 'trim', $options ); |
||
943 | |||
944 | $variations[ $attribute_field_name ] = $options; |
||
945 | } |
||
946 | |||
947 | // Quit out if none were found |
||
948 | if ( sizeof( $variations ) == 0 ) { |
||
949 | die(); |
||
950 | } |
||
951 | |||
952 | // Get existing variations so we don't create duplicates |
||
953 | $available_variations = array(); |
||
954 | |||
955 | foreach( $_product->get_children() as $child_id ) { |
||
956 | $child = $_product->get_child( $child_id ); |
||
957 | |||
958 | if ( ! empty( $child->variation_id ) ) { |
||
959 | $available_variations[] = $child->get_variation_attributes(); |
||
960 | } |
||
961 | } |
||
962 | |||
963 | // Created posts will all have the following data |
||
964 | $variation_post_data = array( |
||
965 | 'post_title' => 'Product #' . $post_id . ' Variation', |
||
966 | 'post_content' => '', |
||
967 | 'post_status' => 'publish', |
||
968 | 'post_author' => get_current_user_id(), |
||
969 | 'post_parent' => $post_id, |
||
970 | 'post_type' => 'product_variation' |
||
971 | ); |
||
972 | |||
973 | $variation_ids = array(); |
||
974 | $added = 0; |
||
975 | $possible_variations = wc_array_cartesian( $variations ); |
||
976 | |||
977 | foreach ( $possible_variations as $variation ) { |
||
978 | |||
979 | // Check if variation already exists |
||
980 | if ( in_array( $variation, $available_variations ) ) { |
||
981 | continue; |
||
982 | } |
||
983 | |||
984 | $variation_id = wp_insert_post( $variation_post_data ); |
||
985 | |||
986 | $variation_ids[] = $variation_id; |
||
987 | |||
988 | foreach ( $variation as $key => $value ) { |
||
989 | update_post_meta( $variation_id, $key, $value ); |
||
990 | } |
||
991 | |||
992 | // Save stock status |
||
993 | update_post_meta( $variation_id, '_stock_status', 'instock' ); |
||
994 | |||
995 | $added++; |
||
996 | |||
997 | do_action( 'product_variation_linked', $variation_id ); |
||
998 | |||
999 | if ( $added > WC_MAX_LINKED_VARIATIONS ) { |
||
1000 | break; |
||
1001 | } |
||
1002 | } |
||
1003 | |||
1004 | delete_transient( 'wc_product_children_' . $post_id ); |
||
1005 | |||
1006 | echo $added; |
||
1007 | |||
1008 | die(); |
||
1009 | } |
||
1010 | |||
1011 | /** |
||
1012 | * Delete download permissions via ajax function. |
||
1013 | */ |
||
1014 | public static function revoke_access_to_download() { |
||
1015 | |||
1016 | check_ajax_referer( 'revoke-access', 'security' ); |
||
1017 | |||
1018 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1019 | die(-1); |
||
1020 | } |
||
1021 | |||
1022 | global $wpdb; |
||
1023 | |||
1024 | $download_id = $_POST['download_id']; |
||
1025 | $product_id = intval( $_POST['product_id'] ); |
||
1026 | $order_id = intval( $_POST['order_id'] ); |
||
1027 | |||
1028 | $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d AND product_id = %d AND download_id = %s;", $order_id, $product_id, $download_id ) ); |
||
1029 | |||
1030 | do_action( 'woocommerce_ajax_revoke_access_to_product_download', $download_id, $product_id, $order_id ); |
||
1031 | |||
1032 | die(); |
||
1033 | } |
||
1034 | |||
1035 | /** |
||
1036 | * Grant download permissions via ajax function. |
||
1037 | */ |
||
1038 | public static function grant_access_to_download() { |
||
1039 | |||
1040 | check_ajax_referer( 'grant-access', 'security' ); |
||
1041 | |||
1042 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1043 | die(-1); |
||
1044 | } |
||
1045 | |||
1046 | global $wpdb; |
||
1047 | |||
1048 | $wpdb->hide_errors(); |
||
1049 | |||
1050 | $order_id = intval( $_POST['order_id'] ); |
||
1051 | $product_ids = $_POST['product_ids']; |
||
1052 | $loop = intval( $_POST['loop'] ); |
||
1053 | $file_counter = 0; |
||
1054 | $order = wc_get_order( $order_id ); |
||
1055 | |||
1056 | if ( ! is_array( $product_ids ) ) { |
||
1057 | $product_ids = array( $product_ids ); |
||
1058 | } |
||
1059 | |||
1060 | foreach ( $product_ids as $product_id ) { |
||
1061 | $product = wc_get_product( $product_id ); |
||
1062 | $files = $product->get_files(); |
||
1063 | |||
1064 | if ( ! $order->billing_email ) { |
||
1065 | die(); |
||
1066 | } |
||
1067 | |||
1068 | if ( $files ) { |
||
1069 | foreach ( $files as $download_id => $file ) { |
||
1070 | if ( $inserted_id = wc_downloadable_file_permission( $download_id, $product_id, $order ) ) { |
||
1071 | |||
1072 | // insert complete - get inserted data |
||
1073 | $download = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE permission_id = %d", $inserted_id ) ); |
||
1074 | |||
1075 | $loop ++; |
||
1076 | $file_counter ++; |
||
1077 | |||
1078 | View Code Duplication | if ( isset( $file['name'] ) ) { |
|
1079 | $file_count = $file['name']; |
||
1080 | } else { |
||
1081 | $file_count = sprintf( __( 'File %d', 'woocommerce' ), $file_counter ); |
||
1082 | } |
||
1083 | include( 'admin/meta-boxes/views/html-order-download-permission.php' ); |
||
1084 | } |
||
1085 | } |
||
1086 | } |
||
1087 | } |
||
1088 | |||
1089 | die(); |
||
1090 | } |
||
1091 | |||
1092 | /** |
||
1093 | * Get customer details via ajax. |
||
1094 | */ |
||
1095 | public static function get_customer_details() { |
||
1096 | ob_start(); |
||
1097 | |||
1098 | check_ajax_referer( 'get-customer-details', 'security' ); |
||
1099 | |||
1100 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1101 | die(-1); |
||
1102 | } |
||
1103 | |||
1104 | $user_id = (int) trim(stripslashes($_POST['user_id'])); |
||
1105 | $type_to_load = esc_attr(trim(stripslashes($_POST['type_to_load']))); |
||
1106 | |||
1107 | $customer_data = array( |
||
1108 | $type_to_load . '_first_name' => get_user_meta( $user_id, $type_to_load . '_first_name', true ), |
||
1109 | $type_to_load . '_last_name' => get_user_meta( $user_id, $type_to_load . '_last_name', true ), |
||
1110 | $type_to_load . '_company' => get_user_meta( $user_id, $type_to_load . '_company', true ), |
||
1111 | $type_to_load . '_address_1' => get_user_meta( $user_id, $type_to_load . '_address_1', true ), |
||
1112 | $type_to_load . '_address_2' => get_user_meta( $user_id, $type_to_load . '_address_2', true ), |
||
1113 | $type_to_load . '_city' => get_user_meta( $user_id, $type_to_load . '_city', true ), |
||
1114 | $type_to_load . '_postcode' => get_user_meta( $user_id, $type_to_load . '_postcode', true ), |
||
1115 | $type_to_load . '_country' => get_user_meta( $user_id, $type_to_load . '_country', true ), |
||
1116 | $type_to_load . '_state' => get_user_meta( $user_id, $type_to_load . '_state', true ), |
||
1117 | $type_to_load . '_email' => get_user_meta( $user_id, $type_to_load . '_email', true ), |
||
1118 | $type_to_load . '_phone' => get_user_meta( $user_id, $type_to_load . '_phone', true ), |
||
1119 | ); |
||
1120 | |||
1121 | $customer_data = apply_filters( 'woocommerce_found_customer_details', $customer_data, $user_id, $type_to_load ); |
||
1122 | |||
1123 | wp_send_json( $customer_data ); |
||
1124 | } |
||
1125 | |||
1126 | /** |
||
1127 | * Add order item via ajax. |
||
1128 | */ |
||
1129 | public static function add_order_item() { |
||
1130 | check_ajax_referer( 'order-item', 'security' ); |
||
1131 | |||
1132 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1133 | die(-1); |
||
1134 | } |
||
1135 | |||
1136 | $item_to_add = sanitize_text_field( $_POST['item_to_add'] ); |
||
1137 | $order_id = absint( $_POST['order_id'] ); |
||
1138 | |||
1139 | // Find the item |
||
1140 | if ( ! is_numeric( $item_to_add ) ) { |
||
1141 | die(); |
||
1142 | } |
||
1143 | |||
1144 | $post = get_post( $item_to_add ); |
||
1145 | |||
1146 | if ( ! $post || ( 'product' !== $post->post_type && 'product_variation' !== $post->post_type ) ) { |
||
1147 | die(); |
||
1148 | } |
||
1149 | |||
1150 | $_product = wc_get_product( $post->ID ); |
||
1151 | $order = wc_get_order( $order_id ); |
||
1152 | $order_taxes = $order->get_taxes(); |
||
1153 | $class = 'new_row'; |
||
1154 | |||
1155 | // Set values |
||
1156 | $item = array(); |
||
1157 | |||
1158 | $item['product_id'] = $_product->id; |
||
1159 | $item['variation_id'] = isset( $_product->variation_id ) ? $_product->variation_id : ''; |
||
1160 | $item['variation_data'] = $item['variation_id'] ? $_product->get_variation_attributes() : ''; |
||
1161 | $item['name'] = $_product->get_title(); |
||
1162 | $item['tax_class'] = $_product->get_tax_class(); |
||
1163 | $item['qty'] = 1; |
||
1164 | $item['line_subtotal'] = wc_format_decimal( $_product->get_price_excluding_tax() ); |
||
1165 | $item['line_subtotal_tax'] = ''; |
||
1166 | $item['line_total'] = wc_format_decimal( $_product->get_price_excluding_tax() ); |
||
1167 | $item['line_tax'] = ''; |
||
1168 | $item['type'] = 'line_item'; |
||
1169 | |||
1170 | // Add line item |
||
1171 | $item_id = wc_add_order_item( $order_id, array( |
||
1172 | 'order_item_name' => $item['name'], |
||
1173 | 'order_item_type' => 'line_item' |
||
1174 | ) ); |
||
1175 | |||
1176 | // Add line item meta |
||
1177 | if ( $item_id ) { |
||
1178 | wc_add_order_item_meta( $item_id, '_qty', $item['qty'] ); |
||
1179 | wc_add_order_item_meta( $item_id, '_tax_class', $item['tax_class'] ); |
||
1180 | wc_add_order_item_meta( $item_id, '_product_id', $item['product_id'] ); |
||
1181 | wc_add_order_item_meta( $item_id, '_variation_id', $item['variation_id'] ); |
||
1182 | wc_add_order_item_meta( $item_id, '_line_subtotal', $item['line_subtotal'] ); |
||
1183 | wc_add_order_item_meta( $item_id, '_line_subtotal_tax', $item['line_subtotal_tax'] ); |
||
1184 | wc_add_order_item_meta( $item_id, '_line_total', $item['line_total'] ); |
||
1185 | wc_add_order_item_meta( $item_id, '_line_tax', $item['line_tax'] ); |
||
1186 | |||
1187 | // Since 2.2 |
||
1188 | wc_add_order_item_meta( $item_id, '_line_tax_data', array( 'total' => array(), 'subtotal' => array() ) ); |
||
1189 | |||
1190 | // Store variation data in meta |
||
1191 | View Code Duplication | if ( $item['variation_data'] && is_array( $item['variation_data'] ) ) { |
|
1192 | foreach ( $item['variation_data'] as $key => $value ) { |
||
1193 | wc_add_order_item_meta( $item_id, str_replace( 'attribute_', '', $key ), $value ); |
||
1194 | } |
||
1195 | } |
||
1196 | |||
1197 | do_action( 'woocommerce_ajax_add_order_item_meta', $item_id, $item ); |
||
1198 | } |
||
1199 | |||
1200 | $item['item_meta'] = $order->get_item_meta( $item_id ); |
||
1201 | $item['item_meta_array'] = $order->get_item_meta_array( $item_id ); |
||
1202 | $item = $order->expand_item_meta( $item ); |
||
1203 | $item = apply_filters( 'woocommerce_ajax_order_item', $item, $item_id ); |
||
1204 | |||
1205 | include( 'admin/meta-boxes/views/html-order-item.php' ); |
||
1206 | |||
1207 | // Quit out |
||
1208 | die(); |
||
1209 | } |
||
1210 | |||
1211 | /** |
||
1212 | * Add order fee via ajax. |
||
1213 | */ |
||
1214 | public static function add_order_fee() { |
||
1215 | |||
1216 | check_ajax_referer( 'order-item', 'security' ); |
||
1217 | |||
1218 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1219 | die(-1); |
||
1220 | } |
||
1221 | |||
1222 | $order_id = absint( $_POST['order_id'] ); |
||
1223 | $order = wc_get_order( $order_id ); |
||
1224 | $order_taxes = $order->get_taxes(); |
||
1225 | $item = array(); |
||
1226 | |||
1227 | // Add new fee |
||
1228 | $fee = new stdClass(); |
||
1229 | $fee->name = ''; |
||
1230 | $fee->tax_class = ''; |
||
1231 | $fee->taxable = $fee->tax_class !== '0'; |
||
1232 | $fee->amount = ''; |
||
1233 | $fee->tax = ''; |
||
1234 | $fee->tax_data = array(); |
||
1235 | $item_id = $order->add_fee( $fee ); |
||
1236 | |||
1237 | include( 'admin/meta-boxes/views/html-order-fee.php' ); |
||
1238 | |||
1239 | // Quit out |
||
1240 | die(); |
||
1241 | } |
||
1242 | |||
1243 | /** |
||
1244 | * Add order shipping cost via ajax. |
||
1245 | */ |
||
1246 | public static function add_order_shipping() { |
||
1247 | |||
1248 | check_ajax_referer( 'order-item', 'security' ); |
||
1249 | |||
1250 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1251 | die(-1); |
||
1252 | } |
||
1253 | |||
1254 | $order_id = absint( $_POST['order_id'] ); |
||
1255 | $order = wc_get_order( $order_id ); |
||
1256 | $order_taxes = $order->get_taxes(); |
||
1257 | $shipping_methods = WC()->shipping() ? WC()->shipping->load_shipping_methods() : array(); |
||
1258 | $item = array(); |
||
1259 | |||
1260 | // Add new shipping |
||
1261 | $shipping = new WC_Shipping_Rate(); |
||
1262 | $item_id = $order->add_shipping( $shipping ); |
||
1263 | |||
1264 | include( 'admin/meta-boxes/views/html-order-shipping.php' ); |
||
1265 | |||
1266 | // Quit out |
||
1267 | die(); |
||
1268 | } |
||
1269 | |||
1270 | /** |
||
1271 | * Add order tax column via ajax. |
||
1272 | */ |
||
1273 | public static function add_order_tax() { |
||
1274 | global $wpdb; |
||
1275 | |||
1276 | check_ajax_referer( 'order-item', 'security' ); |
||
1277 | |||
1278 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1279 | die(-1); |
||
1280 | } |
||
1281 | |||
1282 | $order_id = absint( $_POST['order_id'] ); |
||
1283 | $rate_id = absint( $_POST['rate_id'] ); |
||
1284 | $order = wc_get_order( $order_id ); |
||
1285 | $data = get_post_meta( $order_id ); |
||
1286 | |||
1287 | // Add new tax |
||
1288 | $order->add_tax( $rate_id, 0, 0 ); |
||
1289 | |||
1290 | // Return HTML items |
||
1291 | include( 'admin/meta-boxes/views/html-order-items.php' ); |
||
1292 | |||
1293 | die(); |
||
1294 | } |
||
1295 | |||
1296 | /** |
||
1297 | * Remove an order item. |
||
1298 | */ |
||
1299 | public static function remove_order_item() { |
||
1300 | check_ajax_referer( 'order-item', 'security' ); |
||
1301 | |||
1302 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1303 | die(-1); |
||
1304 | } |
||
1305 | |||
1306 | $order_item_ids = $_POST['order_item_ids']; |
||
1307 | |||
1308 | if ( ! is_array( $order_item_ids ) && is_numeric( $order_item_ids ) ) { |
||
1309 | $order_item_ids = array( $order_item_ids ); |
||
1310 | } |
||
1311 | |||
1312 | if ( sizeof( $order_item_ids ) > 0 ) { |
||
1313 | foreach( $order_item_ids as $id ) { |
||
1314 | wc_delete_order_item( absint( $id ) ); |
||
1315 | } |
||
1316 | } |
||
1317 | |||
1318 | die(); |
||
1319 | } |
||
1320 | |||
1321 | /** |
||
1322 | * Remove an order tax. |
||
1323 | */ |
||
1324 | public static function remove_order_tax() { |
||
1325 | |||
1326 | check_ajax_referer( 'order-item', 'security' ); |
||
1327 | |||
1328 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1329 | die(-1); |
||
1330 | } |
||
1331 | |||
1332 | $order_id = absint( $_POST['order_id'] ); |
||
1333 | $rate_id = absint( $_POST['rate_id'] ); |
||
1334 | |||
1335 | wc_delete_order_item( $rate_id ); |
||
1336 | |||
1337 | // Return HTML items |
||
1338 | $order = wc_get_order( $order_id ); |
||
1339 | $data = get_post_meta( $order_id ); |
||
1340 | include( 'admin/meta-boxes/views/html-order-items.php' ); |
||
1341 | |||
1342 | die(); |
||
1343 | } |
||
1344 | |||
1345 | /** |
||
1346 | * Reduce order item stock. |
||
1347 | */ |
||
1348 | public static function reduce_order_item_stock() { |
||
1349 | check_ajax_referer( 'order-item', 'security' ); |
||
1350 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1351 | die(-1); |
||
1352 | } |
||
1353 | $order_id = absint( $_POST['order_id'] ); |
||
1354 | $order_item_ids = isset( $_POST['order_item_ids'] ) ? $_POST['order_item_ids'] : array(); |
||
1355 | $order_item_qty = isset( $_POST['order_item_qty'] ) ? $_POST['order_item_qty'] : array(); |
||
1356 | $order = wc_get_order( $order_id ); |
||
1357 | $order_items = $order->get_items(); |
||
1358 | $return = array(); |
||
1359 | if ( $order && ! empty( $order_items ) && sizeof( $order_item_ids ) > 0 ) { |
||
1360 | foreach ( $order_items as $item_id => $order_item ) { |
||
1361 | // Only reduce checked items |
||
1362 | if ( ! in_array( $item_id, $order_item_ids ) ) { |
||
1363 | continue; |
||
1364 | } |
||
1365 | $_product = $order->get_product_from_item( $order_item ); |
||
1366 | if ( $_product->exists() && $_product->managing_stock() && isset( $order_item_qty[ $item_id ] ) && $order_item_qty[ $item_id ] > 0 ) { |
||
1367 | $stock_change = apply_filters( 'woocommerce_reduce_order_stock_quantity', $order_item_qty[ $item_id ], $item_id ); |
||
1368 | $new_stock = $_product->reduce_stock( $stock_change ); |
||
1369 | $item_name = $_product->get_sku() ? $_product->get_sku() : $order_item['product_id']; |
||
1370 | $note = sprintf( __( 'Item %s stock reduced from %s to %s.', 'woocommerce' ), $item_name, $new_stock + $stock_change, $new_stock ); |
||
1371 | $return[] = $note; |
||
1372 | $order->add_order_note( $note ); |
||
1373 | $order->send_stock_notifications( $_product, $new_stock, $order_item_qty[ $item_id ] ); |
||
1374 | } |
||
1375 | } |
||
1376 | do_action( 'woocommerce_reduce_order_stock', $order ); |
||
1377 | if ( empty( $return ) ) { |
||
1378 | $return[] = __( 'No products had their stock reduced - they may not have stock management enabled.', 'woocommerce' ); |
||
1379 | } |
||
1380 | echo implode( ', ', $return ); |
||
1381 | } |
||
1382 | die(); |
||
1383 | } |
||
1384 | |||
1385 | /** |
||
1386 | * Increase order item stock. |
||
1387 | */ |
||
1388 | public static function increase_order_item_stock() { |
||
1389 | check_ajax_referer( 'order-item', 'security' ); |
||
1390 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1391 | die(-1); |
||
1392 | } |
||
1393 | $order_id = absint( $_POST['order_id'] ); |
||
1394 | $order_item_ids = isset( $_POST['order_item_ids'] ) ? $_POST['order_item_ids'] : array(); |
||
1395 | $order_item_qty = isset( $_POST['order_item_qty'] ) ? $_POST['order_item_qty'] : array(); |
||
1396 | $order = wc_get_order( $order_id ); |
||
1397 | $order_items = $order->get_items(); |
||
1398 | $return = array(); |
||
1399 | if ( $order && ! empty( $order_items ) && sizeof( $order_item_ids ) > 0 ) { |
||
1400 | foreach ( $order_items as $item_id => $order_item ) { |
||
1401 | // Only reduce checked items |
||
1402 | if ( ! in_array( $item_id, $order_item_ids ) ) { |
||
1403 | continue; |
||
1404 | } |
||
1405 | $_product = $order->get_product_from_item( $order_item ); |
||
1406 | if ( $_product->exists() && $_product->managing_stock() && isset( $order_item_qty[ $item_id ] ) && $order_item_qty[ $item_id ] > 0 ) { |
||
1407 | $old_stock = $_product->get_stock_quantity(); |
||
1408 | $stock_change = apply_filters( 'woocommerce_restore_order_stock_quantity', $order_item_qty[ $item_id ], $item_id ); |
||
1409 | $new_quantity = $_product->increase_stock( $stock_change ); |
||
1410 | $item_name = $_product->get_sku() ? $_product->get_sku(): $order_item['product_id']; |
||
1411 | $note = sprintf( __( 'Item %s stock increased from %s to %s.', 'woocommerce' ), $item_name, $old_stock, $new_quantity ); |
||
1412 | $return[] = $note; |
||
1413 | $order->add_order_note( $note ); |
||
1414 | } |
||
1415 | } |
||
1416 | do_action( 'woocommerce_restore_order_stock', $order ); |
||
1417 | if ( empty( $return ) ) { |
||
1418 | $return[] = __( 'No products had their stock increased - they may not have stock management enabled.', 'woocommerce' ); |
||
1419 | } |
||
1420 | echo implode( ', ', $return ); |
||
1421 | } |
||
1422 | die(); |
||
1423 | } |
||
1424 | |||
1425 | /** |
||
1426 | * Add some meta to a line item. |
||
1427 | */ |
||
1428 | public static function add_order_item_meta() { |
||
1429 | check_ajax_referer( 'order-item', 'security' ); |
||
1430 | |||
1431 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1432 | die(-1); |
||
1433 | } |
||
1434 | |||
1435 | $meta_id = wc_add_order_item_meta( absint( $_POST['order_item_id'] ), __( 'Name', 'woocommerce' ), __( 'Value', 'woocommerce' ) ); |
||
1436 | |||
1437 | if ( $meta_id ) { |
||
1438 | echo '<tr data-meta_id="' . esc_attr( $meta_id ) . '"><td><input type="text" name="meta_key[' . $meta_id . ']" /><textarea name="meta_value[' . $meta_id . ']"></textarea></td><td width="1%"><button class="remove_order_item_meta button">×</button></td></tr>'; |
||
1439 | } |
||
1440 | |||
1441 | die(); |
||
1442 | } |
||
1443 | |||
1444 | /** |
||
1445 | * Remove meta from a line item. |
||
1446 | */ |
||
1447 | public static function remove_order_item_meta() { |
||
1448 | check_ajax_referer( 'order-item', 'security' ); |
||
1449 | |||
1450 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1451 | die(-1); |
||
1452 | } |
||
1453 | |||
1454 | global $wpdb; |
||
1455 | |||
1456 | $wpdb->delete( "{$wpdb->prefix}woocommerce_order_itemmeta", array( |
||
1457 | 'meta_id' => absint( $_POST['meta_id'] ), |
||
1458 | ) ); |
||
1459 | |||
1460 | die(); |
||
1461 | } |
||
1462 | |||
1463 | /** |
||
1464 | * Calc line tax. |
||
1465 | */ |
||
1466 | public static function calc_line_taxes() { |
||
1467 | global $wpdb; |
||
1468 | |||
1469 | check_ajax_referer( 'calc-totals', 'security' ); |
||
1470 | |||
1471 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1472 | die(-1); |
||
1473 | } |
||
1474 | |||
1475 | $tax = new WC_Tax(); |
||
1476 | $tax_based_on = get_option( 'woocommerce_tax_based_on' ); |
||
1477 | $order_id = absint( $_POST['order_id'] ); |
||
1478 | $items = array(); |
||
1479 | $country = strtoupper( esc_attr( $_POST['country'] ) ); |
||
1480 | $state = strtoupper( esc_attr( $_POST['state'] ) ); |
||
1481 | $postcode = strtoupper( esc_attr( $_POST['postcode'] ) ); |
||
1482 | $city = wc_clean( esc_attr( $_POST['city'] ) ); |
||
1483 | $order = wc_get_order( $order_id ); |
||
1484 | $taxes = array(); |
||
1485 | $shipping_taxes = array(); |
||
1486 | $order_item_tax_classes = array(); |
||
1487 | |||
1488 | // Default to base |
||
1489 | View Code Duplication | if ( 'base' === $tax_based_on || empty( $country ) ) { |
|
1490 | $default = wc_get_base_location(); |
||
1491 | $country = $default['country']; |
||
1492 | $state = $default['state']; |
||
1493 | $postcode = ''; |
||
1494 | $city = ''; |
||
1495 | } |
||
1496 | |||
1497 | // Parse the jQuery serialized items |
||
1498 | parse_str( $_POST['items'], $items ); |
||
1499 | |||
1500 | // Prevent undefined warnings |
||
1501 | if ( ! isset( $items['line_tax'] ) ) { |
||
1502 | $items['line_tax'] = array(); |
||
1503 | } |
||
1504 | if ( ! isset( $items['line_subtotal_tax'] ) ) { |
||
1505 | $items['line_subtotal_tax'] = array(); |
||
1506 | } |
||
1507 | $items['order_taxes'] = array(); |
||
1508 | |||
1509 | // Action |
||
1510 | $items = apply_filters( 'woocommerce_ajax_calc_line_taxes', $items, $order_id, $country, $_POST ); |
||
1511 | |||
1512 | $is_vat_exempt = get_post_meta( $order_id, '_is_vat_exempt', true ); |
||
1513 | |||
1514 | // Tax is calculated only if tax is enabled and order is not vat exempted |
||
1515 | if ( wc_tax_enabled() && $is_vat_exempt !== 'yes' ) { |
||
1516 | |||
1517 | // Get items and fees taxes |
||
1518 | if ( isset( $items['order_item_id'] ) ) { |
||
1519 | $line_total = $line_subtotal = array(); |
||
1520 | |||
1521 | foreach ( $items['order_item_id'] as $item_id ) { |
||
1522 | $item_id = absint( $item_id ); |
||
1523 | $line_total[ $item_id ] = isset( $items['line_total'][ $item_id ] ) ? wc_format_decimal( $items['line_total'][ $item_id ] ) : 0; |
||
1524 | $line_subtotal[ $item_id ] = isset( $items['line_subtotal'][ $item_id ] ) ? wc_format_decimal( $items['line_subtotal'][ $item_id ] ) : $line_total[ $item_id ]; |
||
1525 | $order_item_tax_classes[ $item_id ] = isset( $items['order_item_tax_class'][ $item_id ] ) ? sanitize_text_field( $items['order_item_tax_class'][ $item_id ] ) : ''; |
||
1526 | $product_id = $order->get_item_meta( $item_id, '_product_id', true ); |
||
1527 | |||
1528 | // Get product details |
||
1529 | if ( get_post_type( $product_id ) == 'product' ) { |
||
1530 | $_product = wc_get_product( $product_id ); |
||
1531 | $item_tax_status = $_product->get_tax_status(); |
||
1532 | } else { |
||
1533 | $item_tax_status = 'taxable'; |
||
1534 | } |
||
1535 | |||
1536 | if ( '0' !== $order_item_tax_classes[ $item_id ] && 'taxable' === $item_tax_status ) { |
||
1537 | $tax_rates = WC_Tax::find_rates( array( |
||
1538 | 'country' => $country, |
||
1539 | 'state' => $state, |
||
1540 | 'postcode' => $postcode, |
||
1541 | 'city' => $city, |
||
1542 | 'tax_class' => $order_item_tax_classes[ $item_id ] |
||
1543 | ) ); |
||
1544 | |||
1545 | $line_taxes = WC_Tax::calc_tax( $line_total[ $item_id ], $tax_rates, false ); |
||
1546 | $line_subtotal_taxes = WC_Tax::calc_tax( $line_subtotal[ $item_id ], $tax_rates, false ); |
||
1547 | |||
1548 | // Set the new line_tax |
||
1549 | foreach ( $line_taxes as $_tax_id => $_tax_value ) { |
||
1550 | $items['line_tax'][ $item_id ][ $_tax_id ] = $_tax_value; |
||
1551 | } |
||
1552 | |||
1553 | // Set the new line_subtotal_tax |
||
1554 | foreach ( $line_subtotal_taxes as $_tax_id => $_tax_value ) { |
||
1555 | $items['line_subtotal_tax'][ $item_id ][ $_tax_id ] = $_tax_value; |
||
1556 | } |
||
1557 | |||
1558 | // Sum the item taxes |
||
1559 | View Code Duplication | foreach ( array_keys( $taxes + $line_taxes ) as $key ) { |
|
1560 | $taxes[ $key ] = ( isset( $line_taxes[ $key ] ) ? $line_taxes[ $key ] : 0 ) + ( isset( $taxes[ $key ] ) ? $taxes[ $key ] : 0 ); |
||
1561 | } |
||
1562 | } |
||
1563 | } |
||
1564 | } |
||
1565 | |||
1566 | // Get shipping taxes |
||
1567 | if ( isset( $items['shipping_method_id'] ) ) { |
||
1568 | $matched_tax_rates = array(); |
||
1569 | $order_item_tax_classes = array_unique( array_values( $order_item_tax_classes ) ); |
||
1570 | |||
1571 | // If multiple classes are found, use the first one. Don't bother with standard rate, we can get that later. |
||
1572 | View Code Duplication | if ( sizeof( $order_item_tax_classes ) > 1 && ! in_array( '', $order_item_tax_classes ) ) { |
|
1573 | $tax_classes = WC_Tax::get_tax_classes(); |
||
1574 | |||
1575 | foreach ( $tax_classes as $tax_class ) { |
||
1576 | $tax_class = sanitize_title( $tax_class ); |
||
1577 | if ( in_array( $tax_class, $order_item_tax_classes ) ) { |
||
1578 | $matched_tax_rates = WC_Tax::find_shipping_rates( array( |
||
1579 | 'country' => $country, |
||
1580 | 'state' => $state, |
||
1581 | 'postcode' => $postcode, |
||
1582 | 'city' => $city, |
||
1583 | 'tax_class' => $tax_class, |
||
1584 | ) ); |
||
1585 | break; |
||
1586 | } |
||
1587 | } |
||
1588 | // If a single tax class is found, use it |
||
1589 | } elseif ( sizeof( $order_item_tax_classes ) === 1 ) { |
||
1590 | $matched_tax_rates = WC_Tax::find_shipping_rates( array( |
||
1591 | 'country' => $country, |
||
1592 | 'state' => $state, |
||
1593 | 'postcode' => $postcode, |
||
1594 | 'city' => $city, |
||
1595 | 'tax_class' => $order_item_tax_classes[0] |
||
1596 | ) ); |
||
1597 | } |
||
1598 | |||
1599 | // Get standard rate if no taxes were found |
||
1600 | if ( ! sizeof( $matched_tax_rates ) ) { |
||
1601 | $matched_tax_rates = WC_Tax::find_shipping_rates( array( |
||
1602 | 'country' => $country, |
||
1603 | 'state' => $state, |
||
1604 | 'postcode' => $postcode, |
||
1605 | 'city' => $city |
||
1606 | ) ); |
||
1607 | } |
||
1608 | |||
1609 | $shipping_cost = $shipping_taxes = array(); |
||
1610 | |||
1611 | foreach ( $items['shipping_method_id'] as $item_id ) { |
||
1612 | $item_id = absint( $item_id ); |
||
1613 | $shipping_cost[ $item_id ] = isset( $items['shipping_cost'][ $item_id ] ) ? wc_format_decimal( $items['shipping_cost'][ $item_id ] ) : 0; |
||
1614 | $_shipping_taxes = WC_Tax::calc_shipping_tax( $shipping_cost[ $item_id ], $matched_tax_rates ); |
||
1615 | |||
1616 | // Set the new shipping_taxes |
||
1617 | foreach ( $_shipping_taxes as $_tax_id => $_tax_value ) { |
||
1618 | $items['shipping_taxes'][ $item_id ][ $_tax_id ] = $_tax_value; |
||
1619 | |||
1620 | $shipping_taxes[ $_tax_id ] = isset( $shipping_taxes[ $_tax_id ] ) ? $shipping_taxes[ $_tax_id ] + $_tax_value : $_tax_value; |
||
1621 | } |
||
1622 | } |
||
1623 | } |
||
1624 | } |
||
1625 | |||
1626 | // Remove old tax rows |
||
1627 | $order->remove_order_items( 'tax' ); |
||
1628 | |||
1629 | // Add tax rows |
||
1630 | foreach ( array_keys( $taxes + $shipping_taxes ) as $tax_rate_id ) { |
||
1631 | $order->add_tax( $tax_rate_id, isset( $taxes[ $tax_rate_id ] ) ? $taxes[ $tax_rate_id ] : 0, isset( $shipping_taxes[ $tax_rate_id ] ) ? $shipping_taxes[ $tax_rate_id ] : 0 ); |
||
1632 | } |
||
1633 | |||
1634 | // Create the new order_taxes |
||
1635 | foreach ( $order->get_taxes() as $tax_id => $tax_item ) { |
||
1636 | $items['order_taxes'][ $tax_id ] = absint( $tax_item['rate_id'] ); |
||
1637 | } |
||
1638 | |||
1639 | $items = apply_filters( 'woocommerce_ajax_after_calc_line_taxes', $items, $order_id, $country, $_POST ); |
||
1640 | |||
1641 | // Save order items |
||
1642 | wc_save_order_items( $order_id, $items ); |
||
1643 | |||
1644 | // Return HTML items |
||
1645 | $order = wc_get_order( $order_id ); |
||
1646 | $data = get_post_meta( $order_id ); |
||
1647 | include( 'admin/meta-boxes/views/html-order-items.php' ); |
||
1648 | |||
1649 | die(); |
||
1650 | } |
||
1651 | |||
1652 | /** |
||
1653 | * Save order items via ajax. |
||
1654 | */ |
||
1655 | public static function save_order_items() { |
||
1656 | check_ajax_referer( 'order-item', 'security' ); |
||
1657 | |||
1658 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1659 | die(-1); |
||
1660 | } |
||
1661 | |||
1662 | if ( isset( $_POST['order_id'] ) && isset( $_POST['items'] ) ) { |
||
1663 | $order_id = absint( $_POST['order_id'] ); |
||
1664 | |||
1665 | // Parse the jQuery serialized items |
||
1666 | $items = array(); |
||
1667 | parse_str( $_POST['items'], $items ); |
||
1668 | |||
1669 | // Save order items |
||
1670 | wc_save_order_items( $order_id, $items ); |
||
1671 | |||
1672 | // Return HTML items |
||
1673 | $order = wc_get_order( $order_id ); |
||
1674 | $data = get_post_meta( $order_id ); |
||
1675 | include( 'admin/meta-boxes/views/html-order-items.php' ); |
||
1676 | } |
||
1677 | |||
1678 | die(); |
||
1679 | } |
||
1680 | |||
1681 | /** |
||
1682 | * Load order items via ajax. |
||
1683 | */ |
||
1684 | public static function load_order_items() { |
||
1685 | check_ajax_referer( 'order-item', 'security' ); |
||
1686 | |||
1687 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1688 | die(-1); |
||
1689 | } |
||
1690 | |||
1691 | // Return HTML items |
||
1692 | $order_id = absint( $_POST['order_id'] ); |
||
1693 | $order = wc_get_order( $order_id ); |
||
1694 | $data = get_post_meta( $order_id ); |
||
1695 | include( 'admin/meta-boxes/views/html-order-items.php' ); |
||
1696 | |||
1697 | die(); |
||
1698 | } |
||
1699 | |||
1700 | /** |
||
1701 | * Add order note via ajax. |
||
1702 | */ |
||
1703 | public static function add_order_note() { |
||
1704 | |||
1705 | check_ajax_referer( 'add-order-note', 'security' ); |
||
1706 | |||
1707 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1708 | die(-1); |
||
1709 | } |
||
1710 | |||
1711 | $post_id = absint( $_POST['post_id'] ); |
||
1712 | $note = wp_kses_post( trim( stripslashes( $_POST['note'] ) ) ); |
||
1713 | $note_type = $_POST['note_type']; |
||
1714 | |||
1715 | $is_customer_note = $note_type == 'customer' ? 1 : 0; |
||
1716 | |||
1717 | if ( $post_id > 0 ) { |
||
1718 | $order = wc_get_order( $post_id ); |
||
1719 | $comment_id = $order->add_order_note( $note, $is_customer_note, true ); |
||
1720 | |||
1721 | echo '<li rel="' . esc_attr( $comment_id ) . '" class="note '; |
||
1722 | if ( $is_customer_note ) { |
||
1723 | echo 'customer-note'; |
||
1724 | } |
||
1725 | echo '"><div class="note_content">'; |
||
1726 | echo wpautop( wptexturize( $note ) ); |
||
1727 | echo '</div><p class="meta"><a href="#" class="delete_note">'.__( 'Delete note', 'woocommerce' ).'</a></p>'; |
||
1728 | echo '</li>'; |
||
1729 | } |
||
1730 | |||
1731 | // Quit out |
||
1732 | die(); |
||
1733 | } |
||
1734 | |||
1735 | /** |
||
1736 | * Delete order note via ajax. |
||
1737 | */ |
||
1738 | public static function delete_order_note() { |
||
1739 | |||
1740 | check_ajax_referer( 'delete-order-note', 'security' ); |
||
1741 | |||
1742 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1743 | die(-1); |
||
1744 | } |
||
1745 | |||
1746 | $note_id = (int) $_POST['note_id']; |
||
1747 | |||
1748 | if ( $note_id > 0 ) { |
||
1749 | wp_delete_comment( $note_id ); |
||
1750 | } |
||
1751 | |||
1752 | // Quit out |
||
1753 | die(); |
||
1754 | } |
||
1755 | |||
1756 | /** |
||
1757 | * Search for products and echo json. |
||
1758 | * |
||
1759 | * @param string $x (default: '') |
||
1760 | * @param string $post_types (default: array('product')) |
||
1761 | */ |
||
1762 | public static function json_search_products( $x = '', $post_types = array( 'product' ) ) { |
||
0 ignored issues
–
show
|
|||
1763 | global $wpdb; |
||
1764 | |||
1765 | ob_start(); |
||
1766 | |||
1767 | check_ajax_referer( 'search-products', 'security' ); |
||
1768 | |||
1769 | $term = (string) wc_clean( stripslashes( $_GET['term'] ) ); |
||
1770 | |||
1771 | if ( empty( $term ) ) { |
||
1772 | die(); |
||
1773 | } |
||
1774 | |||
1775 | $like_term = '%' . $wpdb->esc_like( $term ) . '%'; |
||
1776 | |||
1777 | if ( is_numeric( $term ) ) { |
||
1778 | $query = $wpdb->prepare( " |
||
1779 | SELECT ID FROM {$wpdb->posts} posts LEFT JOIN {$wpdb->postmeta} postmeta ON posts.ID = postmeta.post_id |
||
1780 | WHERE posts.post_status = 'publish' |
||
1781 | AND ( |
||
1782 | posts.post_parent = %s |
||
1783 | OR posts.ID = %s |
||
1784 | OR posts.post_title LIKE %s |
||
1785 | OR ( |
||
1786 | postmeta.meta_key = '_sku' AND postmeta.meta_value LIKE %s |
||
1787 | ) |
||
1788 | ) |
||
1789 | ", $term, $term, $term, $like_term ); |
||
1790 | } else { |
||
1791 | $query = $wpdb->prepare( " |
||
1792 | SELECT ID FROM {$wpdb->posts} posts LEFT JOIN {$wpdb->postmeta} postmeta ON posts.ID = postmeta.post_id |
||
1793 | WHERE posts.post_status = 'publish' |
||
1794 | AND ( |
||
1795 | posts.post_title LIKE %s |
||
1796 | or posts.post_content LIKE %s |
||
1797 | OR ( |
||
1798 | postmeta.meta_key = '_sku' AND postmeta.meta_value LIKE %s |
||
1799 | ) |
||
1800 | ) |
||
1801 | ", $like_term, $like_term, $like_term ); |
||
1802 | } |
||
1803 | |||
1804 | $query .= " AND posts.post_type IN ('" . implode( "','", array_map( 'esc_sql', $post_types ) ) . "')"; |
||
1805 | |||
1806 | if ( ! empty( $_GET['exclude'] ) ) { |
||
1807 | $query .= " AND posts.ID NOT IN (" . implode( ',', array_map( 'intval', explode( ',', $_GET['exclude'] ) ) ) . ")"; |
||
1808 | } |
||
1809 | |||
1810 | if ( ! empty( $_GET['include'] ) ) { |
||
1811 | $query .= " AND posts.ID IN (" . implode( ',', array_map( 'intval', explode( ',', $_GET['include'] ) ) ) . ")"; |
||
1812 | } |
||
1813 | |||
1814 | if ( ! empty( $_GET['limit'] ) ) { |
||
1815 | $query .= " LIMIT " . intval( $_GET['limit'] ); |
||
1816 | } |
||
1817 | |||
1818 | $posts = array_unique( $wpdb->get_col( $query ) ); |
||
1819 | $found_products = array(); |
||
1820 | |||
1821 | if ( ! empty( $posts ) ) { |
||
1822 | foreach ( $posts as $post ) { |
||
1823 | $product = wc_get_product( $post ); |
||
1824 | |||
1825 | if ( ! current_user_can( 'read_product', $post ) ) { |
||
1826 | continue; |
||
1827 | } |
||
1828 | |||
1829 | if ( ! $product || ( $product->is_type( 'variation' ) && empty( $product->parent ) ) ) { |
||
1830 | continue; |
||
1831 | } |
||
1832 | |||
1833 | $found_products[ $post ] = rawurldecode( $product->get_formatted_name() ); |
||
1834 | } |
||
1835 | } |
||
1836 | |||
1837 | $found_products = apply_filters( 'woocommerce_json_search_found_products', $found_products ); |
||
1838 | |||
1839 | wp_send_json( $found_products ); |
||
1840 | } |
||
1841 | |||
1842 | /** |
||
1843 | * Search for product variations and return json. |
||
1844 | * |
||
1845 | * @see WC_AJAX::json_search_products() |
||
1846 | */ |
||
1847 | public static function json_search_products_and_variations() { |
||
1848 | self::json_search_products( '', array( 'product', 'product_variation' ) ); |
||
1849 | } |
||
1850 | |||
1851 | /** |
||
1852 | * Search for grouped products and return json. |
||
1853 | */ |
||
1854 | public static function json_search_grouped_products() { |
||
1855 | ob_start(); |
||
1856 | |||
1857 | check_ajax_referer( 'search-products', 'security' ); |
||
1858 | |||
1859 | $term = (string) wc_clean( stripslashes( $_GET['term'] ) ); |
||
1860 | $exclude = array(); |
||
1861 | |||
1862 | if ( empty( $term ) ) { |
||
1863 | die(); |
||
1864 | } |
||
1865 | |||
1866 | View Code Duplication | if ( ! empty( $_GET['exclude'] ) ) { |
|
1867 | $exclude = array_map( 'intval', explode( ',', $_GET['exclude'] ) ); |
||
1868 | } |
||
1869 | |||
1870 | $found_products = array(); |
||
1871 | |||
1872 | if ( $grouped_term = get_term_by( 'slug', 'grouped', 'product_type' ) ) { |
||
1873 | |||
1874 | $posts_in = array_unique( (array) get_objects_in_term( $grouped_term->term_id, 'product_type' ) ); |
||
1875 | |||
1876 | if ( sizeof( $posts_in ) > 0 ) { |
||
1877 | |||
1878 | $args = array( |
||
1879 | 'post_type' => 'product', |
||
1880 | 'post_status' => 'any', |
||
1881 | 'numberposts' => -1, |
||
1882 | 'orderby' => 'title', |
||
1883 | 'order' => 'asc', |
||
1884 | 'post_parent' => 0, |
||
1885 | 'suppress_filters' => 0, |
||
1886 | 'include' => $posts_in, |
||
1887 | 's' => $term, |
||
1888 | 'fields' => 'ids', |
||
1889 | 'exclude' => $exclude |
||
1890 | ); |
||
1891 | |||
1892 | $posts = get_posts( $args ); |
||
1893 | |||
1894 | if ( ! empty( $posts ) ) { |
||
1895 | foreach ( $posts as $post ) { |
||
1896 | $product = wc_get_product( $post ); |
||
1897 | |||
1898 | if ( ! current_user_can( 'read_product', $post ) ) { |
||
1899 | continue; |
||
1900 | } |
||
1901 | |||
1902 | $found_products[ $post ] = rawurldecode( $product->get_formatted_name() ); |
||
1903 | } |
||
1904 | } |
||
1905 | } |
||
1906 | } |
||
1907 | |||
1908 | $found_products = apply_filters( 'woocommerce_json_search_found_grouped_products', $found_products ); |
||
1909 | |||
1910 | wp_send_json( $found_products ); |
||
1911 | } |
||
1912 | |||
1913 | /** |
||
1914 | * Search for downloadable product variations and return json. |
||
1915 | * |
||
1916 | * @see WC_AJAX::json_search_products() |
||
1917 | */ |
||
1918 | public static function json_search_downloadable_products_and_variations() { |
||
1919 | ob_start(); |
||
1920 | |||
1921 | check_ajax_referer( 'search-products', 'security' ); |
||
1922 | |||
1923 | $term = (string) wc_clean( stripslashes( $_GET['term'] ) ); |
||
1924 | $exclude = array(); |
||
1925 | |||
1926 | View Code Duplication | if ( ! empty( $_GET['exclude'] ) ) { |
|
1927 | $exclude = array_map( 'intval', explode( ',', $_GET['exclude'] ) ); |
||
1928 | } |
||
1929 | |||
1930 | $args = array( |
||
1931 | 'post_type' => array( 'product', 'product_variation' ), |
||
1932 | 'posts_per_page' => -1, |
||
1933 | 'post_status' => 'publish', |
||
1934 | 'order' => 'ASC', |
||
1935 | 'orderby' => 'parent title', |
||
1936 | 'meta_query' => array( |
||
1937 | array( |
||
1938 | 'key' => '_downloadable', |
||
1939 | 'value' => 'yes' |
||
1940 | ) |
||
1941 | ), |
||
1942 | 's' => $term, |
||
1943 | 'exclude' => $exclude |
||
1944 | ); |
||
1945 | |||
1946 | $posts = get_posts( $args ); |
||
1947 | $found_products = array(); |
||
1948 | |||
1949 | if ( ! empty( $posts ) ) { |
||
1950 | foreach ( $posts as $post ) { |
||
1951 | $product = wc_get_product( $post->ID ); |
||
1952 | |||
1953 | if ( ! current_user_can( 'read_product', $post->ID ) ) { |
||
1954 | continue; |
||
1955 | } |
||
1956 | |||
1957 | $found_products[ $post->ID ] = $product->get_formatted_name(); |
||
1958 | } |
||
1959 | } |
||
1960 | |||
1961 | wp_send_json( $found_products ); |
||
1962 | } |
||
1963 | |||
1964 | /** |
||
1965 | * Search for customers and return json. |
||
1966 | */ |
||
1967 | public static function json_search_customers() { |
||
1968 | ob_start(); |
||
1969 | |||
1970 | check_ajax_referer( 'search-customers', 'security' ); |
||
1971 | |||
1972 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
1973 | die(-1); |
||
1974 | } |
||
1975 | |||
1976 | $term = wc_clean( stripslashes( $_GET['term'] ) ); |
||
1977 | $exclude = array(); |
||
1978 | |||
1979 | if ( empty( $term ) ) { |
||
1980 | die(); |
||
1981 | } |
||
1982 | |||
1983 | if ( ! empty( $_GET['exclude'] ) ) { |
||
1984 | $exclude = array_map( 'intval', explode( ',', $_GET['exclude'] ) ); |
||
1985 | } |
||
1986 | |||
1987 | $found_customers = array(); |
||
1988 | |||
1989 | add_action( 'pre_user_query', array( __CLASS__, 'json_search_customer_name' ) ); |
||
1990 | |||
1991 | $customers_query = new WP_User_Query( apply_filters( 'woocommerce_json_search_customers_query', array( |
||
1992 | 'fields' => 'all', |
||
1993 | 'orderby' => 'display_name', |
||
1994 | 'search' => '*' . $term . '*', |
||
1995 | 'search_columns' => array( 'ID', 'user_login', 'user_email', 'user_nicename' ) |
||
1996 | ) ) ); |
||
1997 | |||
1998 | remove_action( 'pre_user_query', array( __CLASS__, 'json_search_customer_name' ) ); |
||
1999 | |||
2000 | $customers = $customers_query->get_results(); |
||
2001 | |||
2002 | if ( ! empty( $customers ) ) { |
||
2003 | foreach ( $customers as $customer ) { |
||
2004 | if ( ! in_array( $customer->ID, $exclude ) ) { |
||
2005 | $found_customers[ $customer->ID ] = $customer->display_name . ' (#' . $customer->ID . ' – ' . sanitize_email( $customer->user_email ) . ')'; |
||
2006 | } |
||
2007 | } |
||
2008 | } |
||
2009 | |||
2010 | $found_customers = apply_filters( 'woocommerce_json_search_found_customers', $found_customers ); |
||
2011 | |||
2012 | wp_send_json( $found_customers ); |
||
2013 | } |
||
2014 | |||
2015 | /** |
||
2016 | * When searching using the WP_User_Query, search names (user meta) too. |
||
2017 | * @param object $query |
||
2018 | * @return object |
||
2019 | */ |
||
2020 | public static function json_search_customer_name( $query ) { |
||
2021 | global $wpdb; |
||
2022 | |||
2023 | $term = wc_clean( stripslashes( $_GET['term'] ) ); |
||
2024 | if ( method_exists( $wpdb, 'esc_like' ) ) { |
||
2025 | $term = $wpdb->esc_like( $term ); |
||
2026 | } else { |
||
2027 | $term = like_escape( $term ); |
||
2028 | } |
||
2029 | |||
2030 | $query->query_from .= " INNER JOIN {$wpdb->usermeta} AS user_name ON {$wpdb->users}.ID = user_name.user_id AND ( user_name.meta_key = 'first_name' OR user_name.meta_key = 'last_name' ) "; |
||
2031 | $query->query_where .= $wpdb->prepare( " OR user_name.meta_value LIKE %s ", '%' . $term . '%' ); |
||
2032 | } |
||
2033 | |||
2034 | /** |
||
2035 | * Ajax request handling for categories ordering. |
||
2036 | */ |
||
2037 | public static function term_ordering() { |
||
2038 | |||
2039 | // check permissions again and make sure we have what we need |
||
2040 | if ( ! current_user_can( 'edit_products' ) || empty( $_POST['id'] ) ) { |
||
2041 | die(-1); |
||
2042 | } |
||
2043 | |||
2044 | $id = (int) $_POST['id']; |
||
2045 | $next_id = isset( $_POST['nextid'] ) && (int) $_POST['nextid'] ? (int) $_POST['nextid'] : null; |
||
2046 | $taxonomy = isset( $_POST['thetaxonomy'] ) ? esc_attr( $_POST['thetaxonomy'] ) : null; |
||
2047 | $term = get_term_by( 'id', $id, $taxonomy ); |
||
2048 | |||
2049 | if ( ! $id || ! $term || ! $taxonomy ) { |
||
2050 | die(0); |
||
2051 | } |
||
2052 | |||
2053 | wc_reorder_terms( $term, $next_id, $taxonomy ); |
||
2054 | |||
2055 | $children = get_terms( $taxonomy, "child_of=$id&menu_order=ASC&hide_empty=0" ); |
||
2056 | |||
2057 | if ( $term && sizeof( $children ) ) { |
||
2058 | echo 'children'; |
||
2059 | die(); |
||
2060 | } |
||
2061 | } |
||
2062 | |||
2063 | /** |
||
2064 | * Ajax request handling for product ordering. |
||
2065 | * |
||
2066 | * Based on Simple Page Ordering by 10up (https://wordpress.org/extend/plugins/simple-page-ordering/). |
||
2067 | */ |
||
2068 | public static function product_ordering() { |
||
2069 | global $wpdb; |
||
2070 | |||
2071 | ob_start(); |
||
2072 | |||
2073 | // check permissions again and make sure we have what we need |
||
2074 | if ( ! current_user_can('edit_products') || empty( $_POST['id'] ) || ( ! isset( $_POST['previd'] ) && ! isset( $_POST['nextid'] ) ) ) { |
||
2075 | die(-1); |
||
2076 | } |
||
2077 | |||
2078 | // real post? |
||
2079 | if ( ! $post = get_post( $_POST['id'] ) ) { |
||
2080 | die(-1); |
||
2081 | } |
||
2082 | |||
2083 | $previd = isset( $_POST['previd'] ) ? $_POST['previd'] : false; |
||
2084 | $nextid = isset( $_POST['nextid'] ) ? $_POST['nextid'] : false; |
||
2085 | $new_pos = array(); // store new positions for ajax |
||
2086 | |||
2087 | $siblings = $wpdb->get_results( $wpdb->prepare( " |
||
2088 | SELECT ID, menu_order FROM {$wpdb->posts} AS posts |
||
2089 | WHERE posts.post_type = 'product' |
||
2090 | AND posts.post_status IN ( 'publish', 'pending', 'draft', 'future', 'private' ) |
||
2091 | AND posts.ID NOT IN (%d) |
||
2092 | ORDER BY posts.menu_order ASC, posts.ID DESC |
||
2093 | ", $post->ID ) ); |
||
2094 | |||
2095 | $menu_order = 0; |
||
2096 | |||
2097 | foreach ( $siblings as $sibling ) { |
||
2098 | |||
2099 | // if this is the post that comes after our repositioned post, set our repositioned post position and increment menu order |
||
2100 | View Code Duplication | if ( $nextid == $sibling->ID ) { |
|
2101 | $wpdb->update( |
||
2102 | $wpdb->posts, |
||
2103 | array( |
||
2104 | 'menu_order' => $menu_order |
||
2105 | ), |
||
2106 | array( 'ID' => $post->ID ), |
||
2107 | array( '%d' ), |
||
2108 | array( '%d' ) |
||
2109 | ); |
||
2110 | $new_pos[ $post->ID ] = $menu_order; |
||
2111 | $menu_order++; |
||
2112 | } |
||
2113 | |||
2114 | // if repositioned post has been set, and new items are already in the right order, we can stop |
||
2115 | if ( isset( $new_pos[ $post->ID ] ) && $sibling->menu_order >= $menu_order ) { |
||
2116 | break; |
||
2117 | } |
||
2118 | |||
2119 | // set the menu order of the current sibling and increment the menu order |
||
2120 | $wpdb->update( |
||
2121 | $wpdb->posts, |
||
2122 | array( |
||
2123 | 'menu_order' => $menu_order |
||
2124 | ), |
||
2125 | array( 'ID' => $sibling->ID ), |
||
2126 | array( '%d' ), |
||
2127 | array( '%d' ) |
||
2128 | ); |
||
2129 | $new_pos[ $sibling->ID ] = $menu_order; |
||
2130 | $menu_order++; |
||
2131 | |||
2132 | View Code Duplication | if ( ! $nextid && $previd == $sibling->ID ) { |
|
2133 | $wpdb->update( |
||
2134 | $wpdb->posts, |
||
2135 | array( |
||
2136 | 'menu_order' => $menu_order |
||
2137 | ), |
||
2138 | array( 'ID' => $post->ID ), |
||
2139 | array( '%d' ), |
||
2140 | array( '%d' ) |
||
2141 | ); |
||
2142 | $new_pos[$post->ID] = $menu_order; |
||
2143 | $menu_order++; |
||
2144 | } |
||
2145 | |||
2146 | } |
||
2147 | |||
2148 | do_action( 'woocommerce_after_product_ordering' ); |
||
2149 | |||
2150 | wp_send_json( $new_pos ); |
||
2151 | } |
||
2152 | |||
2153 | /** |
||
2154 | * Handle a refund via the edit order screen. |
||
2155 | */ |
||
2156 | public static function refund_line_items() { |
||
2157 | ob_start(); |
||
2158 | |||
2159 | check_ajax_referer( 'order-item', 'security' ); |
||
2160 | |||
2161 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
2162 | die(-1); |
||
2163 | } |
||
2164 | |||
2165 | $order_id = absint( $_POST['order_id'] ); |
||
2166 | $refund_amount = wc_format_decimal( sanitize_text_field( $_POST['refund_amount'] ), wc_get_price_decimals() ); |
||
2167 | $refund_reason = sanitize_text_field( $_POST['refund_reason'] ); |
||
2168 | $line_item_qtys = json_decode( sanitize_text_field( stripslashes( $_POST['line_item_qtys'] ) ), true ); |
||
2169 | $line_item_totals = json_decode( sanitize_text_field( stripslashes( $_POST['line_item_totals'] ) ), true ); |
||
2170 | $line_item_tax_totals = json_decode( sanitize_text_field( stripslashes( $_POST['line_item_tax_totals'] ) ), true ); |
||
2171 | $api_refund = $_POST['api_refund'] === 'true' ? true : false; |
||
2172 | $restock_refunded_items = $_POST['restock_refunded_items'] === 'true' ? true : false; |
||
2173 | $refund = false; |
||
2174 | $response_data = array(); |
||
2175 | |||
2176 | try { |
||
2177 | // Validate that the refund can occur |
||
2178 | $order = wc_get_order( $order_id ); |
||
2179 | $order_items = $order->get_items(); |
||
2180 | $max_refund = wc_format_decimal( $order->get_total() - $order->get_total_refunded(), wc_get_price_decimals() ); |
||
2181 | |||
2182 | if ( ! $refund_amount || $max_refund < $refund_amount || 0 > $refund_amount ) { |
||
2183 | throw new exception( __( 'Invalid refund amount', 'woocommerce' ) ); |
||
2184 | } |
||
2185 | |||
2186 | // Prepare line items which we are refunding |
||
2187 | $line_items = array(); |
||
2188 | $item_ids = array_unique( array_merge( array_keys( $line_item_qtys, $line_item_totals ) ) ); |
||
2189 | |||
2190 | foreach ( $item_ids as $item_id ) { |
||
2191 | $line_items[ $item_id ] = array( 'qty' => 0, 'refund_total' => 0, 'refund_tax' => array() ); |
||
2192 | } |
||
2193 | foreach ( $line_item_qtys as $item_id => $qty ) { |
||
2194 | $line_items[ $item_id ]['qty'] = max( $qty, 0 ); |
||
2195 | } |
||
2196 | foreach ( $line_item_totals as $item_id => $total ) { |
||
2197 | $line_items[ $item_id ]['refund_total'] = wc_format_decimal( $total ); |
||
2198 | } |
||
2199 | foreach ( $line_item_tax_totals as $item_id => $tax_totals ) { |
||
2200 | $line_items[ $item_id ]['refund_tax'] = array_map( 'wc_format_decimal', $tax_totals ); |
||
2201 | } |
||
2202 | |||
2203 | // Create the refund object |
||
2204 | $refund = wc_create_refund( array( |
||
2205 | 'amount' => $refund_amount, |
||
2206 | 'reason' => $refund_reason, |
||
2207 | 'order_id' => $order_id, |
||
2208 | 'line_items' => $line_items, |
||
2209 | ) ); |
||
2210 | |||
2211 | if ( is_wp_error( $refund ) ) { |
||
2212 | throw new Exception( $refund->get_error_message() ); |
||
2213 | } |
||
2214 | |||
2215 | // Refund via API |
||
2216 | if ( $api_refund ) { |
||
2217 | if ( WC()->payment_gateways() ) { |
||
2218 | $payment_gateways = WC()->payment_gateways->payment_gateways(); |
||
2219 | } |
||
2220 | if ( isset( $payment_gateways[ $order->payment_method ] ) && $payment_gateways[ $order->payment_method ]->supports( 'refunds' ) ) { |
||
2221 | $result = $payment_gateways[ $order->payment_method ]->process_refund( $order_id, $refund_amount, $refund_reason ); |
||
2222 | |||
2223 | do_action( 'woocommerce_refund_processed', $refund, $result ); |
||
2224 | |||
2225 | if ( is_wp_error( $result ) ) { |
||
2226 | throw new Exception( $result->get_error_message() ); |
||
2227 | } elseif ( ! $result ) { |
||
2228 | throw new Exception( __( 'Refund failed', 'woocommerce' ) ); |
||
2229 | } |
||
2230 | } |
||
2231 | } |
||
2232 | |||
2233 | // restock items |
||
2234 | foreach ( $line_item_qtys as $item_id => $qty ) { |
||
2235 | if ( $restock_refunded_items && $qty && isset( $order_items[ $item_id ] ) ) { |
||
2236 | $order_item = $order_items[ $item_id ]; |
||
2237 | $_product = $order->get_product_from_item( $order_item ); |
||
2238 | |||
2239 | if ( $_product && $_product->exists() && $_product->managing_stock() ) { |
||
2240 | $old_stock = wc_stock_amount( $_product->stock ); |
||
2241 | $new_quantity = $_product->increase_stock( $qty ); |
||
2242 | |||
2243 | $order->add_order_note( sprintf( __( 'Item #%s stock increased from %s to %s.', 'woocommerce' ), $order_item['product_id'], $old_stock, $new_quantity ) ); |
||
2244 | |||
2245 | do_action( 'woocommerce_restock_refunded_item', $_product->id, $old_stock, $new_quantity, $order ); |
||
2246 | } |
||
2247 | } |
||
2248 | } |
||
2249 | |||
2250 | // Trigger notifications and status changes |
||
2251 | if ( $order->get_remaining_refund_amount() > 0 || ( $order->has_free_item() && $order->get_remaining_refund_items() > 0 ) ) { |
||
2252 | /** |
||
2253 | * woocommerce_order_partially_refunded. |
||
2254 | * |
||
2255 | * @since 2.4.0 |
||
2256 | * Note: 3rd arg was added in err. Kept for bw compat. 2.4.3. |
||
2257 | */ |
||
2258 | do_action( 'woocommerce_order_partially_refunded', $order_id, $refund->id, $refund->id ); |
||
2259 | } else { |
||
2260 | do_action( 'woocommerce_order_fully_refunded', $order_id, $refund->id ); |
||
2261 | |||
2262 | $order->update_status( apply_filters( 'woocommerce_order_fully_refunded_status', 'refunded', $order_id, $refund->id ) ); |
||
2263 | $response_data['status'] = 'fully_refunded'; |
||
2264 | } |
||
2265 | |||
2266 | do_action( 'woocommerce_order_refunded', $order_id, $refund->id ); |
||
2267 | |||
2268 | // Clear transients |
||
2269 | wc_delete_shop_order_transients( $order_id ); |
||
2270 | wp_send_json_success( $response_data ); |
||
2271 | |||
2272 | } catch ( Exception $e ) { |
||
2273 | if ( $refund && is_a( $refund, 'WC_Order_Refund' ) ) { |
||
2274 | wp_delete_post( $refund->id, true ); |
||
2275 | } |
||
2276 | |||
2277 | wp_send_json_error( array( 'error' => $e->getMessage() ) ); |
||
2278 | } |
||
2279 | } |
||
2280 | |||
2281 | /** |
||
2282 | * Delete a refund. |
||
2283 | */ |
||
2284 | public static function delete_refund() { |
||
2285 | check_ajax_referer( 'order-item', 'security' ); |
||
2286 | |||
2287 | if ( ! current_user_can( 'edit_shop_orders' ) ) { |
||
2288 | die(-1); |
||
2289 | } |
||
2290 | |||
2291 | $refund_ids = array_map( 'absint', is_array( $_POST['refund_id'] ) ? $_POST['refund_id'] : array( $_POST['refund_id'] ) ); |
||
2292 | foreach ( $refund_ids as $refund_id ) { |
||
2293 | if ( $refund_id && 'shop_order_refund' === get_post_type( $refund_id ) ) { |
||
2294 | $order_id = wp_get_post_parent_id( $refund_id ); |
||
2295 | wc_delete_shop_order_transients( $order_id ); |
||
2296 | wp_delete_post( $refund_id ); |
||
2297 | do_action( 'woocommerce_refund_deleted', $refund_id, $order_id ); |
||
2298 | } |
||
2299 | } |
||
2300 | die(); |
||
2301 | } |
||
2302 | |||
2303 | /** |
||
2304 | * Triggered when clicking the rating footer. |
||
2305 | */ |
||
2306 | public static function rated() { |
||
2307 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
2308 | die(-1); |
||
2309 | } |
||
2310 | |||
2311 | update_option( 'woocommerce_admin_footer_text_rated', 1 ); |
||
2312 | die(); |
||
2313 | } |
||
2314 | |||
2315 | /** |
||
2316 | * Create/Update API key. |
||
2317 | */ |
||
2318 | public static function update_api_key() { |
||
2319 | ob_start(); |
||
2320 | |||
2321 | global $wpdb; |
||
2322 | |||
2323 | check_ajax_referer( 'update-api-key', 'security' ); |
||
2324 | |||
2325 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
2326 | die(-1); |
||
2327 | } |
||
2328 | |||
2329 | try { |
||
2330 | if ( empty( $_POST['description'] ) ) { |
||
2331 | throw new Exception( __( 'Description is missing.', 'woocommerce' ) ); |
||
2332 | } |
||
2333 | if ( empty( $_POST['user'] ) ) { |
||
2334 | throw new Exception( __( 'User is missing.', 'woocommerce' ) ); |
||
2335 | } |
||
2336 | if ( empty( $_POST['permissions'] ) ) { |
||
2337 | throw new Exception( __( 'Permissions is missing.', 'woocommerce' ) ); |
||
2338 | } |
||
2339 | |||
2340 | $key_id = absint( $_POST['key_id'] ); |
||
2341 | $description = sanitize_text_field( wp_unslash( $_POST['description'] ) ); |
||
2342 | $permissions = ( in_array( $_POST['permissions'], array( 'read', 'write', 'read_write' ) ) ) ? sanitize_text_field( $_POST['permissions'] ) : 'read'; |
||
2343 | $user_id = absint( $_POST['user'] ); |
||
2344 | |||
2345 | if ( 0 < $key_id ) { |
||
2346 | $data = array( |
||
2347 | 'user_id' => $user_id, |
||
2348 | 'description' => $description, |
||
2349 | 'permissions' => $permissions |
||
2350 | ); |
||
2351 | |||
2352 | $wpdb->update( |
||
2353 | $wpdb->prefix . 'woocommerce_api_keys', |
||
2354 | $data, |
||
2355 | array( 'key_id' => $key_id ), |
||
2356 | array( |
||
2357 | '%d', |
||
2358 | '%s', |
||
2359 | '%s' |
||
2360 | ), |
||
2361 | array( '%d' ) |
||
2362 | ); |
||
2363 | |||
2364 | $data['consumer_key'] = ''; |
||
2365 | $data['consumer_secret'] = ''; |
||
2366 | $data['message'] = __( 'API Key updated successfully.', 'woocommerce' ); |
||
2367 | } else { |
||
2368 | $consumer_key = 'ck_' . wc_rand_hash(); |
||
2369 | $consumer_secret = 'cs_' . wc_rand_hash(); |
||
2370 | |||
2371 | $data = array( |
||
2372 | 'user_id' => $user_id, |
||
2373 | 'description' => $description, |
||
2374 | 'permissions' => $permissions, |
||
2375 | 'consumer_key' => wc_api_hash( $consumer_key ), |
||
2376 | 'consumer_secret' => $consumer_secret, |
||
2377 | 'truncated_key' => substr( $consumer_key, -7 ) |
||
2378 | ); |
||
2379 | |||
2380 | $wpdb->insert( |
||
2381 | $wpdb->prefix . 'woocommerce_api_keys', |
||
2382 | $data, |
||
2383 | array( |
||
2384 | '%d', |
||
2385 | '%s', |
||
2386 | '%s', |
||
2387 | '%s', |
||
2388 | '%s', |
||
2389 | '%s' |
||
2390 | ) |
||
2391 | ); |
||
2392 | |||
2393 | $key_id = $wpdb->insert_id; |
||
2394 | $data['consumer_key'] = $consumer_key; |
||
2395 | $data['consumer_secret'] = $consumer_secret; |
||
2396 | $data['message'] = __( 'API Key generated successfully. Make sure to copy your new API keys now. You won\'t be able to see it again!', 'woocommerce' ); |
||
2397 | $data['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=api§ion=keys' ) ), 'revoke' ) ). '">' . __( 'Revoke Key', 'woocommerce' ) . '</a>'; |
||
2398 | } |
||
2399 | |||
2400 | wp_send_json_success( $data ); |
||
2401 | } catch ( Exception $e ) { |
||
2402 | wp_send_json_error( array( 'message' => $e->getMessage() ) ); |
||
2403 | } |
||
2404 | } |
||
2405 | |||
2406 | /** |
||
2407 | * Locate user via AJAX. |
||
2408 | */ |
||
2409 | public static function get_customer_location() { |
||
2410 | $location_hash = WC_Cache_Helper::geolocation_ajax_get_location_hash(); |
||
2411 | wp_send_json_success( array( 'hash' => $location_hash ) ); |
||
2412 | } |
||
2413 | |||
2414 | /** |
||
2415 | * Load variations via AJAX. |
||
2416 | */ |
||
2417 | public static function load_variations() { |
||
2418 | ob_start(); |
||
2419 | |||
2420 | check_ajax_referer( 'load-variations', 'security' ); |
||
2421 | |||
2422 | // Check permissions again and make sure we have what we need |
||
2423 | View Code Duplication | if ( ! current_user_can( 'edit_products' ) || empty( $_POST['product_id'] ) || empty( $_POST['attributes'] ) ) { |
|
2424 | die( -1 ); |
||
2425 | } |
||
2426 | |||
2427 | global $post; |
||
2428 | |||
2429 | $product_id = absint( $_POST['product_id'] ); |
||
2430 | $post = get_post( $product_id ); // Set $post global so its available like within the admin screens |
||
2431 | $per_page = ! empty( $_POST['per_page'] ) ? absint( $_POST['per_page'] ) : 10; |
||
2432 | $page = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1; |
||
2433 | |||
2434 | // Get attributes |
||
2435 | $attributes = array(); |
||
2436 | $posted_attributes = wp_unslash( $_POST['attributes'] ); |
||
2437 | |||
2438 | foreach ( $posted_attributes as $key => $value ) { |
||
2439 | $attributes[ $key ] = array_map( 'wc_clean', $value ); |
||
2440 | } |
||
2441 | |||
2442 | // Get tax classes |
||
2443 | $tax_classes = WC_Tax::get_tax_classes(); |
||
2444 | $tax_class_options = array(); |
||
2445 | $tax_class_options[''] = __( 'Standard', 'woocommerce' ); |
||
2446 | |||
2447 | View Code Duplication | if ( ! empty( $tax_classes ) ) { |
|
2448 | foreach ( $tax_classes as $class ) { |
||
2449 | $tax_class_options[ sanitize_title( $class ) ] = esc_attr( $class ); |
||
2450 | } |
||
2451 | } |
||
2452 | |||
2453 | // Set backorder options |
||
2454 | $backorder_options = array( |
||
2455 | 'no' => __( 'Do not allow', 'woocommerce' ), |
||
2456 | 'notify' => __( 'Allow, but notify customer', 'woocommerce' ), |
||
2457 | 'yes' => __( 'Allow', 'woocommerce' ) |
||
2458 | ); |
||
2459 | |||
2460 | // set stock status options |
||
2461 | $stock_status_options = array( |
||
2462 | 'instock' => __( 'In stock', 'woocommerce' ), |
||
2463 | 'outofstock' => __( 'Out of stock', 'woocommerce' ) |
||
2464 | ); |
||
2465 | |||
2466 | $parent_data = array( |
||
2467 | 'id' => $product_id, |
||
2468 | 'attributes' => $attributes, |
||
2469 | 'tax_class_options' => $tax_class_options, |
||
2470 | 'sku' => get_post_meta( $product_id, '_sku', true ), |
||
2471 | 'weight' => wc_format_localized_decimal( get_post_meta( $product_id, '_weight', true ) ), |
||
2472 | 'length' => wc_format_localized_decimal( get_post_meta( $product_id, '_length', true ) ), |
||
2473 | 'width' => wc_format_localized_decimal( get_post_meta( $product_id, '_width', true ) ), |
||
2474 | 'height' => wc_format_localized_decimal( get_post_meta( $product_id, '_height', true ) ), |
||
2475 | 'tax_class' => get_post_meta( $product_id, '_tax_class', true ), |
||
2476 | 'backorder_options' => $backorder_options, |
||
2477 | 'stock_status_options' => $stock_status_options |
||
2478 | ); |
||
2479 | |||
2480 | if ( ! $parent_data['weight'] ) { |
||
2481 | $parent_data['weight'] = wc_format_localized_decimal( 0 ); |
||
2482 | } |
||
2483 | |||
2484 | if ( ! $parent_data['length'] ) { |
||
2485 | $parent_data['length'] = wc_format_localized_decimal( 0 ); |
||
2486 | } |
||
2487 | |||
2488 | if ( ! $parent_data['width'] ) { |
||
2489 | $parent_data['width'] = wc_format_localized_decimal( 0 ); |
||
2490 | } |
||
2491 | |||
2492 | if ( ! $parent_data['height'] ) { |
||
2493 | $parent_data['height'] = wc_format_localized_decimal( 0 ); |
||
2494 | } |
||
2495 | |||
2496 | // Get variations |
||
2497 | $args = apply_filters( 'woocommerce_ajax_admin_get_variations_args', array( |
||
2498 | 'post_type' => 'product_variation', |
||
2499 | 'post_status' => array( 'private', 'publish' ), |
||
2500 | 'posts_per_page' => $per_page, |
||
2501 | 'paged' => $page, |
||
2502 | 'orderby' => array( 'menu_order' => 'ASC', 'ID' => 'DESC' ), |
||
2503 | 'post_parent' => $product_id |
||
2504 | ), $product_id ); |
||
2505 | |||
2506 | $variations = get_posts( $args ); |
||
2507 | $loop = 0; |
||
2508 | |||
2509 | if ( $variations ) { |
||
2510 | |||
2511 | foreach ( $variations as $variation ) { |
||
2512 | $variation_id = absint( $variation->ID ); |
||
2513 | $variation_meta = get_post_meta( $variation_id ); |
||
2514 | $variation_data = array(); |
||
2515 | $shipping_classes = get_the_terms( $variation_id, 'product_shipping_class' ); |
||
2516 | $variation_fields = array( |
||
2517 | '_sku' => '', |
||
2518 | '_stock' => '', |
||
2519 | '_regular_price' => '', |
||
2520 | '_sale_price' => '', |
||
2521 | '_weight' => '', |
||
2522 | '_length' => '', |
||
2523 | '_width' => '', |
||
2524 | '_height' => '', |
||
2525 | '_download_limit' => '', |
||
2526 | '_download_expiry' => '', |
||
2527 | '_downloadable_files' => '', |
||
2528 | '_downloadable' => '', |
||
2529 | '_virtual' => '', |
||
2530 | '_thumbnail_id' => '', |
||
2531 | '_sale_price_dates_from' => '', |
||
2532 | '_sale_price_dates_to' => '', |
||
2533 | '_manage_stock' => '', |
||
2534 | '_stock_status' => '', |
||
2535 | '_backorders' => null, |
||
2536 | '_tax_class' => null, |
||
2537 | '_variation_description' => '' |
||
2538 | ); |
||
2539 | |||
2540 | View Code Duplication | foreach ( $variation_fields as $field => $value ) { |
|
2541 | $variation_data[ $field ] = isset( $variation_meta[ $field ][0] ) ? maybe_unserialize( $variation_meta[ $field ][0] ) : $value; |
||
2542 | } |
||
2543 | |||
2544 | // Add the variation attributes |
||
2545 | $variation_data = array_merge( $variation_data, wc_get_product_variation_attributes( $variation_id ) ); |
||
2546 | |||
2547 | // Formatting |
||
2548 | $variation_data['_regular_price'] = wc_format_localized_price( $variation_data['_regular_price'] ); |
||
2549 | $variation_data['_sale_price'] = wc_format_localized_price( $variation_data['_sale_price'] ); |
||
2550 | $variation_data['_weight'] = wc_format_localized_decimal( $variation_data['_weight'] ); |
||
2551 | $variation_data['_length'] = wc_format_localized_decimal( $variation_data['_length'] ); |
||
2552 | $variation_data['_width'] = wc_format_localized_decimal( $variation_data['_width'] ); |
||
2553 | $variation_data['_height'] = wc_format_localized_decimal( $variation_data['_height'] ); |
||
2554 | $variation_data['_thumbnail_id'] = absint( $variation_data['_thumbnail_id'] ); |
||
2555 | $variation_data['image'] = $variation_data['_thumbnail_id'] ? wp_get_attachment_thumb_url( $variation_data['_thumbnail_id'] ) : ''; |
||
2556 | $variation_data['shipping_class'] = $shipping_classes && ! is_wp_error( $shipping_classes ) ? current( $shipping_classes )->term_id : ''; |
||
2557 | $variation_data['menu_order'] = $variation->menu_order; |
||
2558 | $variation_data['_stock'] = '' === $variation_data['_stock'] ? '' : wc_stock_amount( $variation_data['_stock'] ); |
||
2559 | |||
2560 | include( 'admin/meta-boxes/views/html-variation-admin.php' ); |
||
2561 | |||
2562 | $loop++; |
||
2563 | } |
||
2564 | } |
||
2565 | |||
2566 | die(); |
||
2567 | } |
||
2568 | |||
2569 | /** |
||
2570 | * Save variations via AJAX. |
||
2571 | */ |
||
2572 | public static function save_variations() { |
||
2573 | ob_start(); |
||
2574 | |||
2575 | check_ajax_referer( 'save-variations', 'security' ); |
||
2576 | |||
2577 | // Check permissions again and make sure we have what we need |
||
2578 | View Code Duplication | if ( ! current_user_can( 'edit_products' ) || empty( $_POST ) || empty( $_POST['product_id'] ) ) { |
|
2579 | die( -1 ); |
||
2580 | } |
||
2581 | |||
2582 | // Remove previous meta box errors |
||
2583 | WC_Admin_Meta_Boxes::$meta_box_errors = array(); |
||
2584 | |||
2585 | $product_id = absint( $_POST['product_id'] ); |
||
2586 | $product_type = empty( $_POST['product-type'] ) ? 'simple' : sanitize_title( stripslashes( $_POST['product-type'] ) ); |
||
2587 | |||
2588 | $product_type_terms = wp_get_object_terms( $product_id, 'product_type' ); |
||
2589 | |||
2590 | // If the product type hasn't been set or it has changed, update it before saving variations |
||
2591 | if ( empty( $product_type_terms ) || $product_type !== sanitize_title( current( $product_type_terms )->name ) ) { |
||
2592 | wp_set_object_terms( $product_id, $product_type, 'product_type' ); |
||
2593 | } |
||
2594 | |||
2595 | WC_Meta_Box_Product_Data::save_variations( $product_id, get_post( $product_id ) ); |
||
2596 | |||
2597 | do_action( 'woocommerce_ajax_save_product_variations', $product_id ); |
||
2598 | |||
2599 | // Clear cache/transients |
||
2600 | wc_delete_product_transients( $product_id ); |
||
2601 | |||
2602 | if ( $errors = WC_Admin_Meta_Boxes::$meta_box_errors ) { |
||
2603 | echo '<div class="error notice is-dismissible">'; |
||
2604 | |||
2605 | foreach ( $errors as $error ) { |
||
2606 | echo '<p>' . wp_kses_post( $error ) . '</p>'; |
||
2607 | } |
||
2608 | |||
2609 | echo '<button type="button" class="notice-dismiss"><span class="screen-reader-text">' . __( 'Dismiss this notice.', 'woocommerce' ) . '</span></button>'; |
||
2610 | echo '</div>'; |
||
2611 | |||
2612 | delete_option( 'woocommerce_meta_box_errors' ); |
||
2613 | } |
||
2614 | |||
2615 | die(); |
||
2616 | } |
||
2617 | |||
2618 | /** |
||
2619 | * Bulk action - Toggle Enabled. |
||
2620 | * @access private |
||
2621 | * @param array $variations |
||
2622 | * @param array $data |
||
2623 | */ |
||
2624 | private static function variation_bulk_action_toggle_enabled( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2625 | global $wpdb; |
||
2626 | |||
2627 | foreach ( $variations as $variation_id ) { |
||
2628 | $post_status = get_post_status( $variation_id ); |
||
2629 | $new_status = 'private' === $post_status ? 'publish' : 'private'; |
||
2630 | $wpdb->update( $wpdb->posts, array( 'post_status' => $new_status ), array( 'ID' => $variation_id ) ); |
||
2631 | } |
||
2632 | } |
||
2633 | |||
2634 | /** |
||
2635 | * Bulk action - Toggle Downloadable Checkbox. |
||
2636 | * @access private |
||
2637 | * @param array $variations |
||
2638 | * @param array $data |
||
2639 | */ |
||
2640 | View Code Duplication | private static function variation_bulk_action_toggle_downloadable( $variations, $data ) { |
|
0 ignored issues
–
show
|
|||
2641 | foreach ( $variations as $variation_id ) { |
||
2642 | $_downloadable = get_post_meta( $variation_id, '_downloadable', true ); |
||
2643 | $is_downloadable = 'no' === $_downloadable ? 'yes' : 'no'; |
||
2644 | update_post_meta( $variation_id, '_downloadable', wc_clean( $is_downloadable ) ); |
||
2645 | } |
||
2646 | } |
||
2647 | |||
2648 | /** |
||
2649 | * Bulk action - Toggle Virtual Checkbox. |
||
2650 | * @access private |
||
2651 | * @param array $variations |
||
2652 | * @param array $data |
||
2653 | */ |
||
2654 | View Code Duplication | private static function variation_bulk_action_toggle_virtual( $variations, $data ) { |
|
0 ignored issues
–
show
|
|||
2655 | foreach ( $variations as $variation_id ) { |
||
2656 | $_virtual = get_post_meta( $variation_id, '_virtual', true ); |
||
2657 | $is_virtual = 'no' === $_virtual ? 'yes' : 'no'; |
||
2658 | update_post_meta( $variation_id, '_virtual', wc_clean( $is_virtual ) ); |
||
2659 | } |
||
2660 | } |
||
2661 | |||
2662 | /** |
||
2663 | * Bulk action - Toggle Manage Stock Checkbox. |
||
2664 | * @access private |
||
2665 | * @param array $variations |
||
2666 | * @param array $data |
||
2667 | */ |
||
2668 | private static function variation_bulk_action_toggle_manage_stock( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2669 | foreach ( $variations as $variation_id ) { |
||
2670 | $_manage_stock = get_post_meta( $variation_id, '_manage_stock', true ); |
||
2671 | $is_manage_stock = 'no' === $_manage_stock || '' === $_manage_stock ? 'yes' : 'no'; |
||
2672 | update_post_meta( $variation_id, '_manage_stock', $is_manage_stock ); |
||
2673 | } |
||
2674 | } |
||
2675 | |||
2676 | /** |
||
2677 | * Bulk action - Set Regular Prices. |
||
2678 | * @access private |
||
2679 | * @param array $variations |
||
2680 | * @param array $data |
||
2681 | */ |
||
2682 | View Code Duplication | private static function variation_bulk_action_variable_regular_price( $variations, $data ) { |
|
0 ignored issues
–
show
|
|||
2683 | if ( ! isset( $data['value'] ) ) { |
||
2684 | return; |
||
2685 | } |
||
2686 | |||
2687 | foreach ( $variations as $variation_id ) { |
||
2688 | // Price fields |
||
2689 | $regular_price = wc_clean( $data['value'] ); |
||
2690 | $sale_price = get_post_meta( $variation_id, '_sale_price', true ); |
||
2691 | |||
2692 | // Date fields |
||
2693 | $date_from = get_post_meta( $variation_id, '_sale_price_dates_from', true ); |
||
2694 | $date_to = get_post_meta( $variation_id, '_sale_price_dates_to', true ); |
||
2695 | $date_from = ! empty( $date_from ) ? date( 'Y-m-d', $date_from ) : ''; |
||
2696 | $date_to = ! empty( $date_to ) ? date( 'Y-m-d', $date_to ) : ''; |
||
2697 | |||
2698 | _wc_save_product_price( $variation_id, $regular_price, $sale_price, $date_from, $date_to ); |
||
2699 | } |
||
2700 | } |
||
2701 | |||
2702 | /** |
||
2703 | * Bulk action - Set Sale Prices. |
||
2704 | * @access private |
||
2705 | * @param array $variations |
||
2706 | * @param array $data |
||
2707 | */ |
||
2708 | View Code Duplication | private static function variation_bulk_action_variable_sale_price( $variations, $data ) { |
|
0 ignored issues
–
show
|
|||
2709 | if ( ! isset( $data['value'] ) ) { |
||
2710 | return; |
||
2711 | } |
||
2712 | |||
2713 | foreach ( $variations as $variation_id ) { |
||
2714 | // Price fields |
||
2715 | $regular_price = get_post_meta( $variation_id, '_regular_price', true ); |
||
2716 | $sale_price = wc_clean( $data['value'] ); |
||
2717 | |||
2718 | // Date fields |
||
2719 | $date_from = get_post_meta( $variation_id, '_sale_price_dates_from', true ); |
||
2720 | $date_to = get_post_meta( $variation_id, '_sale_price_dates_to', true ); |
||
2721 | $date_from = ! empty( $date_from ) ? date( 'Y-m-d', $date_from ) : ''; |
||
2722 | $date_to = ! empty( $date_to ) ? date( 'Y-m-d', $date_to ) : ''; |
||
2723 | |||
2724 | _wc_save_product_price( $variation_id, $regular_price, $sale_price, $date_from, $date_to ); |
||
2725 | } |
||
2726 | } |
||
2727 | |||
2728 | /** |
||
2729 | * Bulk action - Set Stock. |
||
2730 | * @access private |
||
2731 | * @param array $variations |
||
2732 | * @param array $data |
||
2733 | */ |
||
2734 | private static function variation_bulk_action_variable_stock( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2735 | if ( ! isset( $data['value'] ) ) { |
||
2736 | return; |
||
2737 | } |
||
2738 | |||
2739 | $value = wc_clean( $data['value'] ); |
||
2740 | |||
2741 | foreach ( $variations as $variation_id ) { |
||
2742 | if ( 'yes' === get_post_meta( $variation_id, '_manage_stock', true ) ) { |
||
2743 | wc_update_product_stock( $variation_id, wc_stock_amount( $value ) ); |
||
2744 | } else { |
||
2745 | delete_post_meta( $variation_id, '_stock' ); |
||
2746 | } |
||
2747 | } |
||
2748 | } |
||
2749 | |||
2750 | /** |
||
2751 | * Bulk action - Set Weight. |
||
2752 | * @access private |
||
2753 | * @param array $variations |
||
2754 | * @param array $data |
||
2755 | */ |
||
2756 | private static function variation_bulk_action_variable_weight( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2757 | self::variation_bulk_set_meta( $variations, '_weight', wc_clean( $data['value'] ) ); |
||
2758 | } |
||
2759 | |||
2760 | /** |
||
2761 | * Bulk action - Set Length. |
||
2762 | * @access private |
||
2763 | * @param array $variations |
||
2764 | * @param array $data |
||
2765 | */ |
||
2766 | private static function variation_bulk_action_variable_length( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2767 | self::variation_bulk_set_meta( $variations, '_length', wc_clean( $data['value'] ) ); |
||
2768 | } |
||
2769 | |||
2770 | /** |
||
2771 | * Bulk action - Set Width. |
||
2772 | * @access private |
||
2773 | * @param array $variations |
||
2774 | * @param array $data |
||
2775 | */ |
||
2776 | private static function variation_bulk_action_variable_width( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2777 | self::variation_bulk_set_meta( $variations, '_width', wc_clean( $data['value'] ) ); |
||
2778 | } |
||
2779 | |||
2780 | /** |
||
2781 | * Bulk action - Set Height. |
||
2782 | * @access private |
||
2783 | * @param array $variations |
||
2784 | * @param array $data |
||
2785 | */ |
||
2786 | private static function variation_bulk_action_variable_height( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2787 | self::variation_bulk_set_meta( $variations, '_height', wc_clean( $data['value'] ) ); |
||
2788 | } |
||
2789 | |||
2790 | /** |
||
2791 | * Bulk action - Set Download Limit. |
||
2792 | * @access private |
||
2793 | * @param array $variations |
||
2794 | * @param array $data |
||
2795 | */ |
||
2796 | private static function variation_bulk_action_variable_download_limit( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2797 | self::variation_bulk_set_meta( $variations, '_download_limit', wc_clean( $data['value'] ) ); |
||
2798 | } |
||
2799 | |||
2800 | /** |
||
2801 | * Bulk action - Set Download Expiry. |
||
2802 | * @access private |
||
2803 | * @param array $variations |
||
2804 | * @param array $data |
||
2805 | */ |
||
2806 | private static function variation_bulk_action_variable_download_expiry( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2807 | self::variation_bulk_set_meta( $variations, '_download_expiry', wc_clean( $data['value'] ) ); |
||
2808 | } |
||
2809 | |||
2810 | /** |
||
2811 | * Bulk action - Delete all. |
||
2812 | * @access private |
||
2813 | * @param array $variations |
||
2814 | * @param array $data |
||
2815 | */ |
||
2816 | private static function variation_bulk_action_delete_all( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2817 | if ( isset( $data['allowed'] ) && 'true' === $data['allowed'] ) { |
||
2818 | foreach ( $variations as $variation_id ) { |
||
2819 | wp_delete_post( $variation_id ); |
||
2820 | } |
||
2821 | } |
||
2822 | } |
||
2823 | |||
2824 | /** |
||
2825 | * Bulk action - Sale Schedule. |
||
2826 | * @access private |
||
2827 | * @param array $variations |
||
2828 | * @param array $data |
||
2829 | */ |
||
2830 | private static function variation_bulk_action_variable_sale_schedule( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2831 | if ( ! isset( $data['date_from'] ) && ! isset( $data['date_to'] ) ) { |
||
2832 | return; |
||
2833 | } |
||
2834 | |||
2835 | foreach ( $variations as $variation_id ) { |
||
2836 | // Price fields |
||
2837 | $regular_price = get_post_meta( $variation_id, '_regular_price', true ); |
||
2838 | $sale_price = get_post_meta( $variation_id, '_sale_price', true ); |
||
2839 | |||
2840 | // Date fields |
||
2841 | $date_from = get_post_meta( $variation_id, '_sale_price_dates_from', true ); |
||
2842 | $date_to = get_post_meta( $variation_id, '_sale_price_dates_to', true ); |
||
2843 | |||
2844 | View Code Duplication | if ( 'false' === $data['date_from'] ) { |
|
2845 | $date_from = ! empty( $date_from ) ? date( 'Y-m-d', $date_from ) : ''; |
||
2846 | } else { |
||
2847 | $date_from = $data['date_from']; |
||
2848 | } |
||
2849 | |||
2850 | View Code Duplication | if ( 'false' === $data['date_to'] ) { |
|
2851 | $date_to = ! empty( $date_to ) ? date( 'Y-m-d', $date_to ) : ''; |
||
2852 | } else { |
||
2853 | $date_to = $data['date_to']; |
||
2854 | } |
||
2855 | |||
2856 | _wc_save_product_price( $variation_id, $regular_price, $sale_price, $date_from, $date_to ); |
||
2857 | } |
||
2858 | } |
||
2859 | |||
2860 | /** |
||
2861 | * Bulk action - Increase Regular Prices. |
||
2862 | * @access private |
||
2863 | * @param array $variations |
||
2864 | * @param array $data |
||
2865 | */ |
||
2866 | private static function variation_bulk_action_variable_regular_price_increase( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2867 | self::variation_bulk_adjust_price( $variations, '_regular_price', '+', wc_clean( $data['value'] ) ); |
||
2868 | } |
||
2869 | |||
2870 | /** |
||
2871 | * Bulk action - Decrease Regular Prices. |
||
2872 | * @access private |
||
2873 | * @param array $variations |
||
2874 | * @param array $data |
||
2875 | */ |
||
2876 | private static function variation_bulk_action_variable_regular_price_decrease( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2877 | self::variation_bulk_adjust_price( $variations, '_regular_price', '-', wc_clean( $data['value'] ) ); |
||
2878 | } |
||
2879 | |||
2880 | /** |
||
2881 | * Bulk action - Increase Sale Prices. |
||
2882 | * @access private |
||
2883 | * @param array $variations |
||
2884 | * @param array $data |
||
2885 | */ |
||
2886 | private static function variation_bulk_action_variable_sale_price_increase( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2887 | self::variation_bulk_adjust_price( $variations, '_sale_price', '+', wc_clean( $data['value'] ) ); |
||
2888 | } |
||
2889 | |||
2890 | /** |
||
2891 | * Bulk action - Decrease Sale Prices. |
||
2892 | * @access private |
||
2893 | * @param array $variations |
||
2894 | * @param array $data |
||
2895 | */ |
||
2896 | private static function variation_bulk_action_variable_sale_price_decrease( $variations, $data ) { |
||
0 ignored issues
–
show
|
|||
2897 | self::variation_bulk_adjust_price( $variations, '_sale_price', '-', wc_clean( $data['value'] ) ); |
||
2898 | } |
||
2899 | |||
2900 | /** |
||
2901 | * Bulk action - Set Price. |
||
2902 | * @access private |
||
2903 | * @param array $variations |
||
2904 | * @param string $operator + or - |
||
2905 | * @param string $field price being adjusted |
||
2906 | * @param string $value Price or Percent |
||
2907 | */ |
||
2908 | private static function variation_bulk_adjust_price( $variations, $field, $operator, $value ) { |
||
2909 | foreach ( $variations as $variation_id ) { |
||
2910 | // Get existing data |
||
2911 | $_regular_price = get_post_meta( $variation_id, '_regular_price', true ); |
||
2912 | $_sale_price = get_post_meta( $variation_id, '_sale_price', true ); |
||
2913 | $date_from = get_post_meta( $variation_id, '_sale_price_dates_from', true ); |
||
2914 | $date_to = get_post_meta( $variation_id, '_sale_price_dates_to', true ); |
||
2915 | $date_from = ! empty( $date_from ) ? date( 'Y-m-d', $date_from ) : ''; |
||
2916 | $date_to = ! empty( $date_to ) ? date( 'Y-m-d', $date_to ) : ''; |
||
2917 | |||
2918 | if ( '%' === substr( $value, -1 ) ) { |
||
2919 | $percent = wc_format_decimal( substr( $value, 0, -1 ) ); |
||
2920 | $$field += ( ( $$field / 100 ) * $percent ) * "{$operator}1"; |
||
2921 | } else { |
||
2922 | $$field += $value * "{$operator}1"; |
||
2923 | } |
||
2924 | _wc_save_product_price( $variation_id, $_regular_price, $_sale_price, $date_from, $date_to ); |
||
2925 | } |
||
2926 | } |
||
2927 | |||
2928 | /** |
||
2929 | * Bulk action - Set Meta. |
||
2930 | * @access private |
||
2931 | * @param array $variations |
||
2932 | * @param string $field |
||
2933 | * @param string $value |
||
2934 | */ |
||
2935 | private static function variation_bulk_set_meta( $variations, $field, $value ) { |
||
2936 | foreach ( $variations as $variation_id ) { |
||
2937 | update_post_meta( $variation_id, $field, $value ); |
||
2938 | } |
||
2939 | } |
||
2940 | |||
2941 | |||
2942 | /** |
||
2943 | * Bulk edit variations via AJAX. |
||
2944 | */ |
||
2945 | public static function bulk_edit_variations() { |
||
2946 | ob_start(); |
||
2947 | |||
2948 | check_ajax_referer( 'bulk-edit-variations', 'security' ); |
||
2949 | |||
2950 | // Check permissions again and make sure we have what we need |
||
2951 | View Code Duplication | if ( ! current_user_can( 'edit_products' ) || empty( $_POST['product_id'] ) || empty( $_POST['bulk_action'] ) ) { |
|
2952 | die( -1 ); |
||
2953 | } |
||
2954 | |||
2955 | $product_id = absint( $_POST['product_id'] ); |
||
2956 | $bulk_action = wc_clean( $_POST['bulk_action'] ); |
||
2957 | $data = ! empty( $_POST['data'] ) ? array_map( 'wc_clean', $_POST['data'] ) : array(); |
||
2958 | $variations = array(); |
||
2959 | |||
2960 | if ( apply_filters( 'woocommerce_bulk_edit_variations_need_children', true ) ) { |
||
2961 | $variations = get_posts( array( |
||
2962 | 'post_parent' => $product_id, |
||
2963 | 'posts_per_page' => -1, |
||
2964 | 'post_type' => 'product_variation', |
||
2965 | 'fields' => 'ids', |
||
2966 | 'post_status' => array( 'publish', 'private' ) |
||
2967 | ) ); |
||
2968 | } |
||
2969 | |||
2970 | if ( method_exists( __CLASS__, "variation_bulk_action_$bulk_action" ) ) { |
||
2971 | call_user_func( array( __CLASS__, "variation_bulk_action_$bulk_action" ), $variations, $data ); |
||
2972 | } else { |
||
2973 | do_action( 'woocommerce_bulk_edit_variations_default', $bulk_action, $data, $product_id, $variations ); |
||
2974 | } |
||
2975 | |||
2976 | do_action( 'woocommerce_bulk_edit_variations', $bulk_action, $data, $product_id, $variations ); |
||
2977 | |||
2978 | // Sync and update transients |
||
2979 | WC_Product_Variable::sync( $product_id ); |
||
2980 | wc_delete_product_transients( $product_id ); |
||
2981 | die(); |
||
2982 | } |
||
2983 | |||
2984 | /** |
||
2985 | * Handle submissions from assets/js/settings-views-html-settings-tax.js Backbone model. |
||
2986 | */ |
||
2987 | public static function tax_rates_save_changes() { |
||
2988 | if ( ! isset( $_POST['wc_tax_nonce'], $_POST['changes'] ) ) { |
||
2989 | wp_send_json_error( 'missing_fields' ); |
||
2990 | exit; |
||
2991 | } |
||
2992 | |||
2993 | $current_class = ! empty( $_POST['current_class'] ) ? $_POST['current_class'] : ''; // This is sanitized seven lines later. |
||
2994 | |||
2995 | if ( ! wp_verify_nonce( $_POST['wc_tax_nonce'], 'wc_tax_nonce-class:' . $current_class ) ) { |
||
2996 | wp_send_json_error( 'bad_nonce' ); |
||
2997 | exit; |
||
2998 | } |
||
2999 | |||
3000 | $current_class = WC_Tax::format_tax_rate_class( $current_class ); |
||
3001 | |||
3002 | // Check User Caps |
||
3003 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
3004 | wp_send_json_error( 'missing_capabilities' ); |
||
3005 | exit; |
||
3006 | } |
||
3007 | |||
3008 | $changes = $_POST['changes']; |
||
3009 | foreach ( $changes as $tax_rate_id => $data ) { |
||
3010 | if ( isset( $data['deleted'] ) ) { |
||
3011 | if ( isset( $data['newRow'] ) ) { |
||
3012 | // So the user added and deleted a new row. |
||
3013 | // That's fine, it's not in the database anyways. NEXT! |
||
3014 | continue; |
||
3015 | } |
||
3016 | WC_Tax::_delete_tax_rate( $tax_rate_id ); |
||
3017 | } |
||
3018 | |||
3019 | $tax_rate = array_intersect_key( $data, array( |
||
3020 | 'tax_rate_country' => 1, |
||
3021 | 'tax_rate_state' => 1, |
||
3022 | 'tax_rate' => 1, |
||
3023 | 'tax_rate_name' => 1, |
||
3024 | 'tax_rate_priority' => 1, |
||
3025 | 'tax_rate_compound' => 1, |
||
3026 | 'tax_rate_shipping' => 1, |
||
3027 | 'tax_rate_order' => 1, |
||
3028 | ) ); |
||
3029 | |||
3030 | if ( isset( $data['newRow'] ) ) { |
||
3031 | // Hurrah, shiny and new! |
||
3032 | $tax_rate['tax_rate_class'] = $current_class; |
||
3033 | $tax_rate_id = WC_Tax::_insert_tax_rate( $tax_rate ); |
||
3034 | } else { |
||
3035 | // Updating an existing rate ... |
||
3036 | if ( ! empty( $tax_rate ) ) { |
||
3037 | WC_Tax::_update_tax_rate( $tax_rate_id, $tax_rate ); |
||
3038 | } |
||
3039 | } |
||
3040 | |||
3041 | if ( isset( $data['postcode'] ) ) { |
||
3042 | WC_Tax::_update_tax_rate_postcodes( $tax_rate_id, array_map( 'wc_clean', $data['postcode'] ) ); |
||
3043 | } |
||
3044 | if ( isset( $data['city'] ) ) { |
||
3045 | WC_Tax::_update_tax_rate_cities( $tax_rate_id, array_map( 'wc_clean', $data['city'] ) ); |
||
3046 | } |
||
3047 | } |
||
3048 | |||
3049 | wp_send_json_success( array( |
||
3050 | 'rates' => WC_Tax::get_rates_for_tax_class( $current_class ), |
||
3051 | ) ); |
||
3052 | } |
||
3053 | |||
3054 | /** |
||
3055 | * Handle submissions from assets/js/wc-shipping-zones.js Backbone model. |
||
3056 | */ |
||
3057 | public static function shipping_zones_save_changes() { |
||
3058 | if ( ! isset( $_POST['wc_shipping_zones_nonce'], $_POST['changes'] ) ) { |
||
3059 | wp_send_json_error( 'missing_fields' ); |
||
3060 | exit; |
||
3061 | } |
||
3062 | |||
3063 | if ( ! wp_verify_nonce( $_POST['wc_shipping_zones_nonce'], 'wc_shipping_zones_nonce' ) ) { |
||
3064 | wp_send_json_error( 'bad_nonce' ); |
||
3065 | exit; |
||
3066 | } |
||
3067 | |||
3068 | // Check User Caps |
||
3069 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
3070 | wp_send_json_error( 'missing_capabilities' ); |
||
3071 | exit; |
||
3072 | } |
||
3073 | |||
3074 | $changes = $_POST['changes']; |
||
3075 | foreach ( $changes as $zone_id => $data ) { |
||
3076 | if ( isset( $data['deleted'] ) ) { |
||
3077 | if ( isset( $data['newRow'] ) ) { |
||
3078 | // So the user added and deleted a new row. |
||
3079 | // That's fine, it's not in the database anyways. NEXT! |
||
3080 | continue; |
||
3081 | } |
||
3082 | WC_Shipping_Zones::delete_zone( $zone_id ); |
||
3083 | continue; |
||
3084 | } |
||
3085 | |||
3086 | $zone_data = array_intersect_key( $data, array( |
||
3087 | 'zone_id' => 1, |
||
3088 | 'zone_name' => 1, |
||
3089 | 'zone_order' => 1, |
||
3090 | 'zone_locations' => 1, |
||
3091 | 'zone_postcodes' => 1 |
||
3092 | ) ); |
||
3093 | |||
3094 | if ( isset( $zone_data['zone_id'] ) ) { |
||
3095 | $zone = new WC_Shipping_Zone( $zone_data['zone_id'] ); |
||
3096 | |||
3097 | if ( isset( $zone_data['zone_name'] ) ) { |
||
3098 | $zone->set_zone_name( $zone_data['zone_name'] ); |
||
3099 | } |
||
3100 | |||
3101 | if ( isset( $zone_data['zone_order'] ) ) { |
||
3102 | $zone->set_zone_order( $zone_data['zone_order'] ); |
||
3103 | } |
||
3104 | |||
3105 | if ( isset( $zone_data['zone_locations'] ) ) { |
||
3106 | $zone->clear_locations( array( 'state', 'country', 'continent' ) ); |
||
3107 | $locations = array_filter( array_map( 'wc_clean', (array) $zone_data['zone_locations'] ) ); |
||
3108 | foreach ( $locations as $location ) { |
||
3109 | // Each posted location will be in the format type:code |
||
3110 | $location_parts = explode( ':', $location ); |
||
3111 | switch ( $location_parts[0] ) { |
||
3112 | case 'state' : |
||
3113 | $zone->add_location( $location_parts[1] . ':' . $location_parts[2], 'state' ); |
||
3114 | break; |
||
3115 | case 'country' : |
||
3116 | $zone->add_location( $location_parts[1], 'country' ); |
||
3117 | break; |
||
3118 | case 'continent' : |
||
3119 | $zone->add_location( $location_parts[1], 'continent' ); |
||
3120 | break; |
||
3121 | } |
||
3122 | } |
||
3123 | } |
||
3124 | |||
3125 | if ( isset( $zone_data['zone_postcodes'] ) ) { |
||
3126 | $zone->clear_locations( 'postcode' ); |
||
3127 | $postcodes = array_filter( array_map( 'strtoupper', array_map( 'wc_clean', explode( "\n", $zone_data['zone_postcodes'] ) ) ) ); |
||
3128 | foreach ( $postcodes as $postcode ) { |
||
3129 | $zone->add_location( $postcode, 'postcode' ); |
||
3130 | } |
||
3131 | } |
||
3132 | |||
3133 | $zone->save(); |
||
3134 | } |
||
3135 | } |
||
3136 | |||
3137 | wp_send_json_success( array( |
||
3138 | 'zones' => WC_Shipping_Zones::get_zones() |
||
3139 | ) ); |
||
3140 | } |
||
3141 | |||
3142 | /** |
||
3143 | * Handle submissions from assets/js/wc-shipping-zone-methods.js Backbone model. |
||
3144 | */ |
||
3145 | View Code Duplication | public static function shipping_zone_add_method() { |
|
3146 | if ( ! isset( $_POST['wc_shipping_zones_nonce'], $_POST['zone_id'], $_POST['method_id'] ) ) { |
||
3147 | wp_send_json_error( 'missing_fields' ); |
||
3148 | exit; |
||
3149 | } |
||
3150 | |||
3151 | if ( ! wp_verify_nonce( $_POST['wc_shipping_zones_nonce'], 'wc_shipping_zones_nonce' ) ) { |
||
3152 | wp_send_json_error( 'bad_nonce' ); |
||
3153 | exit; |
||
3154 | } |
||
3155 | |||
3156 | // Check User Caps |
||
3157 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
3158 | wp_send_json_error( 'missing_capabilities' ); |
||
3159 | exit; |
||
3160 | } |
||
3161 | |||
3162 | $zone_id = absint( $_POST['zone_id'] ); |
||
3163 | $zone = WC_Shipping_Zones::get_zone( $zone_id ); |
||
3164 | $instance_id = $zone->add_shipping_method( wc_clean( $_POST['method_id'] ) ); |
||
3165 | |||
3166 | wp_send_json_success( array( |
||
3167 | 'instance_id' => $instance_id, |
||
3168 | 'zone_id' => $zone_id, |
||
3169 | 'methods' => $zone->get_shipping_methods() |
||
3170 | ) ); |
||
3171 | } |
||
3172 | |||
3173 | /** |
||
3174 | * Handle submissions from assets/js/wc-shipping-zone-methods.js Backbone model. |
||
3175 | */ |
||
3176 | public static function shipping_zone_methods_save_changes() { |
||
3177 | if ( ! isset( $_POST['wc_shipping_zones_nonce'], $_POST['zone_id'], $_POST['changes'] ) ) { |
||
3178 | wp_send_json_error( 'missing_fields' ); |
||
3179 | exit; |
||
3180 | } |
||
3181 | |||
3182 | if ( ! wp_verify_nonce( $_POST['wc_shipping_zones_nonce'], 'wc_shipping_zones_nonce' ) ) { |
||
3183 | wp_send_json_error( 'bad_nonce' ); |
||
3184 | exit; |
||
3185 | } |
||
3186 | |||
3187 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
3188 | wp_send_json_error( 'missing_capabilities' ); |
||
3189 | exit; |
||
3190 | } |
||
3191 | |||
3192 | global $wpdb; |
||
3193 | |||
3194 | $zone_id = absint( $_POST['zone_id'] ); |
||
3195 | $zone = new WC_Shipping_Zone( $zone_id ); |
||
3196 | $changes = $_POST['changes']; |
||
3197 | |||
3198 | foreach ( $changes as $instance_id => $data ) { |
||
3199 | $method_id = $wpdb->get_var( $wpdb->prepare( "SELECT method_id FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE instance_id = %d", $instance_id ) ); |
||
3200 | |||
3201 | if ( isset( $data['deleted'] ) ) { |
||
3202 | if ( $wpdb->delete( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'instance_id' => $instance_id ) ) ) { |
||
3203 | do_action( 'woocommerce_shipping_zone_method_deleted', $instance_id, $method_id, $zone_id ); |
||
3204 | } |
||
3205 | continue; |
||
3206 | } |
||
3207 | |||
3208 | $method_data = array_intersect_key( $data, array( |
||
3209 | 'method_order' => 1, |
||
3210 | 'enabled' => 1 |
||
3211 | ) ); |
||
3212 | |||
3213 | if ( isset( $method_data['method_order'] ) ) { |
||
3214 | $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'method_order' => absint( $method_data['method_order'] ) ), array( 'instance_id' => absint( $instance_id ) ) ); |
||
3215 | } |
||
3216 | |||
3217 | if ( isset( $method_data['enabled'] ) ) { |
||
3218 | $is_enabled = absint( 'yes' === $method_data['enabled'] ); |
||
3219 | if ( $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'is_enabled' => $is_enabled ), array( 'instance_id' => absint( $instance_id ) ) ) ) { |
||
3220 | do_action( 'woocommerce_shipping_zone_method_status_toggled', $instance_id, $method_id, $zone_id, $is_enabled ); |
||
3221 | } |
||
3222 | } |
||
3223 | } |
||
3224 | |||
3225 | wp_send_json_success( array( |
||
3226 | 'methods' => $zone->get_shipping_methods() |
||
3227 | ) ); |
||
3228 | } |
||
3229 | |||
3230 | /** |
||
3231 | * Save method settings |
||
3232 | */ |
||
3233 | View Code Duplication | public static function shipping_zone_methods_save_settings() { |
|
3234 | if ( ! isset( $_POST['wc_shipping_zones_nonce'], $_POST['instance_id'], $_POST['data'] ) ) { |
||
3235 | wp_send_json_error( 'missing_fields' ); |
||
3236 | exit; |
||
3237 | } |
||
3238 | |||
3239 | if ( ! wp_verify_nonce( $_POST['wc_shipping_zones_nonce'], 'wc_shipping_zones_nonce' ) ) { |
||
3240 | wp_send_json_error( 'bad_nonce' ); |
||
3241 | exit; |
||
3242 | } |
||
3243 | |||
3244 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
3245 | wp_send_json_error( 'missing_capabilities' ); |
||
3246 | exit; |
||
3247 | } |
||
3248 | |||
3249 | $instance_id = absint( $_POST['instance_id'] ); |
||
3250 | $zone = WC_Shipping_Zones::get_zone_by( 'instance_id', $instance_id ); |
||
3251 | $shipping_method = WC_Shipping_Zones::get_shipping_method( $instance_id ); |
||
3252 | $shipping_method->set_post_data( $_POST['data'] ); |
||
3253 | $shipping_method->process_admin_options(); |
||
3254 | |||
3255 | wp_send_json_success( array( |
||
3256 | 'methods' => $zone->get_shipping_methods(), |
||
3257 | 'errors' => $shipping_method->get_errors(), |
||
3258 | ) ); |
||
3259 | } |
||
3260 | |||
3261 | /** |
||
3262 | * Handle submissions from assets/js/wc-shipping-classes.js Backbone model. |
||
3263 | */ |
||
3264 | public static function shipping_classes_save_changes() { |
||
3265 | if ( ! isset( $_POST['wc_shipping_classes_nonce'], $_POST['changes'] ) ) { |
||
3266 | wp_send_json_error( 'missing_fields' ); |
||
3267 | exit; |
||
3268 | } |
||
3269 | |||
3270 | if ( ! wp_verify_nonce( $_POST['wc_shipping_classes_nonce'], 'wc_shipping_classes_nonce' ) ) { |
||
3271 | wp_send_json_error( 'bad_nonce' ); |
||
3272 | exit; |
||
3273 | } |
||
3274 | |||
3275 | if ( ! current_user_can( 'manage_woocommerce' ) ) { |
||
3276 | wp_send_json_error( 'missing_capabilities' ); |
||
3277 | exit; |
||
3278 | } |
||
3279 | |||
3280 | $changes = $_POST['changes']; |
||
3281 | |||
3282 | foreach ( $changes as $term_id => $data ) { |
||
3283 | $term_id = absint( $term_id ); |
||
3284 | |||
3285 | if ( isset( $data['deleted'] ) ) { |
||
3286 | if ( isset( $data['newRow'] ) ) { |
||
3287 | // So the user added and deleted a new row. |
||
3288 | // That's fine, it's not in the database anyways. NEXT! |
||
3289 | continue; |
||
3290 | } |
||
3291 | wp_delete_term( $term_id, 'product_shipping_class' ); |
||
3292 | continue; |
||
3293 | } |
||
3294 | |||
3295 | $update_args = array(); |
||
3296 | |||
3297 | if ( isset( $data['name'] ) ) { |
||
3298 | $update_args['name'] = wc_clean( $data['name'] ); |
||
3299 | } |
||
3300 | |||
3301 | if ( isset( $data['slug'] ) ) { |
||
3302 | $update_args['slug'] = wc_clean( $data['slug'] ); |
||
3303 | } |
||
3304 | |||
3305 | if ( isset( $data['description'] ) ) { |
||
3306 | $update_args['description'] = wc_clean( $data['description'] ); |
||
3307 | } |
||
3308 | |||
3309 | if ( isset( $data['newRow'] ) ) { |
||
3310 | $update_args = array_filter( $update_args ); |
||
3311 | if ( empty( $update_args['name'] ) ) { |
||
3312 | continue; |
||
3313 | } |
||
3314 | $term_id = wp_insert_term( $update_args['name'], 'product_shipping_class', $update_args ); |
||
3315 | } else { |
||
3316 | wp_update_term( $term_id, 'product_shipping_class', $update_args ); |
||
3317 | } |
||
3318 | |||
3319 | do_action( 'woocommerce_shipping_classes_save_class', $term_id, $data ); |
||
3320 | } |
||
3321 | |||
3322 | $wc_shipping = WC_Shipping::instance(); |
||
3323 | |||
3324 | wp_send_json_success( array( |
||
3325 | 'shipping_classes' => $wc_shipping->get_shipping_classes() |
||
3326 | ) ); |
||
3327 | } |
||
3328 | } |
||
3329 | |||
3330 | WC_AJAX::init(); |
||
3331 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.