diff --git a/dev/public/wp-content/plugins/library-testing/library-testing.php b/dev/public/wp-content/plugins/library-testing/library-testing.php index 87900fc..3b7b06a 100644 --- a/dev/public/wp-content/plugins/library-testing/library-testing.php +++ b/dev/public/wp-content/plugins/library-testing/library-testing.php @@ -31,3 +31,43 @@ function () { do_action( 'stellarwp/telemetry/optin', 'telemetry-library' ); } ); + +// If the 'Send Events' link was used, send some test events once. +add_action( + 'init', + function() { + if ( ! isset( $_GET['send-events'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + return; + } + + do_action( 'stellarwp/telemetry/telemetry-prefix/event', 'opt-in', [ 'one' => 1 ] ); + do_action( 'stellarwp/telemetry/telemetry-prefix/event', 'create-post', [ 'post-title' => 'This is my first post!' ] ); + do_action( 'stellarwp/telemetry/telemetry-prefix/event', 'opt-out', [ 'one' => 1 ] ); + + wp_safe_redirect( remove_query_arg( 'send-events' ) ); + exit; + } +); + +/** + * Adds a helper link to the admin bar for sending a group of events. + * + * @param WP_Admin_Bar $admin_bar The adminbar class. + * + * @return void + */ +function add_event_send_link( $admin_bar ) { + global $wp; + + $admin_bar->add_menu( + [ + 'id' => 'send-events', + 'title' => 'Send Events', + 'href' => add_query_arg( [ 'send-events' => true ], home_url( $wp->request ) ), + 'meta' => [ + 'title' => __( 'Send Events' ), + ], + ] + ); +} +add_action( 'admin_bar_menu', 'add_event_send_link', 100, 1 ); diff --git a/src/Telemetry/Events/Event.php b/src/Telemetry/Events/Event.php index 0b57272..da5ab1c 100644 --- a/src/Telemetry/Events/Event.php +++ b/src/Telemetry/Events/Event.php @@ -21,6 +21,13 @@ */ class Event { + /** + * The hook name for sending events asyncronously. + * + * @since TBD + */ + public const AJAX_ACTION = 'stellarwp_telemetry_send_event'; + /** * An instance of the Telemetry class. * @@ -77,6 +84,30 @@ public function send( string $name, array $data = [] ) { return boolval( $response['status'] ); } + /** + * Send batched events. + * + * @since TBD + * + * @param array $events An array of stored events to send to the telemetry server. + * + * @return bool + */ + public function send_batch( array $events ) { + $data = [ + 'token' => $this->telemetry->get_token(), + 'events' => $events, + ]; + + $response = $this->telemetry->send( $data, $this->get_url() ); + + if ( ! isset( $response['status'] ) ) { + return false; + } + + return boolval( $response['status'] ); + } + /** * Gets the url used for sending events. * diff --git a/src/Telemetry/Events/Event_Subscriber.php b/src/Telemetry/Events/Event_Subscriber.php index 3e58585..b101578 100644 --- a/src/Telemetry/Events/Event_Subscriber.php +++ b/src/Telemetry/Events/Event_Subscriber.php @@ -9,6 +9,7 @@ namespace StellarWP\Telemetry\Events; +use StellarWP\Telemetry\Config; use StellarWP\Telemetry\Contracts\Abstract_Subscriber; /** @@ -28,19 +29,78 @@ class Event_Subscriber extends Abstract_Subscriber { * @return void */ public function register() { - add_action( 'stellarwp/telemetry/event', [ $this, 'send_event' ], 10, 2 ); + add_action( 'shutdown', [ $this, 'send_cached_events' ] ); + add_action( 'stellarwp/telemetry/' . Config::get_hook_prefix() . 'event', [ $this, 'cache_event' ], 10, 2 ); + add_action( 'wp_ajax_' . Event::AJAX_ACTION, [ $this, 'send_events' ], 10, 1 ); + add_action( 'wp_ajax_nopriv_' . Event::AJAX_ACTION, [ $this, 'send_events' ], 10, 1 ); } /** - * Sends an event request to the Telemetry server. + * Caches an event to be sent during shutdown. * - * @since 2.1.0 + * @since TBD + * + * @param string $name The name of the event. + * @param array $data The data sent along with the event. * - * @param string $name The name of the event to send. - * @param array $data Additional information to send with the event. + * @return void */ - public function send_event( string $name, array $data = [] ) { - $this->container->get( Event::class )->send( $name, $data ); + public function cache_event( $name, $data ) { + $events = []; + + if ( $this->container->has( 'events' ) ) { + $events = $this->container->get( 'events' ); + } + + $events[] = [ + 'name' => $name, + 'data' => wp_json_encode( $data ), + 'stellar_slug' => Config::get_stellar_slug(), + ]; + + $this->container->bind( 'events', $events ); } + /** + * Sends the events that have been stored for the current request. + * + * @since TBD + * + * @return void + */ + public function send_cached_events() { + if ( ! $this->container->has( 'events' ) ) { + return; + } + + $url = admin_url( 'admin-ajax.php' ); + + wp_remote_post( + $url, + [ + 'blocking' => false, + 'sslverify' => false, + 'body' => [ + 'action' => Event::AJAX_ACTION, + 'events' => $this->container->get( 'events' ), + ], + ] + ); + + $this->container->bind( 'events', [] ); + } + + /** + * Send the event to the telemetry server. + * + * @since TBD + * + * @return void + */ + public function send_events() { + // Get the passed event array. + $events = filter_input( INPUT_POST, 'events', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ); // phpcs:ignore WordPressVIPMinimum.Security.PHPFilterFunctions.RestrictedFilter + + $this->container->get( Event::class )->send_batch( $events ); + } }