woocommerce/includes/class-wc-ajax.php

3375 lines
104 KiB
PHP
Raw Normal View History

2013-11-14 12:13:34 +00:00
<?php
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
*
* @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
*/
public static function init() {
add_action( 'init', array( __CLASS__, 'define_ajax' ), 0 );
add_action( 'template_redirect', array( __CLASS__, 'do_wc_ajax' ), 0 );
self::add_ajax_events();
}
/**
2015-11-03 13:31:20 +00:00
* Get WC Ajax Endpoint.
* @param string $request Optional
* @return string
*/
public static function get_endpoint( $request = '' ) {
return esc_url_raw( add_query_arg( 'wc-ajax', $request, remove_query_arg( array( 'remove_item', 'add-to-cart', 'added-to-cart' ) ) ) );
}
2015-07-31 18:15:17 +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
if ( ! WP_DEBUG || ( WP_DEBUG && ! WP_DEBUG_DISPLAY ) ) {
@ini_set( 'display_errors', 0 );
}
$GLOBALS['wpdb']->hide_errors();
2015-07-31 18:15:17 +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-11-03 13:31:20 +00:00
* Check for WC Ajax request and fire action.
*/
public static function do_wc_ajax() {
global $wp_query;
2015-03-20 13:10:47 +00:00
if ( ! empty( $_GET['wc-ajax'] ) ) {
$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' ) ) {
self::wc_ajax_headers();
2015-07-07 01:50:35 +00:00
do_action( 'wc_ajax_' . sanitize_text_field( $action ) );
die();
}
}
/**
2015-11-03 13:31:20 +00:00
* Hook in methods - uses WordPress ajax handlers (admin-ajax).
*/
public static function add_ajax_events() {
2013-11-14 12:13:34 +00:00
// woocommerce_EVENT => nopriv
$ajax_events = array(
2014-07-10 12:33:05 +00:00
'get_refreshed_fragments' => true,
'apply_coupon' => true,
'remove_coupon' => true,
2014-07-10 12:33:05 +00:00
'update_shipping_method' => true,
'get_cart_totals' => true,
2014-07-10 12:33:05 +00:00
'update_order_review' => true,
'add_to_cart' => true,
'checkout' => true,
'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,
'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,
'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,
'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,
'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,
'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,
'delete_refund' => false,
2015-06-08 22:41:35 +00:00
'rated' => false,
'update_api_key' => false,
'get_customer_location' => true,
'load_variations' => false,
2015-07-07 01:50:35 +00:00
'save_variations' => false,
'bulk_edit_variations' => false,
'tax_rates_save_changes' => false,
'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,
'shipping_classes_save_changes' => false,
2013-11-14 12:13:34 +00:00
);
2013-11-14 12:13:34 +00:00
foreach ( $ajax_events as $ajax_event => $nopriv ) {
add_action( 'wp_ajax_woocommerce_' . $ajax_event, array( __CLASS__, $ajax_event ) );
2013-11-14 12:13:34 +00:00
if ( $nopriv ) {
add_action( 'wp_ajax_nopriv_woocommerce_' . $ajax_event, array( __CLASS__, $ajax_event ) );
// WC AJAX can be used for frontend ajax requests
add_action( 'wc_ajax_' . $ajax_event, array( __CLASS__, $ajax_event ) );
}
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
*/
public static function get_refreshed_fragments() {
2013-11-14 12:13:34 +00:00
// Get mini cart
ob_start();
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>'
)
),
'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
);
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
*/
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 {
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
}
wc_print_notices();
2013-11-14 12:13:34 +00:00
die();
}
/**
2015-11-03 13:31:20 +00:00
* AJAX remove coupon on cart and checkout page.
*/
public static function remove_coupon() {
check_ajax_referer( 'remove-coupon', 'security' );
$coupon = wc_clean( $_POST['coupon'] );
if ( ! isset( $coupon ) || empty( $coupon ) ) {
wc_add_notice( __( 'Sorry there was a problem removing this coupon.', 'woocommerce' ), 'error' );
} 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
*/
public static function update_shipping_method() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'update-shipping-method', 'security' );
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 ) {
$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();
woocommerce_cart_totals();
2013-11-14 12:13:34 +00:00
die();
}
/**
* AJAX receive updated cart_totals div.
*/
public static function get_cart_totals() {
2016-02-15 03:56:42 +00:00
if ( ! defined( 'WOOCOMMERCE_CART' ) ) {
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
*/
public static function update_order_review() {
ob_start();
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'update-order-review', 'security' );
if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
2013-11-14 12:13:34 +00:00
define( 'WOOCOMMERCE_CHECKOUT', true );
}
2013-11-14 12:13:34 +00:00
2015-05-14 21:18:53 +00:00
if ( WC()->cart->is_empty() ) {
$data = array(
'fragments' => apply_filters( 'woocommerce_update_order_review_fragments', array(
'form.woocommerce-checkout' => '<div class="woocommerce-error">' . __( 'Sorry, your session has expired.', 'woocommerce' ) . ' <a href="' . esc_url( wc_get_page_permalink( 'shop' ) ) . '" class="wc-backward">' . __( 'Return to shop', 'woocommerce' ) . '</a></div>'
) )
);
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' );
if ( isset( $_POST['shipping_method'] ) && is_array( $_POST['shipping_method'] ) ) {
foreach ( $_POST['shipping_method'] as $i => $value ) {
$chosen_shipping_methods[ $i ] = wc_clean( $value );
}
}
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'] );
if ( isset( $_POST['country'] ) ) {
2013-11-14 12:13:34 +00:00
WC()->customer->set_country( $_POST['country'] );
}
2013-11-14 12:13:34 +00:00
if ( isset( $_POST['state'] ) ) {
2013-11-14 12:13:34 +00:00
WC()->customer->set_state( $_POST['state'] );
}
2013-11-14 12:13:34 +00:00
if ( isset( $_POST['postcode'] ) ) {
2013-11-14 12:13:34 +00:00
WC()->customer->set_postcode( $_POST['postcode'] );
}
2013-11-14 12:13:34 +00:00
if ( isset( $_POST['city'] ) ) {
2013-11-14 12:13:34 +00:00
WC()->customer->set_city( $_POST['city'] );
}
2013-11-14 12:13:34 +00:00
if ( isset( $_POST['address'] ) ) {
2013-11-14 12:13:34 +00:00
WC()->customer->set_address( $_POST['address'] );
}
2013-11-14 12:13:34 +00:00
if ( isset( $_POST['address_2'] ) ) {
2013-11-14 12:13:34 +00:00
WC()->customer->set_address_2( $_POST['address_2'] );
}
2013-11-14 12:13:34 +00:00
if ( wc_ship_to_billing_address_only() ) {
2013-11-14 12:13:34 +00:00
if ( ! empty( $_POST['country'] ) ) {
WC()->customer->set_shipping_country( $_POST['country'] );
WC()->customer->calculated_shipping( true );
}
2013-11-14 12:13:34 +00:00
if ( isset( $_POST['state'] ) ) {
WC()->customer->set_shipping_state( $_POST['state'] );
}
2013-11-14 12:13:34 +00:00
if ( isset( $_POST['postcode'] ) ) {
WC()->customer->set_shipping_postcode( $_POST['postcode'] );
}
2013-11-14 12:13:34 +00:00
if ( isset( $_POST['city'] ) ) {
WC()->customer->set_shipping_city( $_POST['city'] );
}
2013-11-14 12:13:34 +00:00
if ( isset( $_POST['address'] ) ) {
WC()->customer->set_shipping_address( $_POST['address'] );
}
if ( isset( $_POST['address_2'] ) ) {
WC()->customer->set_shipping_address_2( $_POST['address_2'] );
}
} else {
if ( ! empty( $_POST['s_country'] ) ) {
WC()->customer->set_shipping_country( $_POST['s_country'] );
WC()->customer->calculated_shipping( true );
}
if ( isset( $_POST['s_state'] ) ) {
WC()->customer->set_shipping_state( $_POST['s_state'] );
}
if ( isset( $_POST['s_postcode'] ) ) {
WC()->customer->set_shipping_postcode( $_POST['s_postcode'] );
}
if ( isset( $_POST['s_city'] ) ) {
WC()->customer->set_shipping_city( $_POST['s_city'] );
}
if ( isset( $_POST['s_address'] ) ) {
WC()->customer->set_shipping_address( $_POST['s_address'] );
}
if ( isset( $_POST['s_address_2'] ) ) {
WC()->customer->set_shipping_address_2( $_POST['s_address_2'] );
}
}
2013-11-14 12:13:34 +00:00
WC()->cart->calculate_totals();
// Get order review fragment
ob_start();
woocommerce_order_review();
$woocommerce_order_review = ob_get_clean();
2015-01-27 22:41:33 +00:00
// Get checkout payment fragment
ob_start();
woocommerce_checkout_payment();
$woocommerce_checkout_payment = ob_get_clean();
// Get messages if reload checkout is not true
$messages = '';
if ( ! isset( WC()->session->reload_checkout ) ) {
ob_start();
wc_print_notices();
$messages = ob_get_clean();
}
$data = array(
'result' => empty( $messages ) ? 'success' : 'failure',
'messages' => $messages,
'reload' => isset( WC()->session->reload_checkout ) ? 'true' : 'false',
'fragments' => apply_filters( 'woocommerce_update_order_review_fragments', array(
'.woocommerce-checkout-review-order-table' => $woocommerce_order_review,
'.woocommerce-checkout-payment' => $woocommerce_checkout_payment
) )
);
unset( WC()->session->refresh_totals, WC()->session->reload_checkout );
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
*/
public static function add_to_cart() {
ob_start();
2013-11-14 12:13:34 +00:00
$product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) );
$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 );
$product_status = get_post_status( $product_id );
2013-11-14 12:13:34 +00:00
2016-06-06 17:57:24 +00:00
if ( $passed_validation && false !== 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' ) {
wc_add_to_cart_message( array( $product_id => $quantity ), true );
2013-11-14 12:13:34 +00:00
}
// Return fragments
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(
'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 )
);
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
*/
public static function checkout() {
if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
2013-11-14 12:13:34 +00:00
define( 'WOOCOMMERCE_CHECKOUT', true );
}
2013-11-14 12:13:34 +00:00
WC()->checkout()->process_checkout();
2013-11-14 12:13:34 +00:00
die(0);
}
/**
2015-11-03 13:31:20 +00:00
* Get a matching variation based on posted attributes.
*/
public static function get_variation() {
ob_start();
if ( empty( $_POST['product_id'] ) || ! ( $variable_product = wc_get_product( absint( $_POST['product_id'] ), array( 'product_type' => 'variable' ) ) ) ) {
die();
}
$variation_id = $variable_product->get_matching_variation( wp_unslash( $_POST ) );
if ( $variation_id ) {
$variation = $variable_product->get_available_variation( $variation_id );
} else {
$variation = false;
}
wp_send_json( $variation );
die();
}
2013-11-14 12:13:34 +00:00
/**
2015-11-03 13:31:20 +00:00
* Feature a product from admin.
2013-11-14 12:13:34 +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' );
}
}
2013-11-14 12:13:34 +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-11-27 15:37:42 +00:00
if ( wc_is_order_status( 'wc-' . $status ) && $order_id ) {
$order = wc_get_order( $order_id );
$order->update_status( $status, '', true );
do_action( 'woocommerce_order_edit_status', $order_id, $status );
2014-11-27 15:37:42 +00:00
}
}
2013-11-14 12:13:34 +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();
}
/**
2015-11-03 13:31:20 +00:00
* Add an attribute row.
*/
public static function add_attribute() {
ob_start();
check_ajax_referer( 'add-attribute', 'security' );
if ( ! current_user_can( 'edit_products' ) ) {
die(-1);
}
global $wc_product_attributes;
$thepostid = 0;
$taxonomy = sanitize_text_field( $_POST['taxonomy'] );
$i = absint( $_POST['i'] );
$position = 0;
$metabox_class = array();
$attribute = array(
'name' => $taxonomy,
'value' => '',
'is_visible' => apply_filters( 'woocommerce_attribute_default_visibility', 1 ),
'is_variation' => apply_filters( 'woocommerce_attribute_default_is_variation', 0 ),
'is_taxonomy' => $taxonomy ? 1 : 0
);
if ( $taxonomy ) {
$attribute_taxonomy = $wc_product_attributes[ $taxonomy ];
$metabox_class[] = 'taxonomy';
$metabox_class[] = $taxonomy;
$attribute_label = wc_attribute_label( $taxonomy );
} else {
$attribute_label = '';
}
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
*/
public static function add_new_attribute() {
ob_start();
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'add-attribute', 'security' );
if ( ! current_user_can( 'manage_product_terms' ) ) {
die(-1);
}
2013-11-14 12:13:34 +00:00
$taxonomy = esc_attr( $_POST['taxonomy'] );
$term = wc_clean( $_POST['term'] );
2013-11-14 12:13:34 +00:00
if ( taxonomy_exists( $taxonomy ) ) {
$result = wp_insert_term( $term, $taxonomy );
if ( is_wp_error( $result ) ) {
wp_send_json( array(
'error' => $result->get_error_message()
) );
} else {
$term = get_term_by( 'id', $result['term_id'], $taxonomy );
wp_send_json( array(
'term_id' => $term->term_id,
'name' => $term->name,
'slug' => $term->slug
) );
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
*/
public static function remove_variations() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'delete-variations', 'security' );
if ( ! current_user_can( 'edit_products' ) ) {
die(-1);
}
2013-11-14 12:13:34 +00:00
$variation_ids = (array) $_POST['variation_ids'];
2013-11-14 12:13:34 +00:00
foreach ( $variation_ids as $variation_id ) {
$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 );
}
2013-11-14 12:13:34 +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
*/
public static function save_attributes() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'save-attributes', 'security' );
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'] );
$attribute_values = isset( $data['attribute_values'] ) ? $data['attribute_values'] : array();
2013-11-14 12:13:34 +00:00
if ( isset( $data['attribute_visibility'] ) ) {
2013-11-14 12:13:34 +00:00
$attribute_visibility = $data['attribute_visibility'];
}
2013-11-14 12:13:34 +00:00
if ( isset( $data['attribute_variation'] ) ) {
2013-11-14 12:13:34 +00:00
$attribute_variation = $data['attribute_variation'];
}
2013-11-14 12:13:34 +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++ ) {
if ( empty( $attribute_names[ $i ] ) ) {
2013-11-14 12:13:34 +00:00
continue;
}
2013-11-14 12:13:34 +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 ] ) ) {
// Select based attributes - Format values (posted values are slugs)
if ( is_array( $attribute_values[ $i ] ) ) {
$values = array_map( 'sanitize_title', $attribute_values[ $i ] );
// Text based attributes - Posted values are term names, wp_set_object_terms wants ids or slugs.
} else {
$values = array();
$raw_values = array_map( 'wc_sanitize_term_text_based', explode( WC_DELIMITER, $attribute_values[ $i ] ) );
foreach ( $raw_values as $value ) {
$term = get_term_by( 'name', $value, $attribute_names[ $i ] );
if ( ! $term ) {
$term = wp_insert_term( $value, $attribute_names[ $i ] );
if ( $term && ! is_wp_error( $term ) ) {
$values[] = $term['term_id'];
}
} else {
$values[] = $term->term_id;
}
}
}
// 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 ] );
}
2016-06-06 18:39:23 +00:00
if ( ! empty( $values ) ) {
// Add attribute to array, but don't set values
$attributes[ sanitize_title( $attribute_names[ $i ] ) ] = array(
'name' => wc_clean( $attribute_names[ $i ] ),
'value' => '',
'position' => $attribute_position[ $i ],
'is_visible' => $is_visible,
'is_variation' => $is_variation,
'is_taxonomy' => $is_taxonomy
);
}
} elseif ( isset( $attribute_values[ $i ] ) ) {
// Text based, 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 ) );
// 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
}
}
2016-06-06 16:24:31 +00:00
uasort( $attributes, 'wc_product_attribute_uasort_comparison' );
2013-11-14 12:13:34 +00:00
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
*/
public static function add_variation() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'add-variation', 'security' );
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(
'post_title' => 'Product #' . $post_id . ' Variation',
'post_content' => '',
'post_status' => 'publish',
'post_author' => get_current_user_id(),
'post_parent' => $post_id,
'post_type' => 'product_variation',
'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 ) {
$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
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
// 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;
$variation_data['_stock'] = wc_stock_amount( $variation_data['_stock'] );
2013-11-14 12:13:34 +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 );
}
}
2013-11-14 12:13:34 +00:00
// 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' )
);
// 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(
'id' => $post_id,
'attributes' => $attributes,
'tax_class_options' => $tax_class_options,
'sku' => get_post_meta( $post_id, '_sku', true ),
'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 ) ),
'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
);
if ( ! $parent_data['weight'] ) {
$parent_data['weight'] = wc_format_localized_decimal( 0 );
}
2013-11-14 12:13:34 +00:00
if ( ! $parent_data['length'] ) {
$parent_data['length'] = wc_format_localized_decimal( 0 );
}
2013-11-14 12:13:34 +00:00
if ( ! $parent_data['width'] ) {
$parent_data['width'] = wc_format_localized_decimal( 0 );
}
2013-11-14 12:13:34 +00:00
if ( ! $parent_data['height'] ) {
$parent_data['height'] = wc_format_localized_decimal( 0 );
}
2013-11-14 12:13:34 +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
*/
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' );
if ( ! current_user_can( 'edit_products' ) ) {
die(-1);
}
2016-06-06 15:55:27 +00:00
wc_set_time_limit( 0 );
2013-11-14 12:13:34 +00:00
$post_id = intval( $_POST['post_id'] );
if ( ! $post_id ) {
die();
}
2013-11-14 12:13:34 +00:00
$variations = array();
$_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 ) {
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'] ) {
$options = wc_get_product_terms( $post_id, $attribute['name'], array( 'fields' => 'slugs' ) );
2013-11-14 12:13:34 +00:00
} else {
$options = explode( WC_DELIMITER, $attribute['value'] );
}
$options = array_map( 'trim', $options );
2013-11-14 12:13:34 +00:00
$variations[ $attribute_field_name ] = $options;
}
// Quit out if none were found
if ( sizeof( $variations ) == 0 ) {
die();
}
2013-11-14 12:13:34 +00:00
// Get existing variations so we don't create duplicates
$available_variations = array();
2013-11-14 12:13:34 +00:00
foreach( $_product->get_children() as $child_id ) {
$child = $_product->get_child( $child_id );
2013-11-14 12:13:34 +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
);
$variation_ids = array();
$added = 0;
$possible_variations = wc_array_cartesian( $variations );
2013-11-14 12:13:34 +00:00
foreach ( $possible_variations as $variation ) {
// Check if variation already exists
if ( in_array( $variation, $available_variations ) ) {
2013-11-14 12:13:34 +00:00
continue;
}
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 );
}
// 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 );
if ( $added > WC_MAX_LINKED_VARIATIONS ) {
2013-11-14 12:13:34 +00:00
break;
}
2013-11-14 12:13:34 +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
*/
public static function revoke_access_to_download() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'revoke-access', 'security' );
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
*/
public static function grant_access_to_download() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'grant-access', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
2013-11-14 12:13:34 +00:00
global $wpdb;
$wpdb->hide_errors();
$order_id = intval( $_POST['order_id'] );
$product_ids = $_POST['product_ids'];
$loop = intval( $_POST['loop'] );
$file_counter = 0;
$order = wc_get_order( $order_id );
2013-11-14 12:13:34 +00:00
if ( ! is_array( $product_ids ) ) {
$product_ids = array( $product_ids );
}
2013-11-14 12:13:34 +00:00
foreach ( $product_ids as $product_id ) {
$product = wc_get_product( $product_id );
$files = $product->get_files();
2013-11-14 12:13:34 +00:00
if ( ! $order->billing_email ) {
die();
}
2013-11-14 12:13:34 +00:00
2016-06-06 18:39:23 +00:00
if ( ! empty( $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
// 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 );
}
include( 'admin/meta-boxes/views/html-order-download-permission.php' );
}
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
*/
public static function get_customer_details() {
ob_start();
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'get-customer-details', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
$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 ),
$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
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
*/
public static function add_order_item() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'order-item', 'security' );
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'] );
$order_id = absint( $_POST['order_id'] );
2013-11-14 12:13:34 +00:00
// Find the item
if ( ! is_numeric( $item_to_add ) ) {
2013-11-14 12:13:34 +00:00
die();
}
2013-11-14 12:13:34 +00:00
$post = get_post( $item_to_add );
if ( ! $post || ( 'product' !== $post->post_type && 'product_variation' !== $post->post_type ) ) {
2013-11-14 12:13:34 +00:00
die();
}
2013-11-14 12:13:34 +00:00
$_product = wc_get_product( $post->ID );
$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();
$item['product_id'] = $_product->id;
$item['variation_id'] = isset( $_product->variation_id ) ? $_product->variation_id : '';
$item['variation_data'] = $item['variation_id'] ? $_product->get_variation_attributes() : '';
$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'] = '';
$item['type'] = 'line_item';
2013-11-14 12:13:34 +00:00
// Add line item
$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() ) );
// Store variation data in meta
if ( $item['variation_data'] && is_array( $item['variation_data'] ) ) {
foreach ( $item['variation_data'] as $key => $value ) {
wc_add_order_item_meta( $item_id, str_replace( 'attribute_', '', $key ), $value );
}
}
do_action( 'woocommerce_ajax_add_order_item_meta', $item_id, $item );
}
2013-11-14 12:13:34 +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
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
*/
public static function add_order_fee() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'order-item', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
$order_id = absint( $_POST['order_id'] );
$order = wc_get_order( $order_id );
$order_taxes = $order->get_taxes();
$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
include( 'admin/meta-boxes/views/html-order-fee.php' );
2013-11-14 12:13:34 +00:00
// Quit out
die();
}
/**
2015-11-03 13:31:20 +00:00
* Add order shipping cost via ajax.
*/
public static function add_order_shipping() {
check_ajax_referer( 'order-item', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
$order_id = absint( $_POST['order_id'] );
$order = wc_get_order( $order_id );
2014-07-20 04:28:16 +00:00
$order_taxes = $order->get_taxes();
$shipping_methods = WC()->shipping() ? WC()->shipping->load_shipping_methods() : array();
$item = array();
// Add new shipping
$shipping = new WC_Shipping_Rate();
$item_id = $order->add_shipping( $shipping );
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' );
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'] );
$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
*/
public static function remove_order_item() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'order-item', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
2013-11-14 12:13:34 +00:00
$order_item_ids = $_POST['order_item_ids'];
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 ) {
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' );
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
$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();
}
/**
* 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
*/
public static function add_order_item_meta() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'order-item', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
$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">&times;</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
*/
public static function remove_order_item_meta() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'order-item', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
global $wpdb;
2013-11-14 12:13:34 +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
*/
public static function calc_line_taxes() {
2013-11-14 12:13:34 +00:00
global $wpdb;
check_ajax_referer( 'calc-totals', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
$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
// 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
// Action
$items = apply_filters( 'woocommerce_ajax_calc_line_taxes', $items, $order_id, $country, $_POST );
$is_vat_exempt = get_post_meta( $order_id, '_is_vat_exempt', true );
// Tax is calculated only if tax is enabled and order is not vat exempted
if ( wc_tax_enabled() && $is_vat_exempt !== 'yes' ) {
2016-02-18 19:35:33 +00:00
// Get items and fees taxes
if ( isset( $items['order_item_id'] ) ) {
$line_total = $line_subtotal = array();
2016-02-18 19:35:33 +00:00
foreach ( $items['order_item_id'] as $item_id ) {
$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-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
}
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,
'tax_class' => $order_item_tax_classes[ $item_id ]
2016-02-18 19:35:33 +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-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-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-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 );
}
}
2013-11-14 12:13:34 +00:00
}
}
2016-02-18 19:35:33 +00:00
// Get shipping taxes
if ( isset( $items['shipping_method_id'] ) ) {
$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
}
// 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-18 19:35:33 +00:00
$shipping_cost = $shipping_taxes = array();
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-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-18 19:35:33 +00:00
$shipping_taxes[ $_tax_id ] = isset( $shipping_taxes[ $_tax_id ] ) ? $shipping_taxes[ $_tax_id ] + $_tax_value : $_tax_value;
}
}
}
}
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
}
$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
$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
}
/**
2015-11-03 13:31:20 +00:00
* Save order items via ajax.
*/
public static function save_order_items() {
check_ajax_referer( 'order-item', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
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
$order = wc_get_order( $order_id );
2014-07-17 21:17:42 +00:00
$data = get_post_meta( $order_id );
include( 'admin/meta-boxes/views/html-order-items.php' );
}
die();
}
/**
2015-11-03 13:31:20 +00:00
* Load order items via ajax.
*/
public static function load_order_items() {
check_ajax_referer( 'order-item', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
// Return HTML items
$order_id = absint( $_POST['order_id'] );
$order = wc_get_order( $order_id );
2014-07-17 21:17:42 +00:00
$data = get_post_meta( $order_id );
include( 'admin/meta-boxes/views/html-order-items.php' );
die();
}
2013-11-14 12:13:34 +00:00
/**
2015-11-03 13:31:20 +00:00
* Add order note via ajax.
2013-11-14 12:13:34 +00:00
*/
public static function add_order_note() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'add-order-note', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
2015-03-03 16:36:47 +00:00
$post_id = absint( $_POST['post_id'] );
$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 ) {
$order = wc_get_order( $post_id );
$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 ';
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
*/
public static function delete_order_note() {
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'delete-order-note', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
$note_id = (int) $_POST['note_id'];
2013-11-14 12:13:34 +00:00
if ( $note_id > 0 ) {
2013-11-14 12:13:34 +00:00
wp_delete_comment( $note_id );
}
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
*
2016-06-07 13:10:23 +00:00
* @param string $term (default: '')
2013-11-14 12:13:34 +00:00
* @param string $post_types (default: array('product'))
*/
2016-06-07 13:10:23 +00:00
public static function json_search_products( $term = '', $post_types = array( 'product' ) ) {
global $wpdb;
ob_start();
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'search-products', 'security' );
2016-06-07 13:10:23 +00:00
if ( empty( $term ) ) {
$term = wc_clean( stripslashes( $_GET['term'] ) );
} else {
$term = wc_clean( $term );
}
2013-11-14 12:13:34 +00:00
if ( empty( $term ) ) {
die();
}
2013-11-14 12:13:34 +00:00
$like_term = '%' . $wpdb->esc_like( $term ) . '%';
2013-11-14 12:13:34 +00:00
if ( is_numeric( $term ) ) {
$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
)
)
", $term, $term, $term, $like_term );
2013-11-14 12:13:34 +00:00
} else {
$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
)
)
", $like_term, $like_term, $like_term );
}
2013-11-14 12:13:34 +00:00
$query .= " AND posts.post_type IN ('" . implode( "','", array_map( 'esc_sql', $post_types ) ) . "')";
2013-11-14 12:13:34 +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
}
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'] );
}
$posts = array_unique( $wpdb->get_col( $query ) );
2013-11-14 12:13:34 +00:00
$found_products = array();
if ( ! empty( $posts ) ) {
foreach ( $posts as $post ) {
$product = wc_get_product( $post );
2013-11-14 12:13:34 +00:00
if ( ! current_user_can( 'read_product', $post ) ) {
continue;
}
if ( ! $product || ( $product->is_type( 'variation' ) && empty( $product->parent ) ) ) {
continue;
}
$found_products[ $post ] = rawurldecode( $product->get_formatted_name() );
}
2013-11-14 12:13:34 +00:00
}
$found_products = apply_filters( 'woocommerce_json_search_found_products', $found_products );
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()
*/
public static function json_search_products_and_variations() {
self::json_search_products( '', array( 'product', 'product_variation' ) );
2013-11-14 12:13:34 +00:00
}
/**
* Search for grouped products and return json.
2013-11-14 12:13:34 +00:00
*/
public static function json_search_grouped_products() {
ob_start();
2013-11-14 12:13:34 +00:00
check_ajax_referer( 'search-products', 'security' );
$term = (string) wc_clean( stripslashes( $_GET['term'] ) );
$exclude = array();
2013-11-14 12:13:34 +00:00
if ( empty( $term ) ) {
2013-11-14 12:13:34 +00:00
die();
}
2013-11-14 12:13:34 +00:00
if ( ! empty( $_GET['exclude'] ) ) {
$exclude = array_map( 'intval', explode( ',', $_GET['exclude'] ) );
}
$found_products = array();
2013-11-14 12:13:34 +00:00
if ( $grouped_term = get_term_by( 'slug', 'grouped', 'product_type' ) ) {
2013-11-14 12:13:34 +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
if ( sizeof( $posts_in ) > 0 ) {
2013-11-14 12:13:34 +00:00
$args = array(
'post_type' => 'product',
'post_status' => 'any',
'numberposts' => -1,
'orderby' => 'title',
'order' => 'asc',
'post_parent' => 0,
'suppress_filters' => 0,
'include' => $posts_in,
's' => $term,
'fields' => 'ids',
'exclude' => $exclude
);
2013-11-14 12:13:34 +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
}
}
$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
}
/**
2015-11-03 13:31:20 +00:00
* Search for downloadable product variations and return json.
*
* @see WC_AJAX::json_search_products()
*/
public static function json_search_downloadable_products_and_variations() {
ob_start();
check_ajax_referer( 'search-products', 'security' );
$term = (string) wc_clean( stripslashes( $_GET['term'] ) );
$exclude = array();
if ( ! empty( $_GET['exclude'] ) ) {
$exclude = array_map( 'intval', explode( ',', $_GET['exclude'] ) );
}
$args = array(
'post_type' => array( 'product', 'product_variation' ),
'posts_per_page' => -1,
'post_status' => 'publish',
'order' => 'ASC',
'orderby' => 'parent title',
'meta_query' => array(
array(
'key' => '_downloadable',
'value' => 'yes'
)
),
's' => $term,
'exclude' => $exclude
);
$posts = get_posts( $args );
$found_products = array();
if ( ! empty( $posts ) ) {
foreach ( $posts as $post ) {
$product = wc_get_product( $post->ID );
if ( ! current_user_can( 'read_product', $post->ID ) ) {
continue;
}
$found_products[ $post->ID ] = $product->get_formatted_name();
}
}
wp_send_json( $found_products );
}
/**
2015-11-03 13:31:20 +00:00
* Search for customers and return json.
*/
public static function json_search_customers() {
ob_start();
check_ajax_referer( 'search-customers', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
$term = wc_clean( stripslashes( $_GET['term'] ) );
$exclude = array();
if ( empty( $term ) ) {
die();
}
if ( ! empty( $_GET['exclude'] ) ) {
$exclude = array_map( 'intval', explode( ',', $_GET['exclude'] ) );
}
$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 ) {
if ( ! in_array( $customer->ID, $exclude ) ) {
$found_customers[ $customer->ID ] = $customer->display_name . ' (#' . $customer->ID . ' &ndash; ' . sanitize_email( $customer->user_email ) . ')';
}
}
}
$found_customers = apply_filters( 'woocommerce_json_search_found_customers', $found_customers );
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
*/
public static function json_search_customer_name( $query ) {
2013-11-14 12:13:34 +00:00
global $wpdb;
$term = wc_clean( stripslashes( $_GET['term'] ) );
if ( method_exists( $wpdb, 'esc_like' ) ) {
$term = $wpdb->esc_like( $term );
} else {
$term = like_escape( $term );
}
2013-11-14 12:13:34 +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' ) ";
$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
*/
public static function term_ordering() {
// check permissions again and make sure we have what we need
if ( ! current_user_can( 'edit_products' ) || empty( $_POST['id'] ) ) {
die(-1);
}
$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;
$term = get_term_by( 'id', $id, $taxonomy );
2013-11-14 12:13:34 +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
$children = get_terms( $taxonomy, "child_of=$id&menu_order=ASC&hide_empty=0" );
2013-11-14 12:13:34 +00:00
if ( $term && sizeof( $children ) ) {
2013-11-14 12:13:34 +00:00
echo 'children';
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
*
2016-05-27 01:48:49 +00:00
* Based on Simple Page Ordering by 10up (https://wordpress.org/extend/plugins/simple-page-ordering/).
2013-11-14 12:13:34 +00:00
*/
public static function product_ordering() {
2013-11-14 12:13:34 +00:00
global $wpdb;
ob_start();
2013-11-14 12:13:34 +00:00
// check permissions again and make sure we have what we need
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);
}
2013-11-14 12:13:34 +00:00
// real post?
if ( ! $post = get_post( $_POST['id'] ) ) {
2013-11-14 12:13:34 +00:00
die(-1);
}
2013-11-14 12:13:34 +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;
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
if ( isset( $new_pos[ $post->ID ] ) && $sibling->menu_order >= $menu_order ) {
2013-11-14 12:13:34 +00:00
break;
}
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++;
}
}
do_action( 'woocommerce_after_product_ordering' );
2013-11-14 12:13:34 +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() {
ob_start();
2014-07-10 12:33:05 +00:00
check_ajax_referer( 'order-item', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
die(-1);
}
2014-07-25 10:29:24 +00:00
$order_id = absint( $_POST['order_id'] );
$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 );
$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;
$refund = false;
$response_data = array();
2014-07-10 13:49:04 +00:00
try {
// Validate that the refund can occur
$order = wc_get_order( $order_id );
2014-07-25 10:29:24 +00:00
$order_items = $order->get_items();
$max_refund = wc_format_decimal( $order->get_total() - $order->get_total_refunded(), wc_get_price_decimals() );
2014-07-10 13:49:04 +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-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 ) {
$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 ) {
$line_items[ $item_id ]['refund_tax'] = array_map( 'wc_format_decimal', $tax_totals );
2014-07-24 14:34:14 +00:00
}
2014-07-10 13:49:04 +00:00
// Create the refund object
$refund = wc_create_refund( array(
2014-07-24 14:34:14 +00:00
'amount' => $refund_amount,
'reason' => $refund_reason,
'order_id' => $order_id,
'line_items' => $line_items,
2014-07-10 13:49:04 +00:00
) );
if ( is_wp_error( $refund ) ) {
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' ) ) {
$result = $payment_gateways[ $order->payment_method ]->process_refund( $order_id, $refund_amount, $refund_reason );
2014-07-10 13:49:04 +00:00
do_action( 'woocommerce_refund_processed', $refund, $result );
2014-07-10 13:49:04 +00:00
if ( is_wp_error( $result ) ) {
throw new Exception( $result->get_error_message() );
2014-07-10 13:49:04 +00:00
} elseif ( ! $result ) {
throw new Exception( __( 'Refund failed', 'woocommerce' ) );
2014-07-10 13:49:04 +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 );
}
}
}
// Trigger notifications and status changes
if ( $order->get_remaining_refund_amount() > 0 || ( $order->has_free_item() && $order->get_remaining_refund_items() > 0 ) ) {
/**
2015-11-03 13:31:20 +00:00
* woocommerce_order_partially_refunded.
*
* @since 2.4.0
2015-11-03 13:31:20 +00:00
* Note: 3rd arg was added in err. Kept for bw compat. 2.4.3.
*/
do_action( 'woocommerce_order_partially_refunded', $order_id, $refund->id, $refund->id );
} else {
do_action( 'woocommerce_order_fully_refunded', $order_id, $refund->id );
$order->update_status( apply_filters( 'woocommerce_order_fully_refunded_status', 'refunded', $order_id, $refund->id ) );
$response_data['status'] = 'fully_refunded';
}
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 );
wp_send_json_success( $response_data );
2014-07-10 13:49:04 +00:00
} catch ( Exception $e ) {
if ( $refund && is_a( $refund, 'WC_Order_Refund' ) ) {
wp_delete_post( $refund->id, true );
}
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' );
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();
}
/**
* Triggered when clicking the rating footer.
*/
public static function rated() {
if ( ! current_user_can( 'manage_woocommerce' ) ) {
die(-1);
}
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 {
$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 ),
'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',
'%s',
2015-06-08 22:41:35 +00:00
'%s'
)
);
$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' );
$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&section=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-11-03 13:31:20 +00:00
* Locate user via AJAX.
*/
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-11-03 13:31:20 +00:00
* Load variations via AJAX.
*/
public static function load_variations() {
ob_start();
check_ajax_referer( 'load-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['attributes'] ) ) {
die( -1 );
}
global $post;
$product_id = absint( $_POST['product_id'] );
$post = get_post( $product_id ); // Set $post global so its available like within the admin screens
$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();
$posted_attributes = wp_unslash( $_POST['attributes'] );
2015-08-13 11:07:05 +00:00
foreach ( $posted_attributes as $key => $value ) {
$attributes[ $key ] = array_map( 'wc_clean', $value );
}
// Get tax classes
$tax_classes = WC_Tax::get_tax_classes();
$tax_class_options = array();
$tax_class_options[''] = __( 'Standard', 'woocommerce' );
if ( ! empty( $tax_classes ) ) {
foreach ( $tax_classes as $class ) {
$tax_class_options[ sanitize_title( $class ) ] = esc_attr( $class );
}
}
// Set backorder options
$backorder_options = array(
'no' => __( 'Do not allow', 'woocommerce' ),
'notify' => __( 'Allow, but notify customer', 'woocommerce' ),
'yes' => __( 'Allow', 'woocommerce' )
);
// set stock status options
$stock_status_options = array(
'instock' => __( 'In stock', 'woocommerce' ),
'outofstock' => __( 'Out of stock', 'woocommerce' )
);
$parent_data = array(
'id' => $product_id,
'attributes' => $attributes,
'tax_class_options' => $tax_class_options,
'sku' => get_post_meta( $product_id, '_sku', true ),
'weight' => wc_format_localized_decimal( get_post_meta( $product_id, '_weight', true ) ),
'length' => wc_format_localized_decimal( get_post_meta( $product_id, '_length', true ) ),
'width' => wc_format_localized_decimal( get_post_meta( $product_id, '_width', true ) ),
'height' => wc_format_localized_decimal( get_post_meta( $product_id, '_height', true ) ),
'tax_class' => get_post_meta( $product_id, '_tax_class', true ),
'backorder_options' => $backorder_options,
'stock_status_options' => $stock_status_options
);
if ( ! $parent_data['weight'] ) {
$parent_data['weight'] = wc_format_localized_decimal( 0 );
}
if ( ! $parent_data['length'] ) {
$parent_data['length'] = wc_format_localized_decimal( 0 );
}
if ( ! $parent_data['width'] ) {
$parent_data['width'] = wc_format_localized_decimal( 0 );
}
if ( ! $parent_data['height'] ) {
$parent_data['height'] = wc_format_localized_decimal( 0 );
}
// Get variations
$args = apply_filters( 'woocommerce_ajax_admin_get_variations_args', array(
'post_type' => 'product_variation',
'post_status' => array( 'private', 'publish' ),
'posts_per_page' => $per_page,
'paged' => $page,
'orderby' => array( 'menu_order' => 'ASC', 'ID' => 'DESC' ),
'post_parent' => $product_id
), $product_id );
$variations = get_posts( $args );
$loop = 0;
if ( $variations ) {
foreach ( $variations as $variation ) {
$variation_id = absint( $variation->ID );
$variation_meta = get_post_meta( $variation_id );
$variation_data = array();
$shipping_classes = get_the_terms( $variation_id, 'product_shipping_class' );
$variation_fields = array(
'_sku' => '',
'_stock' => '',
'_regular_price' => '',
'_sale_price' => '',
'_weight' => '',
'_length' => '',
'_width' => '',
'_height' => '',
'_download_limit' => '',
'_download_expiry' => '',
'_downloadable_files' => '',
'_downloadable' => '',
'_virtual' => '',
'_thumbnail_id' => '',
'_sale_price_dates_from' => '',
'_sale_price_dates_to' => '',
'_manage_stock' => '',
'_stock_status' => '',
'_backorders' => null,
'_tax_class' => null,
'_variation_description' => ''
);
foreach ( $variation_fields as $field => $value ) {
$variation_data[ $field ] = isset( $variation_meta[ $field ][0] ) ? maybe_unserialize( $variation_meta[ $field ][0] ) : $value;
}
// Add the variation attributes
$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;
2016-01-28 11:31:53 +00:00
$variation_data['_stock'] = '' === $variation_data['_stock'] ? '' : wc_stock_amount( $variation_data['_stock'] );
include( 'admin/meta-boxes/views/html-variation-admin.php' );
$loop++;
}
}
die();
}
/**
2015-11-03 13:31:20 +00:00
* Save variations via AJAX.
*/
public static function save_variations() {
ob_start();
check_ajax_referer( 'save-variations', 'security' );
// Check permissions again and make sure we have what we need
2015-07-08 16:55:29 +00:00
if ( ! current_user_can( 'edit_products' ) || empty( $_POST ) || empty( $_POST['product_id'] ) ) {
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' );
}
WC_Meta_Box_Product_Data::save_variations( $product_id, get_post( $product_id ) );
do_action( 'woocommerce_ajax_save_product_variations', $product_id );
// 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 ) {
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>';
}
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-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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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 );
$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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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-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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @param array $variations
* @param array $data
*/
private static function variation_bulk_action_variable_stock( $variations, $data ) {
if ( ! isset( $data['value'] ) ) {
2015-08-11 12:47:12 +00:00
return;
2015-07-14 10:39:48 +00:00
}
2015-07-14 10:39:48 +00:00
$value = wc_clean( $data['value'] );
foreach ( $variations as $variation_id ) {
if ( 'yes' === get_post_meta( $variation_id, '_manage_stock', true ) ) {
wc_update_product_stock( $variation_id, wc_stock_amount( $value ) );
} else {
delete_post_meta( $variation_id, '_stock' );
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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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-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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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-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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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-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-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-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-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-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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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-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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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-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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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-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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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
2016-06-07 13:19:36 +00:00
* @used-by bulk_edit_variations
2015-07-14 10:39:48 +00:00
* @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.
2016-06-07 13:19:36 +00:00
* @uses WC_AJAX::variation_bulk_set_meta()
* @uses WC_AJAX::variation_bulk_adjust_price()
* @uses WC_AJAX::variation_bulk_action_variable_sale_price_decrease()
* @uses WC_AJAX::variation_bulk_action_variable_sale_price_increase()
* @uses WC_AJAX::variation_bulk_action_variable_regular_price_decrease()
* @uses WC_AJAX::variation_bulk_action_variable_regular_price_increase()
* @uses WC_AJAX::variation_bulk_action_variable_sale_schedule()
* @uses WC_AJAX::variation_bulk_action_delete_all()
* @uses WC_AJAX::variation_bulk_action_variable_download_expiry()
* @uses WC_AJAX::variation_bulk_action_variable_download_limit()
* @uses WC_AJAX::variation_bulk_action_variable_height()
* @uses WC_AJAX::variation_bulk_action_variable_width()
* @uses WC_AJAX::variation_bulk_action_variable_length()
* @uses WC_AJAX::variation_bulk_action_variable_weight()
* @uses WC_AJAX::variation_bulk_action_variable_stock()
* @uses WC_AJAX::variation_bulk_action_variable_sale_price()
* @uses WC_AJAX::variation_bulk_action_variable_regular_price()
* @uses WC_AJAX::variation_bulk_action_toggle_manage_stock()
* @uses WC_AJAX::variation_bulk_action_toggle_virtual()
* @uses WC_AJAX::variation_bulk_action_toggle_downloadable()
* @uses WC_AJAX::variation_bulk_action_toggle_enabled
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
}
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();
}
/**
* Handle submissions from assets/js/settings-views-html-settings-tax.js Backbone model.
*/
public static function tax_rates_save_changes() {
if ( ! isset( $_POST['wc_tax_nonce'], $_POST['changes'] ) ) {
wp_send_json_error( 'missing_fields' );
exit;
}
$current_class = ! empty( $_POST['current_class'] ) ? $_POST['current_class'] : ''; // This is sanitized seven lines later.
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 ),
) );
}
/**
* 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' );
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 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();
}
}
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 ) {
$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'] ) ) {
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(
'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 ) ) );
}
if ( isset( $method_data['enabled'] ) ) {
$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 );
}
}
2015-12-15 17:48:03 +00:00
}
wp_send_json_success( array(
'methods' => $zone->get_shipping_methods()
) );
}
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'] );
$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(),
) );
}
/**
* 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'] ) ) {
2016-05-12 11:18:35 +00:00
continue;
}
$term_id = wp_insert_term( $update_args['name'], 'product_shipping_class', $update_args );
} else {
wp_update_term( $term_id, 'product_shipping_class', $update_args );
}
do_action( 'woocommerce_shipping_classes_save_class', $term_id, $data );
}
$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
}
WC_AJAX::init();