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-07-31 18:15:17 +00:00
add_action ( 'init' , array ( __CLASS__ , 'define_ajax' ), 0 );
2015-04-09 11:47:37 +00:00
add_action ( 'template_redirect' , array ( __CLASS__ , 'do_wc_ajax' ), 0 );
2015-03-20 12:28:26 +00:00
self :: add_ajax_events ();
}
/**
* 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-08-11 13:04:42 +00:00
return esc_url_raw ( add_query_arg ( 'wc-ajax' , $request , remove_query_arg ( array ( 'remove_item' , 'add-to-cart' , 'added-to-cart' ) ) ) );
2015-03-20 12:28:26 +00:00
}
2015-07-31 18:15:17 +00:00
/**
2015-08-23 20:17:03 +00:00
* Set WC AJAX constant and headers .
2015-07-31 18:15:17 +00:00
*/
public static function define_ajax () {
if ( ! empty ( $_GET [ 'wc-ajax' ] ) ) {
if ( ! defined ( 'DOING_AJAX' ) ) {
define ( 'DOING_AJAX' , true );
}
if ( ! defined ( 'WC_DOING_AJAX' ) ) {
define ( 'WC_DOING_AJAX' , true );
}
2015-08-12 16:45:49 +00:00
// Turn off display_errors during AJAX events to prevent malformed JSON
2015-08-13 09:27:02 +00:00
if ( ! WP_DEBUG || ( WP_DEBUG && ! WP_DEBUG_DISPLAY ) ) {
@ ini_set ( 'display_errors' , 0 );
}
2015-08-23 20:17:03 +00:00
// Send headers like admin-ajax.php
send_origin_headers ();
@ header ( 'Content-Type: text/html; charset=' . get_option ( 'blog_charset' ) );
@ header ( 'X-Robots-Tag: noindex' );
send_nosniff_header ();
nocache_headers ();
2015-07-31 18:15:17 +00:00
}
}
2015-03-20 12:28:26 +00:00
/**
* 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' ] ) ) {
2015-07-24 19:50:50 +00:00
$wp_query -> set ( 'wc-ajax' , sanitize_text_field ( $_GET [ 'wc-ajax' ] ) );
2015-03-20 13:10:47 +00:00
}
2015-07-07 01:50:35 +00:00
if ( $action = $wp_query -> get ( 'wc-ajax' ) ) {
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 ();
}
2015-08-13 12:03:51 +00:00
$variation_id = $variable_product -> get_matching_variation ( wp_unslash ( $_POST ) );
2015-07-09 14:56:20 +00:00
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 );
2015-10-01 14:15:29 +00:00
$order -> update_status ( $status , '' , true );
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 ();
2015-08-14 18:22:16 +00:00
$raw_values = array_map ( 'wc_sanitize_term_text_based' , explode ( WC_DELIMITER , $attribute_values [ $i ] ) );
2015-04-10 13:50:23 +00:00
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 ] ) ) {
2015-09-04 13:00:27 +00:00
// Text based, possibly separated by pipes (WC_DELIMITER). Preserve line breaks in non-variation attributes.
$values = $is_variation ? wc_clean ( $attribute_values [ $i ] ) : implode ( " \n " , array_map ( 'wc_clean' , explode ( " \n " , $attribute_values [ $i ] ) ) );
$values = implode ( ' ' . WC_DELIMITER . ' ' , wc_get_text_attributes ( $values ) );
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 );
}
2015-07-14 12:49:13 +00:00
global $post ;
2013-11-14 12:13:34 +00:00
$post_id = intval ( $_POST [ 'post_id' ] );
2015-07-14 12:49:13 +00:00
$post = get_post ( $post_id ); // Set $post global so its available like within the admin screens
$loop = intval ( $_POST [ 'loop' ] );
2013-11-14 12:13:34 +00:00
$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 ,
2015-07-31 11:39:23 +00:00
'post_type' => 'product_variation' ,
'menu_order' => - 1
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 ) {
2015-08-17 14:11:34 +00:00
$variation = get_post ( $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' => ''
);
2013-11-14 12:13:34 +00:00
2015-08-17 14:11:34 +00:00
foreach ( $variation_fields as $field => $value ) {
$variation_data [ $field ] = isset ( $variation_meta [ $field ][ 0 ] ) ? maybe_unserialize ( $variation_meta [ $field ][ 0 ] ) : $value ;
}
2013-11-14 12:13:34 +00:00
2015-08-17 14:11:34 +00:00
// Add the variation attributes
$variation_data = array_merge ( $variation_data , wc_get_product_variation_attributes ( $variation_id ) );
// 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 : '' ;
$variation_data [ 'menu_order' ] = $variation -> menu_order ;
2015-08-28 16:17:54 +00:00
$variation_data [ '_stock' ] = wc_stock_amount ( $variation_data [ '_stock' ] );
2013-11-14 12:13:34 +00:00
// Get tax classes
2015-08-17 14:11:34 +00:00
$tax_classes = WC_Tax :: get_tax_classes ();
$tax_class_options = array ();
$tax_class_options [ '' ] = __ ( 'Standard' , 'woocommerce' );
2014-05-12 13:04:36 +00:00
2015-08-17 14:11:34 +00:00
if ( ! empty ( $tax_classes ) ) {
2014-05-12 13:04:36 +00:00
foreach ( $tax_classes as $class ) {
2015-08-17 14:11:34 +00:00
$tax_class_options [ sanitize_title ( $class ) ] = esc_attr ( $class );
2014-05-12 13:04:36 +00:00
}
}
2013-11-14 12:13:34 +00:00
2015-08-17 14:11:34 +00:00
// Set backorder options
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' )
);
2015-08-17 14:11:34 +00:00
// set stock status options
2014-08-13 14:03:30 +00:00
$stock_status_options = array (
'instock' => __ ( 'In stock' , 'woocommerce' ),
'outofstock' => __ ( 'Out of stock' , 'woocommerce' )
);
2014-08-21 17:00:39 +00:00
2015-08-17 14:11:34 +00:00
// Get attributes
$attributes = ( array ) maybe_unserialize ( get_post_meta ( $post_id , '_product_attributes' , true ) );
2013-11-14 12:13:34 +00:00
$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 ),
2015-08-17 14:11:34 +00:00
'weight' => wc_format_localized_decimal ( get_post_meta ( $post_id , '_weight' , true ) ),
'length' => wc_format_localized_decimal ( get_post_meta ( $post_id , '_length' , true ) ),
'width' => wc_format_localized_decimal ( get_post_meta ( $post_id , '_width' , true ) ),
'height' => wc_format_localized_decimal ( get_post_meta ( $post_id , '_height' , true ) ),
2014-08-13 14:03:30 +00:00
'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' ] ) {
2015-08-17 14:11:34 +00:00
$parent_data [ 'weight' ] = wc_format_localized_decimal ( 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 [ 'length' ] ) {
2015-08-17 14:11:34 +00:00
$parent_data [ 'length' ] = wc_format_localized_decimal ( 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' ] ) {
2015-08-17 14:11:34 +00:00
$parent_data [ 'width' ] = wc_format_localized_decimal ( 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' ] ) {
2015-08-17 14:11:34 +00:00
$parent_data [ 'height' ] = wc_format_localized_decimal ( 0 );
2014-05-12 13:04:36 +00:00
}
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 );
}
2015-07-15 15:14:32 +00:00
if ( function_exists ( 'set_time_limit' ) && false === strpos ( ini_get ( 'disable_functions' ), 'set_time_limit' ) && ! ini_get ( 'safe_mode' ) ) {
2015-08-18 12:16:23 +00:00
@ set_time_limit ( 0 );
2015-07-15 15:14:32 +00:00
}
2013-11-14 12:13:34 +00:00
$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' ] );
}
2015-07-22 21:57:50 +00:00
$options = array_map ( 'trim' , $options );
2013-11-14 12:13:34 +00:00
$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' ] = '' ;
2015-08-03 12:21:44 +00:00
$item [ 'type' ] = 'line_item' ;
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
2015-08-03 12:21:44 +00:00
$item [ 'item_meta' ] = $order -> get_item_meta ( $item_id );
$item [ 'item_meta_array' ] = $order -> get_item_meta_array ( $item_id );
$item = $order -> expand_item_meta ( $item );
$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-10-01 16:13:33 +00:00
$item_name = $_product -> get_sku () ? $_product -> get_sku () : $order_item [ 'product_id' ];
$note = sprintf ( __ ( 'Item %s stock reduced from %s to %s.' , 'woocommerce' ), $item_name , $new_stock + $stock_change , $new_stock );
2015-06-04 23:57:43 +00:00
$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 ) {
2015-10-01 16:13:33 +00:00
$old_stock = $_product -> get_stock_quantity ();
2014-05-12 13:04:36 +00:00
$stock_change = apply_filters ( 'woocommerce_restore_order_stock_quantity' , $order_item_qty [ $item_id ], $item_id );
$new_quantity = $_product -> increase_stock ( $stock_change );
2015-10-01 16:13:33 +00:00
$item_name = $_product -> get_sku () ? $_product -> get_sku () : $order_item [ 'product_id' ];
$note = sprintf ( __ ( 'Item %s stock increased from %s to %s.' , 'woocommerce' ), $item_name , $old_stock , $new_quantity );
2015-06-05 00:02:03 +00:00
$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 ();
2015-10-05 14:31:58 +00:00
$tax_based_on = get_option ( 'woocommerce_tax_based_on' );
2014-07-24 20:33:26 +00:00
$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
2015-10-05 14:31:58 +00:00
// Default to base
if ( 'base' === $tax_based_on || empty ( $country ) ) {
$default = wc_get_base_location ();
$country = $default [ 'country' ];
$state = $default [ 'state' ];
$postcode = '' ;
$city = '' ;
}
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' ) ) {
2015-10-02 08:00:26 +00:00
global $wpdb ;
2014-09-16 12:24:02 +00:00
ob_start ();
2013-11-14 12:13:34 +00:00
check_ajax_referer ( 'search-products' , 'security' );
2015-07-20 16:41:14 +00:00
$term = ( string ) wc_clean ( stripslashes ( $_GET [ 'term' ] ) );
$exclude = array ();
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-10-02 08:00:26 +00:00
$like_term = '%' . $wpdb -> esc_like ( $term ) . '%' ;
2015-02-23 18:23:53 +00:00
2013-11-14 12:13:34 +00:00
if ( is_numeric ( $term ) ) {
2015-10-02 08:00:26 +00:00
$query = $wpdb -> prepare ( "
SELECT ID FROM { $wpdb -> posts } posts LEFT JOIN { $wpdb -> postmeta } postmeta ON posts . ID = postmeta . post_id
WHERE posts . post_status = 'publish'
AND (
posts . post_parent = % s
OR posts . ID = % s
OR posts . post_title LIKE % s
OR (
postmeta . meta_key = '_sku' AND postmeta . meta_value LIKE % s
2013-11-14 12:13:34 +00:00
)
2015-10-02 08:00:26 +00:00
)
" , $term , $term , $term , $like_term );
2013-11-14 12:13:34 +00:00
} else {
2015-10-02 08:00:26 +00:00
$query = $wpdb -> prepare ( "
SELECT ID FROM { $wpdb -> posts } posts LEFT JOIN { $wpdb -> postmeta } postmeta ON posts . ID = postmeta . post_id
WHERE posts . post_status = 'publish'
AND (
posts . post_title LIKE % s
or posts . post_content LIKE % s
OR (
postmeta . meta_key = '_sku' AND postmeta . meta_value LIKE % s
2013-11-14 12:13:34 +00:00
)
2015-10-02 08:00:26 +00:00
)
" , $like_term , $like_term , $like_term );
}
2013-11-14 12:13:34 +00:00
2015-10-02 08:00:26 +00:00
$query .= " AND posts.post_type IN (' " . implode ( " ',' " , array_map ( 'esc_sql' , $post_types ) ) . " ') " ;
2013-11-14 12:13:34 +00:00
2015-10-02 08:00:26 +00:00
if ( ! empty ( $_GET [ 'exclude' ] ) ) {
$query .= " AND posts.ID NOT IN ( " . implode ( ',' , array_map ( 'intval' , explode ( ',' , $_GET [ 'exclude' ] ) ) ) . " ) " ;
2013-11-14 12:13:34 +00:00
}
2015-10-02 08:00:26 +00:00
$posts = array_unique ( $wpdb -> get_col ( $query ) );
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-20 16:41:14 +00:00
$term = ( string ) wc_clean ( stripslashes ( $_GET [ 'term' ] ) );
$exclude = array ();
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-20 16:41:14 +00:00
if ( ! empty ( $_GET [ 'exclude' ] ) ) {
$exclude = array_map ( 'intval' , explode ( ',' , $_GET [ 'exclude' ] ) );
}
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 ,
2015-07-20 16:41:14 +00:00
'fields' => 'ids' ,
'exclude' => $exclude
2015-07-08 21:38:17 +00:00
);
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
*
* @ 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' );
2015-07-20 16:41:14 +00:00
$term = ( string ) wc_clean ( stripslashes ( $_GET [ 'term' ] ) );
$exclude = array ();
if ( ! empty ( $_GET [ 'exclude' ] ) ) {
$exclude = array_map ( 'intval' , explode ( ',' , $_GET [ 'exclude' ] ) );
}
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'
)
),
2015-07-20 16:41:14 +00:00
's' => $term ,
'exclude' => $exclude
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
2015-08-07 10:05:27 +00:00
$siblings = $wpdb -> get_results ( $wpdb -> prepare ( "
SELECT ID , menu_order FROM { $wpdb -> posts } AS posts
WHERE posts . post_type = 'product'
AND posts . post_status IN ( 'publish' , 'pending' , 'draft' , 'future' , 'private' )
AND posts . ID NOT IN ( % d )
2013-11-14 12:13:34 +00:00
ORDER BY posts . menu_order ASC , posts . ID DESC
2015-08-07 10:05:27 +00:00
" , $post->ID ) );
2013-11-14 12:13:34 +00:00
$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 ,
2015-10-06 13:43:33 +00:00
'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-10-06 13:43:33 +00:00
// Trigger notifications and status changes
if ( $order -> get_remaining_refund_amount () > 0 || $order -> get_remaining_refund_items () > 0 ) {
/**
* woocommerce_order_partially_refunded
*
* @ since 2.4 . 0
* Note : 3 rd arg was added in err . Kept for bw compat . 2.4 . 3
*/
do_action ( 'woocommerce_order_partially_refunded' , $order_id , $refund -> id , $refund -> id );
} else {
do_action ( 'woocommerce_order_fully_refunded' , $order_id , $refund -> id );
2015-07-29 12:13:41 +00:00
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' ] );
2015-09-07 15:29:03 +00:00
$description = sanitize_text_field ( wp_unslash ( $_POST [ 'description' ] ) );
2015-06-08 22:41:35 +00:00
$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-07-16 18:42:00 +00:00
'consumer_secret' => $consumer_secret ,
'truncated_key' => substr ( $consumer_key , - 7 )
2015-06-08 22:41:35 +00:00
);
$wpdb -> insert (
$wpdb -> prefix . 'woocommerce_api_keys' ,
$data ,
array (
'%d' ,
'%s' ,
'%s' ,
'%s' ,
2015-07-16 18:42:00 +00:00
'%s' ,
2015-06-08 22:41:35 +00:00
'%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
}
2015-07-14 11:28:31 +00:00
global $post ;
2015-07-02 20:42:22 +00:00
$product_id = absint ( $_POST [ 'product_id' ] );
2015-07-14 11:28:31 +00:00
$post = get_post ( $product_id ); // Set $post global so its available like within the admin screens
2015-07-02 20:42:22 +00:00
$per_page = ! empty ( $_POST [ 'per_page' ] ) ? absint ( $_POST [ 'per_page' ] ) : 10 ;
$page = ! empty ( $_POST [ 'page' ] ) ? absint ( $_POST [ 'page' ] ) : 1 ;
// Get attributes
2015-08-13 11:07:05 +00:00
$attributes = array ();
2015-08-13 12:03:51 +00:00
$posted_attributes = wp_unslash ( $_POST [ 'attributes' ] );
2015-08-13 11:07:05 +00:00
foreach ( $posted_attributes as $key => $value ) {
2015-08-19 10:33:39 +00:00
$attributes [ $key ] = array_map ( 'wc_clean' , $value );
2015-07-02 20:42:22 +00:00
}
// 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
2015-07-30 22:11:53 +00:00
$args = apply_filters ( 'woocommerce_ajax_admin_get_variations_args' , array (
2015-07-02 20:42:22 +00:00
'post_type' => 'product_variation' ,
'post_status' => array ( 'private' , 'publish' ),
'posts_per_page' => $per_page ,
'paged' => $page ,
2015-08-13 09:40:50 +00:00
'orderby' => array ( 'menu_order' => 'ASC' , 'ID' => 'DESC' ),
2015-07-02 20:42:22 +00:00
'post_parent' => $product_id
2015-07-30 22:11:53 +00:00
), $product_id );
2015-07-02 20:42:22 +00:00
$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
2015-07-28 15:20:51 +00:00
$variation_data = array_merge ( $variation_data , wc_get_product_variation_attributes ( $variation_id ) );
2015-07-02 20:42:22 +00:00
// 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 : '' ;
2015-07-31 11:39:23 +00:00
$variation_data [ 'menu_order' ] = $variation -> menu_order ;
2015-07-02 20:42:22 +00:00
// 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 );
}
2015-07-27 17:16:52 +00:00
// Remove previous meta box errors
WC_Admin_Meta_Boxes :: $meta_box_errors = array ();
Save product type before saving variations
WooCommerce prior to WC 2.4 saved the product type before any variations were saved because
WC_Meta_Box_Product_Data::save_variations() was called by WC_Meta_Box_Product_Data::save().
However, in WC 2.4 the variations are saved independently of other data about the containing
variable product, including product type. Because the product type hasn't been saved yet,
extensions that need to save their own variation level meta data can't know when saving
variations if the product is of the type they want to act on. They also can't check `$_POST`
to find out when saving variations, because 'product-type' isn't passed to that as it's
variable level meta data, not variation level meta data.
This patch passes the product type along with the variation level meta data when saving variations.
It then uses that to save the product type if the variable product has not yet been saved (and
therefore the product type has never been stored, which means calling get_product() would instantiate
a 'simple' product, as that is the default product type). This can lead to fatal errors if callbacks
expect the product type to be variable and attempt to call methods that only exist on those product
types, like variable_product_sync().
It will also update the product type if it was previously saved but has since changed. This prevents
fatal errors like that mentioned above but caused by switching from one product type, like a simple
product, to another, like a variable product.
2015-07-31 18:42:21 +00:00
$product_id = absint ( $_POST [ 'product_id' ] );
$product_type = empty ( $_POST [ 'product-type' ] ) ? 'simple' : sanitize_title ( stripslashes ( $_POST [ 'product-type' ] ) );
$product_type_terms = wp_get_object_terms ( $product_id , 'product_type' );
// If the product type hasn't been set or it has changed, update it before saving variations
if ( empty ( $product_type_terms ) || $product_type !== sanitize_title ( current ( $product_type_terms ) -> name ) ) {
wp_set_object_terms ( $product_id , $product_type , 'product_type' );
}
2015-07-24 05:15:44 +00:00
WC_Meta_Box_Product_Data :: save_variations ( $product_id , get_post ( $product_id ) );
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-27 17:16:52 +00:00
if ( $errors = WC_Admin_Meta_Boxes :: $meta_box_errors ) {
2015-07-29 22:56:33 +00:00
echo '<div class="error notice is-dismissible">' ;
2015-07-27 17:16:52 +00:00
foreach ( $errors as $error ) {
echo '<p>' . wp_kses_post ( $error ) . '</p>' ;
}
2015-07-29 22:56:33 +00:00
echo '<button type="button" class="notice-dismiss"><span class="screen-reader-text">' . __ ( 'Dismiss this notice.' , 'woocommerce' ) . '</span></button>' ;
2015-07-27 17:16:52 +00:00
echo '</div>' ;
delete_option ( 'woocommerce_meta_box_errors' );
}
die ();
2015-07-06 04:50:20 +00:00
}
2015-07-07 01:50:35 +00:00
/**
2015-07-14 10:39:48 +00:00
* Bulk action - Toggle Enabled
* @ access private
* @ param array $variations
* @ param array $data
2015-07-07 01:50:35 +00:00
*/
2015-07-14 10:39:48 +00:00
private static function variation_bulk_action_toggle_enabled ( $variations , $data ) {
global $wpdb ;
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
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 ) );
}
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Toggle Downloadable Checkbox
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_toggle_downloadable ( $variations , $data ) {
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 ) );
2015-07-07 01:50:35 +00:00
}
2015-07-14 10:39:48 +00:00
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Toggle Virtual Checkbox
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_toggle_virtual ( $variations , $data ) {
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 ) );
}
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Toggle Manage Stock Checkbox
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_toggle_manage_stock ( $variations , $data ) {
foreach ( $variations as $variation_id ) {
$_manage_stock = get_post_meta ( $variation_id , '_manage_stock' , true );
2015-08-21 15:33:55 +00:00
$is_manage_stock = 'no' === $_manage_stock || '' === $_manage_stock ? 'yes' : 'no' ;
update_post_meta ( $variation_id , '_manage_stock' , $is_manage_stock );
2015-07-14 10:39:48 +00:00
}
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Set Regular Prices
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_regular_price ( $variations , $data ) {
2015-09-16 12:20:59 +00:00
if ( ! isset ( $data [ 'value' ] ) ) {
2015-08-11 12:47:12 +00:00
return ;
2015-07-07 01:50:35 +00:00
}
2015-07-14 10:39:48 +00:00
foreach ( $variations as $variation_id ) {
// Price fields
$regular_price = wc_clean ( $data [ 'value' ] );
$sale_price = get_post_meta ( $variation_id , '_sale_price' , true );
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +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 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
_wc_save_product_price ( $variation_id , $regular_price , $sale_price , $date_from , $date_to );
}
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Set Sale Prices
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_sale_price ( $variations , $data ) {
2015-09-16 12:20:59 +00:00
if ( ! isset ( $data [ 'value' ] ) ) {
2015-08-11 12:47:12 +00:00
return ;
2015-07-14 10:39:48 +00:00
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
foreach ( $variations as $variation_id ) {
// Price fields
$regular_price = get_post_meta ( $variation_id , '_regular_price' , true );
$sale_price = wc_clean ( $data [ 'value' ] );
// 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
2015-07-14 10:39:48 +00:00
_wc_save_product_price ( $variation_id , $regular_price , $sale_price , $date_from , $date_to );
}
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Set Stock
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_stock ( $variations , $data ) {
2015-08-21 15:48:25 +00:00
if ( ! isset ( $data [ 'value' ] ) ) {
2015-08-11 12:47:12 +00:00
return ;
2015-07-14 10:39:48 +00:00
}
2015-07-08 07:05:08 +00:00
2015-07-14 10:39:48 +00:00
$value = wc_clean ( $data [ 'value' ] );
2015-07-07 19:07:09 +00:00
2015-08-21 15:48:25 +00:00
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' );
2015-07-14 10:39:48 +00:00
}
}
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Set Weight
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_weight ( $variations , $data ) {
self :: variation_bulk_set_meta ( $variations , '_weight' , wc_clean ( $data [ 'value' ] ) );
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Set Length
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_length ( $variations , $data ) {
self :: variation_bulk_set_meta ( $variations , '_length' , wc_clean ( $data [ 'value' ] ) );
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Set Width
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_width ( $variations , $data ) {
self :: variation_bulk_set_meta ( $variations , '_width' , wc_clean ( $data [ 'value' ] ) );
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Set Height
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_height ( $variations , $data ) {
self :: variation_bulk_set_meta ( $variations , '_height' , wc_clean ( $data [ 'value' ] ) );
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Set Download Limit
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_download_limit ( $variations , $data ) {
self :: variation_bulk_set_meta ( $variations , '_download_limit' , wc_clean ( $data [ 'value' ] ) );
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Set Download Expiry
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_download_expiry ( $variations , $data ) {
self :: variation_bulk_set_meta ( $variations , '_download_expiry' , wc_clean ( $data [ 'value' ] ) );
}
2015-07-07 20:35:21 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Delete all
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_delete_all ( $variations , $data ) {
if ( isset ( $data [ 'allowed' ] ) && 'true' === $data [ 'allowed' ] ) {
foreach ( $variations as $variation_id ) {
wp_delete_post ( $variation_id );
}
}
}
2015-07-07 20:35:21 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Sale Schedule
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_sale_schedule ( $variations , $data ) {
if ( ! isset ( $data [ 'date_from' ] ) && ! isset ( $data [ 'date_to' ] ) ) {
2015-08-11 12:47:12 +00:00
return ;
2015-07-14 10:39:48 +00:00
}
2015-07-08 07:05:08 +00:00
2015-07-14 10:39:48 +00:00
foreach ( $variations as $variation_id ) {
// Price fields
$regular_price = get_post_meta ( $variation_id , '_regular_price' , true );
$sale_price = get_post_meta ( $variation_id , '_sale_price' , true );
2015-07-07 20:35:21 +00:00
2015-07-14 10:39:48 +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 );
2015-07-07 20:35:21 +00:00
2015-07-14 10:39:48 +00:00
if ( 'false' === $data [ 'date_from' ] ) {
$date_from = ! empty ( $date_from ) ? date ( 'Y-m-d' , $date_from ) : '' ;
} else {
$date_from = $data [ 'date_from' ];
}
2015-07-07 20:35:21 +00:00
2015-07-14 10:39:48 +00:00
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-14 10:39:48 +00:00
_wc_save_product_price ( $variation_id , $regular_price , $sale_price , $date_from , $date_to );
}
}
2015-07-07 19:39:59 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Increase Regular Prices
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_regular_price_increase ( $variations , $data ) {
self :: variation_bulk_adjust_price ( $variations , '_regular_price' , '+' , wc_clean ( $data [ 'value' ] ) );
}
2015-07-08 07:05:08 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Decrease Regular Prices
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_regular_price_decrease ( $variations , $data ) {
self :: variation_bulk_adjust_price ( $variations , '_regular_price' , '-' , wc_clean ( $data [ 'value' ] ) );
}
2015-07-08 07:05:08 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Increase Sale Prices
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_sale_price_increase ( $variations , $data ) {
self :: variation_bulk_adjust_price ( $variations , '_sale_price' , '+' , wc_clean ( $data [ 'value' ] ) );
}
2015-07-08 07:05:08 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Decrease Sale Prices
* @ access private
* @ param array $variations
* @ param array $data
*/
private static function variation_bulk_action_variable_sale_price_decrease ( $variations , $data ) {
self :: variation_bulk_adjust_price ( $variations , '_sale_price' , '-' , wc_clean ( $data [ 'value' ] ) );
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Set Price
* @ access private
* @ param array $variations
* @ param string $operator + or -
* @ param string $field price being adjusted
* @ param string $value Price or Percent
*/
private static function variation_bulk_adjust_price ( $variations , $field , $operator , $value ) {
foreach ( $variations as $variation_id ) {
// Get existing data
$_regular_price = get_post_meta ( $variation_id , '_regular_price' , true );
$_sale_price = get_post_meta ( $variation_id , '_sale_price' , true );
$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 ) : '' ;
if ( '%' === substr ( $value , - 1 ) ) {
$percent = wc_format_decimal ( substr ( $value , 0 , - 1 ) );
$$field += ( ( $$field / 100 ) * $percent ) * " { $operator } 1 " ;
} else {
$$field += $value * " { $operator } 1 " ;
}
_wc_save_product_price ( $variation_id , $_regular_price , $_sale_price , $date_from , $date_to );
}
}
2015-07-07 01:50:35 +00:00
2015-07-14 10:39:48 +00:00
/**
* Bulk action - Set Meta
* @ access private
2015-07-16 19:29:01 +00:00
* @ param array $variations
* @ param string $field
* @ param string $value
2015-07-14 10:39:48 +00:00
*/
private static function variation_bulk_set_meta ( $variations , $field , $value ) {
foreach ( $variations as $variation_id ) {
update_post_meta ( $variation_id , $field , $value );
}
}
/**
* 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 );
}
$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 ();
if ( apply_filters ( 'woocommerce_bulk_edit_variations_need_children' , true ) ) {
$variations = get_posts ( array (
'post_parent' => $product_id ,
'posts_per_page' => - 1 ,
'post_type' => 'product_variation' ,
'fields' => 'ids' ,
'post_status' => array ( 'publish' , 'private' )
) );
}
if ( method_exists ( __CLASS__ , " variation_bulk_action_ $bulk_action " ) ) {
call_user_func ( array ( __CLASS__ , " variation_bulk_action_ $bulk_action " ), $variations , $data );
} else {
do_action ( 'woocommerce_bulk_edit_variations_default' , $bulk_action , $data , $product_id , $variations );
2015-07-07 01:50:35 +00:00
}
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 ();