1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) exit;
4
5 6 7 8 9 10 11 12 13 14 15
16 class WC_AJAX {
17
18 19 20
21 public function __construct() {
22
23
24 $ajax_events = array(
25 'get_refreshed_fragments' => true,
26 'apply_coupon' => true,
27 'update_shipping_method' => true,
28 'update_order_review' => true,
29 'add_to_cart' => true,
30 'checkout' => true,
31 'feature_product' => false,
32 'mark_order_complete' => false,
33 'mark_order_processing' => false,
34 'add_new_attribute' => false,
35 'remove_variation' => false,
36 'remove_variations' => false,
37 'save_attributes' => false,
38 'add_variation' => false,
39 'link_all_variations' => false,
40 'revoke_access_to_download' => false,
41 'grant_access_to_download' => false,
42 'get_customer_details' => false,
43 'add_order_item' => false,
44 'add_order_fee' => false,
45 'remove_order_item' => false,
46 'reduce_order_item_stock' => false,
47 'increase_order_item_stock' => false,
48 'add_order_item_meta' => false,
49 'remove_order_item_meta' => false,
50 'calc_line_taxes' => false,
51 'add_order_note' => false,
52 'delete_order_note' => false,
53 'json_search_products' => false,
54 'json_search_products_and_variations' => false,
55 'json_search_downloadable_products_and_variations' => false,
56 'json_search_customers' => false,
57 'term_ordering' => false,
58 'product_ordering' => false
59 );
60
61 foreach ( $ajax_events as $ajax_event => $nopriv ) {
62 add_action( 'wp_ajax_woocommerce_' . $ajax_event, array( $this, $ajax_event ) );
63
64 if ( $nopriv ) {
65 add_action( 'wp_ajax_nopriv_woocommerce_' . $ajax_event, array( $this, $ajax_event ) );
66 }
67 }
68 }
69
70 71 72
73 private function () {
74 header( 'Content-Type: application/json; charset=utf-8' );
75 }
76
77
78 79 80
81 public function get_refreshed_fragments() {
82
83 $this->json_headers();
84
85
86 ob_start();
87
88 woocommerce_mini_cart();
89
90 $mini_cart = ob_get_clean();
91
92
93 $data = array(
94 'fragments' => apply_filters( 'add_to_cart_fragments', array(
95 'div.widget_shopping_cart_content' => '<div class="widget_shopping_cart_content">' . $mini_cart . '</div>'
96 )
97 ),
98 'cart_hash' => WC()->cart->get_cart() ? md5( json_encode( WC()->cart->get_cart() ) ) : ''
99 );
100
101 echo json_encode( $data );
102
103 die();
104 }
105
106 107 108
109 public function apply_coupon() {
110
111 check_ajax_referer( 'apply-coupon', 'security' );
112
113 if ( ! empty( $_POST['coupon_code'] ) ) {
114 WC()->cart->add_discount( sanitize_text_field( $_POST['coupon_code'] ) );
115 } else {
116 wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' );
117 }
118
119 wc_print_notices();
120
121 die();
122 }
123
124 125 126
127 public function update_shipping_method() {
128
129 check_ajax_referer( 'update-shipping-method', 'security' );
130
131 if ( ! defined('WOOCOMMERCE_CART') ) {
132 define( 'WOOCOMMERCE_CART', true );
133 }
134
135 $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
136
137 if ( isset( $_POST['shipping_method'] ) && is_array( $_POST['shipping_method'] ) ) {
138 foreach ( $_POST['shipping_method'] as $i => $value ) {
139 $chosen_shipping_methods[ $i ] = wc_clean( $value );
140 }
141 }
142
143 WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods );
144
145 WC()->cart->calculate_totals();
146
147 woocommerce_cart_totals();
148
149 die();
150 }
151
152 153 154
155 public function update_order_review() {
156
157 check_ajax_referer( 'update-order-review', 'security' );
158
159 if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
160 define( 'WOOCOMMERCE_CHECKOUT', true );
161 }
162
163 if ( 0 == sizeof( WC()->cart->get_cart() ) ) {
164 echo '<div class="woocommerce-error">' . __( 'Sorry, your session has expired.', 'woocommerce' ) . ' <a href="' . home_url() . '" class="wc-backward">' . __( 'Return to homepage', 'woocommerce' ) . '</a></div>';
165 die();
166 }
167
168 do_action( 'woocommerce_checkout_update_order_review', $_POST['post_data'] );
169
170 $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
171
172 if ( isset( $_POST['shipping_method'] ) && is_array( $_POST['shipping_method'] ) ) {
173 foreach ( $_POST['shipping_method'] as $i => $value ) {
174 $chosen_shipping_methods[ $i ] = wc_clean( $value );
175 }
176 }
177
178 WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods );
179 WC()->session->set( 'chosen_payment_method', empty( $_POST['payment_method'] ) ? '' : $_POST['payment_method'] );
180
181 if ( isset( $_POST['country'] ) ) {
182 WC()->customer->set_country( $_POST['country'] );
183 }
184
185 if ( isset( $_POST['state'] ) ) {
186 WC()->customer->set_state( $_POST['state'] );
187 }
188
189 if ( isset( $_POST['postcode'] ) ) {
190 WC()->customer->set_postcode( $_POST['postcode'] );
191 }
192
193 if ( isset( $_POST['city'] ) ) {
194 WC()->customer->set_city( $_POST['city'] );
195 }
196
197 if ( isset( $_POST['address'] ) ) {
198 WC()->customer->set_address( $_POST['address'] );
199 }
200
201 if ( isset( $_POST['address_2'] ) ) {
202 WC()->customer->set_address_2( $_POST['address_2'] );
203 }
204
205 if ( "yes" == get_option( 'woocommerce_ship_to_billing_address_only' ) ) {
206
207 if ( isset( $_POST['country'] ) ) {
208 WC()->customer->set_shipping_country( $_POST['country'] );
209 }
210
211 if ( isset( $_POST['state'] ) ) {
212 WC()->customer->set_shipping_state( $_POST['state'] );
213 }
214
215 if ( isset( $_POST['postcode'] ) ) {
216 WC()->customer->set_shipping_postcode( $_POST['postcode'] );
217 }
218
219 if ( isset( $_POST['city'] ) ) {
220 WC()->customer->set_shipping_city( $_POST['city'] );
221 }
222
223 if ( isset( $_POST['address'] ) ) {
224 WC()->customer->set_shipping_address( $_POST['address'] );
225 }
226
227 if ( isset( $_POST['address_2'] ) ) {
228 WC()->customer->set_shipping_address_2( $_POST['address_2'] );
229 }
230 } else {
231
232 if ( isset( $_POST['s_country'] ) ) {
233 WC()->customer->set_shipping_country( $_POST['s_country'] );
234 }
235
236 if ( isset( $_POST['s_state'] ) ) {
237 WC()->customer->set_shipping_state( $_POST['s_state'] );
238 }
239
240 if ( isset( $_POST['s_postcode'] ) ) {
241 WC()->customer->set_shipping_postcode( $_POST['s_postcode'] );
242 }
243
244 if ( isset( $_POST['s_city'] ) ) {
245 WC()->customer->set_shipping_city( $_POST['s_city'] );
246 }
247
248 if ( isset( $_POST['s_address'] ) ) {
249 WC()->customer->set_shipping_address( $_POST['s_address'] );
250 }
251
252 if ( isset( $_POST['s_address_2'] ) ) {
253 WC()->customer->set_shipping_address_2( $_POST['s_address_2'] );
254 }
255 }
256
257 WC()->cart->calculate_totals();
258
259 do_action( 'woocommerce_checkout_order_review' );
260
261 die();
262 }
263
264 265 266
267 public function add_to_cart() {
268 $product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) );
269 $quantity = empty( $_POST['quantity'] ) ? 1 : apply_filters( 'woocommerce_stock_amount', $_POST['quantity'] );
270 $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity );
271
272 if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity ) ) {
273
274 do_action( 'woocommerce_ajax_added_to_cart', $product_id );
275
276 if ( get_option( 'woocommerce_cart_redirect_after_add' ) == 'yes' ) {
277 wc_add_to_cart_message( $product_id );
278 }
279
280
281 $this->get_refreshed_fragments();
282
283 } else {
284
285 $this->json_headers();
286
287
288 $data = array(
289 'error' => true,
290 'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id )
291 );
292
293 echo json_encode( $data );
294 }
295
296 die();
297 }
298
299 300 301
302 public function checkout() {
303 if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
304 define( 'WOOCOMMERCE_CHECKOUT', true );
305 }
306
307 $woocommerce_checkout = WC()->checkout();
308 $woocommerce_checkout->process_checkout();
309
310 die(0);
311 }
312
313 314 315
316 public function feature_product() {
317 if ( ! current_user_can( 'edit_products' ) ) {
318 wp_die( __( 'You do not have sufficient permissions to access this page.', 'woocommerce' ) );
319 }
320
321 if ( ! check_admin_referer( 'woocommerce-feature-product' ) ) {
322 wp_die( __( 'You have taken too long. Please go back and retry.', 'woocommerce' ) );
323 }
324
325 $post_id = ! empty( $_GET['product_id'] ) ? (int) $_GET['product_id'] : '';
326
327 if ( ! $post_id || get_post_type( $post_id ) !== 'product' ) {
328 die;
329 }
330
331 $featured = get_post_meta( $post_id, '_featured', true );
332
333 if ( 'yes' === $featured ) {
334 update_post_meta( $post_id, '_featured', 'no' );
335 } else {
336 update_post_meta( $post_id, '_featured', 'yes' );
337 }
338
339 wc_delete_product_transients();
340
341 wp_safe_redirect( remove_query_arg( array( 'trashed', 'untrashed', 'deleted', 'ids' ), wp_get_referer() ) );
342
343 die();
344 }
345
346 347 348
349 public function mark_order_complete() {
350 if ( ! current_user_can( 'edit_shop_orders' ) ) {
351 wp_die( __( 'You do not have sufficient permissions to access this page.', 'woocommerce' ) );
352 }
353
354 if ( ! check_admin_referer( 'woocommerce-mark-order-complete' ) ) {
355 wp_die( __( 'You have taken too long. Please go back and retry.', 'woocommerce' ) );
356 }
357
358 $order_id = isset( $_GET['order_id'] ) && (int) $_GET['order_id'] ? (int) $_GET['order_id'] : '';
359 if ( ! $order_id ) {
360 die();
361 }
362
363 $order = new WC_Order( $order_id );
364 $order->update_status( 'completed' );
365
366 wp_safe_redirect( wp_get_referer() );
367
368 die();
369 }
370
371 372 373
374 public function mark_order_processing() {
375 if ( ! current_user_can( 'edit_shop_orders' ) ) {
376 wp_die( __( 'You do not have sufficient permissions to access this page.', 'woocommerce' ) );
377 }
378
379 if ( ! check_admin_referer( 'woocommerce-mark-order-processing' ) ) {
380 wp_die( __( 'You have taken too long. Please go back and retry.', 'woocommerce' ) );
381 }
382
383 $order_id = isset( $_GET['order_id'] ) && (int) $_GET['order_id'] ? (int) $_GET['order_id'] : '';
384 if ( ! $order_id ) {
385 die();
386 }
387
388 $order = new WC_Order( $order_id );
389 $order->update_status( 'processing' );
390
391 wp_safe_redirect( wp_get_referer() );
392
393 die();
394 }
395
396 397 398
399 public function add_new_attribute() {
400
401 check_ajax_referer( 'add-attribute', 'security' );
402
403 $this->json_headers();
404
405 $taxonomy = esc_attr( $_POST['taxonomy'] );
406 $term = stripslashes( $_POST['term'] );
407
408 if ( taxonomy_exists( $taxonomy ) ) {
409
410 $result = wp_insert_term( $term, $taxonomy );
411
412 if ( is_wp_error( $result ) ) {
413 echo json_encode( array(
414 'error' => $result->get_error_message()
415 ));
416 } else {
417 echo json_encode( array(
418 'term_id' => $result['term_id'],
419 'name' => $term,
420 'slug' => sanitize_title( $term ),
421 ));
422 }
423 }
424
425 die();
426 }
427
428 429 430
431 public function remove_variation() {
432
433 check_ajax_referer( 'delete-variation', 'security' );
434
435 $variation_id = intval( $_POST['variation_id'] );
436 $variation = get_post( $variation_id );
437
438 if ( $variation && 'product_variation' == $variation->post_type ) {
439 wp_delete_post( $variation_id );
440 }
441
442 die();
443 }
444
445 446 447
448 public function remove_variations() {
449
450 check_ajax_referer( 'delete-variations', 'security' );
451
452 $variation_ids = (array) $_POST['variation_ids'];
453
454 foreach ( $variation_ids as $variation_id ) {
455 $variation = get_post( $variation_id );
456
457 if ( $variation && 'product_variation' == $variation->post_type ) {
458 wp_delete_post( $variation_id );
459 }
460 }
461
462 die();
463 }
464
465 466 467
468 public function save_attributes() {
469
470 check_ajax_referer( 'save-attributes', 'security' );
471
472
473 parse_str( $_POST['data'], $data );
474 $post_id = absint( $_POST['post_id'] );
475
476
477 $attributes = array();
478
479 if ( isset( $data['attribute_names'] ) ) {
480
481 $attribute_names = array_map( 'stripslashes', $data['attribute_names'] );
482 $attribute_values = isset( $data['attribute_values'] ) ? $data['attribute_values'] : array();
483
484 if ( isset( $data['attribute_visibility'] ) ) {
485 $attribute_visibility = $data['attribute_visibility'];
486 }
487
488 if ( isset( $data['attribute_variation'] ) ) {
489 $attribute_variation = $data['attribute_variation'];
490 }
491
492 $attribute_is_taxonomy = $data['attribute_is_taxonomy'];
493 $attribute_position = $data['attribute_position'];
494 $attribute_names_count = sizeof( $attribute_names );
495
496 for ( $i = 0; $i < $attribute_names_count; $i++ ) {
497 if ( ! $attribute_names[ $i ] ) {
498 continue;
499 }
500
501 $is_visible = isset( $attribute_visibility[ $i ] ) ? 1 : 0;
502 $is_variation = isset( $attribute_variation[ $i ] ) ? 1 : 0;
503 $is_taxonomy = $attribute_is_taxonomy[ $i ] ? 1 : 0;
504
505 if ( $is_taxonomy ) {
506
507 if ( isset( $attribute_values[ $i ] ) ) {
508
509
510 if ( is_array( $attribute_values[ $i ] ) ) {
511 $values = array_map( 'sanitize_title', $attribute_values[ $i ] );
512
513
514 } else {
515 $values = array_map( 'stripslashes', array_map( 'strip_tags', explode( WC_DELIMITER, $attribute_values[ $i ] ) ) );
516 }
517
518
519 $values = array_filter( $values, 'strlen' );
520
521 } else {
522 $values = array();
523 }
524
525
526 if ( taxonomy_exists( $attribute_names[ $i ] ) ) {
527 wp_set_object_terms( $post_id, $values, $attribute_names[ $i ] );
528 }
529
530 if ( $values ) {
531
532 $attributes[ sanitize_title( $attribute_names[ $i ] ) ] = array(
533 'name' => wc_clean( $attribute_names[ $i ] ),
534 'value' => '',
535 'position' => $attribute_position[ $i ],
536 'is_visible' => $is_visible,
537 'is_variation' => $is_variation,
538 'is_taxonomy' => $is_taxonomy
539 );
540 }
541
542 } elseif ( isset( $attribute_values[ $i ] ) ) {
543
544
545 $values = implode( ' ' . WC_DELIMITER . ' ', array_map( 'wc_clean', array_map( 'stripslashes', explode( WC_DELIMITER, $attribute_values[ $i ] ) ) ) );
546
547
548 $attributes[ sanitize_title( $attribute_names[ $i ] ) ] = array(
549 'name' => wc_clean( $attribute_names[ $i ] ),
550 'value' => $values,
551 'position' => $attribute_position[ $i ],
552 'is_visible' => $is_visible,
553 'is_variation' => $is_variation,
554 'is_taxonomy' => $is_taxonomy
555 );
556 }
557
558 }
559 }
560
561 if ( ! function_exists( 'attributes_cmp' ) ) {
562 function attributes_cmp( $a, $b ) {
563 if ( $a['position'] == $b['position'] ) {
564 return 0;
565 }
566
567 return ( $a['position'] < $b['position'] ) ? -1 : 1;
568 }
569 }
570 uasort( $attributes, 'attributes_cmp' );
571
572 update_post_meta( $post_id, '_product_attributes', $attributes );
573
574 die();
575 }
576
577 578 579
580 public function add_variation() {
581
582 check_ajax_referer( 'add-variation', 'security' );
583
584 $post_id = intval( $_POST['post_id'] );
585 $loop = intval( $_POST['loop'] );
586
587 $variation = array(
588 'post_title' => 'Product #' . $post_id . ' Variation',
589 'post_content' => '',
590 'post_status' => 'publish',
591 'post_author' => get_current_user_id(),
592 'post_parent' => $post_id,
593 'post_type' => 'product_variation'
594 );
595
596 $variation_id = wp_insert_post( $variation );
597
598 do_action( 'woocommerce_create_product_variation', $variation_id );
599
600 if ( $variation_id ) {
601
602 $variation_post_status = 'publish';
603 $variation_data = get_post_meta( $variation_id );
604 $variation_data['variation_post_id'] = $variation_id;
605
606
607 $attributes = (array) maybe_unserialize( get_post_meta( $post_id, '_product_attributes', true ) );
608
609
610 $tax_classes = array_filter(array_map('trim', explode("\n", get_option('woocommerce_tax_classes'))));
611 $tax_class_options = array();
612 $tax_class_options['parent'] =__( 'Same as parent', 'woocommerce' );
613 $tax_class_options[''] = __( 'Standard', 'woocommerce' );
614
615 if ( $tax_classes ) {
616 foreach ( $tax_classes as $class ) {
617 $tax_class_options[ sanitize_title( $class ) ] = $class;
618 }
619 }
620
621
622 $parent_data = array(
623 'id' => $post_id,
624 'attributes' => $attributes,
625 'tax_class_options' => $tax_class_options,
626 'sku' => get_post_meta( $post_id, '_sku', true ),
627 'weight' => get_post_meta( $post_id, '_weight', true ),
628 'length' => get_post_meta( $post_id, '_length', true ),
629 'width' => get_post_meta( $post_id, '_width', true ),
630 'height' => get_post_meta( $post_id, '_height', true ),
631 'tax_class' => get_post_meta( $post_id, '_tax_class', true )
632 );
633
634 if ( ! $parent_data['weight'] ) {
635 $parent_data['weight'] = '0.00';
636 }
637
638 if ( ! $parent_data['length'] ) {
639 $parent_data['length'] = '0';
640 }
641
642 if ( ! $parent_data['width'] ) {
643 $parent_data['width'] = '0';
644 }
645
646 if ( ! $parent_data['height'] ) {
647 $parent_data['height'] = '0';
648 }
649
650 $_tax_class = '';
651 $_downloadable_files = '';
652 $image_id = 0;
653 $variation = get_post( $variation_id );
654
655 include( 'admin/post-types/meta-boxes/views/html-variation-admin.php' );
656 }
657
658 die();
659 }
660
661 662 663
664 public function link_all_variations() {
665
666 if ( ! defined( 'WC_MAX_LINKED_VARIATIONS' ) ) {
667 define( 'WC_MAX_LINKED_VARIATIONS', 49 );
668 }
669
670 check_ajax_referer( 'link-variations', 'security' );
671
672 @set_time_limit(0);
673
674 $post_id = intval( $_POST['post_id'] );
675
676 if ( ! $post_id ) {
677 die();
678 }
679
680 $variations = array();
681 $_product = get_product( $post_id, array( 'product_type' => 'variable' ) );
682
683
684 foreach ( $_product->get_attributes() as $attribute ) {
685
686 if ( ! $attribute['is_variation'] ) {
687 continue;
688 }
689
690 $attribute_field_name = 'attribute_' . sanitize_title( $attribute['name'] );
691
692 if ( $attribute['is_taxonomy'] ) {
693 $options = wc_get_product_terms( $post_id, $attribute['name'], array( 'fields' => 'slugs' ) );
694 } else {
695 $options = explode( WC_DELIMITER, $attribute['value'] );
696 }
697
698 $options = array_map( 'sanitize_title', array_map( 'trim', $options ) );
699
700 $variations[ $attribute_field_name ] = $options;
701 }
702
703
704 if ( sizeof( $variations ) == 0 ) {
705 die();
706 }
707
708
709 $available_variations = array();
710
711 foreach( $_product->get_children() as $child_id ) {
712 $child = $_product->get_child( $child_id );
713
714 if ( ! empty( $child->variation_id ) ) {
715 $available_variations[] = $child->get_variation_attributes();
716 }
717 }
718
719
720 $variation_post_data = array(
721 'post_title' => 'Product #' . $post_id . ' Variation',
722 'post_content' => '',
723 'post_status' => 'publish',
724 'post_author' => get_current_user_id(),
725 'post_parent' => $post_id,
726 'post_type' => 'product_variation'
727 );
728
729
730 if ( ! function_exists( 'array_cartesian' ) ) {
731
732 733 734 735
736 function array_cartesian( $input ) {
737 $result = array();
738
739 while ( list( $key, $values ) = each( $input ) ) {
740
741 if ( empty( $values ) ) {
742 continue;
743 }
744
745
746 if ( empty( $result ) ) {
747 foreach ( $values as $value ) {
748 $result[] = array( $key => $value );
749 }
750 }
751 else {
752
753
754
755
756
757
758
759
760
761 $append = array();
762 foreach ( $result as &$product ) {
763
764
765
766 $product[ $key ] = array_shift( $values );
767
768
769
770 $copy = $product;
771
772
773 foreach ( $values as $item ) {
774 $copy[ $key ] = $item;
775 $append[] = $copy;
776 }
777
778
779 array_unshift( $values, $product[ $key ] );
780 }
781
782
783 $result = array_merge( $result, $append );
784 }
785 }
786
787 return $result;
788 }
789 }
790
791 $variation_ids = array();
792 $added = 0;
793 $possible_variations = array_cartesian( $variations );
794
795 foreach ( $possible_variations as $variation ) {
796
797
798 if ( in_array( $variation, $available_variations ) ) {
799 continue;
800 }
801
802 $variation_id = wp_insert_post( $variation_post_data );
803
804 $variation_ids[] = $variation_id;
805
806 foreach ( $variation as $key => $value ) {
807 update_post_meta( $variation_id, $key, $value );
808 }
809
810 $added++;
811
812 do_action( 'product_variation_linked', $variation_id );
813
814 if ( $added > WC_MAX_LINKED_VARIATIONS ) {
815 break;
816 }
817 }
818
819 wc_delete_product_transients( $post_id );
820
821 echo $added;
822
823 die();
824 }
825
826 827 828
829 public function revoke_access_to_download() {
830
831 check_ajax_referer( 'revoke-access', 'security' );
832
833 global $wpdb;
834
835 $download_id = $_POST['download_id'];
836 $product_id = intval( $_POST['product_id'] );
837 $order_id = intval( $_POST['order_id'] );
838
839 $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 ) );
840
841 do_action( 'woocommerce_ajax_revoke_access_to_product_download', $download_id, $product_id, $order_id );
842
843 die();
844 }
845
846 847 848
849 public function grant_access_to_download() {
850
851 check_ajax_referer( 'grant-access', 'security' );
852
853 global $wpdb;
854
855 $wpdb->hide_errors();
856
857 $order_id = intval( $_POST['order_id'] );
858 $product_ids = $_POST['product_ids'];
859 $loop = intval( $_POST['loop'] );
860 $file_counter = 0;
861 $order = new WC_Order( $order_id );
862
863 if ( ! is_array( $product_ids ) ) {
864 $product_ids = array( $product_ids );
865 }
866
867 foreach ( $product_ids as $product_id ) {
868 $product = get_product( $product_id );
869 $files = $product->get_files();
870
871 if ( ! $order->billing_email ) {
872 die();
873 }
874
875 if ( $files ) {
876 foreach ( $files as $download_id => $file ) {
877 if ( $inserted_id = wc_downloadable_file_permission( $download_id, $product_id, $order ) ) {
878
879
880 $download = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE permission_id = %d", $inserted_id ) );
881
882 $loop ++;
883 $file_counter ++;
884
885 if ( isset( $file['name'] ) ) {
886 $file_count = $file['name'];
887 } else {
888 $file_count = sprintf( __( 'File %d', 'woocommerce' ), $file_counter );
889 }
890 include( 'admin/post-types/meta-boxes/views/html-order-download-permission.php' );
891 }
892 }
893 }
894 }
895
896 die();
897 }
898
899 900 901
902 public function get_customer_details() {
903
904 check_ajax_referer( 'get-customer-details', 'security' );
905
906 $this->json_headers();
907
908 $user_id = (int) trim(stripslashes($_POST['user_id']));
909 $type_to_load = esc_attr(trim(stripslashes($_POST['type_to_load'])));
910
911 $customer_data = array(
912 $type_to_load . '_first_name' => get_user_meta( $user_id, $type_to_load . '_first_name', true ),
913 $type_to_load . '_last_name' => get_user_meta( $user_id, $type_to_load . '_last_name', true ),
914 $type_to_load . '_company' => get_user_meta( $user_id, $type_to_load . '_company', true ),
915 $type_to_load . '_address_1' => get_user_meta( $user_id, $type_to_load . '_address_1', true ),
916 $type_to_load . '_address_2' => get_user_meta( $user_id, $type_to_load . '_address_2', true ),
917 $type_to_load . '_city' => get_user_meta( $user_id, $type_to_load . '_city', true ),
918 $type_to_load . '_postcode' => get_user_meta( $user_id, $type_to_load . '_postcode', true ),
919 $type_to_load . '_country' => get_user_meta( $user_id, $type_to_load . '_country', true ),
920 $type_to_load . '_state' => get_user_meta( $user_id, $type_to_load . '_state', true ),
921 $type_to_load . '_email' => get_user_meta( $user_id, $type_to_load . '_email', true ),
922 $type_to_load . '_phone' => get_user_meta( $user_id, $type_to_load . '_phone', true ),
923 );
924
925 $customer_data = apply_filters( 'woocommerce_found_customer_details', $customer_data );
926
927 echo json_encode( $customer_data );
928
929
930 die();
931 }
932
933 934 935
936 public function add_order_item() {
937 global $wpdb;
938
939 check_ajax_referer( 'order-item', 'security' );
940
941 $item_to_add = sanitize_text_field( $_POST['item_to_add'] );
942 $order_id = absint( $_POST['order_id'] );
943
944
945 if ( ! is_numeric( $item_to_add ) ) {
946 die();
947 }
948
949 $post = get_post( $item_to_add );
950
951 if ( ! $post || ( 'product' !== $post->post_type && 'product_variation' !== $post->post_type ) ) {
952 die();
953 }
954
955 $_product = get_product( $post->ID );
956 $order = new WC_Order( $order_id );
957 $class = 'new_row';
958
959
960 $item = array();
961
962 $item['product_id'] = $_product->id;
963 $item['variation_id'] = isset( $_product->variation_id ) ? $_product->variation_id : '';
964 $item['variation_data'] = isset( $_product->variation_data ) ? $_product->variation_data : '';
965 $item['name'] = $_product->get_title();
966 $item['tax_class'] = $_product->get_tax_class();
967 $item['qty'] = 1;
968 $item['line_subtotal'] = wc_format_decimal( $_product->get_price_excluding_tax() );
969 $item['line_subtotal_tax'] = '';
970 $item['line_total'] = wc_format_decimal( $_product->get_price_excluding_tax() );
971 $item['line_tax'] = '';
972
973
974 $item_id = wc_add_order_item( $order_id, array(
975 'order_item_name' => $item['name'],
976 'order_item_type' => 'line_item'
977 ) );
978
979
980 if ( $item_id ) {
981 wc_add_order_item_meta( $item_id, '_qty', $item['qty'] );
982 wc_add_order_item_meta( $item_id, '_tax_class', $item['tax_class'] );
983 wc_add_order_item_meta( $item_id, '_product_id', $item['product_id'] );
984 wc_add_order_item_meta( $item_id, '_variation_id', $item['variation_id'] );
985 wc_add_order_item_meta( $item_id, '_line_subtotal', $item['line_subtotal'] );
986 wc_add_order_item_meta( $item_id, '_line_subtotal_tax', $item['line_subtotal_tax'] );
987 wc_add_order_item_meta( $item_id, '_line_total', $item['line_total'] );
988 wc_add_order_item_meta( $item_id, '_line_tax', $item['line_tax'] );
989
990
991 if ( $item['variation_data'] && is_array( $item['variation_data'] ) ) {
992 foreach ( $item['variation_data'] as $key => $value ) {
993 wc_add_order_item_meta( $item_id, str_replace( 'attribute_', '', $key ), $value );
994 }
995 }
996
997 do_action( 'woocommerce_ajax_add_order_item_meta', $item_id, $item );
998 }
999
1000 $item = apply_filters( 'woocommerce_ajax_order_item', $item, $item_id );
1001
1002 include( 'admin/post-types/meta-boxes/views/html-order-item.php' );
1003
1004
1005 die();
1006 }
1007
1008 1009 1010
1011 public function add_order_fee() {
1012
1013 check_ajax_referer( 'order-item', 'security' );
1014
1015 $order_id = absint( $_POST['order_id'] );
1016 $order = new WC_Order( $order_id );
1017
1018
1019 $item_id = wc_add_order_item( $order_id, array(
1020 'order_item_name' => '',
1021 'order_item_type' => 'fee'
1022 ) );
1023
1024
1025 if ( $item_id ) {
1026 wc_add_order_item_meta( $item_id, '_tax_class', '' );
1027 wc_add_order_item_meta( $item_id, '_line_total', '' );
1028 wc_add_order_item_meta( $item_id, '_line_tax', '' );
1029 }
1030
1031 include( 'admin/post-types/meta-boxes/views/html-order-fee.php' );
1032
1033
1034 die();
1035 }
1036
1037 1038 1039
1040 public function remove_order_item() {
1041 global $wpdb;
1042
1043 check_ajax_referer( 'order-item', 'security' );
1044
1045 $order_item_ids = $_POST['order_item_ids'];
1046
1047 if ( sizeof( $order_item_ids ) > 0 ) {
1048 foreach( $order_item_ids as $id ) {
1049 wc_delete_order_item( absint( $id ) );
1050 }
1051 }
1052
1053 die();
1054 }
1055
1056 1057 1058
1059 public function reduce_order_item_stock() {
1060 global $wpdb;
1061
1062 check_ajax_referer( 'order-item', 'security' );
1063
1064 $order_id = absint( $_POST['order_id'] );
1065 $order_item_ids = isset( $_POST['order_item_ids'] ) ? $_POST['order_item_ids'] : array();
1066 $order_item_qty = isset( $_POST['order_item_qty'] ) ? $_POST['order_item_qty'] : array();
1067 $order = new WC_Order( $order_id );
1068 $order_items = $order->get_items();
1069 $return = array();
1070
1071 if ( $order && ! empty( $order_items ) && sizeof( $order_item_ids ) > 0 ) {
1072
1073 foreach ( $order_items as $item_id => $order_item ) {
1074
1075
1076 if ( ! in_array( $item_id, $order_item_ids ) ) {
1077 continue;
1078 }
1079
1080 $_product = $order->get_product_from_item( $order_item );
1081
1082 if ( $_product->exists() && $_product->managing_stock() && isset( $order_item_qty[ $item_id ] ) && $order_item_qty[ $item_id ] > 0 ) {
1083
1084 $old_stock = $_product->stock;
1085 $stock_change = apply_filters( 'woocommerce_reduce_order_stock_quantity', $order_item_qty[ $item_id ], $item_id );
1086 $new_quantity = $_product->reduce_stock( $stock_change );
1087
1088 $return[] = sprintf( __( 'Item #%s stock reduced from %s to %s.', 'woocommerce' ), $order_item['product_id'], $old_stock, $new_quantity );
1089 $order->add_order_note( sprintf( __( 'Item #%s stock reduced from %s to %s.', 'woocommerce' ), $order_item['product_id'], $old_stock, $new_quantity) );
1090 $order->send_stock_notifications( $_product, $new_quantity, $order_item_qty[ $item_id ] );
1091 }
1092 }
1093
1094 do_action( 'woocommerce_reduce_order_stock', $order );
1095
1096 if ( empty( $return ) ) {
1097 $return[] = __( 'No products had their stock reduced - they may not have stock management enabled.', 'woocommerce' );
1098 }
1099
1100 echo implode( ', ', $return );
1101 }
1102
1103 die();
1104 }
1105
1106 1107 1108
1109 public function increase_order_item_stock() {
1110 global $wpdb;
1111
1112 check_ajax_referer( 'order-item', 'security' );
1113
1114 $order_id = absint( $_POST['order_id'] );
1115 $order_item_ids = isset( $_POST['order_item_ids'] ) ? $_POST['order_item_ids'] : array();
1116 $order_item_qty = isset( $_POST['order_item_qty'] ) ? $_POST['order_item_qty'] : array();
1117 $order = new WC_Order( $order_id );
1118 $order_items = $order->get_items();
1119 $return = array();
1120
1121 if ( $order && ! empty( $order_items ) && sizeof( $order_item_ids ) > 0 ) {
1122
1123 foreach ( $order_items as $item_id => $order_item ) {
1124
1125
1126 if ( ! in_array( $item_id, $order_item_ids ) ) {
1127 continue;
1128 }
1129
1130 $_product = $order->get_product_from_item( $order_item );
1131
1132 if ( $_product->exists() && $_product->managing_stock() && isset( $order_item_qty[ $item_id ] ) && $order_item_qty[ $item_id ] > 0 ) {
1133
1134 $old_stock = $_product->stock;
1135 $stock_change = apply_filters( 'woocommerce_restore_order_stock_quantity', $order_item_qty[ $item_id ], $item_id );
1136 $new_quantity = $_product->increase_stock( $stock_change );
1137
1138 $return[] = sprintf( __( 'Item #%s stock increased from %s to %s.', 'woocommerce' ), $order_item['product_id'], $old_stock, $new_quantity );
1139 $order->add_order_note( sprintf( __( 'Item #%s stock increased from %s to %s.', 'woocommerce' ), $order_item['product_id'], $old_stock, $new_quantity ) );
1140 }
1141 }
1142
1143 do_action( 'woocommerce_restore_order_stock', $order );
1144
1145 if ( empty( $return ) ) {
1146 $return[] = __( 'No products had their stock increased - they may not have stock management enabled.', 'woocommerce' );
1147 }
1148
1149 echo implode( ', ', $return );
1150 }
1151
1152 die();
1153 }
1154
1155 1156 1157
1158 public function add_order_item_meta() {
1159 global $wpdb;
1160
1161 check_ajax_referer( 'order-item', 'security' );
1162
1163 $meta_id = wc_add_order_item_meta( absint( $_POST['order_item_id'] ), __( 'Name', 'woocommerce' ), __( 'Value', 'woocommerce' ) );
1164
1165 if ( $meta_id ) {
1166 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>';
1167 }
1168
1169 die();
1170 }
1171
1172 1173 1174
1175 public function remove_order_item_meta() {
1176 global $wpdb;
1177
1178 check_ajax_referer( 'order-item', 'security' );
1179
1180 $meta_id = absint( $_POST['meta_id'] );
1181
1182 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_id = %d", $meta_id ) );
1183
1184 die();
1185 }
1186
1187 1188 1189
1190 public function calc_line_taxes() {
1191 global $wpdb;
1192
1193 check_ajax_referer( 'calc-totals', 'security' );
1194
1195 $this->json_headers();
1196
1197 $tax = new WC_Tax();
1198 $taxes = $tax_rows = $item_taxes = $shipping_taxes = array();
1199 $order_id = absint( $_POST['order_id'] );
1200 $order = new WC_Order( $order_id );
1201 $country = strtoupper( esc_attr( $_POST['country'] ) );
1202 $state = strtoupper( esc_attr( $_POST['state'] ) );
1203 $postcode = strtoupper( esc_attr( $_POST['postcode'] ) );
1204 $city = sanitize_title( esc_attr( $_POST['city'] ) );
1205 $items = isset( $_POST['items'] ) ? $_POST['items'] : array();
1206 $shipping = $_POST['shipping'];
1207 $item_tax = 0;
1208
1209
1210 if ( sizeof( $items ) > 0 ) {
1211 foreach( $items as $item_id => $item ) {
1212
1213 $item_id = absint( $item_id );
1214 $line_subtotal = isset( $item['line_subtotal'] ) ? wc_format_decimal( $item['line_subtotal'] ) : 0;
1215 $line_total = wc_format_decimal( $item['line_total'] );
1216 $tax_class = sanitize_text_field( $item['tax_class'] );
1217 $product_id = $order->get_item_meta( $item_id, '_product_id', true );
1218
1219 if ( ! $item_id || '0' == $tax_class ) {
1220 continue;
1221 }
1222
1223
1224 if ( get_post_type( $product_id ) == 'product' ) {
1225 $_product = get_product( $product_id );
1226 $item_tax_status = $_product->get_tax_status();
1227 } else {
1228 $item_tax_status = 'taxable';
1229 }
1230
1231
1232 if ( 'taxable' == $item_tax_status ) {
1233
1234 $tax_rates = $tax->find_rates( array(
1235 'country' => $country,
1236 'state' => $state,
1237 'postcode' => $postcode,
1238 'city' => $city,
1239 'tax_class' => $tax_class
1240 ) );
1241
1242 $line_subtotal_taxes = $tax->calc_tax( $line_subtotal, $tax_rates, false );
1243 $line_taxes = $tax->calc_tax( $line_total, $tax_rates, false );
1244 $line_subtotal_tax = array_sum( $line_subtotal_taxes );
1245 $line_tax = array_sum( $line_taxes );
1246
1247 if ( $line_subtotal_tax < 0 ) {
1248 $line_subtotal_tax = 0;
1249 }
1250
1251 if ( $line_tax < 0 ) {
1252 $line_tax = 0;
1253 }
1254
1255 $item_taxes[ $item_id ] = array(
1256 'line_subtotal_tax' => wc_format_localized_price( $line_subtotal_tax ),
1257 'line_tax' => wc_format_localized_price( $line_tax )
1258 );
1259
1260 $item_tax += $line_tax;
1261
1262
1263 foreach ( array_keys( $taxes + $line_taxes ) as $key ) {
1264 $taxes[ $key ] = ( isset( $line_taxes[ $key ] ) ? $line_taxes[ $key ] : 0 ) + ( isset( $taxes[ $key ] ) ? $taxes[ $key ] : 0 );
1265 }
1266 }
1267
1268 }
1269 }
1270
1271
1272 $matched_tax_rates = array();
1273
1274 $tax_rates = $tax->find_rates( array(
1275 'country' => $country,
1276 'state' => $state,
1277 'postcode' => $postcode,
1278 'city' => $city,
1279 'tax_class' => ''
1280 ) );
1281
1282 if ( $tax_rates ) {
1283 foreach ( $tax_rates as $key => $rate ) {
1284 if ( isset( $rate['shipping'] ) && 'yes' == $rate['shipping'] ) {
1285 $matched_tax_rates[ $key ] = $rate;
1286 }
1287 }
1288 }
1289
1290 $shipping_taxes = $tax->calc_shipping_tax( $shipping, $matched_tax_rates );
1291 $shipping_tax = $tax->round( array_sum( $shipping_taxes ) );
1292
1293
1294 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = 'tax' )", $order_id ) );
1295
1296 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = 'tax'", $order_id ) );
1297
1298
1299 $rates = $wpdb->get_results( "SELECT tax_rate_id, tax_rate_country, tax_rate_state, tax_rate_name, tax_rate_priority FROM {$wpdb->prefix}woocommerce_tax_rates ORDER BY tax_rate_name" );
1300
1301 $tax_codes = array();
1302
1303 foreach( $rates as $rate ) {
1304 $code = array();
1305
1306 $code[] = $rate->tax_rate_country;
1307 $code[] = $rate->tax_rate_state;
1308 $code[] = $rate->tax_rate_name ? sanitize_title( $rate->tax_rate_name ) : 'TAX';
1309 $code[] = absint( $rate->tax_rate_priority );
1310
1311 $tax_codes[ $rate->tax_rate_id ] = strtoupper( implode( '-', array_filter( $code ) ) );
1312 }
1313
1314
1315 ob_start();
1316
1317 foreach ( array_keys( $taxes + $shipping_taxes ) as $key ) {
1318
1319 $item = array();
1320 $item['rate_id'] = $key;
1321 $item['name'] = $tax_codes[ $key ];
1322 $item['label'] = $tax->get_rate_label( $key );
1323 $item['compound'] = $tax->is_compound( $key ) ? 1 : 0;
1324 $item['tax_amount'] = wc_format_decimal( isset( $taxes[ $key ] ) ? $taxes[ $key ] : 0 );
1325 $item['shipping_tax_amount'] = wc_format_decimal( isset( $shipping_taxes[ $key ] ) ? $shipping_taxes[ $key ] : 0 );
1326
1327 if ( ! $item['label'] ) {
1328 $item['label'] = WC()->countries->tax_or_vat();
1329 }
1330
1331
1332 $item_id = wc_add_order_item( $order_id, array(
1333 'order_item_name' => $item['name'],
1334 'order_item_type' => 'tax'
1335 ) );
1336
1337
1338 if ( $item_id ) {
1339 wc_add_order_item_meta( $item_id, 'rate_id', $item['rate_id'] );
1340 wc_add_order_item_meta( $item_id, 'label', $item['label'] );
1341 wc_add_order_item_meta( $item_id, 'compound', $item['compound'] );
1342 wc_add_order_item_meta( $item_id, 'tax_amount', $item['tax_amount'] );
1343 wc_add_order_item_meta( $item_id, 'shipping_tax_amount', $item['shipping_tax_amount'] );
1344 }
1345
1346 include( 'admin/post-types/meta-boxes/views/html-order-tax.php' );
1347 }
1348
1349 $tax_row_html = ob_get_clean();
1350
1351
1352 echo json_encode( array(
1353 'item_tax' => $item_tax,
1354 'item_taxes' => $item_taxes,
1355 'shipping_tax' => $shipping_tax,
1356 'tax_row_html' => $tax_row_html
1357 ) );
1358
1359
1360 die();
1361 }
1362
1363 1364 1365
1366 public function add_order_note() {
1367
1368 check_ajax_referer( 'add-order-note', 'security' );
1369
1370 $post_id = (int) $_POST['post_id'];
1371 $note = wp_kses_post( trim( stripslashes( $_POST['note'] ) ) );
1372 $note_type = $_POST['note_type'];
1373
1374 $is_customer_note = $note_type == 'customer' ? 1 : 0;
1375
1376 if ( $post_id > 0 ) {
1377 $order = new WC_Order( $post_id );
1378 $comment_id = $order->add_order_note( $note, $is_customer_note );
1379
1380 echo '<li rel="' . esc_attr( $comment_id ) . '" class="note ';
1381 if ( $is_customer_note ) {
1382 echo 'customer-note';
1383 }
1384 echo '"><div class="note_content">';
1385 echo wpautop( wptexturize( $note ) );
1386 echo '</div><p class="meta"><a href="#" class="delete_note">'.__( 'Delete note', 'woocommerce' ).'</a></p>';
1387 echo '</li>';
1388 }
1389
1390
1391 die();
1392 }
1393
1394 1395 1396
1397 public function delete_order_note() {
1398
1399 check_ajax_referer( 'delete-order-note', 'security' );
1400
1401 $note_id = (int) $_POST['note_id'];
1402
1403 if ( $note_id > 0 ) {
1404 wp_delete_comment( $note_id );
1405 }
1406
1407
1408 die();
1409 }
1410
1411 1412 1413 1414 1415 1416
1417 public function json_search_products( $x = '', $post_types = array('product') ) {
1418
1419 check_ajax_referer( 'search-products', 'security' );
1420
1421 $this->json_headers();
1422
1423 $term = (string) wc_clean( stripslashes( $_GET['term'] ) );
1424
1425 if ( empty( $term ) ) {
1426 die();
1427 }
1428
1429 if ( is_numeric( $term ) ) {
1430
1431 $args = array(
1432 'post_type' => $post_types,
1433 'post_status' => 'publish',
1434 'posts_per_page' => -1,
1435 'post__in' => array(0, $term),
1436 'fields' => 'ids'
1437 );
1438
1439 $args2 = array(
1440 'post_type' => $post_types,
1441 'post_status' => 'publish',
1442 'posts_per_page' => -1,
1443 'post_parent' => $term,
1444 'fields' => 'ids'
1445 );
1446
1447 $args3 = array(
1448 'post_type' => $post_types,
1449 'post_status' => 'publish',
1450 'posts_per_page' => -1,
1451 'meta_query' => array(
1452 array(
1453 'key' => '_sku',
1454 'value' => $term,
1455 'compare' => 'LIKE'
1456 )
1457 ),
1458 'fields' => 'ids'
1459 );
1460
1461 $posts = array_unique( array_merge( get_posts( $args ), get_posts( $args2 ), get_posts( $args3 ) ) );
1462
1463 } else {
1464
1465 $args = array(
1466 'post_type' => $post_types,
1467 'post_status' => 'publish',
1468 'posts_per_page' => -1,
1469 's' => $term,
1470 'fields' => 'ids'
1471 );
1472
1473 $args2 = array(
1474 'post_type' => $post_types,
1475 'post_status' => 'publish',
1476 'posts_per_page' => -1,
1477 'meta_query' => array(
1478 array(
1479 'key' => '_sku',
1480 'value' => $term,
1481 'compare' => 'LIKE'
1482 )
1483 ),
1484 'fields' => 'ids'
1485 );
1486
1487 $posts = array_unique( array_merge( get_posts( $args ), get_posts( $args2 ) ) );
1488
1489 }
1490
1491 $found_products = array();
1492
1493 if ( $posts ) {
1494 foreach ( $posts as $post ) {
1495 $product = get_product( $post );
1496
1497 $found_products[ $post ] = $product->get_formatted_name();
1498 }
1499 }
1500
1501 $found_products = apply_filters( 'woocommerce_json_search_found_products', $found_products );
1502
1503 echo json_encode( $found_products );
1504
1505 die();
1506 }
1507
1508 1509 1510 1511 1512 1513 1514
1515 public function json_search_products_and_variations() {
1516 $this->json_search_products( '', array('product', 'product_variation') );
1517 }
1518
1519 1520 1521
1522 public function json_search_customers() {
1523
1524 check_ajax_referer( 'search-customers', 'security' );
1525
1526 $this->json_headers();
1527
1528 $term = wc_clean( stripslashes( $_GET['term'] ) );
1529
1530 if ( empty( $term ) ) {
1531 die();
1532 }
1533
1534 $default = isset( $_GET['default'] ) ? $_GET['default'] : __( 'Guest', 'woocommerce' );
1535
1536 $found_customers = array( '' => $default );
1537
1538 add_action( 'pre_user_query', array( $this, 'json_search_customer_name' ) );
1539
1540 $customers_query = new WP_User_Query( apply_filters( 'woocommerce_json_search_customers_query', array(
1541 'fields' => 'all',
1542 'orderby' => 'display_name',
1543 'search' => '*' . $term . '*',
1544 'search_columns' => array( 'ID', 'user_login', 'user_email', 'user_nicename' )
1545 ) ) );
1546
1547 remove_action( 'pre_user_query', array( $this, 'json_search_customer_name' ) );
1548
1549 $customers = $customers_query->get_results();
1550
1551 if ( $customers ) {
1552 foreach ( $customers as $customer ) {
1553 $found_customers[ $customer->ID ] = $customer->display_name . ' (#' . $customer->ID . ' – ' . sanitize_email( $customer->user_email ) . ')';
1554 }
1555 }
1556
1557 echo json_encode( $found_customers );
1558 die();
1559 }
1560
1561 1562 1563 1564 1565 1566 1567
1568 public function json_search_downloadable_products_and_variations() {
1569 $term = (string) wc_clean( stripslashes( $_GET['term'] ) );
1570
1571 $args = array(
1572 'post_type' => array( 'product', 'product_variation' ),
1573 'posts_per_page' => -1,
1574 'post_status' => 'publish',
1575 'order' => 'ASC',
1576 'orderby' => 'parent title',
1577 'meta_query' => array(
1578 array(
1579 'key' => '_downloadable',
1580 'value' => 'yes'
1581 )
1582 ),
1583 's' => $term
1584 );
1585
1586 $posts = get_posts( $args );
1587 $found_products = array();
1588
1589 if ( $posts ) {
1590 foreach ( $posts as $post ) {
1591 $product = get_product( $post->ID );
1592 $found_products[ $post->ID ] = $product->get_formatted_name();
1593 }
1594 }
1595
1596 echo json_encode( $found_products );
1597 die();
1598 }
1599
1600 1601 1602 1603 1604
1605 public function json_search_customer_name( $query ) {
1606 global $wpdb;
1607
1608 $term = wc_clean( stripslashes( $_GET['term'] ) );
1609
1610 $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' ) ";
1611 $query->query_where .= $wpdb->prepare( " OR user_name.meta_value LIKE %s ", '%' . like_escape( $term ) . '%' );
1612 }
1613
1614 1615 1616
1617 public function term_ordering() {
1618 global $wpdb;
1619
1620 $id = (int) $_POST['id'];
1621 $next_id = isset( $_POST['nextid'] ) && (int) $_POST['nextid'] ? (int) $_POST['nextid'] : null;
1622 $taxonomy = isset( $_POST['thetaxonomy'] ) ? esc_attr( $_POST['thetaxonomy'] ) : null;
1623 $term = get_term_by('id', $id, $taxonomy);
1624
1625 if ( ! $id || ! $term || ! $taxonomy ) {
1626 die(0);
1627 }
1628
1629 wc_reorder_terms( $term, $next_id, $taxonomy );
1630
1631 $children = get_terms( $taxonomy, "child_of=$id&menu_order=ASC&hide_empty=0" );
1632
1633 if ( $term && sizeof( $children ) ) {
1634 echo 'children';
1635 die();
1636 }
1637 }
1638
1639 1640 1641 1642 1643
1644 public function product_ordering() {
1645 global $wpdb;
1646
1647
1648 if ( ! current_user_can('edit_products') || empty( $_POST['id'] ) || ( ! isset( $_POST['previd'] ) && ! isset( $_POST['nextid'] ) ) ) {
1649 die(-1);
1650 }
1651
1652
1653 if ( ! $post = get_post( $_POST['id'] ) ) {
1654 die(-1);
1655 }
1656
1657 $this->json_headers();
1658
1659 $previd = isset( $_POST['previd'] ) ? $_POST['previd'] : false;
1660 $nextid = isset( $_POST['nextid'] ) ? $_POST['nextid'] : false;
1661 $new_pos = array();
1662
1663 $siblings = $wpdb->get_results( $wpdb->prepare('
1664 SELECT ID, menu_order FROM %1$s AS posts
1665 WHERE posts.post_type = \'product\'
1666 AND posts.post_status IN ( \'publish\', \'pending\', \'draft\', \'future\', \'private\' )
1667 AND posts.ID NOT IN (%2$d)
1668 ORDER BY posts.menu_order ASC, posts.ID DESC
1669 ', $wpdb->posts, $post->ID) );
1670
1671 $menu_order = 0;
1672
1673 foreach ( $siblings as $sibling ) {
1674
1675
1676 if ( $nextid == $sibling->ID ) {
1677 $wpdb->update(
1678 $wpdb->posts,
1679 array(
1680 'menu_order' => $menu_order
1681 ),
1682 array( 'ID' => $post->ID ),
1683 array( '%d' ),
1684 array( '%d' )
1685 );
1686 $new_pos[ $post->ID ] = $menu_order;
1687 $menu_order++;
1688 }
1689
1690
1691 if ( isset( $new_pos[ $post->ID ] ) && $sibling->menu_order >= $menu_order ) {
1692 break;
1693 }
1694
1695
1696 $wpdb->update(
1697 $wpdb->posts,
1698 array(
1699 'menu_order' => $menu_order
1700 ),
1701 array( 'ID' => $sibling->ID ),
1702 array( '%d' ),
1703 array( '%d' )
1704 );
1705 $new_pos[ $sibling->ID ] = $menu_order;
1706 $menu_order++;
1707
1708 if ( ! $nextid && $previd == $sibling->ID ) {
1709 $wpdb->update(
1710 $wpdb->posts,
1711 array(
1712 'menu_order' => $menu_order
1713 ),
1714 array( 'ID' => $post->ID ),
1715 array( '%d' ),
1716 array( '%d' )
1717 );
1718 $new_pos[$post->ID] = $menu_order;
1719 $menu_order++;
1720 }
1721
1722 }
1723
1724 die( json_encode( $new_pos ) );
1725 }
1726 }
1727
1728 new WC_AJAX();
1729