Fix for duplicate webhook deliveries

This commit is contained in:
James Collins 2019-12-06 09:54:24 +08:00
parent 7c5d06c309
commit b262ac8e53
1 changed files with 25 additions and 1 deletions

View File

@ -20,6 +20,14 @@ require_once 'legacy/class-wc-legacy-webhook.php';
*/
class WC_Webhook extends WC_Legacy_Webhook {
/**
* Store which object IDs this webhook has processed (ie scheduled to be delivered)
* within the current page request.
*
* @var array
*/
protected $processed = array();
/**
* Stores webhook data.
*
@ -103,6 +111,9 @@ class WC_Webhook extends WC_Legacy_Webhook {
return;
}
// Mark this $arg as processed to ensure it doesn't get processed again within the current request.
$this->processed[] = $arg;
/**
* Process webhook delivery.
*
@ -123,7 +134,7 @@ class WC_Webhook extends WC_Legacy_Webhook {
* @return bool True if webhook should be delivered, false otherwise.
*/
private function should_deliver( $arg ) {
$should_deliver = $this->is_active() && $this->is_valid_topic() && $this->is_valid_action( $arg ) && $this->is_valid_resource( $arg );
$should_deliver = $this->is_active() && $this->is_valid_topic() && $this->is_valid_action( $arg ) && $this->is_valid_resource( $arg ) && ! $this->is_already_processed( $arg );
/**
* Let other plugins intercept deliver for some messages queue like rabbit/zeromq.
@ -280,6 +291,19 @@ class WC_Webhook extends WC_Legacy_Webhook {
return true;
}
/**
* Checks if the specified resource has already been queued for delivery within the current request.
*
* Helps avoid duplication of data being sent for topics that have more than one hook defined.
*
* @param mixed $arg First hook argument.
*
* @return bool
*/
protected function is_already_processed( $arg ) {
return false !== array_search( $arg, $this->processed, true );
}
/**
* Deliver the webhook payload using wp_safe_remote_request().
*