You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
6.9 KiB
223 lines
6.9 KiB
<?php
|
|
/**
|
|
* WooCommerce Subscriptions Webhook class
|
|
*
|
|
* This class introduces webhooks to, storing and retrieving webhook data from the associated
|
|
* `shop_webhook` custom post type, as well as delivery logs from the `webhook_delivery`
|
|
* comment type.
|
|
*
|
|
* Subscription Webhooks are enqueued to their associated actions, delivered, and logged.
|
|
*
|
|
* @author Prospress
|
|
* @category Webhooks
|
|
* @since 2.0
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit; // Exit if accessed directly
|
|
}
|
|
|
|
class WCS_Webhooks {
|
|
|
|
/**
|
|
* Setup webhook for subscriptions
|
|
*
|
|
* @since 2.0
|
|
*/
|
|
public static function init() {
|
|
|
|
add_filter( 'woocommerce_webhook_topic_hooks', __CLASS__ . '::add_topics', 20, 2 );
|
|
|
|
add_filter( 'woocommerce_webhook_payload', __CLASS__ . '::create_payload', 10, 4 );
|
|
|
|
add_filter( 'woocommerce_valid_webhook_resources', __CLASS__ . '::add_resource', 10, 1 );
|
|
|
|
add_filter( 'woocommerce_valid_webhook_events', __CLASS__ . '::add_event', 10, 1 );
|
|
|
|
add_action( 'woocommerce_checkout_subscription_created', __CLASS__ . '::add_subscription_created_callback', 10, 1 );
|
|
|
|
add_action( 'woocommerce_subscription_date_updated', __CLASS__ . '::add_subscription_updated_callback', 10, 1 );
|
|
|
|
add_action( 'woocommerce_subscriptions_switch_completed', __CLASS__ . '::add_subscription_switched_callback', 10, 1 );
|
|
|
|
add_filter( 'woocommerce_webhook_topics', __CLASS__ . '::add_topics_admin_menu', 10, 1 );
|
|
|
|
add_filter( 'wcs_new_order_created', __CLASS__ . '::add_subscription_created_order_callback', 10, 1 );
|
|
|
|
}
|
|
|
|
/**
|
|
* Trigger `order.create` every time an order is created by Subscriptions.
|
|
*
|
|
* @param WC_Order $order WC_Order Object
|
|
*/
|
|
public static function add_subscription_created_order_callback( $order ) {
|
|
|
|
do_action( 'wcs_webhook_order_created', wcs_get_objects_property( $order, 'id' ) );
|
|
|
|
return $order;
|
|
}
|
|
|
|
/**
|
|
* Add Subscription webhook topics
|
|
*
|
|
* @param array $topic_hooks
|
|
* @since 2.0
|
|
*/
|
|
public static function add_topics( $topic_hooks, $webhook ) {
|
|
|
|
switch ( $webhook->get_resource() ) {
|
|
case 'order':
|
|
$topic_hooks['order.created'][] = 'wcs_webhook_order_created';
|
|
break;
|
|
|
|
case 'subscription':
|
|
$topic_hooks = apply_filters( 'woocommerce_subscriptions_webhook_topics', array(
|
|
'subscription.created' => array(
|
|
'wcs_api_subscription_created',
|
|
'wcs_webhook_subscription_created',
|
|
'woocommerce_process_shop_subscription_meta',
|
|
),
|
|
'subscription.updated' => array(
|
|
'wcs_webhook_subscription_updated',
|
|
'woocommerce_update_subscription',
|
|
),
|
|
'subscription.deleted' => array(
|
|
'woocommerce_subscription_trashed',
|
|
'woocommerce_subscription_deleted',
|
|
'woocommerce_api_delete_subscription',
|
|
),
|
|
'subscription.switched' => array(
|
|
'wcs_webhook_subscription_switched',
|
|
),
|
|
), $webhook );
|
|
break;
|
|
}
|
|
|
|
return $topic_hooks;
|
|
}
|
|
|
|
/**
|
|
* Add Subscription topics to the Webhooks dropdown menu in when creating a new webhook.
|
|
*
|
|
* @since 2.0
|
|
*/
|
|
public static function add_topics_admin_menu( $topics ) {
|
|
|
|
$front_end_topics = array(
|
|
'subscription.created' => __( ' Subscription created', 'woocommerce-subscriptions' ),
|
|
'subscription.updated' => __( ' Subscription updated', 'woocommerce-subscriptions' ),
|
|
'subscription.deleted' => __( ' Subscription deleted', 'woocommerce-subscriptions' ),
|
|
'subscription.switched' => __( ' Subscription switched', 'woocommerce-subscriptions' ),
|
|
);
|
|
|
|
return array_merge( $topics, $front_end_topics );
|
|
}
|
|
|
|
/**
|
|
* Setup payload for subscription webhook delivery.
|
|
*
|
|
* @since 2.0
|
|
*/
|
|
public static function create_payload( $payload, $resource, $resource_id, $id ) {
|
|
|
|
if ( 'subscription' == $resource && empty( $payload ) && wcs_is_subscription( $resource_id ) ) {
|
|
$webhook = new WC_Webhook( $id );
|
|
$current_user = get_current_user_id();
|
|
|
|
// Build the payload with the same user context as the user who created
|
|
// the webhook -- this avoids permission errors as background processing
|
|
// runs with no user context.
|
|
wp_set_current_user( $webhook->get_user_id() ); // phpcs:ignore Generic.PHP.ForbiddenFunctions.Discouraged -- user ID can only be provided by WC_Webhook::get_user_id() which is the webhook author's ID.
|
|
|
|
switch ( $webhook->get_api_version() ) {
|
|
case 'legacy_v3':
|
|
|
|
if ( is_null( wc()->api ) ) {
|
|
throw new \Exception( 'The Legacy REST API plugin is not installed on this site. More information: https://developer.woocommerce.com/2023/10/03/the-legacy-rest-api-will-move-to-a-dedicated-extension-in-woocommerce-9-0/ ' );
|
|
}
|
|
|
|
WC()->api->WC_API_Subscriptions->register_routes( array() );
|
|
$payload = WC()->api->WC_API_Subscriptions->get_subscription( $resource_id );
|
|
break;
|
|
case 'wp_api_v1':
|
|
case 'wp_api_v2':
|
|
// There is no v2 subscritpion endpoint support so they fall back to v1.
|
|
$request = new WP_REST_Request( 'GET' );
|
|
$controller = new WC_REST_Subscriptions_v1_Controller();
|
|
|
|
$request->set_param( 'id', $resource_id );
|
|
$result = $controller->get_item( $request );
|
|
$payload = isset( $result->data ) ? $result->data : array();
|
|
|
|
break;
|
|
case 'wp_api_v3':
|
|
$payload = WCS_API::get_wc_api_endpoint_data( "/wc/v3/subscriptions/{$resource_id}" );
|
|
break;
|
|
}
|
|
|
|
// Restore the current user.
|
|
wp_set_current_user( $current_user ); // phpcs:ignore Generic.PHP.ForbiddenFunctions.Discouraged -- this ID was provided by get_current_user_id() above.
|
|
}
|
|
|
|
return $payload;
|
|
}
|
|
|
|
/**
|
|
* Add webhook resource for subscription.
|
|
*
|
|
* @param array $resources
|
|
* @since 2.0
|
|
*/
|
|
public static function add_resource( $resources ) {
|
|
|
|
$resources[] = 'subscription';
|
|
|
|
return $resources;
|
|
}
|
|
|
|
/**
|
|
* Add webhook event for subscription switched.
|
|
*
|
|
* @param array $events
|
|
* @since 2.1
|
|
*/
|
|
public static function add_event( $events ) {
|
|
|
|
$events[] = 'switched';
|
|
|
|
return $events;
|
|
}
|
|
|
|
/**
|
|
* Call a "subscription created" action hook with the first parameter being a subscription id so that it can be used
|
|
* for webhooks.
|
|
*
|
|
* @since 2.0
|
|
*/
|
|
public static function add_subscription_created_callback( $subscription ) {
|
|
do_action( 'wcs_webhook_subscription_created', $subscription->get_id() );
|
|
}
|
|
|
|
/**
|
|
* Call a "subscription updated" action hook with a subscription id as the first parameter to be used for webhooks payloads.
|
|
*
|
|
* @since 2.0
|
|
*/
|
|
public static function add_subscription_updated_callback( $subscription ) {
|
|
do_action( 'wcs_webhook_subscription_updated', $subscription->get_id() );
|
|
}
|
|
|
|
/**
|
|
* For each switched subscription in an order, call a "subscription switched" action hook with a subscription id as the first parameter to be used for webhooks payloads.
|
|
*
|
|
* @since 2.1
|
|
*/
|
|
public static function add_subscription_switched_callback( $order ) {
|
|
$switched_subscriptions = wcs_get_subscriptions_for_switch_order( $order );
|
|
foreach ( array_keys( $switched_subscriptions ) as $subscription_id ) {
|
|
do_action( 'wcs_webhook_subscription_switched', $subscription_id );
|
|
}
|
|
}
|
|
|
|
}
|
|
|