rebase on oct-10-2023

This commit is contained in:
Rachit Bhargava
2023-10-10 17:23:21 -04:00
parent d37566ffb6
commit d096058d7d
4789 changed files with 254611 additions and 307223 deletions

View File

@@ -157,6 +157,7 @@ class WC_AJAX {
'json_search_downloadable_products_and_variations',
'json_search_customers',
'json_search_categories',
'json_search_categories_tree',
'json_search_taxonomy_terms',
'json_search_product_attributes',
'json_search_pages',
@@ -172,6 +173,7 @@ class WC_AJAX {
'tax_rates_save_changes',
'shipping_zones_save_changes',
'shipping_zone_add_method',
'shipping_zone_remove_method',
'shipping_zone_methods_save_changes',
'shipping_zone_methods_save_settings',
'shipping_classes_save_changes',
@@ -195,6 +197,22 @@ class WC_AJAX {
}
);
}
// WP's heartbeat.
$ajax_heartbeat_callbacks = array(
'order_refresh_lock',
'check_locked_orders',
);
foreach ( $ajax_heartbeat_callbacks as $ajax_callback ) {
add_filter(
'heartbeat_received',
function( $response, $data ) use ( $ajax_callback ) {
return call_user_func_array( array( __CLASS__, $ajax_callback ), func_get_args() );
},
10,
2
);
}
}
/**
@@ -298,7 +316,12 @@ class WC_AJAX {
'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>',
'form.woocommerce-checkout' => wc_print_notice(
esc_html__( 'Sorry, your session has expired.', 'woocommerce' ) . ' <a href="' . esc_url( wc_get_page_permalink( 'shop' ) ) . '" class="wc-backward">' . esc_html__( 'Return to shop', 'woocommerce' ) . '</a>',
'error',
array(),
true
),
)
),
)
@@ -588,6 +611,8 @@ class WC_AJAX {
wp_die( -1 );
}
$product_type = isset( $_POST['product_type'] ) ? sanitize_text_field( wp_unslash( $_POST['product_type'] ) ) : 'simple';
$i = absint( $_POST['i'] );
$metabox_class = array();
$attribute = new WC_Product_Attribute();
@@ -596,7 +621,13 @@ class WC_AJAX {
$attribute->set_name( sanitize_text_field( wp_unslash( $_POST['taxonomy'] ) ) );
/* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */
$attribute->set_visible( apply_filters( 'woocommerce_attribute_default_visibility', 1 ) );
$attribute->set_variation( apply_filters( 'woocommerce_attribute_default_is_variation', 1 ) );
$attribute->set_variation(
apply_filters(
'woocommerce_attribute_default_is_variation',
'variable' === $product_type ? 1 : 0,
$product_type
)
);
/* phpcs: enable */
if ( $attribute->is_taxonomy() ) {
@@ -940,6 +971,8 @@ class WC_AJAX {
$data['date_created'] = $data['date_created'] ? $data['date_created']->getTimestamp() : null;
$data['date_modified'] = $data['date_modified'] ? $data['date_modified']->getTimestamp() : null;
unset( $data['meta_data'] );
$customer_data = apply_filters( 'woocommerce_ajax_get_customer_details', $data, $customer, $user_id );
wp_send_json( $customer_data );
}
@@ -1764,12 +1797,13 @@ class WC_AJAX {
wp_die();
}
$show_empty = isset( $_GET['show_empty'] ) ? wp_validate_boolean( wc_clean( wp_unslash( $_GET['show_empty'] ) ) ) : false;
$found_categories = array();
$args = array(
'taxonomy' => array( 'product_cat' ),
'orderby' => 'id',
'order' => 'ASC',
'hide_empty' => true,
'hide_empty' => ! $show_empty,
'fields' => 'all',
'name__like' => $search_text,
);
@@ -1780,6 +1814,7 @@ class WC_AJAX {
foreach ( $terms as $term ) {
$term->formatted_name = '';
$ancestors = array();
if ( $term->parent ) {
$ancestors = array_reverse( get_ancestors( $term->term_id, 'product_cat' ) );
foreach ( $ancestors as $ancestor ) {
@@ -1790,6 +1825,7 @@ class WC_AJAX {
}
}
$term->parents = $ancestors;
$term->formatted_name .= $term->name . ' (' . $term->count . ')';
$found_categories[ $term->term_id ] = $term;
}
@@ -1798,6 +1834,75 @@ class WC_AJAX {
wp_send_json( apply_filters( 'woocommerce_json_search_found_categories', $found_categories ) );
}
/**
* Search for categories and return json.
*/
public static function json_search_categories_tree() {
ob_start();
check_ajax_referer( 'search-categories', 'security' );
if ( ! current_user_can( 'edit_products' ) ) {
wp_die( -1 );
}
$search_text = isset( $_GET['term'] ) ? wc_clean( wp_unslash( $_GET['term'] ) ) : '';
$number = isset( $_GET['number'] ) ? absint( $_GET['number'] ) : 50;
$args = array(
'taxonomy' => array( 'product_cat' ),
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false,
'fields' => 'all',
'number' => $number,
'name__like' => $search_text,
);
$terms = get_terms( $args );
$terms_map = array();
if ( $terms ) {
foreach ( $terms as $term ) {
$terms_map[ $term->term_id ] = $term;
if ( $term->parent ) {
$ancestors = get_ancestors( $term->term_id, 'product_cat' );
$current_child = $term;
foreach ( $ancestors as $ancestor ) {
if ( ! isset( $terms_map[ $ancestor ] ) ) {
$ancestor_term = get_term( $ancestor, 'product_cat' );
$terms_map[ $ancestor ] = $ancestor_term;
}
if ( ! $terms_map[ $ancestor ]->children ) {
$terms_map[ $ancestor ]->children = array();
}
$item_exists = count(
array_filter(
$terms_map[ $ancestor ]->children,
function( $term ) use ( $current_child ) {
return $term->term_id === $current_child->term_id;
}
)
) === 1;
if ( ! $item_exists ) {
$terms_map[ $ancestor ]->children[] = $current_child;
}
$current_child = $terms_map[ $ancestor ];
}
}
}
}
$parent_terms = array_filter(
array_values( $terms_map ),
function( $term ) {
return 0 === $term->parent;
}
);
wp_send_json( apply_filters( 'woocommerce_json_search_found_categories', $parent_terms ) );
}
/**
* Search for taxonomy terms and return json.
*/
@@ -1814,11 +1919,12 @@ class WC_AJAX {
$limit = isset( $_GET['limit'] ) ? absint( wp_unslash( $_GET['limit'] ) ) : null;
$taxonomy = isset( $_GET['taxonomy'] ) ? wc_clean( wp_unslash( $_GET['taxonomy'] ) ) : '';
$orderby = isset( $_GET['orderby'] ) ? wc_clean( wp_unslash( $_GET['orderby'] ) ) : 'name';
$order = isset( $_GET['order'] ) ? wc_clean( wp_unslash( $_GET['order'] ) ) : 'ASC';
$args = array(
'taxonomy' => $taxonomy,
'orderby' => $orderby,
'order' => 'ASC',
'order' => $order,
'hide_empty' => false,
'fields' => 'all',
'number' => $limit,
@@ -2899,6 +3005,18 @@ class WC_AJAX {
// That's fine, it's not in the database anyways. NEXT!
continue;
}
/**
* Notify that a non-option setting has been deleted.
*
* @since 7.8.0
*/
do_action(
'woocommerce_update_non_option_setting',
array(
'id' => 'shipping_zone',
'action' => 'delete',
)
);
WC_Shipping_Zones::delete_zone( $zone_id );
continue;
}
@@ -2915,13 +3033,31 @@ class WC_AJAX {
$zone = new WC_Shipping_Zone( $zone_data['zone_id'] );
if ( isset( $zone_data['zone_order'] ) ) {
/**
* Notify that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action(
'woocommerce_update_non_option_setting',
array(
'id' => 'zone_order',
)
);
$zone->set_zone_order( $zone_data['zone_order'] );
}
$zone->save();
}
}
global $current_tab;
$current_tab = 'shipping';
/**
* Completes the saving process for options.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_options' );
wp_send_json_success(
array(
'zones' => WC_Shipping_Zones::get_zones( 'json' ),
@@ -2949,10 +3085,46 @@ class WC_AJAX {
wp_die();
}
$zone_id = wc_clean( wp_unslash( $_POST['zone_id'] ) );
$zone = new WC_Shipping_Zone( $zone_id );
$zone_id = wc_clean( wp_unslash( $_POST['zone_id'] ) );
$zone = new WC_Shipping_Zone( $zone_id );
// A shipping zone can be created here if the user is adding a method without first saving the shipping zone.
if ( '' === $zone_id ) {
/**
* Notified that a non-option setting has been added.
*
* @since 7.8.0
*/
do_action(
'woocommerce_update_non_option_setting',
array(
'id' => 'shipping_zone',
'action' => 'add',
)
);
}
/**
* Notify that a non-option setting has been added.
*
* @since 7.8.0
*/
do_action(
'woocommerce_update_non_option_setting',
array(
'id' => 'zone_method',
'action' => 'add',
)
);
$instance_id = $zone->add_shipping_method( wc_clean( wp_unslash( $_POST['method_id'] ) ) );
global $current_tab;
$current_tab = 'shipping';
/**
* Completes the saving process for options.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_options' );
wp_send_json_success(
array(
'instance_id' => $instance_id,
@@ -2963,6 +3135,63 @@ class WC_AJAX {
);
}
/**
* Handle submissions from assets/js/wc-shipping-zone-methods.js Backbone model.
*/
public static function shipping_zone_remove_method() {
if ( ! isset( $_POST['wc_shipping_zones_nonce'], $_POST['instance_id'], $_POST['zone_id'] ) ) {
wp_send_json_error( 'missing_fields' );
wp_die();
}
if ( ! wp_verify_nonce( wp_unslash( $_POST['wc_shipping_zones_nonce'] ), 'wc_shipping_zones_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
wp_send_json_error( 'bad_nonce' );
wp_die();
}
// Check User Caps.
if ( ! current_user_can( 'manage_woocommerce' ) ) {
wp_send_json_error( 'missing_capabilities' );
wp_die();
}
$zone_id = wc_clean( wp_unslash( $_POST['zone_id'] ) );
$zone = new WC_Shipping_Zone( $zone_id );
$instance_id = wc_clean( wp_unslash( $_POST['instance_id'] ) );
/**
* Notify that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action(
'woocommerce_update_non_option_setting',
array(
'id' => $instance_id,
)
);
if ( ! $zone->delete_shipping_method( $instance_id ) ) {
wp_send_json_error( 'missing_shipping_method_instance_id' );
wp_die();
}
global $current_tab;
$current_tab = 'shipping';
/**
* Completes the saving process for options.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_options' );
wp_send_json_success(
array(
'instance_id' => $instance_id,
'methods' => $zone->get_shipping_methods( false, 'json' ),
)
);
}
/**
* Handle submissions from assets/js/wc-shipping-zone-methods.js Backbone model.
*/
@@ -2986,13 +3215,40 @@ class WC_AJAX {
$zone_id = wc_clean( wp_unslash( $_POST['zone_id'] ) );
$zone = new WC_Shipping_Zone( $zone_id );
// A shipping zone can be created here if the user is adding a method without first saving the shipping zone.
if ( '' === $zone_id ) {
/**
* Notifies that a non-option setting has been added.
*
* @since 7.8.0
*/
do_action(
'woocommerce_update_non_option_setting',
array(
'id' => 'shipping_zone',
'action' => 'add',
)
);
}
$changes = wp_unslash( $_POST['changes'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
if ( isset( $changes['zone_name'] ) ) {
/**
* Notifies that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_non_option_setting', array( 'id' => 'zone_name' ) );
$zone->set_zone_name( wc_clean( $changes['zone_name'] ) );
}
if ( isset( $changes['zone_locations'] ) ) {
/**
* Notifies that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_non_option_setting', array( 'id' => 'zone_locations' ) );
$zone->clear_locations( array( 'state', 'country', 'continent' ) );
$locations = array_filter( array_map( 'wc_clean', (array) $changes['zone_locations'] ) );
foreach ( $locations as $location ) {
@@ -3013,6 +3269,12 @@ class WC_AJAX {
}
if ( isset( $changes['zone_postcodes'] ) ) {
/**
* Notifies that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_non_option_setting', array( 'id' => 'zone_postcodes' ) );
$zone->clear_locations( 'postcode' );
$postcodes = array_filter( array_map( 'strtoupper', array_map( 'wc_clean', explode( "\n", $changes['zone_postcodes'] ) ) ) );
foreach ( $postcodes as $postcode ) {
@@ -3029,6 +3291,18 @@ class WC_AJAX {
$option_key = $shipping_method->get_instance_option_key();
if ( $wpdb->delete( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'instance_id' => $instance_id ) ) ) {
delete_option( $option_key );
/**
* Notifies that a non-option setting has been deleted.
*
* @since 7.8.0
*/
do_action(
'woocommerce_update_non_option_setting',
array(
'id' => 'zone_method',
'action' => 'delete',
)
);
do_action( 'woocommerce_shipping_zone_method_deleted', $instance_id, $method_id, $zone_id );
}
continue;
@@ -3043,10 +3317,22 @@ class WC_AJAX {
);
if ( isset( $method_data['method_order'] ) ) {
/**
* Notifies that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_non_option_setting', array( 'id' => 'zone_methods_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'] ) ) {
/**
* Notifies that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_non_option_setting', array( 'id' => 'zone_methods_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 );
@@ -3057,6 +3343,15 @@ class WC_AJAX {
$zone->save();
global $current_tab;
$current_tab = 'shipping';
/**
* Completes the saving process for options.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_options' );
wp_send_json_success(
array(
'zone_id' => $zone->get_id(),
@@ -3088,7 +3383,22 @@ class WC_AJAX {
$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 );
/**
* Notify that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_non_option_setting', array( 'id' => 'zone_method_settings' ) );
$shipping_method->set_post_data( wp_unslash( $_POST['data'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
global $current_tab;
$current_tab = 'shipping';
/**
* Completes the saving process for options.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_options' );
$shipping_method->process_admin_options();
WC_Cache_Helper::get_transient_version( 'shipping', true );
@@ -3133,6 +3443,18 @@ class WC_AJAX {
// That's fine, it's not in the database anyways. NEXT!
continue;
}
/**
* Notifies that a non-option setting has been deleted.
*
* @since 7.8.0
*/
do_action(
'woocommerce_update_non_option_setting',
array(
'id' => 'shipping_class',
'action' => 'delete',
)
);
wp_delete_term( $term_id, 'product_shipping_class' );
continue;
}
@@ -3140,14 +3462,32 @@ class WC_AJAX {
$update_args = array();
if ( isset( $data['name'] ) ) {
/**
* Notify that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_non_option_setting', array( 'id' => 'shipping_class_name' ) );
$update_args['name'] = wc_clean( $data['name'] );
}
if ( isset( $data['slug'] ) ) {
/**
* Notify that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_non_option_setting', array( 'id' => 'shipping_class_slug' ) );
$update_args['slug'] = wc_clean( $data['slug'] );
}
if ( isset( $data['description'] ) ) {
/**
* Notify that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_non_option_setting', array( 'id' => 'shipping_class_description' ) );
$update_args['description'] = wc_clean( $data['description'] );
}
@@ -3156,15 +3496,42 @@ class WC_AJAX {
if ( empty( $update_args['name'] ) ) {
continue;
}
/**
* Notifies that a non-option setting has been added.
*
* @since 7.8.0
*/
do_action(
'woocommerce_update_non_option_setting',
array(
'id' => 'shipping_class',
'action' => 'add',
)
);
$inserted_term = wp_insert_term( $update_args['name'], 'product_shipping_class', $update_args );
$term_id = is_wp_error( $inserted_term ) ? 0 : $inserted_term['term_id'];
} else {
/**
* Notifies that a non-option setting has been updated.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_non_option_setting', array( 'id' => 'shipping_class' ) );
wp_update_term( $term_id, 'product_shipping_class', $update_args );
}
do_action( 'woocommerce_shipping_classes_save_class', $term_id, $data );
}
global $current_tab, $current_section;
$current_tab = 'shipping';
$current_section = 'classes';
/**
* Completes the saving process for options.
*
* @since 7.8.0
*/
do_action( 'woocommerce_update_options' );
$wc_shipping = WC_Shipping::instance();
wp_send_json_success(
@@ -3217,7 +3584,6 @@ class WC_AJAX {
// Disable the gateway.
$gateway->update_option( 'enabled', 'no' );
}
do_action( 'woocommerce_update_options' );
wp_send_json_success( ! wc_string_to_bool( $enabled ) );
wp_die();
@@ -3243,6 +3609,31 @@ class WC_AJAX {
private static function order_delete_meta() : void {
wc_get_container()->get( CustomMetaBox::class )->delete_meta_ajax();
}
/**
* Hooked to 'heartbeat_received' on the edit order page to refresh the lock on an order being edited by the current user.
*
* @param array $response The heartbeat response to be sent.
* @param array $data Data sent through the heartbeat.
* @return array Response to be sent.
*/
private static function order_refresh_lock( $response, $data ) {
return wc_get_container()->get( Automattic\WooCommerce\Internal\Admin\Orders\EditLock::class )->refresh_lock_ajax( $response, $data );
}
/**
* Hooked to 'heartbeat_received' on the orders screen to refresh the locked status of orders in the list table.
*
* @since 7.8.0
*
* @param array $response The heartbeat response to be sent.
* @param array $data Data sent through the heartbeat.
* @return array Response to be sent.
*/
private static function check_locked_orders( $response, $data ) {
return wc_get_container()->get( Automattic\WooCommerce\Internal\Admin\Orders\EditLock::class )->check_locked_orders_ajax( $response, $data );
}
}
WC_AJAX::init();