tracking_server_url)); ?> 'tracked_element', 'class' => '', 'style' => '', ), $atts, 'track_element'); // Sanitize attributes $event = esc_attr($atts['event']); $class = esc_attr($atts['class']); $style = esc_attr($atts['style']); // Return the div with content and onclick attribute return sprintf( '
%s
', $class, $style, $event, do_shortcode($content) ); } /** * Register Gutenberg tracking block */ public function register_tracking_block() { // Only register block if Gutenberg is available if (!function_exists('register_block_type')) { return; } // Register block script wp_register_script( 'tracking-block-editor', plugins_url('block.js', __FILE__), array( 'wp-blocks', 'wp-element', 'wp-block-editor', 'wp-components', 'wp-i18n' ), filemtime(plugin_dir_path(__FILE__) . 'block.js') ); // Register block styles wp_register_style( 'tracking-block-editor-style', plugins_url('block.css', __FILE__), array(), filemtime(plugin_dir_path(__FILE__) . 'tracking-block.css') ); // Register the block register_block_type('simplified-tracking/track-element', array( 'editor_script' => 'tracking-block-editor', 'editor_style' => 'tracking-block-editor-style', 'attributes' => array( 'eventName' => array( 'type' => 'string', 'default' => 'tracked_element', ), ), )); // Add inline script to ensure tE function is available in editor wp_add_inline_script('tracking-block-editor', " // Mock tE function for the editor if it doesn't exist if (typeof window.tE === 'undefined') { window.tE = function(eventName) { console.log('Tracking event: ' + eventName); }; } "); } /** * Register tracking endpoint */ public function register_tracking_endpoint() { add_rewrite_rule('^track/?$', 'index.php?tracking_endpoint=1', 'top'); add_rewrite_tag('%tracking_endpoint%', '1'); add_action('parse_request', array($this, 'handle_tracking_request')); // Flush rewrite rules only on plugin activation if (get_option('simple_tracking_flush_rules', false)) { flush_rewrite_rules(); update_option('simple_tracking_flush_rules', false); } } /** * Handle tracking request */ public function handle_tracking_request($wp) { if (isset($wp->query_vars['tracking_endpoint'])) { $this->forward_to_tracker(); exit; } } /** * Forward the request to the tracking server */ public function forward_to_tracker() { // Get tracking server URL from settings $tracking_server_url = get_option('simple_tracking_server_url', $this->tracking_server_url); $forward_url = 'https://' . $tracking_server_url . '/spur'; // Create a new cURL resource $ch = curl_init(); // Set URL and other appropriate options curl_setopt($ch, CURLOPT_URL, $forward_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $_SERVER['REQUEST_METHOD']); // Get query parameters and add IP $query = $_GET; $query['ip'] = $this->get_real_ip(); // Build query string $query_string = http_build_query($query); curl_setopt($ch, CURLOPT_URL, $forward_url . '?' . $query_string); // Prepare headers $headers = array(); $all_headers = function_exists('getallheaders') ? getallheaders() : $this->get_all_headers(); // Forward all headers, checking for the final destination foreach ($all_headers as $name => $value) { if ($name == 'X-Final-Destination' && !empty($value)) { // If a custom destination is provided in the header, use it $forward_url = 'https://' . $value . '/spur'; curl_setopt($ch, CURLOPT_URL, $forward_url . '?' . $query_string); } $headers[] = "$name: $value"; } curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // Execute request $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if (curl_errno($ch)) { $http_code = 500; } // Close cURL resource curl_close($ch); // Send response http_response_code($http_code); header('Content-Type: application/json'); echo '{}'; exit; } /** * Fallback implementation of getallheaders() for servers that don't have it */ private function get_all_headers() { $headers = []; foreach ($_SERVER as $name => $value) { if (substr($name, 0, 5) == 'HTTP_') { $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; } } return $headers; } /** * Get the real IP address */ private function get_real_ip() { if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; } else { $ip = $_SERVER['REMOTE_ADDR']; } return $ip; } /** * Add settings page */ public function add_settings_page() { add_options_page( 'Tracking Settings', 'Tracking Settings', 'manage_options', 'simple-tracking-settings', array($this, 'render_settings_page') ); } /** * Register settings */ public function register_settings() { register_setting('simple_tracking_settings', 'simple_tracking_server_url'); register_setting('simple_tracking_settings', 'simple_tracking_track_classes'); add_settings_section( 'simple_tracking_section', 'Tracking Settings', array($this, 'settings_section_callback'), 'simple-tracking-settings' ); add_settings_field( 'simple_tracking_server_url', 'Tracking Server URL', array($this, 'server_url_callback'), 'simple-tracking-settings', 'simple_tracking_section' ); add_settings_section( 'simple_tracking_auto_section', 'Element Tracking Settings', array($this, 'auto_settings_section_callback'), 'simple-tracking-settings' ); add_settings_field( 'simple_tracking_track_classes', 'Track Elements with Classes', array($this, 'track_classes_callback'), 'simple-tracking-settings', 'simple_tracking_auto_section' ); } /** * Settings section callback */ public function settings_section_callback() { echo '

Configure your tracking server settings.

'; } /** * Auto tracking settings section callback */ public function auto_settings_section_callback() { echo '

Configure which elements to track based on CSS classes.

'; } /** * Server URL field callback */ public function server_url_callback() { $value = get_option('simple_tracking_server_url', $this->tracking_server_url); echo ''; echo '

Enter the tracking server URL without https:// (e.g., tracking1.karlbreuer.com)

'; echo '

You will find this in your domain screen in the Palantics app

'; } /** * Track classes callback */ public function track_classes_callback() { $value = get_option('simple_tracking_track_classes', ''); echo ''; echo '

Enter comma-separated class names to automatically track clicks on elements with these classes (e.g., cta-button, featured-product)

'; } /** * Render settings page */ public function render_settings_page() { ?>

Manual Tracking Methods

Method 1: Using Data Attributes

Add the data-track attribute to any HTML element to track clicks:

<button data-track="signup_button_click">Sign Up</button>

Method 2: Using Shortcode

Wrap any content with the shortcode to track clicks:

[track_element event="download_click" class="your-class" style="your-style"]
    Your content here (can include other shortcodes)
[/track_element]

Method 3: Using Direct JavaScript

You can also manually add onclick="tE('your_event_name')" to any HTML element.