Merge branch 'master' into fix/28232

This commit is contained in:
Rodrigo Primo 2020-11-17 14:47:33 -03:00
commit 246710fce8
17 changed files with 387 additions and 43 deletions

View File

@ -88,3 +88,13 @@ branches:
- master - master
- /^\d+\.\d+(\.\d+)?(-\S*)?$/ - /^\d+\.\d+(\.\d+)?(-\S*)?$/
- /^release\// - /^release\//
# Composer 2.0.7 introduced a change that broke the jetpack autoloader in PHP 7.0 - 7.3.
before_install:
- composer self-update 2.0.6
# Git clone depth
# By default Travis CI clones repositories to a depth of 50 commits. Using a depth of 1 makes this step a bit faster.
git:
depth: 1

View File

@ -507,9 +507,8 @@ jQuery( function( $ ) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: wc_checkout_params.checkout_url, url: wc_checkout_params.checkout_url,
data: new FormData( this ), data: $form.serialize(),
contentType: false, dataType: 'json',
processData: false,
success: function( result ) { success: function( result ) {
// Detach the unload handler that prevents a reload / redirect // Detach the unload handler that prevents a reload / redirect
wc_checkout_form.detachUnloadEventsOnSubmit(); wc_checkout_form.detachUnloadEventsOnSubmit();

45
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "928d8825a02fc4217b3af36a83c2fbc8", "content-hash": "6494b4d4b956386e32381541ebd79839",
"packages": [ "packages": [
{ {
"name": "automattic/jetpack-autoloader", "name": "automattic/jetpack-autoloader",
@ -493,22 +493,27 @@
}, },
{ {
"name": "symfony/css-selector", "name": "symfony/css-selector",
"version": "v3.4.46", "version": "v3.3.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/css-selector.git", "url": "https://github.com/symfony/css-selector.git",
"reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33" "reference": "4d882dced7b995d5274293039370148e291808f2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/da3d9da2ce0026771f5fe64cb332158f1bd2bc33", "url": "https://api.github.com/repos/symfony/css-selector/zipball/4d882dced7b995d5274293039370148e291808f2",
"reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33", "reference": "4d882dced7b995d5274293039370148e291808f2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^5.5.9|>=7.0.8" "php": ">=5.5.9"
}, },
"type": "library", "type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.3-dev"
}
},
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Symfony\\Component\\CssSelector\\": "" "Symfony\\Component\\CssSelector\\": ""
@ -522,14 +527,14 @@
"MIT" "MIT"
], ],
"authors": [ "authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{ {
"name": "Jean-François Simon", "name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com" "email": "jeanfrancois.simon@sensiolabs.com"
}, },
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{ {
"name": "Symfony Community", "name": "Symfony Community",
"homepage": "https://symfony.com/contributors" "homepage": "https://symfony.com/contributors"
@ -538,23 +543,9 @@
"description": "Symfony CssSelector Component", "description": "Symfony CssSelector Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/css-selector/tree/v3.4.46" "source": "https://github.com/symfony/css-selector/tree/master"
}, },
"funding": [ "time": "2017-05-01T15:01:29+00:00"
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-24T10:57:07+00:00"
}, },
{ {
"name": "woocommerce/action-scheduler", "name": "woocommerce/action-scheduler",
@ -758,7 +749,7 @@
}, },
"platform-dev": [], "platform-dev": [],
"platform-overrides": { "platform-overrides": {
"php": "7.1" "php": "7.0"
}, },
"plugin-api-version": "2.0.0" "plugin-api-version": "2.0.0"
} }

View File

@ -519,6 +519,50 @@ abstract class WC_Data {
} }
} }
/**
* Helper method to compute meta cache key. Different from WP Meta cache key in that meta data cached using this key also contains meta_id column.
*
* @since 4.7.0
*
* @return string
*/
public function get_meta_cache_key() {
if ( ! $this->get_id() ) {
wc_doing_it_wrong( 'get_meta_cache_key', 'ID needs to be set before fetching a cache key.', '4.7.0' );
return false;
}
return self::generate_meta_cache_key( $this->get_id(), $this->cache_group );
}
/**
* Generate cache key from id and group.
*
* @since 4.7.0
*
* @param int|string $id Object ID.
* @param string $cache_group Group name use to store cache. Whole group cache can be invalidated in one go.
*
* @return string Meta cache key.
*/
public static function generate_meta_cache_key( $id, $cache_group ) {
return WC_Cache_Helper::get_cache_prefix( $cache_group ) . WC_Cache_Helper::get_cache_prefix( 'object_' . $id ) . 'object_meta_' . $id;
}
/**
* Prime caches for raw meta data. This includes meta_id column as well, which is not included by default in WP meta data.
*
* @since 4.7.0
*
* @param array $raw_meta_data_collection Array of objects of { object_id => array( meta_row_1, meta_row_2, ... }.
* @param string $cache_group Name of cache group.
*/
public static function prime_raw_meta_data_cache( $raw_meta_data_collection, $cache_group ) {
foreach ( $raw_meta_data_collection as $object_id => $raw_meta_data_array ) {
$cache_key = self::generate_meta_cache_key( $object_id, $cache_group );
wp_cache_set( $cache_key, $raw_meta_data_array, $cache_group );
}
}
/** /**
* Read Meta Data from the database. Ignore any internal properties. * Read Meta Data from the database. Ignore any internal properties.
* Uses it's own caches because get_metadata does not provide meta_ids. * Uses it's own caches because get_metadata does not provide meta_ids.
@ -540,7 +584,7 @@ abstract class WC_Data {
if ( ! empty( $this->cache_group ) ) { if ( ! empty( $this->cache_group ) ) {
// Prefix by group allows invalidation by group until https://core.trac.wordpress.org/ticket/4476 is implemented. // Prefix by group allows invalidation by group until https://core.trac.wordpress.org/ticket/4476 is implemented.
$cache_key = WC_Cache_Helper::get_cache_prefix( $this->cache_group ) . WC_Cache_Helper::get_cache_prefix( 'object_' . $this->get_id() ) . 'object_meta_' . $this->get_id(); $cache_key = $this->get_meta_cache_key();
} }
if ( ! $force_read ) { if ( ! $force_read ) {
@ -550,7 +594,9 @@ abstract class WC_Data {
} }
} }
$raw_meta_data = $cache_loaded ? $cached_meta : $this->data_store->read_meta( $this ); // We filter the raw meta data again when loading from cache, in case we cached in an earlier version where filter conditions were different.
$raw_meta_data = $cache_loaded ? $this->data_store->filter_raw_meta_data( $this, $cached_meta ) : $this->data_store->read_meta( $this );
if ( $raw_meta_data ) { if ( $raw_meta_data ) {
foreach ( $raw_meta_data as $meta ) { foreach ( $raw_meta_data as $meta ) {
$this->meta_data[] = new WC_Meta_Data( $this->meta_data[] = new WC_Meta_Data(

View File

@ -57,6 +57,10 @@ class WC_Helper_Updater {
'upgrade_notice' => $data['upgrade_notice'], 'upgrade_notice' => $data['upgrade_notice'],
); );
if ( isset( $data['requires_php'] ) ) {
$item['requires_php'] = $data['requires_php'];
}
// We don't want to deliver a valid upgrade package when their subscription has expired. // We don't want to deliver a valid upgrade package when their subscription has expired.
// To avoid the generic "no_package" error that empty strings give, we will store an // To avoid the generic "no_package" error that empty strings give, we will store an
// indication of expiration for the `upgrader_pre_download` filter to error on. // indication of expiration for the `upgrader_pre_download` filter to error on.

View File

@ -22,7 +22,7 @@ final class WooCommerce {
* *
* @var string * @var string
*/ */
public $version = '4.8.0'; public $version = '4.9.0';
/** /**
* WooCommerce Schema version. * WooCommerce Schema version.

View File

@ -93,14 +93,13 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/** /**
* Method to read an order from the database. * Method to read an order from the database.
* *
* @param WC_Data $order Order object. * @param WC_Order $order Order object.
* *
* @throws Exception If passed order is invalid. * @throws Exception If passed order is invalid.
*/ */
public function read( &$order ) { public function read( &$order ) {
$order->set_defaults(); $order->set_defaults();
$post_object = get_post( $order->get_id() ); $post_object = get_post( $order->get_id() );
if ( ! $order->get_id() || ! $post_object || ! in_array( $post_object->post_type, wc_get_order_types(), true ) ) { if ( ! $order->get_id() || ! $post_object || ! in_array( $post_object->post_type, wc_get_order_types(), true ) ) {
throw new Exception( __( 'Invalid order.', 'woocommerce' ) ); throw new Exception( __( 'Invalid order.', 'woocommerce' ) );
} }

View File

@ -94,7 +94,20 @@ class WC_Data_Store_WP {
$object->get_id() $object->get_id()
) )
); );
return $this->filter_raw_meta_data( $object, $raw_meta_data );
}
/**
* Helper method to filter internal meta keys from all meta data rows for the object.
*
* @since 4.7.0
*
* @param WC_Data $object WC_Data object.
* @param array $raw_meta_data Array of std object of meta data to be filtered.
*
* @return mixed|void
*/
public function filter_raw_meta_data( &$object, $raw_meta_data ) {
$this->internal_meta_keys = array_merge( array_map( array( $this, 'prefix_key' ), $object->get_data_keys() ), $this->internal_meta_keys ); $this->internal_meta_keys = array_merge( array_map( array( $this, 'prefix_key' ), $object->get_data_keys() ), $this->internal_meta_keys );
$meta_data = array_filter( $raw_meta_data, array( $this, 'exclude_internal_meta_keys' ) ); $meta_data = array_filter( $raw_meta_data, array( $this, 'exclude_internal_meta_keys' ) );
return apply_filters( "woocommerce_data_store_wp_{$this->meta_type}_read_meta", $meta_data, $object, $this ); return apply_filters( "woocommerce_data_store_wp_{$this->meta_type}_read_meta", $meta_data, $object, $this );

View File

@ -734,11 +734,12 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
* Get the order type based on Order ID. * Get the order type based on Order ID.
* *
* @since 3.0.0 * @since 3.0.0
* @param int $order_id Order ID. * @param int|WP_Post $order Order | Order id.
*
* @return string * @return string
*/ */
public function get_order_type( $order_id ) { public function get_order_type( $order ) {
return get_post_type( $order_id ); return get_post_type( $order );
} }
/** /**
@ -865,7 +866,13 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
$query = new WP_Query( $args ); $query = new WP_Query( $args );
} }
$orders = ( isset( $query_vars['return'] ) && 'ids' === $query_vars['return'] ) ? $query->posts : array_filter( array_map( 'wc_get_order', $query->posts ) ); if ( isset( $query_vars['return'] ) && 'ids' === $query_vars['return'] ) {
$orders = $query->posts;
} else {
update_post_caches( $query->posts ); // We already fetching posts, might as well hydrate some caches.
$order_ids = wp_list_pluck( $query->posts, 'ID' );
$orders = $this->compile_orders( $order_ids, $query_vars, $query );
}
if ( isset( $query_vars['paginate'] ) && $query_vars['paginate'] ) { if ( isset( $query_vars['paginate'] ) && $query_vars['paginate'] ) {
return (object) array( return (object) array(
@ -878,6 +885,213 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
return $orders; return $orders;
} }
/**
* Compile order response and set caches as needed for order ids.
*
* @param array $order_ids List of order IDS to compile.
* @param array $query_vars Original query arguments.
* @param WP_Query $query Query object.
*
* @return array Orders.
*/
private function compile_orders( $order_ids, $query_vars, $query ) {
if ( empty( $order_ids ) ) {
return array();
}
$orders = array();
// Lets do some cache hydrations so that we don't have to fetch data from DB for every order.
$this->prime_raw_meta_cache_for_orders( $order_ids, $query_vars );
$this->prime_refund_caches_for_order( $order_ids, $query_vars );
$this->prime_order_item_caches_for_orders( $order_ids, $query_vars );
foreach ( $query->posts as $post ) {
$orders[] = wc_get_order( $post );
}
return $orders;
}
/**
* Prime refund cache for orders.
*
* @param array $order_ids Order Ids to prime cache for.
* @param array $query_vars Query vars for the query.
*/
private function prime_refund_caches_for_order( $order_ids, $query_vars ) {
if ( ! isset( $query_vars['type'] ) || ! ( 'shop_order' === $query_vars['type'] ) ) {
return;
}
if ( isset( $query_vars['fields'] ) && 'all' !== $query_vars['fields'] ) {
if ( is_array( $query_vars['fields'] ) && ! in_array( 'refunds', $query_vars['fields'] ) ) {
return;
}
}
$cache_keys_mapping = array();
foreach ( $order_ids as $order_id ) {
$cache_keys_mapping[ $order_id ] = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'refunds' . $order_id;
}
$non_cached_ids = array();
$cache_values = wc_cache_get_multiple( array_values( $cache_keys_mapping ), 'orders' );
foreach ( $order_ids as $order_id ) {
if ( false === $cache_values[ $cache_keys_mapping[ $order_id ] ] ) {
$non_cached_ids[] = $order_id;
}
}
if ( empty( $non_cached_ids ) ) {
return;
}
$refunds = wc_get_orders(
array(
'type' => 'shop_order_refund',
'post_parent__in' => $non_cached_ids,
'limit' => - 1,
)
);
$order_refunds = array_reduce(
$refunds,
function ( $order_refunds_array, WC_Order_Refund $refund ) {
if ( ! isset( $order_refunds_array[ $refund->get_parent_id() ] ) ) {
$order_refunds_array[ $refund->get_parent_id() ] = array();
}
$order_refunds_array[ $refund->get_parent_id() ][] = $refund;
return $order_refunds_array;
},
array()
);
foreach ( $non_cached_ids as $order_id ) {
$refunds = array();
if ( isset( $order_refunds[ $order_id ] ) ) {
$refunds = $order_refunds[ $order_id ];
}
wp_cache_set( $cache_keys_mapping[ $order_id ], $refunds, 'orders' );
}
}
/**
* Prime following caches:
* 1. item-$order_item_id For individual items.
* 2. order-items-$order-id For fetching items associated with an order.
* 3. order-item meta.
*
* @param array $order_ids Order Ids to prime cache for.
* @param array $query_vars Query vars for the query.
*/
private function prime_order_item_caches_for_orders( $order_ids, $query_vars ) {
global $wpdb;
if ( isset( $query_vars['fields'] ) && 'all' !== $query_vars['fields'] ) {
$line_items = array(
'line_items',
'shipping_lines',
'fee_lines',
'coupon_lines',
);
if ( is_array( $query_vars['fields'] ) && 0 === count( array_intersect( $line_items, $query_vars['fields'] ) ) ) {
return;
}
}
$cache_keys = array_map(
function ( $order_id ) {
return 'order-items-' . $order_id;
},
$order_ids
);
$cache_values = wc_cache_get_multiple( $cache_keys, 'orders' );
$non_cached_ids = array();
foreach ( $order_ids as $order_id ) {
if ( false === $cache_values[ 'order-items-' . $order_id ] ) {
$non_cached_ids[] = $order_id;
}
}
if ( empty( $non_cached_ids ) ) {
return;
}
$non_cached_ids = esc_sql( $non_cached_ids );
$non_cached_ids_string = implode( ',', $non_cached_ids );
$order_items = $wpdb->get_results(
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
"SELECT order_item_type, order_item_id, order_id, order_item_name FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id in ( $non_cached_ids_string ) ORDER BY order_item_id;"
);
if ( empty( $order_items ) ) {
return;
}
$order_items_for_all_orders = array_reduce(
$order_items,
function ( $order_items_collection, $order_item ) {
if ( ! isset( $order_items_collection[ $order_item->order_id ] ) ) {
$order_items_collection[ $order_item->order_id ] = array();
}
$order_items_collection[ $order_item->order_id ][] = $order_item;
return $order_items_collection;
}
);
foreach ( $order_items_for_all_orders as $order_id => $items ) {
wp_cache_set( 'order-items-' . $order_id, $items, 'orders' );
}
foreach ( $order_items as $item ) {
wp_cache_set( 'item-' . $item->order_item_id, $item, 'order-items' );
}
$order_item_ids = wp_list_pluck( $order_items, 'order_item_id' );
update_meta_cache( 'order_item', $order_item_ids );
}
/**
* Prime cache for raw meta data for orders in bulk. Difference between this and WP built-in metadata is that this method also fetches `meta_id` field which we use and cache it.
*
* @param array $order_ids Order Ids to prime cache for.
* @param array $query_vars Query vars for the query.
*/
private function prime_raw_meta_cache_for_orders( $order_ids, $query_vars ) {
global $wpdb;
if ( isset( $query_vars['fields'] ) && 'all' !== $query_vars['fields'] ) {
if ( is_array( $query_vars['fields'] ) && ! in_array( 'meta_data', $query_vars['fields'] ) ) {
return;
}
}
$cache_keys_mapping = array();
foreach ( $order_ids as $order_id ) {
$cache_keys_mapping[ $order_id ] = WC_Order::generate_meta_cache_key( $order_id, 'orders' );
}
$cache_values = wc_cache_get_multiple( array_values( $cache_keys_mapping ), 'orders' );
$non_cached_ids = array();
foreach ( $order_ids as $order_id ) {
if ( false === $cache_values[ $cache_keys_mapping[ $order_id ] ] ) {
$non_cached_ids[] = $order_id;
}
}
if ( empty( $non_cached_ids ) ) {
return;
}
$order_ids = esc_sql( $non_cached_ids );
$order_ids_in = "'" . implode( "', '", $order_ids ) . "'";
$raw_meta_data_array = $wpdb->get_results(
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
"SELECT post_id as object_id, meta_id, meta_key, meta_value
FROM {$wpdb->postmeta}
WHERE post_id IN ( $order_ids_in )
ORDER BY post_id"
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
);
$raw_meta_data_collection = array_reduce(
$raw_meta_data_array,
function ( $collection, $raw_meta_data ) {
if ( ! isset( $collection[ $raw_meta_data->object_id ] ) ) {
$collection[ $raw_meta_data->object_id ] = array();
}
$collection[ $raw_meta_data->object_id ][] = $raw_meta_data;
return $collection;
},
array()
);
WC_Order::prime_raw_meta_data_cache( $raw_meta_data_collection, 'orders' );
}
/** /**
* Return the order type of a given item which belongs to WC_Order. * Return the order type of a given item which belongs to WC_Order.
* *

View File

@ -47,12 +47,15 @@ class WC_Order_Refund_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT im
*/ */
public function delete( &$order, $args = array() ) { public function delete( &$order, $args = array() ) {
$id = $order->get_id(); $id = $order->get_id();
$parent_order_id = $order->get_parent_id();
$refund_cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'refunds' . $parent_order_id;
if ( ! $id ) { if ( ! $id ) {
return; return;
} }
wp_delete_post( $id ); wp_delete_post( $id );
wp_cache_delete( $refund_cache_key, 'orders' );
$order->set_id( 0 ); $order->set_id( 0 );
do_action( 'woocommerce_delete_order_refund', $id ); do_action( 'woocommerce_delete_order_refund', $id );
} }

View File

@ -283,6 +283,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller {
$args['post_parent__in'] = $request['parent']; $args['post_parent__in'] = $request['parent'];
$args['post_parent__not_in'] = $request['parent_exclude']; $args['post_parent__not_in'] = $request['parent_exclude'];
$args['s'] = $request['search']; $args['s'] = $request['search'];
$args['fields'] = $this->get_fields_for_response( $request );
if ( 'date' === $args['orderby'] ) { if ( 'date' === $args['orderby'] ) {
$args['orderby'] = 'date ID'; $args['orderby'] = 'date ID';

View File

@ -2501,3 +2501,23 @@ function wc_is_running_from_async_action_scheduler() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended // phpcs:ignore WordPress.Security.NonceVerification.Recommended
return isset( $_REQUEST['action'] ) && 'as_async_request_queue_runner' === $_REQUEST['action']; return isset( $_REQUEST['action'] ) && 'as_async_request_queue_runner' === $_REQUEST['action'];
} }
/**
* Polyfill for wp_cache_get_multiple for WP versions before 5.5.
*
* @param array $keys Array of keys to get from group.
* @param string $group Optional. Where the cache contents are grouped. Default empty.
* @param bool $force Optional. Whether to force an update of the local cache from the persistent
* cache. Default false.
* @return array|bool Array of values.
*/
function wc_cache_get_multiple( $keys, $group = '', $force = false ) {
if ( function_exists( 'wp_cache_get_multiple' ) ) {
return wp_cache_get_multiple( $keys, $group, $force );
}
$values = array();
foreach ( $keys as $key ) {
$values[ $key ] = wp_cache_get( $key, $group, $force );
}
return $values;
}

View File

@ -71,7 +71,7 @@ function wc_get_orders( $args ) {
* *
* @since 2.2 * @since 2.2
* *
* @param mixed $the_order Post object or post ID of the order. * @param mixed $the_order Post object or post ID of the order.
* *
* @return bool|WC_Order|WC_Order_Refund * @return bool|WC_Order|WC_Order_Refund
*/ */

View File

@ -1,7 +1,7 @@
{ {
"name": "woocommerce", "name": "woocommerce",
"title": "WooCommerce", "title": "WooCommerce",
"version": "4.8.0", "version": "4.9.0",
"homepage": "https://woocommerce.com/", "homepage": "https://woocommerce.com/",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -160,7 +160,7 @@ WooCommerce comes with some sample data you can use to see how products look; im
== Changelog == == Changelog ==
= 4.8.0 - 2020-12-xx = = 4.9.0 - 2021-01-xx =
[See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce/master/changelog.txt). [See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce/master/changelog.txt).

View File

@ -0,0 +1,44 @@
<?php
/**
* Class WC_Order_Data_Store_CPT_Test.
*/
class WC_Order_Data_Store_CPT_Test extends WC_Unit_Test_Case {
/**
* Test that refund cache are invalidated correctly when refund is deleted.
*/
public function test_refund_cache_invalidation() {
$order = WC_Helper_Order::create_order();
$refund = wc_create_refund(
array(
'order_id' => $order->get_id(),
'reason' => 'testing',
'amount' => 1,
)
);
$this->assertNotWPError( $refund );
// Prime cache.
$fetched_order = wc_get_orders(
array(
'post__in' => array( $order->get_id() ),
'type' => 'shop_order',
)
)[0];
$refund_cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'refunds' . $order->get_id();
$cached_refunds = wp_cache_get( $refund_cache_key, 'orders' );
$this->assertEquals( $cached_refunds[0]->get_id(), $fetched_order->get_refunds()[0]->get_id() );
$refund->delete( true );
// Cache should be cleared now.
$cached_refunds = wp_cache_get( $refund_cache_key, 'orders' );
$this->assertEquals( false, $cached_refunds );
}
}

View File

@ -3,7 +3,7 @@
* Plugin Name: WooCommerce * Plugin Name: WooCommerce
* Plugin URI: https://woocommerce.com/ * Plugin URI: https://woocommerce.com/
* Description: An eCommerce toolkit that helps you sell anything. Beautifully. * Description: An eCommerce toolkit that helps you sell anything. Beautifully.
* Version: 4.8.0-dev * Version: 4.9.0-dev
* Author: Automattic * Author: Automattic
* Author URI: https://woocommerce.com * Author URI: https://woocommerce.com
* Text Domain: woocommerce * Text Domain: woocommerce