2013-11-14 12:13:34 +00:00
< ? php
2014-05-28 13:52:50 +00:00
if ( ! defined ( 'ABSPATH' ) ) {
exit ; // Exit if accessed directly
}
2013-11-14 12:13:34 +00:00
/**
* WooCommerce WC_AJAX
*
* AJAX Event Handler
*
2015-07-02 20:42:22 +00:00
* @ class WC_AJAX
* @ version 2.4 . 0
* @ package WooCommerce / Classes
* @ category Class
* @ author WooThemes
2013-11-14 12:13:34 +00:00
*/
class WC_AJAX {
/**
2015-03-20 12:28:26 +00:00
* Hook in ajax handlers
2013-11-14 12:13:34 +00:00
*/
2014-05-28 13:52:50 +00:00
public static function init () {
2015-03-20 12:28:26 +00:00
add_action ( 'init' , array ( __CLASS__ , 'add_endpoint' ) );
2015-04-09 11:47:37 +00:00
add_action ( 'template_redirect' , array ( __CLASS__ , 'do_wc_ajax' ), 0 );
2013-11-14 12:13:34 +00:00
2015-03-20 12:28:26 +00:00
self :: add_ajax_events ();
}
/**
* Add our endpoint for frontend ajax requests
*/
public static function add_endpoint () {
add_rewrite_tag ( '%wc-ajax%' , '([^/]*)' );
2015-03-20 14:20:12 +00:00
add_rewrite_rule ( 'wc-ajax/([^/]*)/?' , 'index.php?wc-ajax=$matches[1]' , 'top' );
2015-06-23 10:45:04 +00:00
add_rewrite_rule ( 'index.php/wc-ajax/([^/]*)/?' , 'index.php?wc-ajax=$matches[1]' , 'top' );
2015-03-20 12:28:26 +00:00
}
/**
* Get WC Ajax Endpoint
* @ param string $request Optional
* @ return string
*/
2015-06-19 12:30:57 +00:00
public static function get_endpoint ( $request = '' ) {
2015-03-20 12:28:26 +00:00
if ( strstr ( get_option ( 'permalink_structure' ), '/index.php/' ) ) {
2015-06-19 12:30:57 +00:00
$endpoint = trailingslashit ( home_url ( '/index.php/wc-ajax/' . $request , 'relative' ) );
2015-03-20 12:28:26 +00:00
} elseif ( get_option ( 'permalink_structure' ) ) {
2015-06-19 12:30:57 +00:00
$endpoint = trailingslashit ( home_url ( '/wc-ajax/' . $request , 'relative' ) );
2015-03-20 12:28:26 +00:00
} else {
2015-06-19 12:30:57 +00:00
$endpoint = add_query_arg ( 'wc-ajax=' , $request , trailingslashit ( home_url ( '' , 'relative' ) ) );
2015-03-20 12:28:26 +00:00
}
return esc_url_raw ( $endpoint );
}
/**
* Check for WC Ajax request and fire action
*/
public static function do_wc_ajax () {
global $wp_query ;
2015-03-20 13:10:47 +00:00
if ( ! empty ( $_GET [ 'wc-ajax' ] ) ) {
$wp_query -> set ( 'wc-ajax' , sanitize_text_field ( $_GET [ 'wc-ajax' ] ) );
}
2015-07-07 01:50:35 +00:00
if ( $action = $wp_query -> get ( 'wc-ajax' ) ) {
if ( ! defined ( 'DOING_AJAX' ) ) {
2015-03-20 12:28:26 +00:00
define ( 'DOING_AJAX' , true );
}
2015-07-07 01:50:35 +00:00
do_action ( 'wc_ajax_' . sanitize_text_field ( $action ) );
die ();
}
2015-03-20 12:28:26 +00:00
}
/**
* Hook in methods - uses WordPress ajax handlers ( admin - ajax )
*/
public static function add_ajax_events () {
2013-11-14 12:13:34 +00:00
// woocommerce_EVENT => nopriv
$ajax_events = array (
2014-07-10 12:33:05 +00:00
'get_refreshed_fragments' => true ,
'apply_coupon' => true ,
2014-12-08 06:15:03 +00:00
'remove_coupon' => true ,
2014-07-10 12:33:05 +00:00
'update_shipping_method' => true ,
'update_order_review' => true ,
'add_to_cart' => true ,
'checkout' => true ,
2015-07-09 14:56:20 +00:00
'get_variation' => true ,
2014-07-10 12:33:05 +00:00
'feature_product' => false ,
2014-11-19 12:13:24 +00:00
'mark_order_status' => false ,
2014-12-22 14:16:12 +00:00
'add_attribute' => false ,
2014-07-10 12:33:05 +00:00
'add_new_attribute' => false ,
'remove_variation' => false ,
'remove_variations' => false ,
'save_attributes' => false ,
'add_variation' => false ,
'link_all_variations' => false ,
'revoke_access_to_download' => false ,
'grant_access_to_download' => false ,
'get_customer_details' => false ,
'add_order_item' => false ,
'add_order_fee' => false ,
2014-07-16 18:41:18 +00:00
'add_order_shipping' => false ,
2014-07-21 01:36:12 +00:00
'add_order_tax' => false ,
2014-07-10 12:33:05 +00:00
'remove_order_item' => false ,
2014-08-27 20:03:49 +00:00
'remove_order_tax' => false ,
2014-07-10 12:33:05 +00:00
'reduce_order_item_stock' => false ,
'increase_order_item_stock' => false ,
'add_order_item_meta' => false ,
'remove_order_item_meta' => false ,
'calc_line_taxes' => false ,
2014-07-17 20:17:54 +00:00
'save_order_items' => false ,
'load_order_items' => false ,
2014-07-10 12:33:05 +00:00
'add_order_note' => false ,
'delete_order_note' => false ,
'json_search_products' => false ,
'json_search_products_and_variations' => false ,
2015-07-08 21:38:17 +00:00
'json_search_grouped_products' => false ,
2014-07-10 12:33:05 +00:00
'json_search_downloadable_products_and_variations' => false ,
'json_search_customers' => false ,
'term_ordering' => false ,
'product_ordering' => false ,
2014-07-10 15:39:10 +00:00
'refund_line_items' => false ,
2015-02-19 11:38:35 +00:00
'delete_refund' => false ,
2015-06-08 22:41:35 +00:00
'rated' => false ,
2015-06-17 11:12:49 +00:00
'update_api_key' => false ,
2015-07-02 20:42:22 +00:00
'get_customer_location' => true ,
2015-07-06 04:50:20 +00:00
'load_variations' => false ,
2015-07-07 01:50:35 +00:00
'save_variations' => false ,
'bulk_edit_variations' => false
2013-11-14 12:13:34 +00:00
);
2014-01-26 09:19:17 +00:00
2013-11-14 12:13:34 +00:00
foreach ( $ajax_events as $ajax_event => $nopriv ) {
2014-05-28 13:52:50 +00:00
add_action ( 'wp_ajax_woocommerce_' . $ajax_event , array ( __CLASS__ , $ajax_event ) );
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( $nopriv ) {
2014-05-28 13:52:50 +00:00
add_action ( 'wp_ajax_nopriv_woocommerce_' . $ajax_event , array ( __CLASS__ , $ajax_event ) );
2015-03-20 12:28:26 +00:00
// WC AJAX can be used for frontend ajax requests
add_action ( 'wc_ajax_' . $ajax_event , array ( __CLASS__ , $ajax_event ) );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
}
}
/**
* Get a refreshed cart fragment
*/
2014-05-28 13:52:50 +00:00
public static function get_refreshed_fragments () {
2014-01-26 09:19:17 +00:00
2013-11-14 12:13:34 +00:00
// Get mini cart
ob_start ();
2013-11-25 14:16:26 +00:00
woocommerce_mini_cart ();
2013-11-14 12:13:34 +00:00
$mini_cart = ob_get_clean ();
// Fragments and mini cart are returned
$data = array (
2014-10-20 15:12:35 +00:00
'fragments' => apply_filters ( 'woocommerce_add_to_cart_fragments' , array (
2013-11-14 12:13:34 +00:00
'div.widget_shopping_cart_content' => '<div class="widget_shopping_cart_content">' . $mini_cart . '</div>'
)
),
2015-03-20 13:00:05 +00:00
'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 () )
2013-11-14 12:13:34 +00:00
);
2014-05-31 07:32:22 +00:00
wp_send_json ( $data );
2013-11-14 12:13:34 +00:00
}
/**
* AJAX apply coupon on checkout page
*/
2014-05-28 13:52:50 +00:00
public static function apply_coupon () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'apply-coupon' , 'security' );
if ( ! empty ( $_POST [ 'coupon_code' ] ) ) {
WC () -> cart -> add_discount ( sanitize_text_field ( $_POST [ 'coupon_code' ] ) );
} else {
2013-11-18 11:44:22 +00:00
wc_add_notice ( WC_Coupon :: get_generic_coupon_error ( WC_Coupon :: E_WC_COUPON_PLEASE_ENTER ), 'error' );
2013-11-14 12:13:34 +00:00
}
2013-11-18 11:44:22 +00:00
wc_print_notices ();
2013-11-14 12:13:34 +00:00
die ();
}
2014-12-08 06:15:03 +00:00
/**
* AJAX remove coupon on cart and checkout page
*/
public static function remove_coupon () {
check_ajax_referer ( 'remove-coupon' , 'security' );
$coupon = wc_clean ( $_POST [ 'coupon' ] );
if ( ! isset ( $coupon ) || empty ( $coupon ) ) {
wc_add_notice ( __ ( 'Sorry there was a problem removing this coupon.' , 'woocommerce' ) );
} else {
WC () -> cart -> remove_coupon ( $coupon );
wc_add_notice ( __ ( 'Coupon has been removed.' , 'woocommerce' ) );
}
wc_print_notices ();
die ();
}
2013-11-14 12:13:34 +00:00
/**
* AJAX update shipping method on cart page
*/
2014-05-28 13:52:50 +00:00
public static function update_shipping_method () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'update-shipping-method' , 'security' );
2014-05-12 13:04:36 +00:00
if ( ! defined ( 'WOOCOMMERCE_CART' ) ) {
define ( 'WOOCOMMERCE_CART' , true );
}
2013-11-14 12:13:34 +00:00
$chosen_shipping_methods = WC () -> session -> get ( 'chosen_shipping_methods' );
2014-04-25 11:30:39 +00:00
if ( isset ( $_POST [ 'shipping_method' ] ) && is_array ( $_POST [ 'shipping_method' ] ) ) {
foreach ( $_POST [ 'shipping_method' ] as $i => $value ) {
2013-11-25 13:34:21 +00:00
$chosen_shipping_methods [ $i ] = wc_clean ( $value );
2014-04-25 11:30:39 +00:00
}
}
2013-11-14 12:13:34 +00:00
WC () -> session -> set ( 'chosen_shipping_methods' , $chosen_shipping_methods );
WC () -> cart -> calculate_totals ();
2013-11-25 14:16:26 +00:00
woocommerce_cart_totals ();
2013-11-14 12:13:34 +00:00
die ();
}
/**
* AJAX update order review on checkout
*/
2014-05-28 13:52:50 +00:00
public static function update_order_review () {
2014-11-26 14:19:53 +00:00
ob_start ();
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'update-order-review' , 'security' );
2014-05-12 13:04:36 +00:00
if ( ! defined ( 'WOOCOMMERCE_CHECKOUT' ) ) {
2013-11-14 12:13:34 +00:00
define ( 'WOOCOMMERCE_CHECKOUT' , true );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2015-05-14 21:18:53 +00:00
if ( WC () -> cart -> is_empty () ) {
2014-11-26 14:19:53 +00:00
$data = array (
'fragments' => apply_filters ( 'woocommerce_update_order_review_fragments' , array (
2015-01-27 22:14:17 +00:00
'form.woocommerce-checkout' => '<div class="woocommerce-error">' . __ ( 'Sorry, your session has expired.' , 'woocommerce' ) . ' <a href="' . home_url () . '" class="wc-backward">' . __ ( 'Return to homepage' , 'woocommerce' ) . '</a></div>'
2014-11-26 14:19:53 +00:00
) )
);
wp_send_json ( $data );
2013-11-14 12:13:34 +00:00
die ();
}
do_action ( 'woocommerce_checkout_update_order_review' , $_POST [ 'post_data' ] );
$chosen_shipping_methods = WC () -> session -> get ( 'chosen_shipping_methods' );
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'shipping_method' ] ) && is_array ( $_POST [ 'shipping_method' ] ) ) {
foreach ( $_POST [ 'shipping_method' ] as $i => $value ) {
2013-11-25 13:34:21 +00:00
$chosen_shipping_methods [ $i ] = wc_clean ( $value );
2014-05-12 13:04:36 +00:00
}
}
2013-11-14 12:13:34 +00:00
WC () -> session -> set ( 'chosen_shipping_methods' , $chosen_shipping_methods );
WC () -> session -> set ( 'chosen_payment_method' , empty ( $_POST [ 'payment_method' ] ) ? '' : $_POST [ 'payment_method' ] );
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'country' ] ) ) {
2013-11-14 12:13:34 +00:00
WC () -> customer -> set_country ( $_POST [ 'country' ] );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'state' ] ) ) {
2013-11-14 12:13:34 +00:00
WC () -> customer -> set_state ( $_POST [ 'state' ] );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'postcode' ] ) ) {
2013-11-14 12:13:34 +00:00
WC () -> customer -> set_postcode ( $_POST [ 'postcode' ] );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'city' ] ) ) {
2013-11-14 12:13:34 +00:00
WC () -> customer -> set_city ( $_POST [ 'city' ] );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'address' ] ) ) {
2013-11-14 12:13:34 +00:00
WC () -> customer -> set_address ( $_POST [ 'address' ] );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'address_2' ] ) ) {
2013-11-14 12:13:34 +00:00
WC () -> customer -> set_address_2 ( $_POST [ 'address_2' ] );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-04-08 15:28:27 +00:00
if ( wc_ship_to_billing_address_only () ) {
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'country' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_country ( $_POST [ 'country' ] );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'state' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_state ( $_POST [ 'state' ] );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'postcode' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_postcode ( $_POST [ 'postcode' ] );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'city' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_city ( $_POST [ 'city' ] );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'address' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_address ( $_POST [ 'address' ] );
2014-05-12 13:04:36 +00:00
}
2014-02-14 11:19:32 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 'address_2' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_address_2 ( $_POST [ 'address_2' ] );
2014-05-12 13:04:36 +00:00
}
2014-02-14 11:19:32 +00:00
} else {
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 's_country' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_country ( $_POST [ 's_country' ] );
2014-05-12 13:04:36 +00:00
}
2014-02-14 11:19:32 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 's_state' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_state ( $_POST [ 's_state' ] );
2014-05-12 13:04:36 +00:00
}
2014-02-14 11:19:32 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 's_postcode' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_postcode ( $_POST [ 's_postcode' ] );
2014-05-12 13:04:36 +00:00
}
2014-02-14 11:19:32 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 's_city' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_city ( $_POST [ 's_city' ] );
2014-05-12 13:04:36 +00:00
}
2014-02-14 11:19:32 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 's_address' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_address ( $_POST [ 's_address' ] );
2014-05-12 13:04:36 +00:00
}
2014-02-14 11:19:32 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $_POST [ 's_address_2' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_address_2 ( $_POST [ 's_address_2' ] );
2014-05-12 13:04:36 +00:00
}
2014-02-14 11:19:32 +00:00
}
2013-11-14 12:13:34 +00:00
WC () -> cart -> calculate_totals ();
2014-12-04 08:40:49 +00:00
// Get order review fragment
2014-11-26 14:19:53 +00:00
ob_start ();
woocommerce_order_review ();
$woocommerce_order_review = ob_get_clean ();
2015-01-27 22:41:33 +00:00
// Get checkout payment fragment
2014-11-26 14:19:53 +00:00
ob_start ();
woocommerce_checkout_payment ();
$woocommerce_checkout_payment = ob_get_clean ();
2014-12-04 08:40:49 +00:00
// Get messages if reload checkout is not true
$messages = '' ;
if ( ! isset ( WC () -> session -> reload_checkout ) ) {
ob_start ();
wc_print_notices ();
$messages = ob_get_clean ();
}
2014-11-26 14:19:53 +00:00
$data = array (
2014-12-04 08:40:49 +00:00
'result' => empty ( $messages ) ? 'success' : 'failure' ,
'messages' => $messages ,
'reload' => isset ( WC () -> session -> reload_checkout ) ? 'true' : 'false' ,
2014-11-26 14:19:53 +00:00
'fragments' => apply_filters ( 'woocommerce_update_order_review_fragments' , array (
'.woocommerce-checkout-review-order-table' => $woocommerce_order_review ,
'.woocommerce-checkout-payment' => $woocommerce_checkout_payment
) )
);
wp_send_json ( $data );
2013-11-14 12:13:34 +00:00
die ();
}
/**
* AJAX add to cart
*/
2014-05-28 13:52:50 +00:00
public static function add_to_cart () {
2014-09-16 12:24:02 +00:00
ob_start ();
2013-11-14 12:13:34 +00:00
$product_id = apply_filters ( 'woocommerce_add_to_cart_product_id' , absint ( $_POST [ 'product_id' ] ) );
2014-06-25 10:25:28 +00:00
$quantity = empty ( $_POST [ 'quantity' ] ) ? 1 : wc_stock_amount ( $_POST [ 'quantity' ] );
2013-11-14 12:13:34 +00:00
$passed_validation = apply_filters ( 'woocommerce_add_to_cart_validation' , true , $product_id , $quantity );
2015-01-29 18:30:07 +00:00
$product_status = get_post_status ( $product_id );
2013-11-14 12:13:34 +00:00
2015-01-29 18:30:07 +00:00
if ( $passed_validation && WC () -> cart -> add_to_cart ( $product_id , $quantity ) && 'publish' === $product_status ) {
2013-11-14 12:13:34 +00:00
do_action ( 'woocommerce_ajax_added_to_cart' , $product_id );
if ( get_option ( 'woocommerce_cart_redirect_after_add' ) == 'yes' ) {
2013-11-25 12:44:32 +00:00
wc_add_to_cart_message ( $product_id );
2013-11-14 12:13:34 +00:00
}
// Return fragments
2014-05-28 13:52:50 +00:00
self :: get_refreshed_fragments ();
2013-11-14 12:13:34 +00:00
} else {
// If there was an error adding to the cart, redirect to the product page to show any errors
$data = array (
2015-01-29 18:30:07 +00:00
'error' => true ,
2013-11-14 12:13:34 +00:00
'product_url' => apply_filters ( 'woocommerce_cart_redirect_after_error' , get_permalink ( $product_id ), $product_id )
);
2014-05-31 07:32:22 +00:00
wp_send_json ( $data );
2013-11-14 12:13:34 +00:00
}
die ();
}
/**
* Process ajax checkout form
*/
2014-05-28 13:52:50 +00:00
public static function checkout () {
2014-05-12 13:04:36 +00:00
if ( ! defined ( 'WOOCOMMERCE_CHECKOUT' ) ) {
2013-11-14 12:13:34 +00:00
define ( 'WOOCOMMERCE_CHECKOUT' , true );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-28 13:52:50 +00:00
WC () -> checkout () -> process_checkout ();
2013-11-14 12:13:34 +00:00
die ( 0 );
}
2015-07-09 14:56:20 +00:00
/**
* Get a matching variation based on posted attributes
*/
public static function get_variation () {
ob_start ();
if ( empty ( $_POST [ 'product_id' ] ) || ! ( $variable_product = wc_get_product ( absint ( $_POST [ 'product_id' ] ), array ( 'product_type' => 'variable' ) ) ) ) {
die ();
}
$variation_id = $variable_product -> get_matching_variation ( $_POST );
if ( $variation_id ) {
$variation = $variable_product -> get_available_variation ( $variation_id );
} else {
$variation = false ;
}
wp_send_json ( $variation );
die ();
}
2013-11-14 12:13:34 +00:00
/**
* Feature a product from admin
*/
2014-05-28 13:52:50 +00:00
public static function feature_product () {
2014-11-27 15:40:39 +00:00
if ( current_user_can ( 'edit_products' ) && check_admin_referer ( 'woocommerce-feature-product' ) ) {
$product_id = absint ( $_GET [ 'product_id' ] );
2013-11-14 12:13:34 +00:00
2014-11-27 15:40:39 +00:00
if ( 'product' === get_post_type ( $product_id ) ) {
update_post_meta ( $product_id , '_featured' , get_post_meta ( $product_id , '_featured' , true ) === 'yes' ? 'no' : 'yes' );
2013-11-14 12:13:34 +00:00
2014-11-27 15:40:39 +00:00
delete_transient ( 'wc_featured_products' );
}
2014-04-04 13:16:11 +00:00
}
2013-11-14 12:13:34 +00:00
2014-10-23 11:13:42 +00:00
wp_safe_redirect ( wp_get_referer () ? remove_query_arg ( array ( 'trashed' , 'untrashed' , 'deleted' , 'ids' ), wp_get_referer () ) : admin_url ( 'edit.php?post_type=shop_order' ) );
2013-11-14 12:13:34 +00:00
die ();
}
/**
2014-11-19 12:13:24 +00:00
* Mark an order with a status
2013-11-14 12:13:34 +00:00
*/
2014-11-19 12:13:24 +00:00
public static function mark_order_status () {
2014-11-27 15:37:42 +00:00
if ( current_user_can ( 'edit_shop_orders' ) && check_admin_referer ( 'woocommerce-mark-order-status' ) ) {
$status = sanitize_text_field ( $_GET [ 'status' ] );
$order_id = absint ( $_GET [ 'order_id' ] );
2014-05-12 13:04:36 +00:00
2014-11-27 15:37:42 +00:00
if ( wc_is_order_status ( 'wc-' . $status ) && $order_id ) {
$order = wc_get_order ( $order_id );
$order -> update_status ( $status );
2015-06-05 16:43:24 +00:00
do_action ( 'woocommerce_order_edit_status' , $order_id , $status );
2014-11-27 15:37:42 +00:00
}
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-10-23 11:13:42 +00:00
wp_safe_redirect ( wp_get_referer () ? wp_get_referer () : admin_url ( 'edit.php?post_type=shop_order' ) );
2013-11-14 12:13:34 +00:00
die ();
}
2014-12-22 14:16:12 +00:00
/**
* Add an attribute row
*/
public static function add_attribute () {
ob_start ();
check_ajax_referer ( 'add-attribute' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_products' ) ) {
die ( - 1 );
}
2014-12-22 14:16:12 +00:00
global $wc_product_attributes ;
2015-01-19 13:38:47 +00:00
$thepostid = 0 ;
$taxonomy = sanitize_text_field ( $_POST [ 'taxonomy' ] );
$i = absint ( $_POST [ 'i' ] );
$position = 0 ;
$metabox_class = array ();
$attribute = array (
2014-12-22 14:16:12 +00:00
'name' => $taxonomy ,
'value' => '' ,
2015-02-26 16:23:19 +00:00
'is_visible' => apply_filters ( 'woocommerce_attribute_default_visibility' , 1 ),
2014-12-22 14:16:12 +00:00
'is_variation' => 0 ,
'is_taxonomy' => $taxonomy ? 1 : 0
);
if ( $taxonomy ) {
$attribute_taxonomy = $wc_product_attributes [ $taxonomy ];
$metabox_class [] = 'taxonomy' ;
$metabox_class [] = $taxonomy ;
$attribute_label = wc_attribute_label ( $taxonomy );
} else {
2015-01-19 13:38:47 +00:00
$attribute_label = '' ;
2014-12-22 14:16:12 +00:00
}
include ( 'admin/meta-boxes/views/html-product-attribute.php' );
die ();
}
2013-11-14 12:13:34 +00:00
/**
* Add a new attribute via ajax function
*/
2014-05-28 13:52:50 +00:00
public static function add_new_attribute () {
2014-09-16 12:24:02 +00:00
ob_start ();
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'add-attribute' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'manage_product_terms' ) ) {
die ( - 1 );
}
2013-11-14 12:13:34 +00:00
$taxonomy = esc_attr ( $_POST [ 'taxonomy' ] );
2015-03-13 09:21:55 +00:00
$term = wc_clean ( $_POST [ 'term' ] );
2013-11-14 12:13:34 +00:00
if ( taxonomy_exists ( $taxonomy ) ) {
$result = wp_insert_term ( $term , $taxonomy );
2014-05-12 13:04:36 +00:00
if ( is_wp_error ( $result ) ) {
2014-05-31 07:32:22 +00:00
wp_send_json ( array (
2014-05-12 13:04:36 +00:00
'error' => $result -> get_error_message ()
2014-05-31 07:32:22 +00:00
) );
2014-05-12 13:04:36 +00:00
} else {
2015-03-13 09:21:55 +00:00
$term = get_term_by ( 'id' , $result [ 'term_id' ], $taxonomy );
2014-05-31 07:32:22 +00:00
wp_send_json ( array (
2015-03-13 09:21:55 +00:00
'term_id' => $term -> term_id ,
'name' => $term -> name ,
'slug' => $term -> slug
2014-05-31 07:32:22 +00:00
) );
2013-11-14 12:13:34 +00:00
}
}
die ();
}
/**
* Delete variations via ajax function
*/
2014-05-28 13:52:50 +00:00
public static function remove_variations () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'delete-variations' , 'security' );
2014-05-12 13:04:36 +00:00
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_products' ) ) {
die ( - 1 );
}
2013-11-14 12:13:34 +00:00
$variation_ids = ( array ) $_POST [ 'variation_ids' ];
2014-05-12 13:04:36 +00:00
2013-11-14 12:13:34 +00:00
foreach ( $variation_ids as $variation_id ) {
2014-05-12 13:04:36 +00:00
$variation = get_post ( $variation_id );
if ( $variation && 'product_variation' == $variation -> post_type ) {
2013-11-14 12:13:34 +00:00
wp_delete_post ( $variation_id );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
}
2014-05-12 13:04:36 +00:00
2013-11-14 12:13:34 +00:00
die ();
}
/**
* Save attributes via ajax
*/
2014-05-28 13:52:50 +00:00
public static function save_attributes () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'save-attributes' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_products' ) ) {
die ( - 1 );
}
2013-11-14 12:13:34 +00:00
// Get post data
parse_str ( $_POST [ 'data' ], $data );
$post_id = absint ( $_POST [ 'post_id' ] );
// Save Attributes
$attributes = array ();
if ( isset ( $data [ 'attribute_names' ] ) ) {
$attribute_names = array_map ( 'stripslashes' , $data [ 'attribute_names' ] );
2013-11-14 18:40:15 +00:00
$attribute_values = isset ( $data [ 'attribute_values' ] ) ? $data [ 'attribute_values' ] : array ();
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $data [ 'attribute_visibility' ] ) ) {
2013-11-14 12:13:34 +00:00
$attribute_visibility = $data [ 'attribute_visibility' ];
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( isset ( $data [ 'attribute_variation' ] ) ) {
2013-11-14 12:13:34 +00:00
$attribute_variation = $data [ 'attribute_variation' ];
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2015-05-19 16:46:32 +00:00
$attribute_is_taxonomy = $data [ 'attribute_is_taxonomy' ];
$attribute_position = $data [ 'attribute_position' ];
2015-06-05 12:37:45 +00:00
$attribute_names_max_key = max ( array_keys ( $attribute_names ) );
2013-11-14 12:13:34 +00:00
2015-05-19 16:53:00 +00:00
for ( $i = 0 ; $i <= $attribute_names_max_key ; $i ++ ) {
2015-05-19 16:46:32 +00:00
if ( empty ( $attribute_names [ $i ] ) ) {
2013-11-14 12:13:34 +00:00
continue ;
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
$is_visible = isset ( $attribute_visibility [ $i ] ) ? 1 : 0 ;
$is_variation = isset ( $attribute_variation [ $i ] ) ? 1 : 0 ;
$is_taxonomy = $attribute_is_taxonomy [ $i ] ? 1 : 0 ;
2013-11-14 12:13:34 +00:00
if ( $is_taxonomy ) {
if ( isset ( $attribute_values [ $i ] ) ) {
2014-05-12 13:04:36 +00:00
// Select based attributes - Format values (posted values are slugs)
if ( is_array ( $attribute_values [ $i ] ) ) {
$values = array_map ( 'sanitize_title' , $attribute_values [ $i ] );
2015-04-10 13:50:23 +00:00
// Text based attributes - Posted values are term names, wp_set_object_terms wants ids or slugs.
2014-05-12 13:04:36 +00:00
} else {
2015-04-10 13:50:23 +00:00
$values = array ();
$raw_values = array_map ( 'stripslashes' , array_map ( 'strip_tags' , explode ( WC_DELIMITER , $attribute_values [ $i ] ) ) );
foreach ( $raw_values as $value ) {
$term = get_term_by ( 'name' , $value , $attribute_names [ $i ] );
if ( ! $term ) {
$term = wp_insert_term ( $value , $attribute_names [ $i ] );
if ( $term && ! is_wp_error ( $term ) ) {
$values [] = $term [ 'term_id' ];
}
} else {
$values [] = $term -> term_id ;
}
}
2014-05-12 13:04:36 +00:00
}
// Remove empty items in the array
$values = array_filter ( $values , 'strlen' );
} else {
$values = array ();
}
// Update post terms
if ( taxonomy_exists ( $attribute_names [ $i ] ) ) {
wp_set_object_terms ( $post_id , $values , $attribute_names [ $i ] );
}
if ( $values ) {
// Add attribute to array, but don't set values
$attributes [ sanitize_title ( $attribute_names [ $i ] ) ] = array (
'name' => wc_clean ( $attribute_names [ $i ] ),
'value' => '' ,
'position' => $attribute_position [ $i ],
'is_visible' => $is_visible ,
'is_variation' => $is_variation ,
'is_taxonomy' => $is_taxonomy
);
}
} elseif ( isset ( $attribute_values [ $i ] ) ) {
// Text based, separate by pipe
2015-06-11 13:43:02 +00:00
$values = implode ( ' ' . WC_DELIMITER . ' ' , array_map ( 'wc_clean' , wc_get_text_attributes ( $attribute_values [ $i ] ) ) );
2014-05-12 13:04:36 +00:00
// Custom attribute - Add attribute to array and set the values
$attributes [ sanitize_title ( $attribute_names [ $i ] ) ] = array (
'name' => wc_clean ( $attribute_names [ $i ] ),
'value' => $values ,
'position' => $attribute_position [ $i ],
'is_visible' => $is_visible ,
'is_variation' => $is_variation ,
'is_taxonomy' => $is_taxonomy
);
}
2013-11-14 12:13:34 +00:00
}
}
if ( ! function_exists ( 'attributes_cmp' ) ) {
function attributes_cmp ( $a , $b ) {
2014-05-12 13:04:36 +00:00
if ( $a [ 'position' ] == $b [ 'position' ] ) {
return 0 ;
}
return ( $a [ 'position' ] < $b [ 'position' ] ) ? - 1 : 1 ;
2013-11-14 12:13:34 +00:00
}
}
uasort ( $attributes , 'attributes_cmp' );
update_post_meta ( $post_id , '_product_attributes' , $attributes );
die ();
}
/**
* Add variation via ajax function
*/
2014-05-28 13:52:50 +00:00
public static function add_variation () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'add-variation' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_products' ) ) {
die ( - 1 );
}
2013-11-14 12:13:34 +00:00
$post_id = intval ( $_POST [ 'post_id' ] );
$loop = intval ( $_POST [ 'loop' ] );
$variation = array (
2014-05-12 13:04:36 +00:00
'post_title' => 'Product #' . $post_id . ' Variation' ,
'post_content' => '' ,
'post_status' => 'publish' ,
'post_author' => get_current_user_id (),
'post_parent' => $post_id ,
'post_type' => 'product_variation'
2013-11-14 12:13:34 +00:00
);
$variation_id = wp_insert_post ( $variation );
do_action ( 'woocommerce_create_product_variation' , $variation_id );
if ( $variation_id ) {
$variation_post_status = 'publish' ;
$variation_data = get_post_meta ( $variation_id );
$variation_data [ 'variation_post_id' ] = $variation_id ;
// Get attributes
$attributes = ( array ) maybe_unserialize ( get_post_meta ( $post_id , '_product_attributes' , true ) );
// Get tax classes
2014-11-21 13:06:30 +00:00
$tax_classes = WC_Tax :: get_tax_classes ();
2014-05-12 13:04:36 +00:00
$tax_class_options = array ();
$tax_class_options [ '' ] = __ ( 'Standard' , 'woocommerce' );
if ( $tax_classes ) {
foreach ( $tax_classes as $class ) {
$tax_class_options [ sanitize_title ( $class ) ] = $class ;
}
}
2013-11-14 12:13:34 +00:00
2014-08-13 14:03:30 +00:00
$backorder_options = array (
'no' => __ ( 'Do not allow' , 'woocommerce' ),
'notify' => __ ( 'Allow, but notify customer' , 'woocommerce' ),
'yes' => __ ( 'Allow' , 'woocommerce' )
);
$stock_status_options = array (
'instock' => __ ( 'In stock' , 'woocommerce' ),
'outofstock' => __ ( 'Out of stock' , 'woocommerce' )
);
2014-08-21 17:00:39 +00:00
2013-11-14 12:13:34 +00:00
// Get parent data
$parent_data = array (
2014-08-13 14:03:30 +00:00
'id' => $post_id ,
'attributes' => $attributes ,
'tax_class_options' => $tax_class_options ,
'sku' => get_post_meta ( $post_id , '_sku' , true ),
'weight' => get_post_meta ( $post_id , '_weight' , true ),
'length' => get_post_meta ( $post_id , '_length' , true ),
'width' => get_post_meta ( $post_id , '_width' , true ),
'height' => get_post_meta ( $post_id , '_height' , true ),
'tax_class' => get_post_meta ( $post_id , '_tax_class' , true ),
'backorder_options' => $backorder_options ,
'stock_status_options' => $stock_status_options
2013-11-14 12:13:34 +00:00
);
2014-05-12 13:04:36 +00:00
if ( ! $parent_data [ 'weight' ] ) {
2013-11-14 12:13:34 +00:00
$parent_data [ 'weight' ] = '0.00' ;
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( ! $parent_data [ 'length' ] ) {
2013-11-14 12:13:34 +00:00
$parent_data [ 'length' ] = '0' ;
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( ! $parent_data [ 'width' ] ) {
2013-11-14 12:13:34 +00:00
$parent_data [ 'width' ] = '0' ;
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( ! $parent_data [ 'height' ] ) {
2013-11-14 12:13:34 +00:00
$parent_data [ 'height' ] = '0' ;
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2015-04-24 10:05:14 +00:00
$_tax_class = null ;
2013-11-14 12:13:34 +00:00
$_downloadable_files = '' ;
2014-09-11 21:16:37 +00:00
$_stock_status = '' ;
$_backorders = '' ;
2014-05-12 13:04:36 +00:00
$image_id = 0 ;
2015-02-04 14:04:02 +00:00
$_thumbnail_id = '' ;
2014-05-12 13:04:36 +00:00
$variation = get_post ( $variation_id ); // Get the variation object
2013-11-14 12:13:34 +00:00
2014-06-04 10:16:19 +00:00
include ( 'admin/meta-boxes/views/html-variation-admin.php' );
2013-11-14 12:13:34 +00:00
}
die ();
}
/**
* Link all variations via ajax function
*/
2014-05-28 13:52:50 +00:00
public static function link_all_variations () {
2013-11-14 12:13:34 +00:00
if ( ! defined ( 'WC_MAX_LINKED_VARIATIONS' ) ) {
define ( 'WC_MAX_LINKED_VARIATIONS' , 49 );
}
check_ajax_referer ( 'link-variations' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_products' ) ) {
die ( - 1 );
}
2013-11-14 12:13:34 +00:00
@ set_time_limit ( 0 );
$post_id = intval ( $_POST [ 'post_id' ] );
2014-05-12 13:04:36 +00:00
if ( ! $post_id ) {
die ();
}
2013-11-14 12:13:34 +00:00
$variations = array ();
2014-08-19 10:09:29 +00:00
$_product = wc_get_product ( $post_id , array ( 'product_type' => 'variable' ) );
2013-11-14 12:13:34 +00:00
// Put variation attributes into an array
foreach ( $_product -> get_attributes () as $attribute ) {
2014-05-12 13:04:36 +00:00
if ( ! $attribute [ 'is_variation' ] ) {
continue ;
}
2013-11-14 12:13:34 +00:00
$attribute_field_name = 'attribute_' . sanitize_title ( $attribute [ 'name' ] );
if ( $attribute [ 'is_taxonomy' ] ) {
2014-12-18 20:09:07 +00:00
$options = wc_get_product_terms ( $post_id , $attribute [ 'name' ], array ( 'fields' => 'slugs' ) );
2013-11-14 12:13:34 +00:00
} else {
$options = explode ( WC_DELIMITER , $attribute [ 'value' ] );
}
$options = array_map ( 'sanitize_title' , array_map ( 'trim' , $options ) );
$variations [ $attribute_field_name ] = $options ;
}
// Quit out if none were found
2014-05-12 13:04:36 +00:00
if ( sizeof ( $variations ) == 0 ) {
die ();
}
2013-11-14 12:13:34 +00:00
// Get existing variations so we don't create duplicates
2014-05-12 13:04:36 +00:00
$available_variations = array ();
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
foreach ( $_product -> get_children () as $child_id ) {
$child = $_product -> get_child ( $child_id );
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( ! empty ( $child -> variation_id ) ) {
$available_variations [] = $child -> get_variation_attributes ();
}
}
2013-11-14 12:13:34 +00:00
// Created posts will all have the following data
$variation_post_data = array (
2014-02-07 11:39:37 +00:00
'post_title' => 'Product #' . $post_id . ' Variation' ,
2013-11-14 12:13:34 +00:00
'post_content' => '' ,
2014-02-07 11:39:37 +00:00
'post_status' => 'publish' ,
'post_author' => get_current_user_id (),
'post_parent' => $post_id ,
'post_type' => 'product_variation'
2013-11-14 12:13:34 +00:00
);
// Now find all combinations and create posts
if ( ! function_exists ( 'array_cartesian' ) ) {
2014-05-12 13:04:36 +00:00
2013-11-28 17:59:09 +00:00
/**
* @ param array $input
* @ return array
*/
2013-11-14 12:13:34 +00:00
function array_cartesian ( $input ) {
2014-05-12 13:04:36 +00:00
$result = array ();
while ( list ( $key , $values ) = each ( $input ) ) {
// If a sub-array is empty, it doesn't affect the cartesian product
if ( empty ( $values ) ) {
continue ;
}
// Special case: seeding the product array with the values from the first sub-array
if ( empty ( $result ) ) {
foreach ( $values as $value ) {
$result [] = array ( $key => $value );
}
}
else {
// Second and subsequent input sub-arrays work like this:
// 1. In each existing array inside $product, add an item with
// key == $key and value == first item in input sub-array
// 2. Then, for each remaining item in current input sub-array,
// add a copy of each existing array inside $product with
// key == $key and value == first item in current input sub-array
// Store all items to be added to $product here; adding them on the spot
// inside the foreach will result in an infinite loop
$append = array ();
foreach ( $result as & $product ) {
// Do step 1 above. array_shift is not the most efficient, but it
// allows us to iterate over the rest of the items with a simple
// foreach, making the code short and familiar.
$product [ $key ] = array_shift ( $values );
// $product is by reference (that's why the key we added above
// will appear in the end result), so make a copy of it here
$copy = $product ;
// Do step 2 above.
foreach ( $values as $item ) {
$copy [ $key ] = $item ;
$append [] = $copy ;
}
// Undo the side effecst of array_shift
array_unshift ( $values , $product [ $key ] );
}
// Out of the foreach, we can add to $results now
$result = array_merge ( $result , $append );
}
}
return $result ;
2013-11-14 12:13:34 +00:00
}
}
2014-05-12 13:04:36 +00:00
$variation_ids = array ();
$added = 0 ;
2013-11-14 12:13:34 +00:00
$possible_variations = array_cartesian ( $variations );
foreach ( $possible_variations as $variation ) {
// Check if variation already exists
2014-05-12 13:04:36 +00:00
if ( in_array ( $variation , $available_variations ) ) {
2013-11-14 12:13:34 +00:00
continue ;
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
$variation_id = wp_insert_post ( $variation_post_data );
$variation_ids [] = $variation_id ;
foreach ( $variation as $key => $value ) {
update_post_meta ( $variation_id , $key , $value );
}
2015-07-09 21:28:02 +00:00
// Save stock status
update_post_meta ( $variation_id , '_stock_status' , 'instock' );
2013-11-14 12:13:34 +00:00
$added ++ ;
do_action ( 'product_variation_linked' , $variation_id );
2014-05-12 13:04:36 +00:00
if ( $added > WC_MAX_LINKED_VARIATIONS ) {
2013-11-14 12:13:34 +00:00
break ;
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
}
2015-07-09 15:02:26 +00:00
delete_transient ( 'wc_product_children_' . $post_id );
2013-11-14 12:13:34 +00:00
echo $added ;
die ();
}
/**
* Delete download permissions via ajax function
*/
2014-05-28 13:52:50 +00:00
public static function revoke_access_to_download () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'revoke-access' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2013-11-14 12:13:34 +00:00
global $wpdb ;
$download_id = $_POST [ 'download_id' ];
$product_id = intval ( $_POST [ 'product_id' ] );
$order_id = intval ( $_POST [ 'order_id' ] );
$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 ) );
do_action ( 'woocommerce_ajax_revoke_access_to_product_download' , $download_id , $product_id , $order_id );
die ();
}
/**
* Grant download permissions via ajax function
*/
2014-05-28 13:52:50 +00:00
public static function grant_access_to_download () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'grant-access' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2013-11-14 12:13:34 +00:00
global $wpdb ;
$wpdb -> hide_errors ();
2014-05-12 13:04:36 +00:00
$order_id = intval ( $_POST [ 'order_id' ] );
$product_ids = $_POST [ 'product_ids' ];
$loop = intval ( $_POST [ 'loop' ] );
$file_counter = 0 ;
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $order_id );
2013-11-14 12:13:34 +00:00
2013-11-26 13:54:34 +00:00
if ( ! is_array ( $product_ids ) ) {
$product_ids = array ( $product_ids );
}
2013-11-14 12:13:34 +00:00
2013-11-26 13:54:34 +00:00
foreach ( $product_ids as $product_id ) {
2014-08-19 10:09:29 +00:00
$product = wc_get_product ( $product_id );
2014-05-12 13:04:36 +00:00
$files = $product -> get_files ();
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( ! $order -> billing_email ) {
2013-11-26 13:54:34 +00:00
die ();
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2013-11-26 13:54:34 +00:00
if ( $files ) {
foreach ( $files as $download_id => $file ) {
if ( $inserted_id = wc_downloadable_file_permission ( $download_id , $product_id , $order ) ) {
2013-11-14 12:13:34 +00:00
2013-11-26 13:54:34 +00:00
// insert complete - get inserted data
$download = $wpdb -> get_row ( $wpdb -> prepare ( " SELECT * FROM { $wpdb -> prefix } woocommerce_downloadable_product_permissions WHERE permission_id = %d " , $inserted_id ) );
$loop ++ ;
$file_counter ++ ;
if ( isset ( $file [ 'name' ] ) ) {
$file_count = $file [ 'name' ];
} else {
$file_count = sprintf ( __ ( 'File %d' , 'woocommerce' ), $file_counter );
}
2014-06-04 10:16:19 +00:00
include ( 'admin/meta-boxes/views/html-order-download-permission.php' );
2013-11-26 13:54:34 +00:00
}
2013-11-14 12:13:34 +00:00
}
}
}
die ();
}
/**
* Get customer details via ajax
*/
2014-05-28 13:52:50 +00:00
public static function get_customer_details () {
2014-09-16 12:24:02 +00:00
ob_start ();
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'get-customer-details' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-05-12 13:04:36 +00:00
$user_id = ( int ) trim ( stripslashes ( $_POST [ 'user_id' ]));
2013-11-14 12:13:34 +00:00
$type_to_load = esc_attr ( trim ( stripslashes ( $_POST [ 'type_to_load' ])));
$customer_data = array (
$type_to_load . '_first_name' => get_user_meta ( $user_id , $type_to_load . '_first_name' , true ),
2014-05-12 13:04:36 +00:00
$type_to_load . '_last_name' => get_user_meta ( $user_id , $type_to_load . '_last_name' , true ),
$type_to_load . '_company' => get_user_meta ( $user_id , $type_to_load . '_company' , true ),
$type_to_load . '_address_1' => get_user_meta ( $user_id , $type_to_load . '_address_1' , true ),
$type_to_load . '_address_2' => get_user_meta ( $user_id , $type_to_load . '_address_2' , true ),
$type_to_load . '_city' => get_user_meta ( $user_id , $type_to_load . '_city' , true ),
$type_to_load . '_postcode' => get_user_meta ( $user_id , $type_to_load . '_postcode' , true ),
$type_to_load . '_country' => get_user_meta ( $user_id , $type_to_load . '_country' , true ),
$type_to_load . '_state' => get_user_meta ( $user_id , $type_to_load . '_state' , true ),
$type_to_load . '_email' => get_user_meta ( $user_id , $type_to_load . '_email' , true ),
$type_to_load . '_phone' => get_user_meta ( $user_id , $type_to_load . '_phone' , true ),
2013-11-14 12:13:34 +00:00
);
2014-09-29 07:13:56 +00:00
$customer_data = apply_filters ( 'woocommerce_found_customer_details' , $customer_data , $user_id , $type_to_load );
2013-11-14 12:13:34 +00:00
2014-05-31 07:32:22 +00:00
wp_send_json ( $customer_data );
2013-11-14 12:13:34 +00:00
}
/**
* Add order item via ajax
*/
2014-05-28 13:52:50 +00:00
public static function add_order_item () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2013-11-14 12:13:34 +00:00
$item_to_add = sanitize_text_field ( $_POST [ 'item_to_add' ] );
2014-05-12 13:04:36 +00:00
$order_id = absint ( $_POST [ 'order_id' ] );
2013-11-14 12:13:34 +00:00
// Find the item
2014-05-12 13:04:36 +00:00
if ( ! is_numeric ( $item_to_add ) ) {
2013-11-14 12:13:34 +00:00
die ();
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
$post = get_post ( $item_to_add );
2014-05-12 13:04:36 +00:00
if ( ! $post || ( 'product' !== $post -> post_type && 'product_variation' !== $post -> post_type ) ) {
2013-11-14 12:13:34 +00:00
die ();
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-08-19 10:09:29 +00:00
$_product = wc_get_product ( $post -> ID );
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $order_id );
2014-07-20 04:28:16 +00:00
$order_taxes = $order -> get_taxes ();
$class = 'new_row' ;
2013-11-14 12:13:34 +00:00
// Set values
$item = array ();
2014-03-24 06:02:21 +00:00
$item [ 'product_id' ] = $_product -> id ;
$item [ 'variation_id' ] = isset ( $_product -> variation_id ) ? $_product -> variation_id : '' ;
2014-09-19 11:52:26 +00:00
$item [ 'variation_data' ] = $item [ 'variation_id' ] ? $_product -> get_variation_attributes () : '' ;
2014-03-24 06:02:21 +00:00
$item [ 'name' ] = $_product -> get_title ();
$item [ 'tax_class' ] = $_product -> get_tax_class ();
$item [ 'qty' ] = 1 ;
$item [ 'line_subtotal' ] = wc_format_decimal ( $_product -> get_price_excluding_tax () );
$item [ 'line_subtotal_tax' ] = '' ;
$item [ 'line_total' ] = wc_format_decimal ( $_product -> get_price_excluding_tax () );
$item [ 'line_tax' ] = '' ;
2013-11-14 12:13:34 +00:00
// Add line item
2014-05-12 13:04:36 +00:00
$item_id = wc_add_order_item ( $order_id , array (
'order_item_name' => $item [ 'name' ],
'order_item_type' => 'line_item'
) );
// Add line item meta
if ( $item_id ) {
wc_add_order_item_meta ( $item_id , '_qty' , $item [ 'qty' ] );
wc_add_order_item_meta ( $item_id , '_tax_class' , $item [ 'tax_class' ] );
wc_add_order_item_meta ( $item_id , '_product_id' , $item [ 'product_id' ] );
wc_add_order_item_meta ( $item_id , '_variation_id' , $item [ 'variation_id' ] );
wc_add_order_item_meta ( $item_id , '_line_subtotal' , $item [ 'line_subtotal' ] );
wc_add_order_item_meta ( $item_id , '_line_subtotal_tax' , $item [ 'line_subtotal_tax' ] );
wc_add_order_item_meta ( $item_id , '_line_total' , $item [ 'line_total' ] );
wc_add_order_item_meta ( $item_id , '_line_tax' , $item [ 'line_tax' ] );
2014-07-20 04:28:16 +00:00
// Since 2.2
wc_add_order_item_meta ( $item_id , '_line_tax_data' , array ( 'total' => array (), 'subtotal' => array () ) );
2014-05-12 13:04:36 +00:00
// Store variation data in meta
2014-03-24 06:02:21 +00:00
if ( $item [ 'variation_data' ] && is_array ( $item [ 'variation_data' ] ) ) {
foreach ( $item [ 'variation_data' ] as $key => $value ) {
2014-03-24 13:53:40 +00:00
wc_add_order_item_meta ( $item_id , str_replace ( 'attribute_' , '' , $key ), $value );
2014-03-24 06:02:21 +00:00
}
}
2014-05-12 13:04:36 +00:00
2014-03-24 06:02:21 +00:00
do_action ( 'woocommerce_ajax_add_order_item_meta' , $item_id , $item );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-07-22 20:33:49 +00:00
$item = apply_filters ( 'woocommerce_ajax_order_item' , $item , $item_id );
2013-11-14 12:13:34 +00:00
2014-06-04 10:16:19 +00:00
include ( 'admin/meta-boxes/views/html-order-item.php' );
2013-11-14 12:13:34 +00:00
// Quit out
die ();
}
/**
* Add order fee via ajax
*/
2014-05-28 13:52:50 +00:00
public static function add_order_fee () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-07-22 20:33:49 +00:00
$order_id = absint ( $_POST [ 'order_id' ] );
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $order_id );
2014-07-22 20:33:49 +00:00
$order_taxes = $order -> get_taxes ();
2014-07-24 20:55:25 +00:00
$item = array ();
// Add new fee
$fee = new stdClass ();
$fee -> name = '' ;
$fee -> tax_class = '' ;
$fee -> taxable = $fee -> tax_class !== '0' ;
$fee -> amount = '' ;
$fee -> tax = '' ;
$fee -> tax_data = array ();
$item_id = $order -> add_fee ( $fee );
2013-11-14 12:13:34 +00:00
2014-06-04 10:16:19 +00:00
include ( 'admin/meta-boxes/views/html-order-fee.php' );
2013-11-14 12:13:34 +00:00
// Quit out
die ();
}
2014-07-16 18:41:18 +00:00
/**
* Add order shipping cost via ajax
*/
public static function add_order_shipping () {
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-07-16 18:41:18 +00:00
$order_id = absint ( $_POST [ 'order_id' ] );
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $order_id );
2014-07-20 04:28:16 +00:00
$order_taxes = $order -> get_taxes ();
2014-07-16 18:41:18 +00:00
$shipping_methods = WC () -> shipping () ? WC () -> shipping -> load_shipping_methods () : array ();
2014-07-24 20:55:25 +00:00
$item = array ();
// Add new shipping
$shipping = new stdClass ();
$shipping -> label = '' ;
$shipping -> id = '' ;
$shipping -> cost = '' ;
$shipping -> taxes = array ();
$item_id = $order -> add_shipping ( $shipping );
2014-07-16 18:41:18 +00:00
include ( 'admin/meta-boxes/views/html-order-shipping.php' );
// Quit out
die ();
}
2014-07-21 01:36:12 +00:00
/**
* Add order tax column via ajax
*/
public static function add_order_tax () {
global $wpdb ;
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-07-21 01:36:12 +00:00
$order_id = absint ( $_POST [ 'order_id' ] );
$rate_id = absint ( $_POST [ 'rate_id' ] );
2014-11-26 22:22:38 +00:00
$order = wc_get_order ( $order_id );
2014-07-24 20:37:02 +00:00
$data = get_post_meta ( $order_id );
2014-07-21 01:36:12 +00:00
2014-07-24 20:37:02 +00:00
// Add new tax
$order -> add_tax ( $rate_id , 0 , 0 );
2014-07-21 01:36:12 +00:00
// Return HTML items
include ( 'admin/meta-boxes/views/html-order-items.php' );
die ();
}
2013-11-14 12:13:34 +00:00
/**
* Remove an order item
*/
2014-05-28 13:52:50 +00:00
public static function remove_order_item () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2013-11-14 12:13:34 +00:00
$order_item_ids = $_POST [ 'order_item_ids' ];
2014-07-07 15:45:08 +00:00
if ( ! is_array ( $order_item_ids ) && is_numeric ( $order_item_ids ) ) {
$order_item_ids = array ( $order_item_ids );
}
2013-11-14 12:13:34 +00:00
if ( sizeof ( $order_item_ids ) > 0 ) {
foreach ( $order_item_ids as $id ) {
2013-11-25 13:54:52 +00:00
wc_delete_order_item ( absint ( $id ) );
2013-11-14 12:13:34 +00:00
}
}
die ();
}
2014-07-21 01:57:23 +00:00
/**
* Remove an order tax
*/
2014-08-27 20:03:49 +00:00
public static function remove_order_tax () {
2014-07-21 01:57:23 +00:00
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-07-21 01:57:23 +00:00
$order_id = absint ( $_POST [ 'order_id' ] );
$rate_id = absint ( $_POST [ 'rate_id' ] );
wc_delete_order_item ( $rate_id );
// Return HTML items
2014-11-26 22:22:38 +00:00
$order = wc_get_order ( $order_id );
2014-07-21 01:57:23 +00:00
$data = get_post_meta ( $order_id );
include ( 'admin/meta-boxes/views/html-order-items.php' );
die ();
}
2013-11-14 12:13:34 +00:00
/**
* Reduce order item stock
*/
2014-05-28 13:52:50 +00:00
public static function reduce_order_item_stock () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-05-12 13:04:36 +00:00
$order_id = absint ( $_POST [ 'order_id' ] );
$order_item_ids = isset ( $_POST [ 'order_item_ids' ] ) ? $_POST [ 'order_item_ids' ] : array ();
$order_item_qty = isset ( $_POST [ 'order_item_qty' ] ) ? $_POST [ 'order_item_qty' ] : array ();
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $order_id );
2014-05-12 13:04:36 +00:00
$order_items = $order -> get_items ();
$return = array ();
2013-11-14 12:13:34 +00:00
if ( $order && ! empty ( $order_items ) && sizeof ( $order_item_ids ) > 0 ) {
foreach ( $order_items as $item_id => $order_item ) {
// Only reduce checked items
2014-05-12 13:04:36 +00:00
if ( ! in_array ( $item_id , $order_item_ids ) ) {
2013-11-14 12:13:34 +00:00
continue ;
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
$_product = $order -> get_product_from_item ( $order_item );
if ( $_product -> exists () && $_product -> managing_stock () && isset ( $order_item_qty [ $item_id ] ) && $order_item_qty [ $item_id ] > 0 ) {
2014-04-25 14:27:58 +00:00
$stock_change = apply_filters ( 'woocommerce_reduce_order_stock_quantity' , $order_item_qty [ $item_id ], $item_id );
$new_stock = $_product -> reduce_stock ( $stock_change );
2015-06-04 23:57:43 +00:00
$note = sprintf ( __ ( 'Item #%s stock reduced from %s to %s.' , 'woocommerce' ), $order_item [ 'product_id' ], $new_stock + $stock_change , $new_stock );
$return [] = $note ;
2013-11-14 12:13:34 +00:00
2015-06-04 23:57:43 +00:00
$order -> add_order_note ( $note );
2014-04-25 14:27:58 +00:00
$order -> send_stock_notifications ( $_product , $new_stock , $order_item_qty [ $item_id ] );
2013-11-14 12:13:34 +00:00
}
}
do_action ( 'woocommerce_reduce_order_stock' , $order );
2014-05-12 13:04:36 +00:00
if ( empty ( $return ) ) {
2013-11-14 12:13:34 +00:00
$return [] = __ ( 'No products had their stock reduced - they may not have stock management enabled.' , 'woocommerce' );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
echo implode ( ', ' , $return );
}
die ();
}
/**
* Increase order item stock
*/
2014-05-28 13:52:50 +00:00
public static function increase_order_item_stock () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-05-12 13:04:36 +00:00
$order_id = absint ( $_POST [ 'order_id' ] );
$order_item_ids = isset ( $_POST [ 'order_item_ids' ] ) ? $_POST [ 'order_item_ids' ] : array ();
$order_item_qty = isset ( $_POST [ 'order_item_qty' ] ) ? $_POST [ 'order_item_qty' ] : array ();
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $order_id );
2014-05-12 13:04:36 +00:00
$order_items = $order -> get_items ();
$return = array ();
2013-11-14 12:13:34 +00:00
if ( $order && ! empty ( $order_items ) && sizeof ( $order_item_ids ) > 0 ) {
foreach ( $order_items as $item_id => $order_item ) {
// Only reduce checked items
2014-05-12 13:04:36 +00:00
if ( ! in_array ( $item_id , $order_item_ids ) ) {
2013-11-14 12:13:34 +00:00
continue ;
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
$_product = $order -> get_product_from_item ( $order_item );
if ( $_product -> exists () && $_product -> managing_stock () && isset ( $order_item_qty [ $item_id ] ) && $order_item_qty [ $item_id ] > 0 ) {
2014-05-12 13:04:36 +00:00
$old_stock = $_product -> stock ;
$stock_change = apply_filters ( 'woocommerce_restore_order_stock_quantity' , $order_item_qty [ $item_id ], $item_id );
$new_quantity = $_product -> increase_stock ( $stock_change );
2015-06-05 00:02:03 +00:00
$note = sprintf ( __ ( 'Item #%s stock increased from %s to %s.' , 'woocommerce' ), $order_item [ 'product_id' ], $old_stock , $new_quantity );
$return [] = $note ;
2013-11-14 12:13:34 +00:00
2015-06-05 00:02:03 +00:00
$order -> add_order_note ( $note );
2013-11-14 12:13:34 +00:00
}
}
do_action ( 'woocommerce_restore_order_stock' , $order );
2014-05-12 13:04:36 +00:00
if ( empty ( $return ) ) {
2013-11-14 12:13:34 +00:00
$return [] = __ ( 'No products had their stock increased - they may not have stock management enabled.' , 'woocommerce' );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
echo implode ( ', ' , $return );
}
die ();
}
/**
* Add some meta to a line item
*/
2014-05-28 13:52:50 +00:00
public static function add_order_item_meta () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2013-11-25 13:54:52 +00:00
$meta_id = wc_add_order_item_meta ( absint ( $_POST [ 'order_item_id' ] ), __ ( 'Name' , 'woocommerce' ), __ ( 'Value' , 'woocommerce' ) );
2013-11-14 12:13:34 +00:00
if ( $meta_id ) {
2013-11-20 19:11:59 +00:00
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>' ;
2013-11-14 12:13:34 +00:00
}
die ();
}
/**
* Remove meta from a line item
*/
2014-05-28 13:52:50 +00:00
public static function remove_order_item_meta () {
2013-11-14 12:13:34 +00:00
global $wpdb ;
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2013-11-14 12:13:34 +00:00
$meta_id = absint ( $_POST [ 'meta_id' ] );
$wpdb -> query ( $wpdb -> prepare ( " DELETE FROM { $wpdb -> prefix } woocommerce_order_itemmeta WHERE meta_id = %d " , $meta_id ) );
die ();
}
/**
* Calc line tax
*/
2014-05-28 13:52:50 +00:00
public static function calc_line_taxes () {
2013-11-14 12:13:34 +00:00
global $wpdb ;
check_ajax_referer ( 'calc-totals' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-07-24 20:33:26 +00:00
$tax = new WC_Tax ();
$order_id = absint ( $_POST [ 'order_id' ] );
$items = array ();
$country = strtoupper ( esc_attr ( $_POST [ 'country' ] ) );
$state = strtoupper ( esc_attr ( $_POST [ 'state' ] ) );
$postcode = strtoupper ( esc_attr ( $_POST [ 'postcode' ] ) );
2015-07-10 10:02:08 +00:00
$city = wc_clean ( esc_attr ( $_POST [ 'city' ] ) );
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $order_id );
2014-07-24 20:33:26 +00:00
$taxes = array ();
$shipping_taxes = array ();
2013-11-14 12:13:34 +00:00
2014-07-24 21:09:13 +00:00
// Parse the jQuery serialized items
parse_str ( $_POST [ 'items' ], $items );
2014-07-24 20:33:26 +00:00
// Prevent undefined warnings
2014-07-24 21:09:13 +00:00
if ( ! isset ( $items [ 'line_tax' ] ) ) {
2014-07-24 20:33:26 +00:00
$items [ 'line_tax' ] = array ();
}
2014-07-24 21:09:13 +00:00
if ( ! isset ( $items [ 'line_subtotal_tax' ] ) ) {
2014-07-24 20:33:26 +00:00
$items [ 'line_subtotal_tax' ] = array ();
}
2014-07-24 21:09:13 +00:00
$items [ 'order_taxes' ] = array ();
2014-07-24 20:33:26 +00:00
2014-12-02 11:57:53 +00:00
// Action
$items = apply_filters ( 'woocommerce_ajax_calc_line_taxes' , $items , $order_id , $country , $_POST );
2014-07-24 20:33:26 +00:00
// Get items and fees taxes
if ( isset ( $items [ 'order_item_id' ] ) ) {
2014-12-01 23:55:48 +00:00
$line_total = $line_subtotal = $order_item_tax_class = array ();
2014-07-24 20:33:26 +00:00
2014-12-01 23:55:48 +00:00
foreach ( $items [ 'order_item_id' ] as $item_id ) {
2014-07-24 20:33:26 +00:00
$item_id = absint ( $item_id );
2014-12-01 23:55:48 +00:00
$line_total [ $item_id ] = isset ( $items [ 'line_total' ][ $item_id ] ) ? wc_format_decimal ( $items [ 'line_total' ][ $item_id ] ) : 0 ;
$line_subtotal [ $item_id ] = isset ( $items [ 'line_subtotal' ][ $item_id ] ) ? wc_format_decimal ( $items [ 'line_subtotal' ][ $item_id ] ) : $line_total [ $item_id ];
$order_item_tax_class [ $item_id ] = isset ( $items [ 'order_item_tax_class' ][ $item_id ] ) ? sanitize_text_field ( $items [ 'order_item_tax_class' ][ $item_id ] ) : '' ;
2014-07-24 20:33:26 +00:00
$product_id = $order -> get_item_meta ( $item_id , '_product_id' , true );
2013-11-14 12:13:34 +00:00
// Get product details
if ( get_post_type ( $product_id ) == 'product' ) {
2014-08-19 10:09:29 +00:00
$_product = wc_get_product ( $product_id );
2014-05-12 13:04:36 +00:00
$item_tax_status = $_product -> get_tax_status ();
2013-11-14 12:13:34 +00:00
} else {
2014-05-12 13:04:36 +00:00
$item_tax_status = 'taxable' ;
2013-11-14 12:13:34 +00:00
}
2014-07-24 20:33:26 +00:00
if ( '0' !== $order_item_tax_class [ $item_id ] && 'taxable' === $item_tax_status ) {
2014-06-12 15:47:43 +00:00
$tax_rates = WC_Tax :: find_rates ( array (
2014-05-12 13:04:36 +00:00
'country' => $country ,
'state' => $state ,
'postcode' => $postcode ,
'city' => $city ,
2014-07-24 20:33:26 +00:00
'tax_class' => $order_item_tax_class [ $item_id ]
2013-11-14 12:13:34 +00:00
) );
2014-07-24 20:33:26 +00:00
$line_taxes = WC_Tax :: calc_tax ( $line_total [ $item_id ], $tax_rates , false );
$line_subtotal_taxes = WC_Tax :: calc_tax ( $line_subtotal [ $item_id ], $tax_rates , false );
2013-11-14 12:13:34 +00:00
2014-07-24 20:33:26 +00:00
// Set the new line_tax
foreach ( $line_taxes as $_tax_id => $_tax_value ) {
$items [ 'line_tax' ][ $item_id ][ $_tax_id ] = $_tax_value ;
}
2013-11-14 12:13:34 +00:00
2014-07-24 20:33:26 +00:00
// Set the new line_subtotal_tax
foreach ( $line_subtotal_taxes as $_tax_id => $_tax_value ) {
$items [ 'line_subtotal_tax' ][ $item_id ][ $_tax_id ] = $_tax_value ;
}
2013-11-14 12:13:34 +00:00
// Sum the item taxes
2014-05-12 13:04:36 +00:00
foreach ( array_keys ( $taxes + $line_taxes ) as $key ) {
2013-11-14 12:13:34 +00:00
$taxes [ $key ] = ( isset ( $line_taxes [ $key ] ) ? $line_taxes [ $key ] : 0 ) + ( isset ( $taxes [ $key ] ) ? $taxes [ $key ] : 0 );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
}
}
}
2014-07-24 20:33:26 +00:00
// Get shipping taxes
if ( isset ( $items [ 'shipping_method_id' ] ) ) {
$matched_tax_rates = array ();
$tax_rates = WC_Tax :: find_rates ( array (
'country' => $country ,
'state' => $state ,
'postcode' => $postcode ,
'city' => $city ,
'tax_class' => ''
) );
if ( $tax_rates ) {
foreach ( $tax_rates as $key => $rate ) {
if ( isset ( $rate [ 'shipping' ] ) && 'yes' == $rate [ 'shipping' ] ) {
$matched_tax_rates [ $key ] = $rate ;
}
}
}
2013-11-14 12:13:34 +00:00
2014-12-01 23:55:48 +00:00
$shipping_cost = $shipping_taxes = array ();
2014-07-24 20:33:26 +00:00
2014-12-01 23:55:48 +00:00
foreach ( $items [ 'shipping_method_id' ] as $item_id ) {
2014-07-24 20:33:26 +00:00
$item_id = absint ( $item_id );
2014-12-01 23:55:48 +00:00
$shipping_cost [ $item_id ] = isset ( $items [ 'shipping_cost' ][ $item_id ] ) ? wc_format_decimal ( $items [ 'shipping_cost' ][ $item_id ] ) : 0 ;
$_shipping_taxes = WC_Tax :: calc_shipping_tax ( $shipping_cost [ $item_id ], $matched_tax_rates );
2013-11-14 12:13:34 +00:00
2014-07-24 20:33:26 +00:00
// Set the new shipping_taxes
2014-12-01 23:55:48 +00:00
foreach ( $_shipping_taxes as $_tax_id => $_tax_value ) {
2014-07-24 20:33:26 +00:00
$items [ 'shipping_taxes' ][ $item_id ][ $_tax_id ] = $_tax_value ;
2014-12-01 23:55:48 +00:00
$shipping_taxes [ $_tax_id ] = isset ( $shipping_taxes [ $_tax_id ] ) ? $shipping_taxes [ $_tax_id ] + $_tax_value : $_tax_value ;
2014-05-12 13:04:36 +00:00
}
}
}
2013-11-14 12:13:34 +00:00
// Remove old tax rows
2014-06-13 14:54:08 +00:00
$order -> remove_order_items ( 'tax' );
2013-11-14 12:13:34 +00:00
2014-06-13 14:54:08 +00:00
// Add tax rows
foreach ( array_keys ( $taxes + $shipping_taxes ) as $tax_rate_id ) {
$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 );
2013-11-14 12:13:34 +00:00
}
2014-07-24 20:33:26 +00:00
// Create the new order_taxes
foreach ( $order -> get_taxes () as $tax_id => $tax_item ) {
$items [ 'order_taxes' ][ $tax_id ] = absint ( $tax_item [ 'rate_id' ] );
2013-11-14 12:13:34 +00:00
}
2014-07-24 20:33:26 +00:00
// Save order items
wc_save_order_items ( $order_id , $items );
2013-11-14 12:13:34 +00:00
2014-07-24 20:33:26 +00:00
// Return HTML items
2014-11-26 22:22:38 +00:00
$order = wc_get_order ( $order_id );
2014-07-24 20:33:26 +00:00
$data = get_post_meta ( $order_id );
include ( 'admin/meta-boxes/views/html-order-items.php' );
2013-11-14 12:13:34 +00:00
2014-07-24 20:33:26 +00:00
die ();
2013-11-14 12:13:34 +00:00
}
2014-07-17 20:17:54 +00:00
/**
* Save order items via ajax
*/
public static function save_order_items () {
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-07-17 20:17:54 +00:00
if ( isset ( $_POST [ 'order_id' ] ) && isset ( $_POST [ 'items' ] ) ) {
$order_id = absint ( $_POST [ 'order_id' ] );
// Parse the jQuery serialized items
$items = array ();
parse_str ( $_POST [ 'items' ], $items );
// Save order items
wc_save_order_items ( $order_id , $items );
// Return HTML items
2014-11-26 22:22:38 +00:00
$order = wc_get_order ( $order_id );
2014-07-17 21:17:42 +00:00
$data = get_post_meta ( $order_id );
2014-07-17 20:17:54 +00:00
include ( 'admin/meta-boxes/views/html-order-items.php' );
}
die ();
}
/**
* Load order items via ajax
*/
public static function load_order_items () {
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-07-17 20:17:54 +00:00
// Return HTML items
$order_id = absint ( $_POST [ 'order_id' ] );
2014-11-26 22:22:38 +00:00
$order = wc_get_order ( $order_id );
2014-07-17 21:17:42 +00:00
$data = get_post_meta ( $order_id );
2014-07-17 20:17:54 +00:00
include ( 'admin/meta-boxes/views/html-order-items.php' );
die ();
}
2013-11-14 12:13:34 +00:00
/**
* Add order note via ajax
*/
2014-05-28 13:52:50 +00:00
public static function add_order_note () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'add-order-note' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2015-03-03 16:36:47 +00:00
$post_id = absint ( $_POST [ 'post_id' ] );
2014-05-12 13:04:36 +00:00
$note = wp_kses_post ( trim ( stripslashes ( $_POST [ 'note' ] ) ) );
$note_type = $_POST [ 'note_type' ];
2013-11-14 12:13:34 +00:00
$is_customer_note = $note_type == 'customer' ? 1 : 0 ;
if ( $post_id > 0 ) {
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $post_id );
2015-04-17 10:23:09 +00:00
$comment_id = $order -> add_order_note ( $note , $is_customer_note , true );
2013-11-14 12:13:34 +00:00
2013-11-20 19:11:59 +00:00
echo '<li rel="' . esc_attr ( $comment_id ) . '" class="note ' ;
2014-05-12 13:04:36 +00:00
if ( $is_customer_note ) {
echo 'customer-note' ;
}
2013-11-14 12:13:34 +00:00
echo '"><div class="note_content">' ;
echo wpautop ( wptexturize ( $note ) );
echo '</div><p class="meta"><a href="#" class="delete_note">' . __ ( 'Delete note' , 'woocommerce' ) . '</a></p>' ;
echo '</li>' ;
}
// Quit out
die ();
}
/**
* Delete order note via ajax
*/
2014-05-28 13:52:50 +00:00
public static function delete_order_note () {
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'delete-order-note' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-05-12 13:04:36 +00:00
$note_id = ( int ) $_POST [ 'note_id' ];
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( $note_id > 0 ) {
2013-11-14 12:13:34 +00:00
wp_delete_comment ( $note_id );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
// Quit out
die ();
}
/**
* Search for products and echo json
*
* @ param string $x ( default : '' )
* @ param string $post_types ( default : array ( 'product' ))
*/
2015-02-19 13:21:02 +00:00
public static function json_search_products ( $x = '' , $post_types = array ( 'product' ) ) {
2014-09-16 12:24:02 +00:00
ob_start ();
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'search-products' , 'security' );
2014-01-26 09:19:17 +00:00
$term = ( string ) wc_clean ( stripslashes ( $_GET [ 'term' ] ) );
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( empty ( $term ) ) {
die ();
}
2013-11-14 12:13:34 +00:00
2015-02-23 18:23:53 +00:00
$args = array (
'post_type' => $post_types ,
'post_status' => 'publish' ,
'posts_per_page' => - 1 ,
's' => $term ,
'fields' => 'ids'
);
2013-11-14 12:13:34 +00:00
if ( is_numeric ( $term ) ) {
2015-02-23 18:23:53 +00:00
$args2 = array (
2014-05-12 13:04:36 +00:00
'post_type' => $post_types ,
'post_status' => 'publish' ,
'posts_per_page' => - 1 ,
2015-02-23 18:23:53 +00:00
'post__in' => array ( 0 , $term ),
2014-05-12 13:04:36 +00:00
'fields' => 'ids'
2013-11-14 12:13:34 +00:00
);
2015-02-23 18:23:53 +00:00
$args3 = array (
2014-05-12 13:04:36 +00:00
'post_type' => $post_types ,
'post_status' => 'publish' ,
'posts_per_page' => - 1 ,
'post_parent' => $term ,
'fields' => 'ids'
2013-11-14 12:13:34 +00:00
);
2015-02-23 18:23:53 +00:00
$args4 = array (
2014-05-12 13:04:36 +00:00
'post_type' => $post_types ,
'post_status' => 'publish' ,
'posts_per_page' => - 1 ,
'meta_query' => array (
2013-11-14 12:13:34 +00:00
array (
2014-05-12 13:04:36 +00:00
'key' => '_sku' ,
'value' => $term ,
'compare' => 'LIKE'
2013-11-14 12:13:34 +00:00
)
),
2014-05-12 13:04:36 +00:00
'fields' => 'ids'
2013-11-14 12:13:34 +00:00
);
2015-02-23 18:23:53 +00:00
$posts = array_unique ( array_merge ( get_posts ( $args ), get_posts ( $args2 ), get_posts ( $args3 ), get_posts ( $args4 ) ) );
2013-11-14 12:13:34 +00:00
} else {
$args2 = array (
2014-05-12 13:04:36 +00:00
'post_type' => $post_types ,
'post_status' => 'publish' ,
'posts_per_page' => - 1 ,
'meta_query' => array (
2013-11-14 12:13:34 +00:00
array (
2014-05-12 13:04:36 +00:00
'key' => '_sku' ,
'value' => $term ,
2013-11-14 12:13:34 +00:00
'compare' => 'LIKE'
)
),
2014-05-12 13:04:36 +00:00
'fields' => 'ids'
2013-11-14 12:13:34 +00:00
);
2014-05-12 13:04:36 +00:00
$posts = array_unique ( array_merge ( get_posts ( $args ), get_posts ( $args2 ) ) );
2013-11-14 12:13:34 +00:00
}
$found_products = array ();
2015-06-02 17:10:02 +00:00
if ( ! empty ( $posts ) ) {
2014-05-12 13:04:36 +00:00
foreach ( $posts as $post ) {
2014-08-19 10:09:29 +00:00
$product = wc_get_product ( $post );
2013-11-14 12:13:34 +00:00
2015-06-09 12:33:13 +00:00
if ( ! current_user_can ( 'read_product' , $post ) ) {
continue ;
}
2015-02-19 13:21:02 +00:00
$found_products [ $post ] = rawurldecode ( $product -> get_formatted_name () );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
}
$found_products = apply_filters ( 'woocommerce_json_search_found_products' , $found_products );
2014-05-31 07:32:22 +00:00
wp_send_json ( $found_products );
2013-11-14 12:13:34 +00:00
}
/**
* Search for product variations and return json
*
* @ see WC_AJAX :: json_search_products ()
*/
2014-05-28 13:52:50 +00:00
public static function json_search_products_and_variations () {
2015-02-19 13:21:02 +00:00
self :: json_search_products ( '' , array ( 'product' , 'product_variation' ) );
2013-11-14 12:13:34 +00:00
}
/**
2015-07-08 21:38:17 +00:00
* Search for gruoped products and return json
2013-11-14 12:13:34 +00:00
*/
2015-07-08 21:38:17 +00:00
public static function json_search_grouped_products () {
2014-09-16 12:24:02 +00:00
ob_start ();
2013-11-14 12:13:34 +00:00
2015-07-08 21:38:17 +00:00
check_ajax_referer ( 'search-products' , 'security' );
2015-05-29 13:55:26 +00:00
2015-07-08 21:38:17 +00:00
$term = ( string ) wc_clean ( stripslashes ( $_GET [ 'term' ] ) );
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( empty ( $term ) ) {
2013-11-14 12:13:34 +00:00
die ();
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2015-07-08 21:38:17 +00:00
$found_products = array ();
2013-11-14 12:13:34 +00:00
2015-07-08 21:38:17 +00:00
if ( $grouped_term = get_term_by ( 'slug' , 'grouped' , 'product_type' ) ) {
2013-11-14 12:13:34 +00:00
2015-07-08 21:38:17 +00:00
$posts_in = array_unique ( ( array ) get_objects_in_term ( $grouped_term -> term_id , 'product_type' ) );
2013-11-14 12:13:34 +00:00
2015-07-08 21:38:17 +00:00
if ( sizeof ( $posts_in ) > 0 ) {
2013-11-14 12:13:34 +00:00
2015-07-08 21:38:17 +00:00
$args = array (
'post_type' => 'product' ,
'post_status' => 'any' ,
'numberposts' => - 1 ,
'orderby' => 'title' ,
'order' => 'asc' ,
'post_parent' => 0 ,
'suppress_filters' => 0 ,
'include' => $posts_in ,
's' => $term ,
'fields' => 'ids'
);
2013-11-14 12:13:34 +00:00
2015-07-08 21:38:17 +00:00
$posts = get_posts ( $args );
if ( ! empty ( $posts ) ) {
foreach ( $posts as $post ) {
$product = wc_get_product ( $post );
if ( ! current_user_can ( 'read_product' , $post ) ) {
continue ;
}
$found_products [ $post ] = rawurldecode ( $product -> get_formatted_name () );
}
}
2013-11-14 12:13:34 +00:00
}
}
2015-07-08 21:38:17 +00:00
$found_products = apply_filters ( 'woocommerce_json_search_found_grouped_products' , $found_products );
wp_send_json ( $found_products );
2013-11-14 12:13:34 +00:00
}
2013-11-26 13:54:34 +00:00
/**
* Search for downloadable product variations and return json
*
* @ access public
* @ return void
* @ see WC_AJAX :: json_search_products ()
*/
2014-05-28 13:52:50 +00:00
public static function json_search_downloadable_products_and_variations () {
2014-09-16 12:24:02 +00:00
ob_start ();
2015-05-29 13:55:26 +00:00
check_ajax_referer ( 'search-products' , 'security' );
2014-01-26 09:19:17 +00:00
$term = ( string ) wc_clean ( stripslashes ( $_GET [ 'term' ] ) );
2013-11-26 13:54:34 +00:00
$args = array (
2014-05-12 13:04:36 +00:00
'post_type' => array ( 'product' , 'product_variation' ),
'posts_per_page' => - 1 ,
'post_status' => 'publish' ,
'order' => 'ASC' ,
'orderby' => 'parent title' ,
'meta_query' => array (
2013-11-26 13:54:34 +00:00
array (
2014-05-12 13:04:36 +00:00
'key' => '_downloadable' ,
2013-11-26 13:54:34 +00:00
'value' => 'yes'
)
),
2014-05-12 13:04:36 +00:00
's' => $term
2013-11-26 13:54:34 +00:00
);
2014-05-12 13:04:36 +00:00
2013-11-26 13:54:34 +00:00
$posts = get_posts ( $args );
$found_products = array ();
2014-05-12 13:04:36 +00:00
2015-06-02 17:13:52 +00:00
if ( ! empty ( $posts ) ) {
2014-05-12 13:04:36 +00:00
foreach ( $posts as $post ) {
2014-08-19 10:09:29 +00:00
$product = wc_get_product ( $post -> ID );
2015-06-09 12:33:13 +00:00
if ( ! current_user_can ( 'read_product' , $post -> ID ) ) {
continue ;
}
2014-05-12 13:04:36 +00:00
$found_products [ $post -> ID ] = $product -> get_formatted_name ();
}
2013-11-26 13:54:34 +00:00
}
2014-05-31 07:32:22 +00:00
wp_send_json ( $found_products );
2013-11-26 13:54:34 +00:00
}
2015-07-08 21:38:17 +00:00
/**
* Search for customers and return json
*/
public static function json_search_customers () {
ob_start ();
check_ajax_referer ( 'search-customers' , 'security' );
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
$term = wc_clean ( stripslashes ( $_GET [ 'term' ] ) );
if ( empty ( $term ) ) {
die ();
}
$found_customers = array ();
add_action ( 'pre_user_query' , array ( __CLASS__ , 'json_search_customer_name' ) );
$customers_query = new WP_User_Query ( apply_filters ( 'woocommerce_json_search_customers_query' , array (
'fields' => 'all' ,
'orderby' => 'display_name' ,
'search' => '*' . $term . '*' ,
'search_columns' => array ( 'ID' , 'user_login' , 'user_email' , 'user_nicename' )
) ) );
remove_action ( 'pre_user_query' , array ( __CLASS__ , 'json_search_customer_name' ) );
$customers = $customers_query -> get_results ();
if ( ! empty ( $customers ) ) {
foreach ( $customers as $customer ) {
$found_customers [ $customer -> ID ] = $customer -> display_name . ' (#' . $customer -> ID . ' – ' . sanitize_email ( $customer -> user_email ) . ')' ;
}
}
wp_send_json ( $found_customers );
}
2013-11-14 12:13:34 +00:00
/**
* When searching using the WP_User_Query , search names ( user meta ) too
* @ param object $query
* @ return object
*/
2014-05-28 13:52:50 +00:00
public static function json_search_customer_name ( $query ) {
2013-11-14 12:13:34 +00:00
global $wpdb ;
2014-01-26 09:19:17 +00:00
$term = wc_clean ( stripslashes ( $_GET [ 'term' ] ) );
2014-08-21 17:00:39 +00:00
if ( method_exists ( $wpdb , 'esc_like' ) ) {
$term = $wpdb -> esc_like ( $term );
} else {
$term = like_escape ( $term );
}
2013-11-14 12:13:34 +00:00
2014-04-15 10:10:57 +00:00
$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' ) " ;
2014-08-21 17:00:39 +00:00
$query -> query_where .= $wpdb -> prepare ( " OR user_name.meta_value LIKE %s " , '%' . $term . '%' );
2013-11-14 12:13:34 +00:00
}
/**
* Ajax request handling for categories ordering
*/
2014-05-28 13:52:50 +00:00
public static function term_ordering () {
2015-05-29 13:55:26 +00:00
// check permissions again and make sure we have what we need
if ( ! current_user_can ( 'edit_products' ) || empty ( $_POST [ 'id' ] ) ) {
die ( - 1 );
}
2014-05-12 13:04:36 +00:00
$id = ( int ) $_POST [ 'id' ];
$next_id = isset ( $_POST [ 'nextid' ] ) && ( int ) $_POST [ 'nextid' ] ? ( int ) $_POST [ 'nextid' ] : null ;
$taxonomy = isset ( $_POST [ 'thetaxonomy' ] ) ? esc_attr ( $_POST [ 'thetaxonomy' ] ) : null ;
2015-05-29 13:55:26 +00:00
$term = get_term_by ( 'id' , $id , $taxonomy );
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( ! $id || ! $term || ! $taxonomy ) {
die ( 0 );
}
2013-11-14 12:13:34 +00:00
2013-12-05 16:07:44 +00:00
wc_reorder_terms ( $term , $next_id , $taxonomy );
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
$children = get_terms ( $taxonomy , " child_of= $id &menu_order=ASC&hide_empty=0 " );
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( $term && sizeof ( $children ) ) {
2013-11-14 12:13:34 +00:00
echo 'children' ;
2014-05-12 13:04:36 +00:00
die ();
2013-11-14 12:13:34 +00:00
}
}
/**
* Ajax request handling for product ordering
*
* Based on Simple Page Ordering by 10 up ( http :// wordpress . org / extend / plugins / simple - page - ordering / )
*/
2014-05-28 13:52:50 +00:00
public static function product_ordering () {
2013-11-14 12:13:34 +00:00
global $wpdb ;
2014-09-16 12:24:02 +00:00
ob_start ();
2013-11-14 12:13:34 +00:00
// check permissions again and make sure we have what we need
2014-05-12 13:04:36 +00:00
if ( ! current_user_can ( 'edit_products' ) || empty ( $_POST [ 'id' ] ) || ( ! isset ( $_POST [ 'previd' ] ) && ! isset ( $_POST [ 'nextid' ] ) ) ) {
2013-11-14 12:13:34 +00:00
die ( - 1 );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
// real post?
2014-05-12 13:04:36 +00:00
if ( ! $post = get_post ( $_POST [ 'id' ] ) ) {
2013-11-14 12:13:34 +00:00
die ( - 1 );
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
$previd = isset ( $_POST [ 'previd' ] ) ? $_POST [ 'previd' ] : false ;
$nextid = isset ( $_POST [ 'nextid' ] ) ? $_POST [ 'nextid' ] : false ;
2013-11-14 12:13:34 +00:00
$new_pos = array (); // store new positions for ajax
$siblings = $wpdb -> get_results ( $wpdb -> prepare ( '
SELECT ID , menu_order FROM % 1 $s AS posts
WHERE posts . post_type = \ ' product\ '
AND posts . post_status IN ( \ ' publish\ ' , \ ' pending\ ' , \ ' draft\ ' , \ ' future\ ' , \ ' private \ ' )
AND posts . ID NOT IN ( % 2 $d )
ORDER BY posts . menu_order ASC , posts . ID DESC
' , $wpdb -> posts , $post -> ID ) );
$menu_order = 0 ;
2014-05-12 13:04:36 +00:00
foreach ( $siblings as $sibling ) {
2013-11-14 12:13:34 +00:00
// if this is the post that comes after our repositioned post, set our repositioned post position and increment menu order
if ( $nextid == $sibling -> ID ) {
$wpdb -> update (
$wpdb -> posts ,
array (
'menu_order' => $menu_order
),
array ( 'ID' => $post -> ID ),
array ( '%d' ),
array ( '%d' )
);
$new_pos [ $post -> ID ] = $menu_order ;
$menu_order ++ ;
}
// if repositioned post has been set, and new items are already in the right order, we can stop
2014-05-12 13:04:36 +00:00
if ( isset ( $new_pos [ $post -> ID ] ) && $sibling -> menu_order >= $menu_order ) {
2013-11-14 12:13:34 +00:00
break ;
2014-05-12 13:04:36 +00:00
}
2013-11-14 12:13:34 +00:00
// set the menu order of the current sibling and increment the menu order
$wpdb -> update (
$wpdb -> posts ,
array (
'menu_order' => $menu_order
),
array ( 'ID' => $sibling -> ID ),
array ( '%d' ),
array ( '%d' )
);
$new_pos [ $sibling -> ID ] = $menu_order ;
$menu_order ++ ;
if ( ! $nextid && $previd == $sibling -> ID ) {
$wpdb -> update (
$wpdb -> posts ,
array (
'menu_order' => $menu_order
),
array ( 'ID' => $post -> ID ),
array ( '%d' ),
array ( '%d' )
);
$new_pos [ $post -> ID ] = $menu_order ;
$menu_order ++ ;
}
}
2014-08-07 18:57:29 +00:00
2014-07-10 14:15:31 +00:00
do_action ( 'woocommerce_after_product_ordering' );
2013-11-14 12:13:34 +00:00
2014-05-31 07:32:22 +00:00
wp_send_json ( $new_pos );
2014-07-10 12:33:05 +00:00
}
/**
* Handle a refund via the edit order screen
*/
public static function refund_line_items () {
2014-09-16 12:24:02 +00:00
ob_start ();
2014-07-10 12:33:05 +00:00
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-07-25 10:29:24 +00:00
$order_id = absint ( $_POST [ 'order_id' ] );
2014-09-08 11:42:30 +00:00
$refund_amount = wc_format_decimal ( sanitize_text_field ( $_POST [ 'refund_amount' ] ) );
2014-07-25 10:29:24 +00:00
$refund_reason = sanitize_text_field ( $_POST [ 'refund_reason' ] );
$line_item_qtys = json_decode ( sanitize_text_field ( stripslashes ( $_POST [ 'line_item_qtys' ] ) ), true );
2014-09-08 11:45:32 +00:00
$line_item_totals = json_decode ( sanitize_text_field ( stripslashes ( $_POST [ 'line_item_totals' ] ) ), true );
$line_item_tax_totals = json_decode ( sanitize_text_field ( stripslashes ( $_POST [ 'line_item_tax_totals' ] ) ), true );
2014-07-25 10:29:24 +00:00
$api_refund = $_POST [ 'api_refund' ] === 'true' ? true : false ;
$restock_refunded_items = $_POST [ 'restock_refunded_items' ] === 'true' ? true : false ;
2014-09-12 09:09:22 +00:00
$refund = false ;
2015-01-02 12:43:47 +00:00
$response_data = array ();
2014-05-31 07:32:22 +00:00
2014-07-10 13:49:04 +00:00
try {
// Validate that the refund can occur
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $order_id );
2014-07-25 10:29:24 +00:00
$order_items = $order -> get_items ();
2015-03-02 09:54:43 +00:00
$max_refund = wc_format_decimal ( $order -> get_total () - $order -> get_total_refunded () );
2014-07-10 13:49:04 +00:00
2015-06-15 20:19:52 +00:00
if ( ! $refund_amount || $max_refund < $refund_amount || 0 > $refund_amount ) {
2014-07-10 13:49:04 +00:00
throw new exception ( __ ( 'Invalid refund amount' , 'woocommerce' ) );
}
2014-07-16 18:41:18 +00:00
2014-07-24 14:34:14 +00:00
// Prepare line items which we are refunding
$line_items = array ();
$item_ids = array_unique ( array_merge ( array_keys ( $line_item_qtys , $line_item_totals ) ) );
foreach ( $item_ids as $item_id ) {
$line_items [ $item_id ] = array ( 'qty' => 0 , 'refund_total' => 0 , 'refund_tax' => array () );
}
foreach ( $line_item_qtys as $item_id => $qty ) {
$line_items [ $item_id ][ 'qty' ] = max ( $qty , 0 );
}
foreach ( $line_item_totals as $item_id => $total ) {
2014-09-08 11:45:32 +00:00
$line_items [ $item_id ][ 'refund_total' ] = wc_format_decimal ( $total );
2014-07-24 14:34:14 +00:00
}
foreach ( $line_item_tax_totals as $item_id => $tax_totals ) {
2014-09-08 11:45:32 +00:00
$line_items [ $item_id ][ 'refund_tax' ] = array_map ( 'wc_format_decimal' , $tax_totals );
2014-07-24 14:34:14 +00:00
}
2014-07-10 13:49:04 +00:00
// Create the refund object
$refund = wc_create_refund ( array (
2014-07-24 14:34:14 +00:00
'amount' => $refund_amount ,
'reason' => $refund_reason ,
'order_id' => $order_id ,
'line_items' => $line_items
2014-07-10 13:49:04 +00:00
) );
if ( is_wp_error ( $refund ) ) {
2014-08-07 18:57:29 +00:00
throw new Exception ( $refund -> get_error_message () );
2014-07-10 13:49:04 +00:00
}
// Refund via API
if ( $api_refund ) {
if ( WC () -> payment_gateways () ) {
$payment_gateways = WC () -> payment_gateways -> payment_gateways ();
}
if ( isset ( $payment_gateways [ $order -> payment_method ] ) && $payment_gateways [ $order -> payment_method ] -> supports ( 'refunds' ) ) {
2014-08-07 18:57:29 +00:00
$result = $payment_gateways [ $order -> payment_method ] -> process_refund ( $order_id , $refund_amount , $refund_reason );
2014-07-10 13:49:04 +00:00
2014-10-09 16:15:42 +00:00
do_action ( 'woocommerce_refund_processed' , $refund , $result );
2014-10-07 22:58:21 +00:00
2014-07-10 13:49:04 +00:00
if ( is_wp_error ( $result ) ) {
2014-08-07 18:57:29 +00:00
throw new Exception ( $result -> get_error_message () );
2014-07-10 13:49:04 +00:00
} elseif ( ! $result ) {
2014-08-07 18:57:29 +00:00
throw new Exception ( __ ( 'Refund failed' , 'woocommerce' ) );
2014-07-10 13:49:04 +00:00
}
}
}
2015-02-17 14:56:22 +00:00
// restock items
foreach ( $line_item_qtys as $item_id => $qty ) {
if ( $restock_refunded_items && $qty && isset ( $order_items [ $item_id ] ) ) {
$order_item = $order_items [ $item_id ];
$_product = $order -> get_product_from_item ( $order_item );
if ( $_product && $_product -> exists () && $_product -> managing_stock () ) {
$old_stock = wc_stock_amount ( $_product -> stock );
$new_quantity = $_product -> increase_stock ( $qty );
$order -> add_order_note ( sprintf ( __ ( 'Item #%s stock increased from %s to %s.' , 'woocommerce' ), $order_item [ 'product_id' ], $old_stock , $new_quantity ) );
do_action ( 'woocommerce_restock_refunded_item' , $_product -> id , $old_stock , $new_quantity , $order );
}
}
}
2015-01-02 12:43:47 +00:00
if ( $refund_amount == $max_refund ) {
2015-07-10 23:51:02 +00:00
$order -> update_status ( apply_filters ( 'woocommerce_order_fully_refunded_status' , 'refunded' , $order_id , $refund -> id ) );
2015-01-02 12:43:47 +00:00
$response_data [ 'status' ] = 'fully_refunded' ;
}
2014-12-19 12:29:47 +00:00
do_action ( 'woocommerce_order_refunded' , $order_id , $refund -> id );
2014-07-24 15:03:52 +00:00
// Clear transients
wc_delete_shop_order_transients ( $order_id );
2015-01-02 12:43:47 +00:00
wp_send_json_success ( $response_data );
2014-07-10 13:49:04 +00:00
} catch ( Exception $e ) {
2014-09-12 09:09:22 +00:00
if ( $refund && is_a ( $refund , 'WC_Order_Refund' ) ) {
wp_delete_post ( $refund -> id , true );
}
2015-01-02 12:43:47 +00:00
wp_send_json_error ( array ( 'error' => $e -> getMessage () ) );
2014-07-10 13:49:04 +00:00
}
2013-11-14 12:13:34 +00:00
}
2014-07-10 15:39:10 +00:00
/**
* Delete a refund
*/
public static function delete_refund () {
check_ajax_referer ( 'order-item' , 'security' );
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2014-07-10 15:39:10 +00:00
$refund_id = absint ( $_POST [ 'refund_id' ] );
2014-07-16 18:41:18 +00:00
2014-07-11 11:43:42 +00:00
if ( $refund_id && 'shop_order_refund' === get_post_type ( $refund_id ) ) {
2015-07-04 08:17:05 +00:00
$order_id = wp_get_post_parent_id ( $refund_id );
wc_delete_shop_order_transients ( $order_id );
2014-07-10 15:39:10 +00:00
wp_delete_post ( $refund_id );
2015-05-29 14:34:25 +00:00
2015-07-04 09:22:19 +00:00
do_action ( 'woocommerce_refund_deleted' , $refund_id , $order_id );
2014-07-10 15:39:10 +00:00
}
die ();
}
2015-02-19 11:38:35 +00:00
/**
* Triggered when clicking the rating footer .
*/
public static function rated () {
2015-05-29 13:55:26 +00:00
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
die ( - 1 );
}
2015-02-19 11:38:35 +00:00
update_option ( 'woocommerce_admin_footer_text_rated' , 1 );
die ();
}
2015-06-08 22:41:35 +00:00
/**
* Create / Update API key
*/
public static function update_api_key () {
ob_start ();
global $wpdb ;
check_ajax_referer ( 'update-api-key' , 'security' );
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
die ( - 1 );
}
try {
if ( empty ( $_POST [ 'description' ] ) ) {
throw new Exception ( __ ( 'Description is missing.' , 'woocommerce' ) );
}
if ( empty ( $_POST [ 'user' ] ) ) {
throw new Exception ( __ ( 'User is missing.' , 'woocommerce' ) );
}
if ( empty ( $_POST [ 'permissions' ] ) ) {
throw new Exception ( __ ( 'Permissions is missing.' , 'woocommerce' ) );
}
$key_id = absint ( $_POST [ 'key_id' ] );
$description = sanitize_text_field ( $_POST [ 'description' ] );
$permissions = ( in_array ( $_POST [ 'permissions' ], array ( 'read' , 'write' , 'read_write' ) ) ) ? sanitize_text_field ( $_POST [ 'permissions' ] ) : 'read' ;
$user_id = absint ( $_POST [ 'user' ] );
if ( 0 < $key_id ) {
$data = array (
'user_id' => $user_id ,
'description' => $description ,
'permissions' => $permissions
);
$wpdb -> update (
$wpdb -> prefix . 'woocommerce_api_keys' ,
$data ,
array ( 'key_id' => $key_id ),
array (
'%d' ,
'%s' ,
'%s'
),
array ( '%d' )
);
$data [ 'consumer_key' ] = '' ;
$data [ 'consumer_secret' ] = '' ;
$data [ 'message' ] = __ ( 'API Key updated successfully.' , 'woocommerce' );
} else {
$status = 2 ;
$consumer_key = 'ck_' . wc_rand_hash ();
$consumer_secret = 'cs_' . wc_rand_hash ();
$data = array (
'user_id' => $user_id ,
'description' => $description ,
'permissions' => $permissions ,
'consumer_key' => wc_api_hash ( $consumer_key ),
2015-06-08 22:58:38 +00:00
'consumer_secret' => $consumer_secret
2015-06-08 22:41:35 +00:00
);
$wpdb -> insert (
$wpdb -> prefix . 'woocommerce_api_keys' ,
$data ,
array (
'%d' ,
'%s' ,
'%s' ,
'%s' ,
'%s'
)
);
2015-06-08 23:22:49 +00:00
$key_id = $wpdb -> insert_id ;
2015-06-08 22:41:35 +00:00
$data [ 'consumer_key' ] = $consumer_key ;
$data [ 'consumer_secret' ] = $consumer_secret ;
$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' );
2015-06-08 23:22:49 +00:00
$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>' ;
2015-06-08 22:41:35 +00:00
}
wp_send_json_success ( $data );
} catch ( Exception $e ) {
wp_send_json_error ( array ( 'message' => $e -> getMessage () ) );
}
}
2015-06-17 11:12:49 +00:00
/**
2015-06-22 13:55:15 +00:00
* Locate user via AJAX
2015-06-17 11:12:49 +00:00
*/
2015-06-22 13:55:15 +00:00
public static function get_customer_location () {
$location_hash = WC_Cache_Helper :: geolocation_ajax_get_location_hash ();
wp_send_json_success ( array ( 'hash' => $location_hash ) );
2015-06-17 11:12:49 +00:00
}
2015-07-02 20:42:22 +00:00
/**
* Load variations via AJAX
*/
public static function load_variations () {
ob_start ();
check_ajax_referer ( 'load-variations' , 'security' );
2015-07-06 04:50:20 +00:00
// Check permissions again and make sure we have what we need
if ( ! current_user_can ( 'edit_products' ) || empty ( $_POST [ 'product_id' ] ) || empty ( $_POST [ 'attributes' ] ) ) {
die ( - 1 );
2015-07-02 20:42:22 +00:00
}
$product_id = absint ( $_POST [ 'product_id' ] );
$per_page = ! empty ( $_POST [ 'per_page' ] ) ? absint ( $_POST [ 'per_page' ] ) : 10 ;
$page = ! empty ( $_POST [ 'page' ] ) ? absint ( $_POST [ 'page' ] ) : 1 ;
// Get attributes
$attributes = array ();
foreach ( $_POST [ 'attributes' ] as $key => $value ) {
$attributes [ wc_clean ( $key ) ] = array_map ( 'wc_clean' , $value );
}
// Get tax classes
$tax_classes = WC_Tax :: get_tax_classes ();
$tax_class_options = array ();
$tax_class_options [ '' ] = __ ( 'Standard' , 'woocommerce' );
if ( ! empty ( $tax_classes ) ) {
foreach ( $tax_classes as $class ) {
$tax_class_options [ sanitize_title ( $class ) ] = esc_attr ( $class );
}
}
// Set backorder options
$backorder_options = array (
'no' => __ ( 'Do not allow' , 'woocommerce' ),
'notify' => __ ( 'Allow, but notify customer' , 'woocommerce' ),
'yes' => __ ( 'Allow' , 'woocommerce' )
);
// set stock status options
$stock_status_options = array (
'instock' => __ ( 'In stock' , 'woocommerce' ),
'outofstock' => __ ( 'Out of stock' , 'woocommerce' )
);
$parent_data = array (
'id' => $product_id ,
'attributes' => $attributes ,
'tax_class_options' => $tax_class_options ,
'sku' => get_post_meta ( $product_id , '_sku' , true ),
'weight' => wc_format_localized_decimal ( get_post_meta ( $product_id , '_weight' , true ) ),
'length' => wc_format_localized_decimal ( get_post_meta ( $product_id , '_length' , true ) ),
'width' => wc_format_localized_decimal ( get_post_meta ( $product_id , '_width' , true ) ),
'height' => wc_format_localized_decimal ( get_post_meta ( $product_id , '_height' , true ) ),
'tax_class' => get_post_meta ( $product_id , '_tax_class' , true ),
'backorder_options' => $backorder_options ,
'stock_status_options' => $stock_status_options
);
if ( ! $parent_data [ 'weight' ] ) {
$parent_data [ 'weight' ] = wc_format_localized_decimal ( 0 );
}
if ( ! $parent_data [ 'length' ] ) {
$parent_data [ 'length' ] = wc_format_localized_decimal ( 0 );
}
if ( ! $parent_data [ 'width' ] ) {
$parent_data [ 'width' ] = wc_format_localized_decimal ( 0 );
}
if ( ! $parent_data [ 'height' ] ) {
$parent_data [ 'height' ] = wc_format_localized_decimal ( 0 );
}
// Get variations
$args = array (
'post_type' => 'product_variation' ,
'post_status' => array ( 'private' , 'publish' ),
'posts_per_page' => $per_page ,
'paged' => $page ,
2015-07-06 02:55:08 +00:00
'orderby' => 'ID' ,
'order' => 'DESC' ,
2015-07-02 20:42:22 +00:00
'post_parent' => $product_id
);
$variations = get_posts ( $args );
$loop = 0 ;
if ( $variations ) {
foreach ( $variations as $variation ) {
$variation_id = absint ( $variation -> ID );
$variation_meta = get_post_meta ( $variation_id );
$variation_data = array ();
$shipping_classes = get_the_terms ( $variation_id , 'product_shipping_class' );
$variation_fields = array (
'_sku' => '' ,
'_stock' => '' ,
'_regular_price' => '' ,
'_sale_price' => '' ,
'_weight' => '' ,
'_length' => '' ,
'_width' => '' ,
'_height' => '' ,
'_download_limit' => '' ,
'_download_expiry' => '' ,
'_downloadable_files' => '' ,
'_downloadable' => '' ,
'_virtual' => '' ,
'_thumbnail_id' => '' ,
'_sale_price_dates_from' => '' ,
'_sale_price_dates_to' => '' ,
'_manage_stock' => '' ,
'_stock_status' => '' ,
'_backorders' => null ,
'_tax_class' => null ,
'_variation_description' => ''
);
foreach ( $variation_fields as $field => $value ) {
$variation_data [ $field ] = isset ( $variation_meta [ $field ][ 0 ] ) ? maybe_unserialize ( $variation_meta [ $field ][ 0 ] ) : $value ;
}
// Add the variation attributes
foreach ( $variation_meta as $key => $value ) {
if ( 0 !== strpos ( $key , 'attribute_' ) ) {
continue ;
}
/**
* Pre 2.4 handling where 'slugs' were saved instead of the full text attribute .
* Attempt to get full version of the text attribute from the parent .
*/
if ( sanitize_title ( $value [ 0 ] ) === $value [ 0 ] && version_compare ( get_post_meta ( $product_id , '_product_version' , true ), '2.4.0' , '<' ) ) {
foreach ( $attributes as $attribute ) {
if ( $key !== 'attribute_' . sanitize_title ( $attribute [ 'name' ] ) ) {
continue ;
}
$text_attributes = wc_get_text_attributes ( $attribute [ 'value' ] );
foreach ( $text_attributes as $text_attribute ) {
if ( sanitize_title ( $text_attribute ) === $value [ 0 ] ) {
$value [ 0 ] = $text_attribute ;
}
}
}
}
$variation_data [ $key ] = $value [ 0 ];
}
// Formatting
$variation_data [ '_regular_price' ] = wc_format_localized_price ( $variation_data [ '_regular_price' ] );
$variation_data [ '_sale_price' ] = wc_format_localized_price ( $variation_data [ '_sale_price' ] );
$variation_data [ '_weight' ] = wc_format_localized_decimal ( $variation_data [ '_weight' ] );
$variation_data [ '_length' ] = wc_format_localized_decimal ( $variation_data [ '_length' ] );
$variation_data [ '_width' ] = wc_format_localized_decimal ( $variation_data [ '_width' ] );
$variation_data [ '_height' ] = wc_format_localized_decimal ( $variation_data [ '_height' ] );
$variation_data [ '_thumbnail_id' ] = absint ( $variation_data [ '_thumbnail_id' ] );
$variation_data [ 'image' ] = $variation_data [ '_thumbnail_id' ] ? wp_get_attachment_thumb_url ( $variation_data [ '_thumbnail_id' ] ) : '' ;
$variation_data [ 'shipping_class' ] = $shipping_classes && ! is_wp_error ( $shipping_classes ) ? current ( $shipping_classes ) -> term_id : '' ;
// Stock BW compat
if ( '' !== $variation_data [ '_stock' ] ) {
$variation_data [ '_manage_stock' ] = 'yes' ;
}
include ( 'admin/meta-boxes/views/html-variation-admin.php' );
$loop ++ ;
}
}
die ();
}
2015-07-06 04:50:20 +00:00
/**
* Save variations via AJAX
*/
public static function save_variations () {
ob_start ();
check_ajax_referer ( 'save-variations' , 'security' );
// Check permissions again and make sure we have what we need
2015-07-08 16:55:29 +00:00
if ( ! current_user_can ( 'edit_products' ) || empty ( $_POST ) || empty ( $_POST [ 'product_id' ] ) ) {
2015-07-06 04:50:20 +00:00
die ( - 1 );
}
global $wpdb ;
$product_id = absint ( $_POST [ 'product_id' ] );
$attributes = ( array ) maybe_unserialize ( get_post_meta ( $product_id , '_product_attributes' , true ) );
2015-07-08 16:55:29 +00:00
if ( isset ( $_POST [ 'variable_sku' ] ) ) {
$variable_post_id = $_POST [ 'variable_post_id' ];
$variable_sku = $_POST [ 'variable_sku' ];
$variable_regular_price = $_POST [ 'variable_regular_price' ];
$variable_sale_price = $_POST [ 'variable_sale_price' ];
$upload_image_id = $_POST [ 'upload_image_id' ];
$variable_download_limit = $_POST [ 'variable_download_limit' ];
$variable_download_expiry = $_POST [ 'variable_download_expiry' ];
$variable_shipping_class = $_POST [ 'variable_shipping_class' ];
$variable_tax_class = isset ( $_POST [ 'variable_tax_class' ] ) ? $_POST [ 'variable_tax_class' ] : array ();
$variable_menu_order = $_POST [ 'variation_menu_order' ];
$variable_sale_price_dates_from = $_POST [ 'variable_sale_price_dates_from' ];
$variable_sale_price_dates_to = $_POST [ 'variable_sale_price_dates_to' ];
$variable_weight = isset ( $_POST [ 'variable_weight' ] ) ? $_POST [ 'variable_weight' ] : array ();
$variable_length = isset ( $_POST [ 'variable_length' ] ) ? $_POST [ 'variable_length' ] : array ();
$variable_width = isset ( $_POST [ 'variable_width' ] ) ? $_POST [ 'variable_width' ] : array ();
$variable_height = isset ( $_POST [ 'variable_height' ] ) ? $_POST [ 'variable_height' ] : array ();
$variable_enabled = isset ( $_POST [ 'variable_enabled' ] ) ? $_POST [ 'variable_enabled' ] : array ();
$variable_is_virtual = isset ( $_POST [ 'variable_is_virtual' ] ) ? $_POST [ 'variable_is_virtual' ] : array ();
$variable_is_downloadable = isset ( $_POST [ 'variable_is_downloadable' ] ) ? $_POST [ 'variable_is_downloadable' ] : array ();
$variable_manage_stock = isset ( $_POST [ 'variable_manage_stock' ] ) ? $_POST [ 'variable_manage_stock' ] : array ();
$variable_stock = isset ( $_POST [ 'variable_stock' ] ) ? $_POST [ 'variable_stock' ] : array ();
$variable_backorders = isset ( $_POST [ 'variable_backorders' ] ) ? $_POST [ 'variable_backorders' ] : array ();
$variable_stock_status = isset ( $_POST [ 'variable_stock_status' ] ) ? $_POST [ 'variable_stock_status' ] : array ();
$variable_description = isset ( $_POST [ 'variable_description' ] ) ? $_POST [ 'variable_description' ] : array ();
$max_loop = max ( array_keys ( $_POST [ 'variable_post_id' ] ) );
2015-07-06 04:50:20 +00:00
for ( $i = 0 ; $i <= $max_loop ; $i ++ ) {
if ( ! isset ( $variable_post_id [ $i ] ) ) {
continue ;
}
$variation_id = absint ( $variable_post_id [ $i ] );
// Checkboxes
2015-07-07 19:07:09 +00:00
$is_virtual = isset ( $variable_is_virtual [ $i ] ) ? 'yes' : 'no' ;
$is_downloadable = isset ( $variable_is_downloadable [ $i ] ) ? 'yes' : 'no' ;
$post_status = isset ( $variable_enabled [ $i ] ) ? 'publish' : 'private' ;
$manage_stock = isset ( $variable_manage_stock [ $i ] ) ? 'yes' : 'no' ;
2015-07-06 04:50:20 +00:00
// Generate a useful post title
$variation_post_title = sprintf ( __ ( 'Variation #%s of %s' , 'woocommerce' ), absint ( $variation_id ), esc_html ( get_the_title ( $product_id ) ) );
// Update or Add post
if ( ! $variation_id ) {
$variation = array (
'post_title' => $variation_post_title ,
'post_content' => '' ,
'post_status' => $post_status ,
'post_author' => get_current_user_id (),
'post_parent' => $product_id ,
'post_type' => 'product_variation' ,
'menu_order' => $variable_menu_order [ $i ]
);
$variation_id = wp_insert_post ( $variation );
do_action ( 'woocommerce_create_product_variation' , $variation_id );
} else {
$wpdb -> update ( $wpdb -> posts , array ( 'post_status' => $post_status , 'post_title' => $variation_post_title , 'menu_order' => $variable_menu_order [ $i ] ), array ( 'ID' => $variation_id ) );
do_action ( 'woocommerce_update_product_variation' , $variation_id );
}
// Only continue if we have a variation ID
if ( ! $variation_id ) {
continue ;
}
// Unique SKU
$sku = get_post_meta ( $variation_id , '_sku' , true );
$new_sku = wc_clean ( stripslashes ( $variable_sku [ $i ] ) );
if ( '' == $new_sku ) {
update_post_meta ( $variation_id , '_sku' , '' );
} elseif ( $new_sku !== $sku ) {
if ( ! empty ( $new_sku ) ) {
$unique_sku = wc_product_has_unique_sku ( $variation_id , $new_sku );
if ( ! $unique_sku ) {
WC_Admin_Meta_Boxes :: add_error ( __ ( 'Variation SKU must be unique.' , 'woocommerce' ) );
} else {
update_post_meta ( $variation_id , '_sku' , $new_sku );
}
} else {
update_post_meta ( $variation_id , '_sku' , '' );
}
}
// Update post meta
update_post_meta ( $variation_id , '_thumbnail_id' , absint ( $upload_image_id [ $i ] ) );
update_post_meta ( $variation_id , '_virtual' , wc_clean ( $is_virtual ) );
update_post_meta ( $variation_id , '_downloadable' , wc_clean ( $is_downloadable ) );
if ( isset ( $variable_weight [ $i ] ) ) {
update_post_meta ( $variation_id , '_weight' , ( '' === $variable_weight [ $i ] ) ? '' : wc_format_decimal ( $variable_weight [ $i ] ) );
}
if ( isset ( $variable_length [ $i ] ) ) {
update_post_meta ( $variation_id , '_length' , ( '' === $variable_length [ $i ] ) ? '' : wc_format_decimal ( $variable_length [ $i ] ) );
}
if ( isset ( $variable_width [ $i ] ) ) {
update_post_meta ( $variation_id , '_width' , ( '' === $variable_width [ $i ] ) ? '' : wc_format_decimal ( $variable_width [ $i ] ) );
}
if ( isset ( $variable_height [ $i ] ) ) {
update_post_meta ( $variation_id , '_height' , ( '' === $variable_height [ $i ] ) ? '' : wc_format_decimal ( $variable_height [ $i ] ) );
}
// Stock handling
update_post_meta ( $variation_id , '_manage_stock' , $manage_stock );
// Only update stock status to user setting if changed by the user, but do so before looking at stock levels at variation level
if ( ! empty ( $variable_stock_status [ $i ] ) ) {
wc_update_product_stock_status ( $variation_id , $variable_stock_status [ $i ] );
}
if ( 'yes' === $manage_stock ) {
update_post_meta ( $variation_id , '_backorders' , wc_clean ( $variable_backorders [ $i ] ) );
wc_update_product_stock ( $variation_id , wc_stock_amount ( $variable_stock [ $i ] ) );
} else {
delete_post_meta ( $variation_id , '_backorders' );
delete_post_meta ( $variation_id , '_stock' );
}
// Price handling
$regular_price = wc_format_decimal ( $variable_regular_price [ $i ] );
$sale_price = $variable_sale_price [ $i ] === '' ? '' : wc_format_decimal ( $variable_sale_price [ $i ] );
$date_from = wc_clean ( $variable_sale_price_dates_from [ $i ] );
$date_to = wc_clean ( $variable_sale_price_dates_to [ $i ] );
update_post_meta ( $variation_id , '_regular_price' , $regular_price );
update_post_meta ( $variation_id , '_sale_price' , $sale_price );
// Save Dates
update_post_meta ( $variation_id , '_sale_price_dates_from' , $date_from ? strtotime ( $date_from ) : '' );
update_post_meta ( $variation_id , '_sale_price_dates_to' , $date_to ? strtotime ( $date_to ) : '' );
if ( $date_to && ! $date_from ) {
update_post_meta ( $variation_id , '_sale_price_dates_from' , strtotime ( 'NOW' , current_time ( 'timestamp' ) ) );
}
// Update price if on sale
if ( '' !== $sale_price && '' === $date_to && '' === $date_from ) {
update_post_meta ( $variation_id , '_price' , $sale_price );
} else {
update_post_meta ( $variation_id , '_price' , $regular_price );
}
if ( '' !== $sale_price && $date_from && strtotime ( $date_from ) < strtotime ( 'NOW' , current_time ( 'timestamp' ) ) ) {
update_post_meta ( $variation_id , '_price' , $sale_price );
}
if ( $date_to && strtotime ( $date_to ) < strtotime ( 'NOW' , current_time ( 'timestamp' ) ) ) {
update_post_meta ( $variation_id , '_price' , $regular_price );
update_post_meta ( $variation_id , '_sale_price_dates_from' , '' );
update_post_meta ( $variation_id , '_sale_price_dates_to' , '' );
}
if ( isset ( $variable_tax_class [ $i ] ) && $variable_tax_class [ $i ] !== 'parent' ) {
update_post_meta ( $variation_id , '_tax_class' , wc_clean ( $variable_tax_class [ $i ] ) );
} else {
delete_post_meta ( $variation_id , '_tax_class' );
}
if ( 'yes' == $is_downloadable ) {
update_post_meta ( $variation_id , '_download_limit' , wc_clean ( $variable_download_limit [ $i ] ) );
update_post_meta ( $variation_id , '_download_expiry' , wc_clean ( $variable_download_expiry [ $i ] ) );
$files = array ();
2015-07-08 16:55:29 +00:00
$file_names = isset ( $_POST [ '_wc_variation_file_names' ][ $variation_id ] ) ? array_map ( 'wc_clean' , $_POST [ '_wc_variation_file_names' ][ $variation_id ] ) : array ();
$file_urls = isset ( $_POST [ '_wc_variation_file_urls' ][ $variation_id ] ) ? array_map ( 'wc_clean' , $_POST [ '_wc_variation_file_urls' ][ $variation_id ] ) : array ();
2015-07-06 04:50:20 +00:00
$file_url_size = sizeof ( $file_urls );
$allowed_file_types = get_allowed_mime_types ();
for ( $ii = 0 ; $ii < $file_url_size ; $ii ++ ) {
if ( ! empty ( $file_urls [ $ii ] ) ) {
// Find type and file URL
if ( 0 === strpos ( $file_urls [ $ii ], 'http' ) ) {
$file_is = 'absolute' ;
$file_url = esc_url_raw ( $file_urls [ $ii ] );
} elseif ( '[' === substr ( $file_urls [ $ii ], 0 , 1 ) && ']' === substr ( $file_urls [ $ii ], - 1 ) ) {
$file_is = 'shortcode' ;
$file_url = wc_clean ( $file_urls [ $ii ] );
} else {
$file_is = 'relative' ;
$file_url = wc_clean ( $file_urls [ $ii ] );
}
$file_name = wc_clean ( $file_names [ $ii ] );
$file_hash = md5 ( $file_url );
// Validate the file extension
if ( in_array ( $file_is , array ( 'absolute' , 'relative' ) ) ) {
$file_type = wp_check_filetype ( strtok ( $file_url , '?' ) );
$parsed_url = parse_url ( $file_url , PHP_URL_PATH );
$extension = pathinfo ( $parsed_url , PATHINFO_EXTENSION );
if ( ! empty ( $extension ) && ! in_array ( $file_type [ 'type' ], $allowed_file_types ) ) {
WC_Admin_Meta_Boxes :: add_error ( sprintf ( __ ( 'The downloadable file %s cannot be used as it does not have an allowed file type. Allowed types include: %s' , 'woocommerce' ), '<code>' . basename ( $file_url ) . '</code>' , '<code>' . implode ( ', ' , array_keys ( $allowed_file_types ) ) . '</code>' ) );
continue ;
}
}
// Validate the file exists
if ( 'relative' === $file_is && ! apply_filters ( 'woocommerce_downloadable_file_exists' , file_exists ( $file_url ), $file_url ) ) {
WC_Admin_Meta_Boxes :: add_error ( sprintf ( __ ( 'The downloadable file %s cannot be used as it does not exist on the server.' , 'woocommerce' ), '<code>' . $file_url . '</code>' ) );
continue ;
}
$files [ $file_hash ] = array (
'name' => $file_name ,
'file' => $file_url
);
}
}
// grant permission to any newly added files on any existing orders for this product prior to saving
do_action ( 'woocommerce_process_product_file_download_paths' , $product_id , $variation_id , $files );
update_post_meta ( $variation_id , '_downloadable_files' , $files );
} else {
update_post_meta ( $variation_id , '_download_limit' , '' );
update_post_meta ( $variation_id , '_download_expiry' , '' );
update_post_meta ( $variation_id , '_downloadable_files' , '' );
}
update_post_meta ( $variation_id , '_variation_description' , wp_kses_post ( $variable_description [ $i ] ) );
// Save shipping class
$variable_shipping_class [ $i ] = ! empty ( $variable_shipping_class [ $i ] ) ? ( int ) $variable_shipping_class [ $i ] : '' ;
wp_set_object_terms ( $variation_id , $variable_shipping_class [ $i ], 'product_shipping_class' );
// Update Attributes
$updated_attribute_keys = array ();
foreach ( $attributes as $attribute ) {
if ( $attribute [ 'is_variation' ] ) {
$attribute_key = 'attribute_' . sanitize_title ( $attribute [ 'name' ] );
$updated_attribute_keys [] = $attribute_key ;
if ( $attribute [ 'is_taxonomy' ] ) {
// Don't use wc_clean as it destroys sanitized characters
2015-07-08 16:55:29 +00:00
$value = isset ( $_POST [ $attribute_key ][ $i ] ) ? sanitize_title ( stripslashes ( $_POST [ $attribute_key ][ $i ] ) ) : '' ;
2015-07-06 04:50:20 +00:00
} else {
2015-07-08 16:55:29 +00:00
$value = isset ( $_POST [ $attribute_key ][ $i ] ) ? wc_clean ( stripslashes ( $_POST [ $attribute_key ][ $i ] ) ) : '' ;
2015-07-06 04:50:20 +00:00
}
update_post_meta ( $variation_id , $attribute_key , $value );
}
}
// Remove old taxonomies attributes so data is kept up to date - first get attribute key names
$delete_attribute_keys = $wpdb -> get_col ( $wpdb -> prepare ( " SELECT meta_key FROM { $wpdb -> postmeta } WHERE meta_key LIKE 'attribute_%%' AND meta_key NOT IN ( ' " . implode ( " ',' " , $updated_attribute_keys ) . " ' ) AND post_id = %d; " , $variation_id ) );
foreach ( $delete_attribute_keys as $key ) {
delete_post_meta ( $variation_id , $key );
}
do_action ( 'woocommerce_save_product_variation' , $variation_id , $i );
}
}
// Update parent if variable so price sorting works and stays in sync with the cheapest child
WC_Product_Variable :: sync ( $product_id );
// Update default attribute options setting
$default_attributes = array ();
foreach ( $attributes as $attribute ) {
if ( $attribute [ 'is_variation' ] ) {
// Don't use wc_clean as it destroys sanitized characters
2015-07-08 16:55:29 +00:00
if ( isset ( $_POST [ 'default_attribute_' . sanitize_title ( $attribute [ 'name' ] ) ] ) ) {
$value = sanitize_title ( trim ( stripslashes ( $_POST [ 'default_attribute_' . sanitize_title ( $attribute [ 'name' ] ) ] ) ) );
2015-07-06 04:50:20 +00:00
} else {
$value = '' ;
}
if ( $value ) {
$default_attributes [ sanitize_title ( $attribute [ 'name' ] ) ] = $value ;
}
}
}
update_post_meta ( $product_id , '_default_attributes' , $default_attributes );
2015-07-06 22:07:01 +00:00
2015-07-09 20:43:46 +00:00
do_action ( 'woocommerce_ajax_save_product_variations' , $product_id );
2015-07-06 22:07:01 +00:00
// Clear cache/transients
wc_delete_product_transients ( $product_id );
2015-07-06 04:50:20 +00:00
}
2015-07-07 01:50:35 +00:00
/**
* Bulk edit variations via AJAX
*/
public static function bulk_edit_variations () {
ob_start ();
check_ajax_referer ( 'bulk-edit-variations' , 'security' );
// Check permissions again and make sure we have what we need
if ( ! current_user_can ( 'edit_products' ) || empty ( $_POST [ 'product_id' ] ) || empty ( $_POST [ 'bulk_action' ] ) ) {
die ( - 1 );
}
global $wpdb ;
$product_id = absint ( $_POST [ 'product_id' ] );
$bulk_action = wc_clean ( $_POST [ 'bulk_action' ] );
$data = ! empty ( $_POST [ 'data' ] ) ? array_map ( 'wc_clean' , $_POST [ 'data' ] ) : array ();
$variations = array ();
2015-07-07 19:39:59 +00:00
if ( apply_filters ( 'woocommerce_bulk_edit_variations_need_children' , ! in_array ( $bulk_action , array ( 'variable_weight' , 'variable_length' , 'variable_width' , 'variable_height' ) ) ) ) {
2015-07-07 01:50:35 +00:00
$variations = get_posts ( array (
'post_parent' => $product_id ,
'posts_per_page' => - 1 ,
'post_type' => 'product_variation' ,
'fields' => 'ids' ,
'post_status' => array ( 'publish' , 'private' )
) );
}
switch ( $bulk_action ) {
case 'toggle_enabled' :
foreach ( $variations as $variation_id ) {
$post_status = get_post_status ( $variation_id );
$new_status = 'private' === $post_status ? 'publish' : 'private' ;
$wpdb -> update ( $wpdb -> posts , array ( 'post_status' => $new_status ), array ( 'ID' => $variation_id ) );
}
break ;
case 'toggle_downloadable' :
foreach ( $variations as $variation_id ) {
$_downloadable = get_post_meta ( $variation_id , '_downloadable' , true );
$is_downloadable = 'no' === $_downloadable ? 'yes' : 'no' ;
update_post_meta ( $variation_id , '_downloadable' , wc_clean ( $is_downloadable ) );
}
break ;
case 'toggle_virtual' :
foreach ( $variations as $variation_id ) {
$_virtual = get_post_meta ( $variation_id , '_virtual' , true );
$is_virtual = 'no' === $_virtual ? 'yes' : 'no' ;
update_post_meta ( $variation_id , '_virtual' , wc_clean ( $is_virtual ) );
}
break ;
case 'toggle_manage_stock' :
foreach ( $variations as $variation_id ) {
$_manage_stock = get_post_meta ( $variation_id , '_manage_stock' , true );
$is_manage_stock = 'no' === $_manage_stock ? 'yes' : 'no' ;
update_post_meta ( $variation_id , '_manage_stock' , wc_clean ( $is_manage_stock ) );
}
break ;
case 'variable_regular_price' :
case 'variable_sale_price' :
2015-07-07 19:07:09 +00:00
if ( empty ( $data [ 'value' ] ) ) {
break ;
}
$field = str_replace ( 'variable' , '' , $bulk_action );
2015-07-07 01:50:35 +00:00
2015-07-07 19:07:09 +00:00
foreach ( $variations as $variation_id ) {
2015-07-08 07:05:08 +00:00
// Price fields
2015-07-07 19:07:09 +00:00
$regular_price = '_regular_price' === $field ? $data [ 'value' ] : get_post_meta ( $variation_id , '_regular_price' , true );
$sale_price = '_sale_price' === $field ? $data [ 'value' ] : get_post_meta ( $variation_id , '_sale_price' , true );
2015-07-08 07:05:08 +00:00
// Date fields
$date_from = get_post_meta ( $variation_id , '_sale_price_dates_from' , true );
$date_to = get_post_meta ( $variation_id , '_sale_price_dates_to' , true );
$date_from = ! empty ( $date_from ) ? date ( 'Y-m-d' , $date_from ) : '' ;
$date_to = ! empty ( $date_to ) ? date ( 'Y-m-d' , $date_to ) : '' ;
2015-07-07 19:07:09 +00:00
_wc_save_product_price ( $variation_id , $regular_price , $sale_price , $date_from , $date_to );
}
2015-07-07 01:50:35 +00:00
break ;
case 'variable_stock' :
2015-07-07 19:07:09 +00:00
if ( empty ( $data [ 'value' ] ) ) {
2015-07-07 01:50:35 +00:00
break ;
}
$value = wc_clean ( $data [ 'value' ] );
foreach ( $variations as $variation_id ) {
if ( 'yes' === get_post_meta ( $variation_id , '_manage_stock' , true ) ) {
wc_update_product_stock ( $variation_id , wc_stock_amount ( $value ) );
} else {
delete_post_meta ( $variation_id , '_stock' );
}
}
break ;
case 'variable_weight' :
case 'variable_length' :
case 'variable_width' :
case 'variable_height' :
2015-07-07 19:07:09 +00:00
if ( empty ( $data [ 'value' ] ) ) {
2015-07-07 01:50:35 +00:00
break ;
}
$value = wc_clean ( $data [ 'value' ] );
$field = str_replace ( 'variable' , '' , $bulk_action );
$wpdb -> query ( $wpdb -> prepare ( "
UPDATE $wpdb -> postmeta AS postmeta
INNER JOIN $wpdb -> posts AS posts ON posts . post_parent = % d
SET postmeta . meta_value = % s
WHERE postmeta . meta_key = '%s'
AND postmeta . post_id = posts . ID
" , $product_id , $value , $field ) );
break ;
case 'variable_download_limit' :
case 'variable_download_expiry' :
2015-07-07 19:07:09 +00:00
if ( empty ( $data [ 'value' ] ) ) {
2015-07-07 01:50:35 +00:00
break ;
}
$value = wc_clean ( $data [ 'value' ] );
$field = str_replace ( 'variable' , '' , $bulk_action );
foreach ( $variations as $variation_id ) {
if ( 'yes' === get_post_meta ( $variation_id , '_downloadable' , true ) ) {
update_post_meta ( $variation_id , $field , $value );
} else {
update_post_meta ( $variation_id , $field , '' );
}
}
break ;
case 'delete_all' :
2015-07-07 22:51:50 +00:00
if ( isset ( $data [ 'allowed' ] ) && 'true' === $data [ 'allowed' ] ) {
2015-07-07 01:50:35 +00:00
foreach ( $variations as $variation_id ) {
wp_delete_post ( $variation_id );
}
}
break ;
case 'variable_regular_price_increase' :
case 'variable_regular_price_decrease' :
case 'variable_sale_price_increase' :
case 'variable_sale_price_decrease' :
2015-07-07 20:35:21 +00:00
if ( empty ( $data [ 'value' ] ) ) {
break ;
}
$field = str_replace ( array ( 'variable' , '_increase' , '_decrease' ), '' , $bulk_action );
$operator = 'increase' === substr ( $bulk_action , - 8 ) ? + 1 : - 1 ;
foreach ( $variations as $variation_id ) {
2015-07-08 07:05:08 +00:00
// Price fields
2015-07-07 20:35:21 +00:00
$regular_price = get_post_meta ( $variation_id , '_regular_price' , true );
$sale_price = get_post_meta ( $variation_id , '_sale_price' , true );
2015-07-08 07:05:08 +00:00
// Date fields
$date_from = get_post_meta ( $variation_id , '_sale_price_dates_from' , true );
$date_to = get_post_meta ( $variation_id , '_sale_price_dates_to' , true );
$date_from = ! empty ( $date_from ) ? date ( 'Y-m-d' , $date_from ) : '' ;
$date_to = ! empty ( $date_to ) ? date ( 'Y-m-d' , $date_to ) : '' ;
2015-07-07 20:35:21 +00:00
if ( '%' === substr ( $data [ 'value' ], - 1 ) ) {
$percent = wc_format_decimal ( substr ( $data [ 'value' ], 0 , - 1 ) );
if ( '_regular_price' === $field ) {
$regular_price += ( ( $regular_price / 100 ) * $percent ) * $operator ;
} else {
$sale_price += ( ( $sale_price / 100 ) * $percent ) * $operator ;
}
} else {
if ( '_regular_price' === $field ) {
$regular_price += $data [ 'value' ];
} else {
$sale_price += $data [ 'value' ];
}
}
_wc_save_product_price ( $variation_id , $regular_price , $sale_price , $date_from , $date_to );
}
2015-07-07 01:50:35 +00:00
break ;
case 'variable_sale_schedule' :
2015-07-07 19:39:59 +00:00
if ( ! isset ( $data [ 'date_from' ] ) && ! isset ( $data [ 'date_to' ] ) ) {
break ;
}
foreach ( $variations as $variation_id ) {
2015-07-08 07:05:08 +00:00
// Price fields
2015-07-07 19:39:59 +00:00
$regular_price = get_post_meta ( $variation_id , '_regular_price' , true );
$sale_price = get_post_meta ( $variation_id , '_sale_price' , true );
2015-07-08 07:05:08 +00:00
// Date fields
$date_from = get_post_meta ( $variation_id , '_sale_price_dates_from' , true );
$date_to = get_post_meta ( $variation_id , '_sale_price_dates_to' , true );
if ( 'false' === $data [ 'date_from' ] ) {
$date_from = ! empty ( $date_from ) ? date ( 'Y-m-d' , $date_from ) : '' ;
} else {
$date_from = $data [ 'date_from' ];
}
if ( 'false' === $data [ 'date_to' ] ) {
$date_to = ! empty ( $date_to ) ? date ( 'Y-m-d' , $date_to ) : '' ;
} else {
$date_to = $data [ 'date_to' ];
}
2015-07-07 01:50:35 +00:00
2015-07-07 19:39:59 +00:00
_wc_save_product_price ( $variation_id , $regular_price , $sale_price , $date_from , $date_to );
}
2015-07-07 01:50:35 +00:00
break ;
default :
2015-07-07 19:39:59 +00:00
do_action ( 'woocommerce_bulk_edit_variations_default' , $bulk_action , $data , $product_id , $variations );
2015-07-07 01:50:35 +00:00
break ;
}
2015-07-07 19:39:59 +00:00
do_action ( 'woocommerce_bulk_edit_variations' , $bulk_action , $data , $product_id , $variations );
2015-07-07 01:50:35 +00:00
// Sync and update transients
WC_Product_Variable :: sync ( $product_id );
wc_delete_product_transients ( $product_id );
die ();
}
2013-11-14 12:13:34 +00:00
}
2014-05-28 13:52:50 +00:00
WC_AJAX :: init ();