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
/**
2015-11-03 13:31:20 +00:00
* WooCommerce WC_AJAX .
2013-11-14 12:13:34 +00:00
*
2015-11-03 13:31:20 +00:00
* AJAX Event Handler .
2013-11-14 12:13:34 +00:00
*
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-11-03 13:31:20 +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-11-30 12:10:31 +00:00
add_action ( 'init' , array ( __CLASS__ , 'define_ajax' ), 0 );
add_action ( 'template_redirect' , array ( __CLASS__ , 'do_wc_ajax' ), 0 );
2015-03-20 12:28:26 +00:00
self :: add_ajax_events ();
}
/**
2015-11-03 13:31:20 +00:00
* Get WC Ajax Endpoint .
2015-03-20 12:28:26 +00:00
* @ 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-11-04 13:35:32 +00:00
$GLOBALS [ 'wpdb' ] -> hide_errors ();
2015-07-31 18:15:17 +00:00
}
}
2015-11-30 12:10:31 +00:00
/**
* Send headers for WC Ajax Requests
* @ since 2.5 . 0
*/
private static function wc_ajax_headers () {
send_origin_headers ();
@ header ( 'Content-Type: text/html; charset=' . get_option ( 'blog_charset' ) );
@ header ( 'X-Robots-Tag: noindex' );
send_nosniff_header ();
nocache_headers ();
status_header ( 200 );
}
2015-03-20 12:28:26 +00:00
/**
2015-11-03 13:31:20 +00:00
* Check for WC Ajax request and fire action .
2015-03-20 12:28:26 +00:00
*/
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' ) ) {
2015-11-30 12:10:31 +00:00
self :: wc_ajax_headers ();
2015-07-07 01:50:35 +00:00
do_action ( 'wc_ajax_' . sanitize_text_field ( $action ) );
die ();
}
2015-03-20 12:28:26 +00:00
}
/**
2015-11-03 13:31:20 +00:00
* Hook in methods - uses WordPress ajax handlers ( admin - ajax ) .
2015-03-20 12:28:26 +00:00
*/
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 ,
2016-02-11 06:26:41 +00:00
'get_cart_totals' => true ,
2014-07-10 12:33:05 +00:00
'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 ,
2016-03-22 17:13:39 +00:00
'reduce_order_item_stock' => false ,
'increase_order_item_stock' => false ,
2014-07-10 12:33:05 +00:00
'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 ,
2015-08-13 21:49:59 +00:00
'bulk_edit_variations' => false ,
'tax_rates_save_changes' => false ,
2015-12-10 11:55:03 +00:00
'shipping_zones_save_changes' => false ,
2015-12-16 15:16:52 +00:00
'shipping_zone_add_method' => false ,
2015-12-15 17:48:03 +00:00
'shipping_zone_methods_save_changes' => false ,
2016-03-24 17:26:40 +00:00
'shipping_zone_methods_save_settings' => false ,
2016-01-13 16:52:28 +00:00
'shipping_classes_save_changes' => 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
}
}
/**
2015-11-03 13:31:20 +00:00
* Get a refreshed cart fragment .
2013-11-14 12:13:34 +00:00
*/
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
}
/**
2015-11-03 13:31:20 +00:00
* AJAX apply coupon on checkout page .
2013-11-14 12:13:34 +00:00
*/
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
/**
2015-11-03 13:31:20 +00:00
* AJAX remove coupon on cart and checkout page .
2014-12-08 06:15:03 +00:00
*/
public static function remove_coupon () {
check_ajax_referer ( 'remove-coupon' , 'security' );
$coupon = wc_clean ( $_POST [ 'coupon' ] );
if ( ! isset ( $coupon ) || empty ( $coupon ) ) {
2016-04-12 15:07:11 +00:00
wc_add_notice ( __ ( 'Sorry there was a problem removing this coupon.' , 'woocommerce' ), 'error' );
2014-12-08 06:15:03 +00:00
} 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
/**
2015-11-03 13:31:20 +00:00
* AJAX update shipping method on cart page .
2013-11-14 12:13:34 +00:00
*/
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 ();
}
2016-02-11 06:26:41 +00:00
/**
* AJAX receive updated cart_totals div .
*/
public static function get_cart_totals () {
2016-02-15 03:56:42 +00:00
if ( ! defined ( 'WOOCOMMERCE_CART' ) ) {
2016-02-11 06:26:41 +00:00
define ( 'WOOCOMMERCE_CART' , true );
}
WC () -> cart -> calculate_totals ();
woocommerce_cart_totals ();
die ();
}
2013-11-14 12:13:34 +00:00
/**
2015-11-03 13:31:20 +00:00
* AJAX update order review on checkout .
2013-11-14 12:13:34 +00:00
*/
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
2016-04-18 13:51:39 +00:00
if ( ! empty ( $_POST [ 'country' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_country ( $_POST [ 'country' ] );
2016-01-25 10:16:36 +00:00
WC () -> customer -> calculated_shipping ( true );
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 {
2016-04-18 13:51:39 +00:00
if ( ! empty ( $_POST [ 's_country' ] ) ) {
2014-02-14 11:19:32 +00:00
WC () -> customer -> set_shipping_country ( $_POST [ 's_country' ] );
2016-01-25 10:16:36 +00:00
WC () -> customer -> calculated_shipping ( true );
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
) )
);
2016-01-21 20:29:14 +00:00
unset ( WC () -> session -> refresh_totals , WC () -> session -> reload_checkout );
2014-11-26 14:19:53 +00:00
wp_send_json ( $data );
2013-11-14 12:13:34 +00:00
die ();
}
/**
2015-11-03 13:31:20 +00:00
* AJAX add to cart .
2013-11-14 12:13:34 +00:00
*/
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' ) {
2016-01-20 11:32:49 +00:00
wc_add_to_cart_message ( array ( $product_id => $quantity ), true );
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Process ajax checkout form .
2013-11-14 12:13:34 +00:00
*/
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
/**
2015-11-03 13:31:20 +00:00
* Get a matching variation based on posted attributes .
2015-07-09 14:56:20 +00:00
*/
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
/**
2015-11-03 13:31:20 +00:00
* Feature a product from admin .
2013-11-14 12:13:34 +00:00
*/
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
2016-04-18 10:48:57 +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=product' ) );
2013-11-14 12:13:34 +00:00
die ();
}
/**
2015-11-03 13:31:20 +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
/**
2015-11-03 13:31:20 +00:00
* Add an attribute row .
2014-12-22 14:16:12 +00:00
*/
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 ),
2016-05-06 10:49:06 +00:00
'is_variation' => apply_filters ( 'woocommerce_attribute_default_is_variation' , 0 ),
2014-12-22 14:16:12 +00:00
'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
/**
2015-11-03 13:31:20 +00:00
* Add a new attribute via ajax function .
2013-11-14 12:13:34 +00:00
*/
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Delete variations via ajax function .
2013-11-14 12:13:34 +00:00
*/
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Save attributes via ajax .
2013-11-14 12:13:34 +00:00
*/
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Add variation via ajax function .
2013-11-14 12:13:34 +00:00
*/
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Link all variations via ajax function .
2013-11-14 12:13:34 +00:00
*/
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
);
2014-05-12 13:04:36 +00:00
$variation_ids = array ();
$added = 0 ;
2015-11-04 12:14:48 +00:00
$possible_variations = wc_array_cartesian ( $variations );
2013-11-14 12:13:34 +00:00
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Delete download permissions via ajax function .
2013-11-14 12:13:34 +00:00
*/
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Grant download permissions via ajax function .
2013-11-14 12:13:34 +00:00
*/
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Get customer details via ajax .
2013-11-14 12:13:34 +00:00
*/
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
}
/**
2015-11-03 13:31:20 +00:00
* Add order item via ajax .
2013-11-14 12:13:34 +00:00
*/
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Add order fee via ajax .
2013-11-14 12:13:34 +00:00
*/
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
/**
2015-11-03 13:31:20 +00:00
* Add order shipping cost via ajax .
2014-07-16 18:41:18 +00:00
*/
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
2016-03-23 15:16:09 +00:00
$shipping = new WC_Shipping_Rate ();
2014-07-24 20:55:25 +00:00
$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
/**
2015-11-03 13:31:20 +00:00
* Add order tax column via ajax .
2014-07-21 01:36:12 +00:00
*/
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
/**
2015-11-03 13:31:20 +00:00
* Remove an order item .
2013-11-14 12:13:34 +00:00
*/
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
/**
2015-11-03 13:31:20 +00:00
* Remove an order tax .
2014-07-21 01:57:23 +00:00
*/
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 ();
}
2016-03-22 17:13:39 +00:00
/**
* Reduce order item stock .
*/
public static function reduce_order_item_stock () {
check_ajax_referer ( 'order-item' , 'security' );
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
$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 ();
$order = wc_get_order ( $order_id );
$order_items = $order -> get_items ();
$return = array ();
if ( $order && ! empty ( $order_items ) && sizeof ( $order_item_ids ) > 0 ) {
foreach ( $order_items as $item_id => $order_item ) {
// Only reduce checked items
if ( ! in_array ( $item_id , $order_item_ids ) ) {
continue ;
}
$_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 ) {
$stock_change = apply_filters ( 'woocommerce_reduce_order_stock_quantity' , $order_item_qty [ $item_id ], $item_id );
$new_stock = $_product -> reduce_stock ( $stock_change );
$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 );
$return [] = $note ;
$order -> add_order_note ( $note );
$order -> send_stock_notifications ( $_product , $new_stock , $order_item_qty [ $item_id ] );
}
}
do_action ( 'woocommerce_reduce_order_stock' , $order );
if ( empty ( $return ) ) {
$return [] = __ ( 'No products had their stock reduced - they may not have stock management enabled.' , 'woocommerce' );
}
echo implode ( ', ' , $return );
}
die ();
}
/**
* Increase order item stock .
*/
public static function increase_order_item_stock () {
check_ajax_referer ( 'order-item' , 'security' );
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
$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 ();
$order = wc_get_order ( $order_id );
$order_items = $order -> get_items ();
$return = array ();
if ( $order && ! empty ( $order_items ) && sizeof ( $order_item_ids ) > 0 ) {
foreach ( $order_items as $item_id => $order_item ) {
// Only reduce checked items
if ( ! in_array ( $item_id , $order_item_ids ) ) {
continue ;
}
$_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 ) {
$old_stock = $_product -> get_stock_quantity ();
$stock_change = apply_filters ( 'woocommerce_restore_order_stock_quantity' , $order_item_qty [ $item_id ], $item_id );
$new_quantity = $_product -> increase_stock ( $stock_change );
$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 );
$return [] = $note ;
$order -> add_order_note ( $note );
}
}
do_action ( 'woocommerce_restore_order_stock' , $order );
if ( empty ( $return ) ) {
$return [] = __ ( 'No products had their stock increased - they may not have stock management enabled.' , 'woocommerce' );
}
echo implode ( ', ' , $return );
}
die ();
}
2013-11-14 12:13:34 +00:00
/**
2015-11-03 13:31:20 +00:00
* Add some meta to a line item .
2013-11-14 12:13:34 +00:00
*/
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Remove meta from a line item .
2013-11-14 12:13:34 +00:00
*/
2014-05-28 13:52:50 +00:00
public static function remove_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 );
}
2016-05-11 14:28:40 +00:00
global $wpdb ;
2013-11-14 12:13:34 +00:00
2016-05-11 14:28:40 +00:00
$wpdb -> delete ( " { $wpdb -> prefix } woocommerce_order_itemmeta " , array (
'meta_id' => absint ( $_POST [ 'meta_id' ] ),
) );
2013-11-14 12:13:34 +00:00
die ();
}
/**
2015-11-03 13:31:20 +00:00
* Calc line tax .
2013-11-14 12:13:34 +00:00
*/
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 );
}
2016-04-18 11:56:59 +00:00
$tax = new WC_Tax ();
$tax_based_on = get_option ( 'woocommerce_tax_based_on' );
$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' ] ) );
$city = wc_clean ( esc_attr ( $_POST [ 'city' ] ) );
$order = wc_get_order ( $order_id );
$taxes = array ();
$shipping_taxes = array ();
$order_item_tax_classes = 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 );
2016-02-18 18:57:55 +00:00
$is_vat_exempt = get_post_meta ( $order_id , '_is_vat_exempt' , true );
2016-02-22 15:19:44 +00:00
2016-01-05 20:43:26 +00:00
// Tax is calculated only if tax is enabled and order is not vat exempted
2016-02-18 19:29:10 +00:00
if ( wc_tax_enabled () && $is_vat_exempt !== 'yes' ) {
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +00:00
// Get items and fees taxes
if ( isset ( $items [ 'order_item_id' ] ) ) {
2016-04-18 11:56:59 +00:00
$line_total = $line_subtotal = array ();
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +00:00
foreach ( $items [ 'order_item_id' ] as $item_id ) {
2016-04-18 11:56:59 +00:00
$item_id = absint ( $item_id );
$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_classes [ $item_id ] = isset ( $items [ 'order_item_tax_class' ][ $item_id ] ) ? sanitize_text_field ( $items [ 'order_item_tax_class' ][ $item_id ] ) : '' ;
$product_id = $order -> get_item_meta ( $item_id , '_product_id' , true );
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +00:00
// Get product details
if ( get_post_type ( $product_id ) == 'product' ) {
$_product = wc_get_product ( $product_id );
$item_tax_status = $_product -> get_tax_status ();
} else {
$item_tax_status = 'taxable' ;
2014-07-24 20:33:26 +00:00
}
2016-02-22 15:19:44 +00:00
2016-04-18 11:56:59 +00:00
if ( '0' !== $order_item_tax_classes [ $item_id ] && 'taxable' === $item_tax_status ) {
2016-02-18 19:35:33 +00:00
$tax_rates = WC_Tax :: find_rates ( array (
'country' => $country ,
'state' => $state ,
'postcode' => $postcode ,
'city' => $city ,
2016-04-18 11:56:59 +00:00
'tax_class' => $order_item_tax_classes [ $item_id ]
2016-02-18 19:35:33 +00:00
) );
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +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 );
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +00:00
// Set the new line_tax
foreach ( $line_taxes as $_tax_id => $_tax_value ) {
$items [ 'line_tax' ][ $item_id ][ $_tax_id ] = $_tax_value ;
}
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +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 ;
}
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +00:00
// Sum the item taxes
foreach ( array_keys ( $taxes + $line_taxes ) as $key ) {
$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
}
}
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +00:00
// Get shipping taxes
if ( isset ( $items [ 'shipping_method_id' ] ) ) {
2016-04-18 11:56:59 +00:00
$matched_tax_rates = array ();
$order_item_tax_classes = array_unique ( array_values ( $order_item_tax_classes ) );
// If multiple classes are found, use the first one. Don't bother with standard rate, we can get that later.
if ( sizeof ( $order_item_tax_classes ) > 1 && ! in_array ( '' , $order_item_tax_classes ) ) {
$tax_classes = WC_Tax :: get_tax_classes ();
foreach ( $tax_classes as $tax_class ) {
$tax_class = sanitize_title ( $tax_class );
if ( in_array ( $tax_class , $order_item_tax_classes ) ) {
$matched_tax_rates = WC_Tax :: find_shipping_rates ( array (
'country' => $country ,
'state' => $state ,
'postcode' => $postcode ,
'city' => $city ,
'tax_class' => $tax_class ,
) );
break ;
2016-02-18 19:35:33 +00:00
}
2014-07-24 20:33:26 +00:00
}
2016-04-18 11:56:59 +00:00
// If a single tax class is found, use it
} elseif ( sizeof ( $order_item_tax_classes ) === 1 ) {
$matched_tax_rates = WC_Tax :: find_shipping_rates ( array (
'country' => $country ,
'state' => $state ,
'postcode' => $postcode ,
'city' => $city ,
'tax_class' => $order_item_tax_classes [ 0 ]
) );
}
// Get standard rate if no taxes were found
if ( ! sizeof ( $matched_tax_rates ) ) {
$matched_tax_rates = WC_Tax :: find_shipping_rates ( array (
'country' => $country ,
'state' => $state ,
'postcode' => $postcode ,
'city' => $city
) );
2014-07-24 20:33:26 +00:00
}
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +00:00
$shipping_cost = $shipping_taxes = array ();
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +00:00
foreach ( $items [ 'shipping_method_id' ] as $item_id ) {
$item_id = absint ( $item_id );
$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 );
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +00:00
// Set the new shipping_taxes
foreach ( $_shipping_taxes as $_tax_id => $_tax_value ) {
$items [ 'shipping_taxes' ][ $item_id ][ $_tax_id ] = $_tax_value ;
2016-02-22 15:19:44 +00:00
2016-02-18 19:35:33 +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
}
}
}
2016-02-22 15:19:44 +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
}
2015-10-09 13:46:23 +00:00
$items = apply_filters ( 'woocommerce_ajax_after_calc_line_taxes' , $items , $order_id , $country , $_POST );
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
/**
2015-11-03 13:31:20 +00:00
* Save order items via ajax .
2014-07-17 20:17:54 +00:00
*/
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Load order items via ajax .
2014-07-17 20:17:54 +00:00
*/
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
/**
2015-11-03 13:31:20 +00:00
* Add order note via ajax .
2013-11-14 12:13:34 +00:00
*/
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Delete order note via ajax .
2013-11-14 12:13:34 +00:00
*/
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 ();
}
/**
2015-11-03 13:31:20 +00:00
* Search for products and echo json .
2013-11-14 12:13:34 +00:00
*
* @ 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-12-12 12:28:45 +00:00
$term = ( string ) wc_clean ( stripslashes ( $_GET [ 'term' ] ) );
2013-11-14 12:13:34 +00:00
2014-05-12 13:04:36 +00:00
if ( empty ( $term ) ) {
die ();
}
2013-11-14 12:13:34 +00:00
2015-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-12-12 12:28:45 +00:00
if ( ! empty ( $_GET [ 'include' ] ) ) {
$query .= " AND posts.ID IN ( " . implode ( ',' , array_map ( 'intval' , explode ( ',' , $_GET [ 'include' ] ) ) ) . " ) " ;
}
if ( ! empty ( $_GET [ 'limit' ] ) ) {
$query .= " LIMIT " . intval ( $_GET [ 'limit' ] );
}
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-12-12 14:37:32 +00:00
if ( ! $product || ( $product -> is_type ( 'variation' ) && empty ( $product -> parent ) ) ) {
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
}
/**
2015-11-03 13:31:20 +00:00
* Search for product variations and return json .
2013-11-14 12:13:34 +00:00
*
* @ 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
}
/**
2016-01-05 05:31:54 +00:00
* Search for grouped 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
/**
2015-11-03 13:31:20 +00:00
* Search for downloadable product variations and return json .
2013-11-26 13:54:34 +00:00
*
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Search for customers and return json .
2015-07-08 21:38:17 +00:00
*/
public static function json_search_customers () {
ob_start ();
check_ajax_referer ( 'search-customers' , 'security' );
if ( ! current_user_can ( 'edit_shop_orders' ) ) {
die ( - 1 );
}
2016-02-16 13:55:36 +00:00
$term = wc_clean ( stripslashes ( $_GET [ 'term' ] ) );
$exclude = array ();
2015-07-08 21:38:17 +00:00
if ( empty ( $term ) ) {
die ();
}
2016-02-16 13:55:36 +00:00
if ( ! empty ( $_GET [ 'exclude' ] ) ) {
$exclude = array_map ( 'intval' , explode ( ',' , $_GET [ 'exclude' ] ) );
}
2015-07-08 21:38:17 +00:00
$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 ) {
2016-02-16 18:40:06 +00:00
if ( ! in_array ( $customer -> ID , $exclude ) ) {
$found_customers [ $customer -> ID ] = $customer -> display_name . ' (#' . $customer -> ID . ' – ' . sanitize_email ( $customer -> user_email ) . ')' ;
}
2015-07-08 21:38:17 +00:00
}
}
2016-03-15 17:23:06 +00:00
2016-03-10 12:15:44 +00:00
$found_customers = apply_filters ( 'woocommerce_json_search_found_customers' , $found_customers );
2015-07-08 21:38:17 +00:00
wp_send_json ( $found_customers );
}
2013-11-14 12:13:34 +00:00
/**
2015-11-03 13:31:20 +00:00
* When searching using the WP_User_Query , search names ( user meta ) too .
2013-11-14 12:13:34 +00:00
* @ 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
}
/**
2015-11-03 13:31:20 +00:00
* Ajax request handling for categories ordering .
2013-11-14 12:13:34 +00:00
*/
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
}
}
/**
2015-11-03 13:31:20 +00:00
* Ajax request handling for product ordering .
2013-11-14 12:13:34 +00:00
*
2015-11-03 13:31:20 +00:00
* Based on Simple Page Ordering by 10 up ( http :// wordpress . org / extend / plugins / simple - page - ordering / ) .
2013-11-14 12:13:34 +00:00
*/
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
}
/**
2015-11-03 13:31:20 +00:00
* Handle a refund via the edit order screen .
2014-07-10 12:33:05 +00:00
*/
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' ] );
2016-03-03 13:40:50 +00:00
$refund_amount = wc_format_decimal ( sanitize_text_field ( $_POST [ 'refund_amount' ] ), wc_get_price_decimals () );
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 ();
2016-03-03 13:40:50 +00:00
$max_refund = wc_format_decimal ( $order -> get_total () - $order -> get_total_refunded (), wc_get_price_decimals () );
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
2015-10-29 15:34:33 +00:00
if ( $order -> get_remaining_refund_amount () > 0 || ( $order -> has_free_item () && $order -> get_remaining_refund_items () > 0 ) ) {
2015-10-06 13:43:33 +00:00
/**
2015-11-03 13:31:20 +00:00
* woocommerce_order_partially_refunded .
2015-10-06 13:43:33 +00:00
*
* @ since 2.4 . 0
2015-11-03 13:31:20 +00:00
* Note : 3 rd arg was added in err . Kept for bw compat . 2.4 . 3.
2015-10-06 13:43:33 +00:00
*/
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
/**
2015-11-03 13:31:20 +00:00
* Delete a refund .
2014-07-10 15:39:10 +00:00
*/
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 );
}
2016-03-23 16:32:12 +00:00
$refund_ids = array_map ( 'absint' , is_array ( $_POST [ 'refund_id' ] ) ? $_POST [ 'refund_id' ] : array ( $_POST [ 'refund_id' ] ) );
foreach ( $refund_ids as $refund_id ) {
if ( $refund_id && 'shop_order_refund' === get_post_type ( $refund_id ) ) {
$order_id = wp_get_post_parent_id ( $refund_id );
wc_delete_shop_order_transients ( $order_id );
wp_delete_post ( $refund_id );
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
/**
2015-11-03 13:31:20 +00:00
* Create / Update API key .
2015-06-08 22:41:35 +00:00
*/
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-11-03 13:31:20 +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
/**
2015-11-03 13:31:20 +00:00
* Load variations via AJAX .
2015-07-02 20:42:22 +00:00
*/
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 ;
2016-01-28 11:31:53 +00:00
$variation_data [ '_stock' ] = '' === $variation_data [ '_stock' ] ? '' : wc_stock_amount ( $variation_data [ '_stock' ] );
2015-07-02 20:42:22 +00:00
include ( 'admin/meta-boxes/views/html-variation-admin.php' );
$loop ++ ;
}
}
die ();
}
2015-07-06 04:50:20 +00:00
/**
2015-11-03 13:31:20 +00:00
* Save variations via AJAX .
2015-07-06 04:50:20 +00:00
*/
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-11-03 13:31:20 +00:00
* Bulk action - Toggle Enabled .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Toggle Downloadable Checkbox .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Toggle Virtual Checkbox .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Toggle Manage Stock Checkbox .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Set Regular Prices .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Set Sale Prices .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Set Stock .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Set Weight .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Set Length .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Set Width .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Set Height .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Set Download Limit .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Set Download Expiry .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Delete all .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Sale Schedule .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Increase Regular Prices .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Decrease Regular Prices .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Increase Sale Prices .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Decrease Sale Prices .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Set Price .
2015-07-14 10:39:48 +00:00
* @ 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
/**
2015-11-03 13:31:20 +00:00
* Bulk action - Set Meta .
2015-07-14 10:39:48 +00:00
* @ 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 );
}
}
/**
2015-11-03 13:31:20 +00:00
* Bulk edit variations via AJAX .
2015-07-14 10:39:48 +00:00
*/
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 ();
}
2015-08-13 21:49:59 +00:00
/**
* Handle submissions from assets / js / settings - views - html - settings - tax . js Backbone model .
*/
public static function tax_rates_save_changes () {
2016-02-22 15:19:44 +00:00
if ( ! isset ( $_POST [ 'wc_tax_nonce' ], $_POST [ 'changes' ] ) ) {
2015-08-13 21:49:59 +00:00
wp_send_json_error ( 'missing_fields' );
exit ;
}
2016-02-22 15:19:44 +00:00
$current_class = ! empty ( $_POST [ 'current_class' ] ) ? $_POST [ 'current_class' ] : '' ; // This is sanitized seven lines later.
2015-08-13 21:49:59 +00:00
if ( ! wp_verify_nonce ( $_POST [ 'wc_tax_nonce' ], 'wc_tax_nonce-class:' . $current_class ) ) {
wp_send_json_error ( 'bad_nonce' );
exit ;
}
$current_class = WC_Tax :: format_tax_rate_class ( $current_class );
// Check User Caps
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
wp_send_json_error ( 'missing_capabilities' );
exit ;
}
$changes = $_POST [ 'changes' ];
foreach ( $changes as $tax_rate_id => $data ) {
if ( isset ( $data [ 'deleted' ] ) ) {
if ( isset ( $data [ 'newRow' ] ) ) {
// So the user added and deleted a new row.
// That's fine, it's not in the database anyways. NEXT!
continue ;
}
WC_Tax :: _delete_tax_rate ( $tax_rate_id );
}
$tax_rate = array_intersect_key ( $data , array (
'tax_rate_country' => 1 ,
'tax_rate_state' => 1 ,
'tax_rate' => 1 ,
'tax_rate_name' => 1 ,
'tax_rate_priority' => 1 ,
'tax_rate_compound' => 1 ,
'tax_rate_shipping' => 1 ,
'tax_rate_order' => 1 ,
) );
if ( isset ( $data [ 'newRow' ] ) ) {
// Hurrah, shiny and new!
$tax_rate [ 'tax_rate_class' ] = $current_class ;
$tax_rate_id = WC_Tax :: _insert_tax_rate ( $tax_rate );
} else {
// Updating an existing rate ...
if ( ! empty ( $tax_rate ) ) {
WC_Tax :: _update_tax_rate ( $tax_rate_id , $tax_rate );
}
}
if ( isset ( $data [ 'postcode' ] ) ) {
WC_Tax :: _update_tax_rate_postcodes ( $tax_rate_id , array_map ( 'wc_clean' , $data [ 'postcode' ] ) );
}
if ( isset ( $data [ 'city' ] ) ) {
WC_Tax :: _update_tax_rate_cities ( $tax_rate_id , array_map ( 'wc_clean' , $data [ 'city' ] ) );
}
}
wp_send_json_success ( array (
'rates' => WC_Tax :: get_rates_for_tax_class ( $current_class ),
) );
}
2015-12-10 11:55:03 +00:00
/**
* Handle submissions from assets / js / wc - shipping - zones . js Backbone model .
*/
public static function shipping_zones_save_changes () {
if ( ! isset ( $_POST [ 'wc_shipping_zones_nonce' ], $_POST [ 'changes' ] ) ) {
2015-12-15 17:48:03 +00:00
wp_send_json_error ( 'missing_fields' );
2015-12-10 11:55:03 +00:00
exit ;
}
if ( ! wp_verify_nonce ( $_POST [ 'wc_shipping_zones_nonce' ], 'wc_shipping_zones_nonce' ) ) {
wp_send_json_error ( 'bad_nonce' );
exit ;
}
// Check User Caps
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
wp_send_json_error ( 'missing_capabilities' );
exit ;
}
$changes = $_POST [ 'changes' ];
foreach ( $changes as $zone_id => $data ) {
if ( isset ( $data [ 'deleted' ] ) ) {
if ( isset ( $data [ 'newRow' ] ) ) {
// So the user added and deleted a new row.
// That's fine, it's not in the database anyways. NEXT!
continue ;
}
WC_Shipping_Zones :: delete_zone ( $zone_id );
continue ;
}
$zone_data = array_intersect_key ( $data , array (
2015-12-10 15:09:37 +00:00
'zone_id' => 1 ,
'zone_name' => 1 ,
'zone_order' => 1 ,
2015-12-10 18:33:59 +00:00
'zone_locations' => 1 ,
'zone_postcodes' => 1
2015-12-10 11:55:03 +00:00
) );
2015-12-10 12:31:03 +00:00
if ( isset ( $zone_data [ 'zone_id' ] ) ) {
$zone = new WC_Shipping_Zone ( $zone_data [ 'zone_id' ] );
if ( isset ( $zone_data [ 'zone_name' ] ) ) {
$zone -> set_zone_name ( $zone_data [ 'zone_name' ] );
}
if ( isset ( $zone_data [ 'zone_order' ] ) ) {
$zone -> set_zone_order ( $zone_data [ 'zone_order' ] );
}
2015-12-10 15:09:37 +00:00
if ( isset ( $zone_data [ 'zone_locations' ] ) ) {
2015-12-16 16:09:52 +00:00
$zone -> clear_locations ( array ( 'state' , 'country' , 'continent' ) );
2015-12-10 15:09:37 +00:00
$locations = array_filter ( array_map ( 'wc_clean' , ( array ) $zone_data [ 'zone_locations' ] ) );
foreach ( $locations as $location ) {
// Each posted location will be in the format type:code
$location_parts = explode ( ':' , $location );
switch ( $location_parts [ 0 ] ) {
case 'state' :
$zone -> add_location ( $location_parts [ 1 ] . ':' . $location_parts [ 2 ], 'state' );
break ;
case 'country' :
$zone -> add_location ( $location_parts [ 1 ], 'country' );
break ;
case 'continent' :
$zone -> add_location ( $location_parts [ 1 ], 'continent' );
break ;
}
}
}
2015-12-10 18:33:59 +00:00
if ( isset ( $zone_data [ 'zone_postcodes' ] ) ) {
2015-12-16 16:09:52 +00:00
$zone -> clear_locations ( 'postcode' );
2015-12-10 18:33:59 +00:00
$postcodes = array_filter ( array_map ( 'strtoupper' , array_map ( 'wc_clean' , explode ( " \n " , $zone_data [ 'zone_postcodes' ] ) ) ) );
foreach ( $postcodes as $postcode ) {
$zone -> add_location ( $postcode , 'postcode' );
}
}
2015-12-10 12:31:03 +00:00
$zone -> save ();
}
2015-12-10 11:55:03 +00:00
}
wp_send_json_success ( array (
2015-12-15 17:48:03 +00:00
'zones' => WC_Shipping_Zones :: get_zones ()
) );
}
2015-12-16 15:16:52 +00:00
/**
* Handle submissions from assets / js / wc - shipping - zone - methods . js Backbone model .
*/
public static function shipping_zone_add_method () {
if ( ! isset ( $_POST [ 'wc_shipping_zones_nonce' ], $_POST [ 'zone_id' ], $_POST [ 'method_id' ] ) ) {
wp_send_json_error ( 'missing_fields' );
exit ;
}
if ( ! wp_verify_nonce ( $_POST [ 'wc_shipping_zones_nonce' ], 'wc_shipping_zones_nonce' ) ) {
wp_send_json_error ( 'bad_nonce' );
exit ;
}
// Check User Caps
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
wp_send_json_error ( 'missing_capabilities' );
exit ;
}
$zone_id = absint ( $_POST [ 'zone_id' ] );
$zone = WC_Shipping_Zones :: get_zone ( $zone_id );
$instance_id = $zone -> add_shipping_method ( wc_clean ( $_POST [ 'method_id' ] ) );
wp_send_json_success ( array (
'instance_id' => $instance_id ,
2016-01-13 15:04:10 +00:00
'zone_id' => $zone_id ,
2015-12-16 15:16:52 +00:00
'methods' => $zone -> get_shipping_methods ()
) );
}
2015-12-15 17:48:03 +00:00
/**
* Handle submissions from assets / js / wc - shipping - zone - methods . js Backbone model .
*/
public static function shipping_zone_methods_save_changes () {
if ( ! isset ( $_POST [ 'wc_shipping_zones_nonce' ], $_POST [ 'zone_id' ], $_POST [ 'changes' ] ) ) {
wp_send_json_error ( 'missing_fields' );
exit ;
}
if ( ! wp_verify_nonce ( $_POST [ 'wc_shipping_zones_nonce' ], 'wc_shipping_zones_nonce' ) ) {
wp_send_json_error ( 'bad_nonce' );
exit ;
}
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
wp_send_json_error ( 'missing_capabilities' );
exit ;
}
global $wpdb ;
$zone_id = absint ( $_POST [ 'zone_id' ] );
$zone = new WC_Shipping_Zone ( $zone_id );
$changes = $_POST [ 'changes' ];
foreach ( $changes as $instance_id => $data ) {
2016-05-10 18:43:47 +00:00
$method_id = $wpdb -> get_var ( $wpdb -> prepare ( " SELECT method_id FROM { $wpdb -> prefix } woocommerce_shipping_zone_methods WHERE instance_id = %d " , $instance_id ) );
2015-12-15 17:48:03 +00:00
if ( isset ( $data [ 'deleted' ] ) ) {
2016-05-10 18:43:47 +00:00
if ( $wpdb -> delete ( " { $wpdb -> prefix } woocommerce_shipping_zone_methods " , array ( 'instance_id' => $instance_id ) ) ) {
do_action ( 'woocommerce_shipping_zone_method_deleted' , $instance_id , $method_id , $zone_id );
}
2015-12-15 17:48:03 +00:00
continue ;
}
$method_data = array_intersect_key ( $data , array (
2016-03-15 17:23:06 +00:00
'method_order' => 1 ,
'enabled' => 1
2015-12-15 17:48:03 +00:00
) );
if ( isset ( $method_data [ 'method_order' ] ) ) {
$wpdb -> update ( " { $wpdb -> prefix } woocommerce_shipping_zone_methods " , array ( 'method_order' => absint ( $method_data [ 'method_order' ] ) ), array ( 'instance_id' => absint ( $instance_id ) ) );
}
2016-03-15 17:23:06 +00:00
if ( isset ( $method_data [ 'enabled' ] ) ) {
2016-05-10 18:43:47 +00:00
$is_enabled = absint ( 'yes' === $method_data [ 'enabled' ] );
if ( $wpdb -> update ( " { $wpdb -> prefix } woocommerce_shipping_zone_methods " , array ( 'is_enabled' => $is_enabled ), array ( 'instance_id' => absint ( $instance_id ) ) ) ) {
do_action ( 'woocommerce_shipping_zone_method_status_toggled' , $instance_id , $method_id , $zone_id , $is_enabled );
}
2016-03-15 17:23:06 +00:00
}
2015-12-15 17:48:03 +00:00
}
wp_send_json_success ( array (
'methods' => $zone -> get_shipping_methods ()
2015-12-10 11:55:03 +00:00
) );
}
2016-01-13 16:52:28 +00:00
2016-03-24 17:26:40 +00:00
/**
* Save method settings
*/
public static function shipping_zone_methods_save_settings () {
if ( ! isset ( $_POST [ 'wc_shipping_zones_nonce' ], $_POST [ 'instance_id' ], $_POST [ 'data' ] ) ) {
wp_send_json_error ( 'missing_fields' );
exit ;
}
if ( ! wp_verify_nonce ( $_POST [ 'wc_shipping_zones_nonce' ], 'wc_shipping_zones_nonce' ) ) {
wp_send_json_error ( 'bad_nonce' );
exit ;
}
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
wp_send_json_error ( 'missing_capabilities' );
exit ;
}
$instance_id = absint ( $_POST [ 'instance_id' ] );
$zone = WC_Shipping_Zones :: get_zone_by ( 'instance_id' , $instance_id );
$shipping_method = WC_Shipping_Zones :: get_shipping_method ( $instance_id );
2016-04-20 14:02:41 +00:00
$shipping_method -> set_post_data ( $_POST [ 'data' ] );
2016-04-20 07:48:29 +00:00
$shipping_method -> process_admin_options ();
2016-03-24 17:26:40 +00:00
wp_send_json_success ( array (
'methods' => $zone -> get_shipping_methods (),
'errors' => $shipping_method -> get_errors (),
) );
}
2016-01-13 16:52:28 +00:00
/**
* Handle submissions from assets / js / wc - shipping - classes . js Backbone model .
*/
public static function shipping_classes_save_changes () {
if ( ! isset ( $_POST [ 'wc_shipping_classes_nonce' ], $_POST [ 'changes' ] ) ) {
wp_send_json_error ( 'missing_fields' );
exit ;
}
if ( ! wp_verify_nonce ( $_POST [ 'wc_shipping_classes_nonce' ], 'wc_shipping_classes_nonce' ) ) {
wp_send_json_error ( 'bad_nonce' );
exit ;
}
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
wp_send_json_error ( 'missing_capabilities' );
exit ;
}
$changes = $_POST [ 'changes' ];
foreach ( $changes as $term_id => $data ) {
$term_id = absint ( $term_id );
if ( isset ( $data [ 'deleted' ] ) ) {
if ( isset ( $data [ 'newRow' ] ) ) {
// So the user added and deleted a new row.
// That's fine, it's not in the database anyways. NEXT!
continue ;
}
wp_delete_term ( $term_id , 'product_shipping_class' );
continue ;
}
$update_args = array ();
if ( isset ( $data [ 'name' ] ) ) {
$update_args [ 'name' ] = wc_clean ( $data [ 'name' ] );
}
if ( isset ( $data [ 'slug' ] ) ) {
$update_args [ 'slug' ] = wc_clean ( $data [ 'slug' ] );
}
if ( isset ( $data [ 'description' ] ) ) {
$update_args [ 'description' ] = wc_clean ( $data [ 'description' ] );
}
if ( isset ( $data [ 'newRow' ] ) ) {
$update_args = array_filter ( $update_args );
if ( empty ( $update_args [ 'name' ] ) ) {
wp_send_json_error ( __ ( 'Shipping Class name is required' , 'woocommerce' ) );
2016-02-10 13:21:16 +00:00
exit ;
2016-01-13 16:52:28 +00:00
}
$result = wp_insert_term ( $update_args [ 'name' ], 'product_shipping_class' , $update_args );
} else {
$result = wp_update_term ( $term_id , 'product_shipping_class' , $update_args );
}
if ( is_wp_error ( $result ) ) {
wp_send_json_error ( $result -> get_error_message () );
exit ;
}
}
$wc_shipping = WC_Shipping :: instance ();
wp_send_json_success ( array (
'shipping_classes' => $wc_shipping -> get_shipping_classes ()
) );
}
2013-11-14 12:13:34 +00:00
}
2014-05-28 13:52:50 +00:00
WC_AJAX :: init ();