Merge pull request #22760 from woocommerce/performance/webhook-loading

Performance: webhook loading
This commit is contained in:
Mike Jolley 2019-02-19 09:58:06 +00:00 committed by GitHub
commit 07eadfeb72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 334 additions and 140 deletions

View File

@ -86,8 +86,10 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
add_query_arg(
array(
'delete' => $webhook->get_id(),
), admin_url( 'admin.php?page=wc-settings&tab=advanced&section=webhooks' )
), 'delete-webhook'
),
admin_url( 'admin.php?page=wc-settings&tab=advanced&section=webhooks' )
),
'delete-webhook'
)
) . '">' . esc_html__( 'Delete permanently', 'woocommerce' ) . '</a>',
);
@ -262,7 +264,10 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
echo '<label class="screen-reader-text" for="' . esc_attr( $input_id ) . '">' . esc_html( $text ) . ':</label>';
echo '<input type="search" id="' . esc_attr( $input_id ) . '" name="s" value="' . esc_attr( $search_query ) . '" />';
submit_button(
$text, '', '', false,
$text,
'',
'',
false,
array(
'id' => 'search-submit',
)
@ -292,22 +297,19 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
$args['search'] = sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ); // WPCS: input var okay, CSRF ok.
}
$args['paginate'] = true;
// Get the webhooks.
$data_store = WC_Data_Store::load( 'webhook' );
$webhooks = $data_store->search_webhooks( $args );
$this->items = array_map( 'wc_get_webhook', $webhooks );
// Get total items.
$args['limit'] = -1;
$args['offset'] = 0;
$total_items = count( $data_store->search_webhooks( $args ) );
$this->items = array_map( 'wc_get_webhook', $webhooks->webhooks );
// Set the pagination.
$this->set_pagination_args(
array(
'total_items' => $total_items,
'total_items' => $webhooks->total,
'per_page' => $per_page,
'total_pages' => ceil( $total_items / $per_page ),
'total_pages' => $webhooks->max_num_pages,
)
);
}

View File

@ -270,8 +270,9 @@ class WC_Admin_Webhooks {
echo '<h2>' . esc_html__( 'Webhooks', 'woocommerce' ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=advanced&section=webhooks&edit-webhook=0' ) ) . '" class="add-new-h2">' . esc_html__( 'Add webhook', 'woocommerce' ) . '</a></h2>';
// Get the webhooks count.
$data_store = WC_Data_Store::load( 'webhook' );
$count = count( $data_store->get_webhooks_ids() );
$data_store = WC_Data_Store::load( 'webhook' );
$num_webhooks = $data_store->get_count_webhooks_by_status();
$count = array_sum( $num_webhooks );
if ( 0 < $count ) {
$webhooks_table_list->process_bulk_action();

View File

@ -326,21 +326,6 @@ class WC_API_Webhooks extends WC_API_Resource {
return $webhook->delete( true );
}
/**
* Get webhooks total results
*
* @since 3.3.0
* @param array $args Request arguments for filtering query.
* @return array
*/
private function get_webhooks_total_results( $args = array() ) {
$data_store = WC_Data_Store::load( 'webhook' );
$args['limit'] = -1;
$args['offset'] = 0;
return count( $data_store->search_webhooks( $args ) );
}
/**
* Helper method to get webhook post objects
*
@ -390,6 +375,8 @@ class WC_API_Webhooks extends WC_API_Resource {
unset( $args['date_query'] );
}
$args['paginate'] = true;
// Get the webhooks.
$data_store = WC_Data_Store::load( 'webhook' );
$results = $data_store->search_webhooks( $args );
@ -397,12 +384,12 @@ class WC_API_Webhooks extends WC_API_Resource {
// Get total items.
$headers = new stdClass;
$headers->page = $page;
$headers->total = $this->get_webhooks_total_results( $args );
$headers->total = $results->total;
$headers->is_single = $args['limit'] > $headers->total;
$headers->total_pages = ceil( $headers->total / $args['limit'] );
$headers->total_pages = $results->max_num_pages;
return array(
'results' => $results,
'results' => $results->webhooks,
'headers' => $headers,
);
}

View File

@ -326,21 +326,6 @@ class WC_API_Webhooks extends WC_API_Resource {
return $webhook->delete( true );
}
/**
* Get webhooks total results
*
* @since 3.3.0
* @param array $args Request arguments for filtering query.
* @return array
*/
private function get_webhooks_total_results( $args = array() ) {
$data_store = WC_Data_Store::load( 'webhook' );
$args['limit'] = -1;
$args['offset'] = 0;
return count( $data_store->search_webhooks( $args ) );
}
/**
* Helper method to get webhook post objects
*
@ -390,6 +375,8 @@ class WC_API_Webhooks extends WC_API_Resource {
unset( $args['date_query'] );
}
$args['paginate'] = true;
// Get the webhooks.
$data_store = WC_Data_Store::load( 'webhook' );
$results = $data_store->search_webhooks( $args );
@ -397,12 +384,12 @@ class WC_API_Webhooks extends WC_API_Resource {
// Get total items.
$headers = new stdClass;
$headers->page = $page;
$headers->total = $this->get_webhooks_total_results( $args );
$headers->total = $results->total;
$headers->is_single = $args['limit'] > $headers->total;
$headers->total_pages = ceil( $headers->total / $args['limit'] );
$headers->total_pages = $results->max_num_pages;
return array(
'results' => $results,
'results' => $results->webhooks,
'headers' => $headers,
);
}

View File

@ -247,32 +247,29 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller {
*/
$prepared_args = apply_filters( 'woocommerce_rest_webhook_query', $args, $request );
unset( $prepared_args['page'] );
$prepared_args['paginate'] = true;
// Get the webhooks.
$data_store = WC_Data_Store::load( 'webhook' );
$results = $data_store->search_webhooks( $prepared_args );
$webhooks = array();
$data_store = WC_Data_Store::load( 'webhook' );
$results = $data_store->search_webhooks( $prepared_args );
$webhook_ids = $results->webhooks;
$webhooks = array();
foreach ( $results as $webhook_id ) {
foreach ( $webhook_ids as $webhook_id ) {
$data = $this->prepare_item_for_response( $webhook_id, $request );
$webhooks[] = $this->prepare_response_for_collection( $data );
}
$response = rest_ensure_response( $webhooks );
$response = rest_ensure_response( $webhooks );
$per_page = (int) $prepared_args['limit'];
$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
$total_webhooks = $results->total;
$max_pages = $results->max_num_pages;
$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
// Store pagination values for headers then unset for count query.
$per_page = (int) $prepared_args['limit'];
$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
$response->header( 'X-WP-Total', $total_webhooks );
$response->header( 'X-WP-TotalPages', $max_pages );
// Calculate totals.
$prepared_args['limit'] = -1;
$prepared_args['offset'] = 0;
$total_webhooks = count( $data_store->search_webhooks( $prepared_args ) );
$response->header( 'X-WP-Total', (int) $total_webhooks );
$max_pages = ceil( $total_webhooks / $per_page );
$response->header( 'X-WP-TotalPages', (int) $max_pages );
$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
if ( $page > 1 ) {
$prev_page = $page - 1;
if ( $prev_page > $max_pages ) {

View File

@ -688,7 +688,15 @@ final class WooCommerce {
return;
}
wc_load_webhooks();
/**
* Hook: woocommerce_load_webhooks_limit.
*
* @since 3.6.0
* @param int $limit Used to limit how many webhooks are loaded. Default: no limit.
*/
$limit = apply_filters( 'woocommerce_load_webhooks_limit', null );
wc_load_webhooks( 'active', $limit );
}
/**

View File

@ -59,7 +59,7 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
$webhook->set_id( $webhook_id );
$webhook->apply_changes();
delete_transient( 'woocommerce_webhook_ids' );
$this->delete_transients( $webhook->get_status( 'edit' ) );
WC_Cache_Helper::incr_cache_prefix( 'webhooks' );
do_action( 'woocommerce_new_webhook', $webhook_id );
}
@ -152,6 +152,10 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
$webhook->apply_changes();
if ( isset( $changes['status'] ) ) {
// We need to delete all transients, because we can't be sure of the old status.
$this->delete_transients( 'all' );
}
wp_cache_delete( $webhook->get_id(), 'webhooks' );
WC_Cache_Helper::incr_cache_prefix( 'webhooks' );
@ -179,7 +183,7 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
array( '%d' )
); // WPCS: cache ok, DB call ok.
delete_transient( 'woocommerce_webhook_ids' );
$this->delete_transients( 'all' );
WC_Cache_Helper::incr_cache_prefix( 'webhooks' );
do_action( 'woocommerce_webhook_deleted', $webhook->get_id(), $webhook );
}
@ -196,21 +200,29 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
}
/**
* Get all webhooks IDs.
* Get webhooks IDs from the database.
*
* @since 3.3.0
* @throws InvalidArgumentException If a $status value is passed in that is not in the known wc_get_webhook_statuses() keys.
* @param string $status Optional - status to filter results by. Must be a key in return value of @see wc_get_webhook_statuses(). @since 3.6.0.
* @return int[]
*/
public function get_webhooks_ids() {
global $wpdb;
public function get_webhooks_ids( $status = '' ) {
if ( ! empty( $status ) ) {
$this->validate_status( $status );
}
$ids = get_transient( 'woocommerce_webhook_ids' );
$ids = get_transient( $this->get_transient_key( $status ) );
if ( false === $ids ) {
$results = $wpdb->get_results( "SELECT webhook_id FROM {$wpdb->prefix}wc_webhooks" ); // WPCS: cache ok, DB call ok.
$ids = array_map( 'intval', wp_list_pluck( $results, 'webhook_id' ) );
set_transient( 'woocommerce_webhook_ids', $ids );
$ids = $this->search_webhooks(
array(
'limit' => -1,
'status' => $status,
)
);
$ids = array_map( 'absint', $ids );
set_transient( $this->get_transient_key( $status ), $ids );
}
return $ids;
@ -220,7 +232,7 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
* Search webhooks.
*
* @param array $args Search arguments.
* @return array
* @return array|object
*/
public function search_webhooks( $args ) {
global $wpdb;
@ -228,10 +240,11 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
$args = wp_parse_args(
$args,
array(
'limit' => 10,
'offset' => 0,
'order' => 'DESC',
'orderby' => 'id',
'limit' => 10,
'offset' => 0,
'order' => 'DESC',
'orderby' => 'id',
'paginate' => false,
)
);
@ -258,15 +271,15 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
'post_modified' => 'date_modified_gmt',
);
$orderby = isset( $orderby_mapping[ $args['orderby'] ] ) ? $orderby_mapping[ $args['orderby'] ] : 'webhook_id';
$limit = -1 < $args['limit'] ? sprintf( 'LIMIT %d', $args['limit'] ) : '';
$offset = 0 < $args['offset'] ? sprintf( 'OFFSET %d', $args['offset'] ) : '';
$status = ! empty( $args['status'] ) ? "AND `status` = '" . sanitize_key( isset( $statuses[ $args['status'] ] ) ? $statuses[ $args['status'] ] : $args['status'] ) . "'" : '';
$search = ! empty( $args['search'] ) ? "AND `name` LIKE '%" . $wpdb->esc_like( sanitize_text_field( $args['search'] ) ) . "%'" : '';
$include = '';
$exclude = '';
$date_created = '';
$date_modified = '';
$order = "ORDER BY {$orderby} " . esc_sql( strtoupper( $args['order'] ) );
$limit = -1 < $args['limit'] ? $wpdb->prepare( 'LIMIT %d', $args['limit'] ) : '';
$offset = 0 < $args['offset'] ? $wpdb->prepare( 'OFFSET %d', $args['offset'] ) : '';
$status = ! empty( $args['status'] ) ? $wpdb->prepare( 'AND `status` = %s', isset( $statuses[ $args['status'] ] ) ? $statuses[ $args['status'] ] : $args['status'] ) : '';
$search = ! empty( $args['search'] ) ? "AND `name` LIKE '%" . $wpdb->esc_like( sanitize_text_field( $args['search'] ) ) . "%'" : '';
$include = '';
$exclude = '';
$date_created = '';
$date_modified = '';
if ( ! empty( $args['include'] ) ) {
$args['include'] = implode( ',', wp_parse_id_list( $args['include'] ) );
@ -282,47 +295,91 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
$args['after'] = empty( $args['after'] ) ? '0000-00-00' : $args['after'];
$args['before'] = empty( $args['before'] ) ? current_time( 'mysql', 1 ) : $args['before'];
$date_created = "AND `date_created_gmt` BETWEEN STR_TO_DATE('" . $args['after'] . "', '%Y-%m-%d %H:%i:%s') and STR_TO_DATE('" . $args['before'] . "', '%Y-%m-%d %H:%i:%s')";
$date_created = "AND `date_created_gmt` BETWEEN STR_TO_DATE('" . esc_sql( $args['after'] ) . "', '%Y-%m-%d %H:%i:%s') and STR_TO_DATE('" . esc_sql( $args['before'] ) . "', '%Y-%m-%d %H:%i:%s')";
}
if ( ! empty( $args['modified_after'] ) || ! empty( $args['modified_before'] ) ) {
$args['modified_after'] = empty( $args['modified_after'] ) ? '0000-00-00' : $args['modified_after'];
$args['modified_before'] = empty( $args['modified_before'] ) ? current_time( 'mysql', 1 ) : $args['modified_before'];
$date_modified = "AND `date_modified_gmt` BETWEEN STR_TO_DATE('" . $args['modified_after'] . "', '%Y-%m-%d %H:%i:%s') and STR_TO_DATE('" . $args['modified_before'] . "', '%Y-%m-%d %H:%i:%s')";
$date_modified = "AND `date_modified_gmt` BETWEEN STR_TO_DATE('" . esc_sql( $args['modified_after'] ) . "', '%Y-%m-%d %H:%i:%s') and STR_TO_DATE('" . esc_sql( $args['modified_before'] ) . "', '%Y-%m-%d %H:%i:%s')";
}
$order = "ORDER BY {$orderby} " . strtoupper( sanitize_key( $args['order'] ) );
// Check for cache.
$cache_key = WC_Cache_Helper::get_cache_prefix( 'webhooks' ) . 'search_webhooks' . md5( implode( ',', $args ) );
$ids = wp_cache_get( $cache_key, 'webhook_search_results' );
$cache_key = WC_Cache_Helper::get_cache_prefix( 'webhooks' ) . 'search_webhooks' . md5( implode( ',', $args ) );
$cache_value = wp_cache_get( $cache_key, 'webhook_search_results' );
if ( false !== $ids ) {
return $ids;
if ( $cache_value ) {
return $cache_value;
}
$query = trim(
"SELECT webhook_id
FROM {$wpdb->prefix}wc_webhooks
WHERE 1=1
{$status}
{$search}
{$include}
{$exclude}
{$date_created}
{$date_modified}
{$order}
{$limit}
{$offset}"
);
if ( $args['paginate'] ) {
$query = trim(
"SELECT SQL_CALC_FOUND_ROWS webhook_id
FROM {$wpdb->prefix}wc_webhooks
WHERE 1=1
{$status}
{$search}
{$include}
{$exclude}
{$date_created}
{$date_modified}
{$order}
{$limit}
{$offset}"
);
$results = $wpdb->get_results( $query ); // WPCS: cache ok, DB call ok, unprepared SQL ok.
$webhook_ids = wp_parse_id_list( $wpdb->get_col( $query ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$total = (int) $wpdb->get_var( 'SELECT FOUND_ROWS();' );
$return_value = (object) array(
'webhooks' => $webhook_ids,
'total' => $total,
'max_num_pages' => $args['limit'] > 1 ? ceil( $total / $args['limit'] ) : 1,
);
} else {
$query = trim(
"SELECT webhook_id
FROM {$wpdb->prefix}wc_webhooks
WHERE 1=1
{$status}
{$search}
{$include}
{$exclude}
{$date_created}
{$date_modified}
{$order}
{$limit}
{$offset}"
);
$ids = wp_list_pluck( $results, 'webhook_id' );
wp_cache_set( $cache_key, $ids, 'webhook_search_results' );
$webhook_ids = wp_parse_id_list( $wpdb->get_col( $query ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$return_value = $webhook_ids;
}
return $ids;
wp_cache_set( $cache_key, $return_value, 'webhook_search_results' );
return $return_value;
}
/**
* Count webhooks.
*
* @since 3.6.0
* @param string $status Status to count.
* @return int
*/
protected function get_webhook_count( $status = 'active' ) {
global $wpdb;
$count = wp_cache_get( $status . '_count', 'webhooks' );
if ( false === $count ) {
$count = absint( $wpdb->get_var( $wpdb->prepare( "SELECT count( webhook_id ) FROM {$wpdb->prefix}wc_webhooks WHERE `status` = %s;", $status ) ) );
wp_cache_add( $status . '_count', $count, 'webhooks' );
}
return $count;
}
/**
@ -335,18 +392,55 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
$counts = array();
foreach ( $statuses as $status ) {
$count = count(
$this->search_webhooks(
array(
'limit' => -1,
'status' => $status,
)
)
);
$counts[ $status ] = $count;
$counts[ $status ] = $this->get_webhook_count( $status );
}
return $counts;
}
/**
* Check if a given string is in known statuses, based on return value of @see wc_get_webhook_statuses().
*
* @since 3.6.0
* @throws InvalidArgumentException If $status is not empty and not in the known wc_get_webhook_statuses() keys.
* @param string $status Status to check.
*/
private function validate_status( $status ) {
if ( ! array_key_exists( $status, wc_get_webhook_statuses() ) ) {
throw new InvalidArgumentException( sprintf( 'Invalid status given: %s. Status must be one of: %s.', $status, implode( ', ', array_keys( wc_get_webhook_statuses() ) ) ) );
}
}
/**
* Get the transient key used to cache a set of webhook IDs, optionally filtered by status.
*
* @since 3.6.0
* @param string $status Optional - status of cache key.
* @return string
*/
private function get_transient_key( $status = '' ) {
return empty( $status ) ? 'woocommerce_webhook_ids' : sprintf( 'woocommerce_webhook_ids_status_%s', $status );
}
/**
* Delete the transients used to cache a set of webhook IDs, optionally filtered by status.
*
* @since 3.6.0
* @param string $status Optional - status of cache to delete, or 'all' to delete all caches.
*/
private function delete_transients( $status = '' ) {
// Always delete the non-filtered cache.
delete_transient( $this->get_transient_key( '' ) );
if ( ! empty( $status ) ) {
if ( 'all' === $status ) {
foreach ( wc_get_webhook_statuses() as $status_key => $status_string ) {
delete_transient( $this->get_transient_key( $status_key ) );
}
} else {
delete_transient( $this->get_transient_key( $status ) );
}
}
}
}

View File

@ -28,7 +28,9 @@ interface WC_Webhook_Data_Store_Interface {
* Get all webhooks IDs.
*
* @since 3.2.0
* @throws InvalidArgumentException If a $status value is passed in that is not in the known wc_get_webhook_statuses() keys.
* @param string $status Optional - status to filter results by. Must be a key in return value of @see wc_get_webhook_statuses(). @since 3.6.0.
* @return int[]
*/
public function get_webhooks_ids();
public function get_webhooks_ids( $status = '' );
}

View File

@ -20,6 +20,7 @@ function wc_webhook_process_delivery( $webhook, $arg ) {
// so as to avoid delays or failures in delivery from affecting the
// user who triggered it.
if ( apply_filters( 'woocommerce_webhook_deliver_async', true, $webhook, $arg ) ) {
$queue_args = array(
'webhook_id' => $webhook->get_id(),
'arg' => $arg,
@ -64,7 +65,7 @@ add_action( 'woocommerce_deliver_webhook_async', 'wc_deliver_webhook_async', 10,
* @return bool
*/
function wc_is_webhook_valid_topic( $topic ) {
$invalid_topics = array(
$invalid_topics = array(
'action.woocommerce_login_credentials',
'action.woocommerce_product_csv_importer_check_import_file_path',
'action.woocommerce_webhook_should_deliver',
@ -128,20 +129,26 @@ function wc_get_webhook_statuses() {
*
* @since 3.3.0
* @throws Exception If webhook cannot be read/found and $data parameter of WC_Webhook class constructor is set.
* @param string $status Optional - status to filter results by. Must be a key in return value of @see wc_get_webhook_statuses(). @since 3.5.0.
* @param null|int $limit Limit number of webhooks loaded. @since 3.6.0.
* @return bool
*/
function wc_load_webhooks() {
function wc_load_webhooks( $status = '', $limit = null ) {
$data_store = WC_Data_Store::load( 'webhook' );
$webhooks = $data_store->get_webhooks_ids();
$loaded = false;
$webhooks = $data_store->get_webhooks_ids( $status );
$loaded = 0;
foreach ( $webhooks as $webhook_id ) {
$webhook = new WC_Webhook( $webhook_id );
$webhook->enqueue();
$loaded = true;
$loaded ++;
if ( ! is_null( $limit ) && $loaded >= $limit ) {
break;
}
}
return $loaded;
return 0 < $loaded;
}
/**

View File

@ -103,23 +103,132 @@ class WC_Tests_Webhook_Functions extends WC_Unit_Test_Case {
* @since 3.2.0
*/
public function test_wc_load_webhooks() {
$webhook = $this->create_webhook();
$this->assertTrue( wc_load_webhooks() );
$webhook->delete( true );
$this->assertFalse( wc_load_webhooks() );
}
/**
* Provide webhook statuses for tests.
*
* @since 3.5.0
*/
public function provider_webhook_statuses() {
$webhook_statuses = array();
foreach ( wc_get_webhook_statuses() as $status_key => $status_string ) {
$webhook_statuses[] = array( $status_key );
}
return $webhook_statuses;
}
/**
* Test the $status param on wc_load_webhooks().
*
* @dataProvider provider_webhook_statuses
* @param string $status The status of the webhook to test.
* @since 3.5.0
*/
public function test_wc_load_webhooks_status( $status ) {
$webhook = $this->create_webhook( 'action.woocommerce_some_action', $status );
$this->assertTrue( wc_load_webhooks( '' ) );
$this->assertTrue( wc_load_webhooks( $status ) );
// Find a different, but still valid status.
$other_status = ( 'active' === $status ) ? 'disabled' : 'active';
$this->assertFalse( wc_load_webhooks( $other_status ) );
$webhook->delete( true );
$this->assertFalse( wc_load_webhooks( $status ) );
}
/**
* @expectedException InvalidArgumentException
*/
public function test_wc_load_webhooks_status_invalid() {
wc_load_webhooks( 'invalid_status' );
}
/**
* Test the $limit param on wc_load_webhooks().
*
* @since 3.5.0
*/
public function test_wc_load_webhooks_limit() {
global $wp_filter;
$webhook_one = $this->create_webhook( 'action.woocommerce_one_test' );
$webhook_two = $this->create_webhook( 'action.woocommerce_two_test' );
$this->assertTrue( wc_load_webhooks( '', 1 ) );
$this->assertFalse( isset( $wp_filter['woocommerce_one_test'] ) );
$this->assertTrue( isset( $wp_filter['woocommerce_two_test'] ) );
$webhook_two->delete( true );
$this->assertTrue( wc_load_webhooks( '', 1 ) );
$this->assertTrue( isset( $wp_filter['woocommerce_one_test'] ) );
$webhook_one->delete( true );
$this->assertFalse( wc_load_webhooks( '', 1 ) );
}
/**
* Test the $status and $limit param on wc_load_webhooks().
*
* @dataProvider provider_webhook_statuses
* @param string $status The status of the webhook to test.
*/
public function test_wc_load_webhooks_status_and_limit( $status ) {
global $wp_filter;
$action_one = 'woocommerce_one_test_status_' . $status;
$webhook_one = $this->create_webhook( 'action.' . $action_one, $status );
$action_two = 'woocommerce_two_test_status_' . $status;
$webhook_two = $this->create_webhook( 'action.' . $action_two, $status );
$this->assertTrue( wc_load_webhooks( $status, 1 ) );
$this->assertFalse( isset( $wp_filter[ $action_one ] ) );
$this->assertTrue( isset( $wp_filter[ $action_two ] ) );
$webhook_two->delete( true );
$this->assertTrue( wc_load_webhooks( $status, 1 ) );
$this->assertTrue( isset( $wp_filter[ $action_one ] ) );
$webhook_one->delete( true );
$this->assertFalse( wc_load_webhooks( $status, 1 ) );
}
/**
* Create and save a webhook for testing.
*
* @param string $topic The webhook topic for the test.
* @param string $status The status of the webhook to be tested.
*/
protected function create_webhook( $topic = 'action.woocommerce_some_action', $status = 'active' ) {
$webhook = new WC_Webhook();
$webhook->set_props(
array(
'status' => 'active',
'status' => $status,
'name' => 'Testing webhook',
'user_id' => 0,
'delivery_url' => 'https://requestb.in/17jajv31',
'secret' => 'secret',
'topic' => 'action.woocommerce_some_action',
'topic' => $topic,
'api_version' => 2,
)
);
$webhook->save();
$this->assertTrue( wc_load_webhooks() );
$webhook->delete( true );
$this->assertFalse( wc_load_webhooks() );
return $webhook;
}
}