FileMaster
Search
Toggle Dark Mode
Home
/
.
/
wp-content
/
plugins
/
latepoint
/
lib
/
kit
/
bsf-analytics
Edit File: class-bsf-analytics-events.php
<?php /** * BSF Analytics Events — reusable one-time milestone tracking. * * Tracks events temporarily, sends them once via BSF Analytics, * then cleans up. Only a minimal dedup flag remains. * * @package bsf-analytics * @since 1.1.21 */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } if ( ! class_exists( 'BSF_Analytics_Events' ) ) { /** * BSF Analytics Events Class. * * @since 1.1.21 */ class BSF_Analytics_Events { /** * Plugin slug used as option key prefix in default storage. * * @var string */ private $slug; /** * Option resolver callbacks. * * @var array{get: callable|null, update: callable|null} */ private $option_resolver; /** * Constructor. * * @param string $slug Plugin slug (e.g. 'sureforms', 'astra'). * @param array $option_resolver Optional. Custom callbacks for option storage. * 'get' => callable( $key, $default ) — retrieve an option. * 'update' => callable( $key, $value ) — persist an option. * When omitted, uses get_option( '{slug}_{key}' ) / update_option( '{slug}_{key}' ). * @since 1.1.21 */ public function __construct( $slug, $option_resolver = array() ) { $this->slug = sanitize_key( $slug ); $this->option_resolver = wp_parse_args( $option_resolver, array( 'get' => null, 'update' => null, ) ); } /** * Track a one-time event. Skips if already tracked or pending. * Only stores temporary data — cleaned up after analytics send. * * @param string $event_name Event identifier. * @param string $event_value Primary value (version, form ID, mode, etc.). * @param array<string, mixed> $properties Additional context as key-value pairs. * @since 1.1.21 * @return void */ public function track( $event_name, $event_value = '', $properties = array() ) { // Sanitize inputs once upfront — ensures dedup comparisons match stored values. $event_name = sanitize_text_field( $event_name ); $event_value = sanitize_text_field( (string) $event_value ); $properties = is_array( $properties ) ? $properties : array(); // Check dedup flag — already sent in a previous cycle. $pushed = $this->get_option( 'usage_events_pushed', array() ); $pushed = is_array( $pushed ) ? $pushed : array(); if ( in_array( $event_name, $pushed, true ) ) { return; } // Check if already queued in current cycle. $pending = $this->get_option( 'usage_events_pending', array() ); $pending = is_array( $pending ) ? $pending : array(); if ( in_array( $event_name, array_column( $pending, 'event_name' ), true ) ) { return; } // Add to pending queue. $pending[] = array( 'event_name' => $event_name, 'event_value' => $event_value, 'properties' => $properties, 'date' => current_time( 'mysql' ), ); $this->update_option( 'usage_events_pending', $pending ); } /** * Flush pending events: returns them for the payload, then cleans up. * * After this call: * - usage_events_pending is EMPTY (full event data deleted). * - usage_events_pushed has event_name strings added (minimal dedup). * * @since 1.1.21 * @return array Pending events to include in payload. Empty if none. */ public function flush_pending() { $pending = $this->get_option( 'usage_events_pending', array() ); if ( empty( $pending ) || ! is_array( $pending ) ) { return array(); } // Add event names to dedup flag (minimal — just strings). $pushed = $this->get_option( 'usage_events_pushed', array() ); $pushed = is_array( $pushed ) ? $pushed : array(); $pushed = array_unique( array_merge( $pushed, array_column( $pending, 'event_name' ) ) ); $this->update_option( 'usage_events_pushed', $pushed ); // DELETE all temporary event data. $this->update_option( 'usage_events_pending', array() ); return $pending; } /** * Remove specific event names from the pushed dedup flag, allowing them to be re-tracked. * * Pass an array of event names to remove only those entries. * Pass an empty array (or omit) to clear all pushed events. * * @param array<string> $event_names Event names to remove. Empty = clear all. * @since 1.1.21 * @return void */ public function flush_pushed( $event_names = array() ) { $pushed = $this->get_option( 'usage_events_pushed', array() ); $pushed = is_array( $pushed ) ? $pushed : array(); if ( empty( $event_names ) ) { $this->update_option( 'usage_events_pushed', array() ); return; } $pushed = array_values( array_diff( $pushed, $event_names ) ); $this->update_option( 'usage_events_pushed', $pushed ); } /** * Check if an event has already been tracked (sent or pending). * * @param string $event_name Event identifier. * @since 1.1.21 * @return bool */ public function is_tracked( $event_name ) { $pushed = $this->get_option( 'usage_events_pushed', array() ); $pushed = is_array( $pushed ) ? $pushed : array(); if ( in_array( $event_name, $pushed, true ) ) { return true; } $pending = $this->get_option( 'usage_events_pending', array() ); $pending = is_array( $pending ) ? $pending : array(); return in_array( $event_name, array_column( $pending, 'event_name' ), true ); } /** * Get an option value using custom resolver or default WordPress option. * * @param string $key Option key (e.g. 'usage_events_pending'). * @param mixed $default Default value. * @return mixed */ private function get_option( $key, $default = null ) { if ( is_callable( $this->option_resolver['get'] ) ) { return call_user_func( $this->option_resolver['get'], $key, $default ); } return get_option( $this->slug . '_' . $key, $default ); } /** * Update an option value using custom resolver or default WordPress option. * * @param string $key Option key (e.g. 'usage_events_pending'). * @param mixed $value Value to store. * @return void */ private function update_option( $key, $value ) { if ( is_callable( $this->option_resolver['update'] ) ) { call_user_func( $this->option_resolver['update'], $key, $value ); return; } update_option( $this->slug . '_' . $key, $value ); } } }
Save
Back