__('Permission denied', 'admin-login-guard-branding')], 403); } // Verify nonce for security check_ajax_referer('admilogu_optin_nonce', 'nonce'); // Sanitize and validate the status // phpcs:ignore WordPress.Security.NonceVerification.Missing $status = isset($_POST['status']) ? sanitize_text_field(wp_unslash($_POST['status'])) : ''; if (!in_array($status, ['yes', 'no'], true)) { wp_send_json_error(['message' => __('Invalid selection', 'admin-login-guard-branding')], 400); } // Update the option update_option('admilogu_tracking_optin', $status); // Send success response wp_send_json_success(['status' => $status]); } add_action('wp_ajax_admilogu_tracking_optin', 'admilogu_handle_optin_ajax'); /* --------------------------------------------------------- TRACKING OPT-IN LOGGING ----------------------------------------------------------- */ /** * Log opt-in change if tracking is enabled * * @param string $context Context of the opt-in change (settings_update, settings_modal, etc.) * @return void */ function admilogu_maybe_log_optin_change($context = 'settings_update') { global $admilogu_skip_optin_tracking; // Skip if tracking is disabled for this request if (!empty($admilogu_skip_optin_tracking)) { return; } // Only log if user has opted in if ('yes' !== get_option('admilogu_tracking_optin')) { return; } // Send tracking event admilogu_send_tracking('Optin Yes', ['source' => $context]); } /** * Track when tracking opt-in option is updated * * @param string $option Name of the option being updated * @param mixed $old_value Previous value of the option * @param mixed $value New value of the option * @return void */ function admilogu_track_optin_updates($option, $old_value, $value) { // Only process tracking opt-in option if ('admilogu_tracking_optin' !== $option) { return; } // Skip if value hasn't changed or not opted in if ($old_value === $value || 'yes' !== $value) { return; } // Determine context (modal or settings page) $context = 'settings_update'; if (defined('DOING_AJAX') && DOING_AJAX && did_action('wp_ajax_admilogu_tracking_optin')) { $context = 'settings_modal'; } // Log the change admilogu_maybe_log_optin_change($context); } add_action('updated_option', 'admilogu_track_optin_updates', 10, 3); /** * Track when tracking opt-in option is first added * * @param string $option Name of the option being added * @param mixed $value Value of the option * @return void */ function admilogu_track_optin_added($option, $value) { // Only process tracking opt-in option with 'yes' value if ('admilogu_tracking_optin' !== $option || 'yes' !== $value) { return; } // Determine context (modal or settings page) $context = (defined('DOING_AJAX') && DOING_AJAX && did_action('wp_ajax_admilogu_tracking_optin')) ? 'settings_modal' : 'settings_update'; // Log the change admilogu_maybe_log_optin_change($context); } add_action('added_option', 'admilogu_track_optin_added', 10, 2); /* --------------------------------------------------------- TRACKING QUERY PARAMS HANDLER ----------------------------------------------------------- */ /** * Handle tracking opt-in/opt-out via URL query parameters * * @return void */ function admilogu_handle_tracking_query_params() { // Check if tracking parameters are present // phpcs:ignore WordPress.Security.NonceVerification.Recommended if (!isset($_GET['code-core-tracking']) || !isset($_GET['admilogu_nonce'])) { return; } // Verify nonce // phpcs:ignore WordPress.Security.NonceVerification.Recommended $nonce = sanitize_text_field(wp_unslash($_GET['admilogu_nonce'])); if (!wp_verify_nonce($nonce, 'admilogu_tracking_action')) { return; } // Get tracking action // phpcs:ignore WordPress.Security.NonceVerification.Recommended $tracking_action = sanitize_text_field(wp_unslash($_GET['code-core-tracking'])); // Temporarily disable opt-in tracking to avoid duplicate events global $admilogu_skip_optin_tracking; $admilogu_skip_optin_tracking = true; // Process the action if ($tracking_action === 'allow') { update_option('admilogu_tracking_optin', 'yes'); // Store plugin version $info = admilogu_get_plugin_info(); if (!empty($info['Version'])) { update_option('admilogu_plugin_version', $info['Version']); } // Send tracking event admilogu_send_tracking('Optin Yes'); } elseif ($tracking_action === 'deny') { update_option('admilogu_tracking_optin', 'no'); } // Re-enable opt-in tracking $admilogu_skip_optin_tracking = false; // Redirect to clean URL wp_safe_redirect(remove_query_arg(['code-core-tracking', 'admilogu_nonce'])); exit; } add_action('admin_init', 'admilogu_handle_tracking_query_params'); /* --------------------------------------------------------- PLUGIN ACTIVATION HOOK ----------------------------------------------------------- */ /** * Handle plugin activation * * @return void */ function admilogu_telemetry_activation() { // Store plugin version $info = admilogu_get_plugin_info(); if (!empty($info['Version'])) { update_option('admilogu_plugin_version', $info['Version']); } // Send activation tracking event admilogu_send_tracking('Activation'); } // This will be called from the main activation hook in admin-login-guard-branding.php /* --------------------------------------------------------- PLUGIN DEACTIVATION HOOK ----------------------------------------------------------- */ /** * Handle plugin deactivation * * @return void */ function admilogu_telemetry_deactivation() { // Send deactivation tracking event admilogu_send_tracking('Deactivation'); } // This will be called from the main deactivation hook in admin-login-guard-branding.php /* --------------------------------------------------------- PLUGIN UNINSTALL HOOK ----------------------------------------------------------- */ /** * Handle plugin uninstall cleanup * * @return void */ function admilogu_uninstall_handler() { // Send uninstall tracking event admilogu_send_tracking('Uninstall'); // Clean up options delete_option('admilogu_tracking_optin'); delete_option('admilogu_plugin_version'); } /* --------------------------------------------------------- PLUGIN UPDATE TRACKING ----------------------------------------------------------- */ /** * Track plugin updates * * @param WP_Upgrader $upgrader WP_Upgrader instance * @param array $options Array of bulk item update data * @return void */ function admilogu_track_plugin_update($upgrader, $options) { // Check if this is a plugin update if (empty($options['type']) || $options['type'] !== 'plugin') { return; } // Check if this is an update action if (empty($options['action']) || $options['action'] !== 'update') { return; } // Check if plugins array exists if (empty($options['plugins']) || !is_array($options['plugins'])) { return; } // Check if our plugin is being updated $plugin_slug = plugin_basename(admilogu_PATH . 'admin-login-guard-branding.php'); if (!in_array($plugin_slug, $options['plugins'], true)) { return; } // Get version information $info = admilogu_get_plugin_info(); $new_version = isset($info['Version']) ? $info['Version'] : ''; $old_version = get_option('admilogu_plugin_version', 'unknown'); // Send update tracking event admilogu_send_tracking( 'plugin_update', [ 'old_version' => $old_version, 'new_version' => $new_version, ] ); // Update stored version if ($new_version) { update_option('admilogu_plugin_version', $new_version); } } add_action('upgrader_process_complete', 'admilogu_track_plugin_update', 10, 2); /* --------------------------------------------------------- DYNAMIC PLUGIN INFORMATION ----------------------------------------------------------- */ /** * Get plugin information from the plugin header * * @return array Plugin data array */ function admilogu_get_plugin_info() { static $info = null; // Return cached info if available if ($info !== null) { return $info; } // Load get_plugin_data function if not available if (!function_exists('get_plugin_data')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } // Get and cache plugin data $info = get_plugin_data(admilogu_PATH . 'admin-login-guard-branding.php'); return $info; } /* --------------------------------------------------------- TRACKING: BUILD DYNAMIC PAYLOAD ----------------------------------------------------------- */ /** * Build tracking payload with site and plugin information * * @param string $event Event name to track * @param array $extra Additional data to include in payload * @return array Complete payload array */ function admilogu_build_payload($event, $extra = []) { $info = admilogu_get_plugin_info(); // Build base payload with site information $base_payload = [ 'site_url' => home_url(), 'plugin_name' => $info['Name'], 'plugin_version' => $info['Version'], 'event' => $event, 'php_version' => phpversion(), 'wp_version' => get_bloginfo('version'), 'theme_name' => wp_get_theme()->get('Name'), 'theme_version' => wp_get_theme()->get('Version'), 'is_multisite' => is_multisite() ? 'yes' : 'no', 'site_language' => get_locale(), 'timestamp' => time(), ]; // Merge with extra data and return return array_merge($base_payload, $extra); } /* --------------------------------------------------------- TRACKING: ENCRYPTION ----------------------------------------------------------- */ /** * Encrypt payload data using AES-256-CBC encryption * * @param array $data Data to encrypt * @param string $secret_key Secret key for encryption * @return string Base64 encoded encrypted data */ function admilogu_encrypt_payload($data, $secret_key) { // Generate random initialization vector $iv = openssl_random_pseudo_bytes(16); // Encrypt the JSON-encoded data $encrypted = openssl_encrypt( wp_json_encode($data), 'AES-256-CBC', $secret_key, 0, $iv ); // Return base64 encoded IV + encrypted data return base64_encode($iv . $encrypted); } /* --------------------------------------------------------- TRACKING: SEND TO SERVER ----------------------------------------------------------- */ /** * Send tracking data to remote server * * @param string $event Event name to track * @param array $extra Additional data to include * @return void */ function admilogu_send_tracking($event, $extra = []) { // Only send if user has opted in if (get_option('admilogu_tracking_optin') !== 'yes') { return; } // Build payload $payload = admilogu_build_payload($event, $extra); $secret_key = '8jF29fLkmsP0V9as0DLkso2P9lKs29FjsP4k2F0lskM2k'; // Encrypt payload and create signature $encrypted = admilogu_encrypt_payload($payload, $secret_key); $signature = hash_hmac('sha256', $encrypted, $secret_key); // Send to remote server wp_remote_post( 'https://dashboard.wordpress-plugins.pro/receiver.php', [ 'method' => 'POST', 'body' => [ 'data' => $encrypted, 'signature' => $signature, ], 'timeout' => 20, ] ); }