LLMS_REST_Webhook_Data
LLMS_REST_Webhook class.
Source Source
File: libraries/lifterlms-rest/includes/abstracts/class-llms-rest-webhook-data.php
abstract class LLMS_REST_Webhook_Data extends LLMS_Abstract_Database_Store { /** * Array of table column name => format * * @var string[] */ protected $columns = array( 'status' => '%s', 'name' => '%s', 'delivery_url' => '%s', 'secret' => '%s', 'topic' => '%s', 'user_id' => '%d', 'created' => '%s', 'updated' => '%s', 'failure_count' => '%d', ); /** * Database Table Name * * @var string */ protected $table = 'webhooks'; /** * The record type * * Used for filters/actions. * * @var string */ protected $type = 'webhook'; /** * Constructor * * @since 1.0.0-beta.1 * * @param int $id API Key ID. * @param bool $hydrate If true, hydrates the object on instantiation if an ID is supplied. */ public function __construct( $id = null, $hydrate = true ) { $this->id = $id; if ( $this->id && $hydrate ) { $this->hydrate(); } // Adds created and updated dates on instantiation. parent::__construct(); } /** * Retrieve an admin nonce url for deleting an API key. * * @since 1.0.0-beta.1 * * @return string */ public function get_delete_link() { return add_query_arg( array( 'section' => 'webhooks', 'delete-webhook' => $this->get( 'id' ), 'delete-webhook-nonce' => wp_create_nonce( 'delete' ), ), LLMS_REST_API()->keys()->get_admin_url() ); } /** * Generate a delivery signature from a delivery payload. * * @since 1.0.0-beta.1 * * @param string $payload JSON-encoded payload. * @return string */ public function get_delivery_signature( $payload ) { /** * Allow overriding of signature generation. * * @since 1.0.0-beta.1 * * @param string $signature Custom signature. Return a string to replace the default signature. * @param string $payload JSON-encoded body to be delivered. * @param int $id Webhook id. */ $signature = apply_filters( 'llms_rest_webhook_signature_pre', null, $payload, $this->get( 'id' ) ); if ( $signature && is_string( $signature ) ) { return $signature; } /** * Customize the hash algorithm used to generate the webhook delivery signature. * * @since 1.0.0-beta.1 * * @param string $algo Hash algorithm. Defaults to 'sha256'. List of supported algorithms available at https://www.php.net/manual/en/function.hash-hmac-algos.php. * @param string $payload JSON-encoded body to be delivered. * @param int $id Webhook ID. */ $hash_algo = apply_filters( 'llms_rest_webhook_hash_algorithm', 'sha256', $payload, $this->get( 'id' ) ); $ts = llms_current_time( 'timestamp' ); $message = $ts . '.' . $payload; $hash = hash_hmac( $hash_algo, $message, $this->get( 'secret' ) ); return sprintf( 't=%1$d,v1=%2$s', $ts, $hash ); } /** * Retrieve the admin URL where the api key is managed. * * @since 1.0.0-beta.1 * * @return string */ public function get_edit_link() { return add_query_arg( array( 'section' => 'webhooks', 'edit-webhook' => $this->get( 'id' ), ), LLMS_REST_API()->keys()->get_admin_url() ); } /** * Retrieve the topic event * * @since 1.0.0-beta.1 * * @return string */ public function get_event() { $topic = explode( '.', $this->get( 'topic' ) ); return apply_filters( 'llms_rest_webhook_get_event', isset( $topic[1] ) ? $topic[1] : '', $this->get( 'id' ) ); } /** * Retrieve an array of hooks for the webhook topic. * * @since 1.0.0-beta.1 * * @return string[] */ public function get_hooks() { if ( 'action' === $this->get_resource() ) { $hooks = array( $this->get_event() => 1 ); } else { $all_hooks = LLMS_REST_API()->webhooks()->get_hooks(); $topic = $this->get( 'topic' ); $hooks = isset( $all_hooks[ $topic ] ) ? $all_hooks[ $topic ] : array(); } return apply_filters( 'llms_rest_webhook_get_hooks', $hooks, $this->get( 'id' ) ); } /** * Retrieve a payload for webhook delivery. * * @since 1.0.0-beta.1 * @since 1.0.0-beta.6 Retrieve proper payload for enrollment and progress resources. * * @param array $args Numeric array of arguments from the originating hook. * @return array */ protected function get_payload( $args ) { // Switch current user to the user who created the webhook. $current_user = get_current_user_id(); wp_set_current_user( $this->get( 'user_id' ) ); $resource = $this->get_resource(); $event = $this->get_event(); $payload = array(); if ( 'deleted' === $event ) { if ( in_array( $this->get_resource(), array( 'enrollment', 'progress' ), true ) ) { $payload['student_id'] = $args[0]; $payload['post_id'] = $args[1]; } else { $payload['id'] = $args[0]; } } elseif ( 'action' === $resource ) { $payload['action'] = current( $this->get_hooks() ); $payload['args'] = $args; } else { if ( 'enrollment' === $resource ) { $endpoint = sprintf( '/llms/v1/students/%1$d/enrollments/%2$d', $args[0], $args[1] ); } elseif ( 'progress' === $resource ) { $endpoint = sprintf( '/llms/v1/students/%1$d/progress/%2$d', $args[0], $args[1] ); } else { $endpoint = sprintf( '/llms/v1/%1$ss/%2$d', $resource, $args[0] ); } $payload = llms_rest_get_api_endpoint_data( $endpoint ); } // Restore the current user. wp_set_current_user( $current_user ); /** * Filter the webhook payload prior to delivery * * @since 1.0.0-beta.1 * * @param array $payload Webhook payload. * @param string $resource Webhook resource. * @param string $event Webhook event. * @param array $args Numeric array of arguments from the originating hook. * @param LLMS_REST_Webhook $this Webhook object. */ return apply_filters( 'llms_rest_webhook_get_payload', $payload, $resource, $event, $args, $this ); } /** * Retrieve the topic resource. * * @since 1.0.0-beta.1 * * @return string */ public function get_resource() { $topic = explode( '.', $this->get( 'topic' ) ); return apply_filters( 'llms_rest_webhook_get_resource', $topic[0], $this->get( 'id' ) ); } /** * Retrieve a user agent string to use for delivering webhooks. * * @since 1.0.0-beta.1 * * @return string */ protected function get_user_agent() { global $wp_version; return sprintf( 'LifterLMS/%1$s Hookshot (WordPress/%2$s)', LLMS()->version, $wp_version ); } /** * Increment delivery failures and after max allowed failures are reached, set status to disabled. * * @since 1.0.0-beta.1 * * @return LLMS_REST_Webhook */ protected function set_delivery_failure() { $failures = absint( $this->get( 'failure_count' ) ); $this->set( 'failure_count', ++$failures ); /** * Filter the number of times a webhook is allowed to fail before it is automatically disabled. * * @since 1.0.0-beta.1 * * @param int $num Number of allowed failures. Default: 5. */ $max_allowed = apply_filters( 'llms_rest_webhook_max_delivery_failures', 5 ); if ( $failures > $max_allowed ) { $this->set( 'status', 'disabled' ); /** * Fires immediately after a webhook has been disabled due to exceeding its maximum allowed failures. * * @since 1.0.0-beta.1 * * @param int $webhook_id ID of the webhook. */ do_action( 'llms_rest_webhook_disabled_by_delivery_failures', $this->get( 'id' ) ); } return $this; } }
Expand full source code Collapse full source code View on GitHub
Methods Methods
- __construct — Constructor
- get_delete_link — Retrieve an admin nonce url for deleting an API key.
- get_delivery_signature — Generate a delivery signature from a delivery payload.
- get_edit_link — Retrieve the admin URL where the api key is managed.
- get_event — Retrieve the topic event
- get_hooks — Retrieve an array of hooks for the webhook topic.
- get_payload — Retrieve a payload for webhook delivery.
- get_resource — Retrieve the topic resource.
- get_user_agent — Retrieve a user agent string to use for delivering webhooks.
- set_delivery_failure — Increment delivery failures and after max allowed failures are reached, set status to disabled.
Changelog Changelog
Version | Description |
---|---|
1.0.0-beta.6 | Retrieve proper payload for enrollment and progress resources. |
1.0.0-beta.17 | Remove unused 'pending_delivery' column. |
1.0.0-beta.1 | Introduced. |