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.