Plugin Directory

Changeset 3488532


Ignore:
Timestamp:
03/23/2026 03:22:14 AM (9 days ago)
Author:
epicwpsolutions
Message:

Fix tracking: remove nonce from public endpoints, add table migration from ept_ to epictr_

Location:
epic-tracking
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • epic-tracking/tags/1.3.6/assets/js/tracker.js

    r3480781 r3488532  
    2828        var formData = new FormData();
    2929        formData.append('action', action);
    30         formData.append('nonce', epictrConfig.nonce);
    3130        for (var key in data) {
    3231            formData.append(key, data[key]);
  • epic-tracking/tags/1.3.6/epic-tracking.php

    r3480781 r3488532  
    1919}
    2020
    21 define('EPICTR_VERSION', '1.3.5');
     21define('EPICTR_VERSION', '1.3.6');
    2222define('EPICTR_PLUGIN_DIR', plugin_dir_path(__FILE__));
    2323define('EPICTR_PLUGIN_URL', plugin_dir_url(__FILE__));
  • epic-tracking/tags/1.3.6/readme.txt

    r3480781 r3488532  
    1 === Epic Tracking ===
     1=== Epic Tracking – Click & Event Tracking for WordPress ===
    22Contributors: epicwpsolutions
    33Tags: event tracking, click tracking, analytics, page views, statistics
     
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1010
    11 Easy event tracking for WordPress. Point, click, and track — no code, no tag managers, no third-party scripts.
     11Click and event tracking for WordPress. Point, click, and track — no code, no tag managers, no third-party scripts.
    1212
    1313== Description ==
     
    1515Epic Tracking lets you add event tracking to any element on your WordPress site using a visual editor. Click the element you want to track, give it a name, and you're done — events start recording immediately. No code, no Google Tag Manager, no external scripts.
    1616
    17 = Visual Event Editor =
     17= Visual Click & Event Editor =
    1818
    1919Open the visual editor on any page from the WordPress admin bar. Click a button, link, form, CTA, or any other element — give it a reference name and tag — and save. That's it. The event is live and tracking starts immediately.
  • epic-tracking/tags/1.3.6/src/Database.php

    r3480781 r3488532  
    99class Database
    1010{
    11     const DB_VERSION = '1.2.0';
     11    const DB_VERSION = '1.3.0';
    1212    const DB_VERSION_OPTION = 'epictr_db_version';
    1313
     
    1919    public static function activate(): void
    2020    {
     21        self::migrateOldTables();
    2122        self::createTables();
    2223        update_option(self::DB_VERSION_OPTION, self::DB_VERSION);
     
    2728        $installed = get_option(self::DB_VERSION_OPTION, '0');
    2829        if (version_compare($installed, self::DB_VERSION, '<')) {
     30            self::migrateOldTables();
    2931            self::createTables();
    3032            update_option(self::DB_VERSION_OPTION, self::DB_VERSION);
     33        }
     34    }
     35
     36    /**
     37     * Migrate old ept_ prefixed tables to epictr_ prefix, preserving all data.
     38     */
     39    private static function migrateOldTables(): void
     40    {
     41        global $wpdb;
     42
     43        $old_tables = [
     44            "{$wpdb->prefix}ept_events"    => "{$wpdb->prefix}epictr_events",
     45            "{$wpdb->prefix}ept_visits"    => "{$wpdb->prefix}epictr_visits",
     46            "{$wpdb->prefix}ept_event_log" => "{$wpdb->prefix}epictr_event_log",
     47        ];
     48
     49        foreach ($old_tables as $old_name => $new_name) {
     50            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
     51            $old_exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $old_name));
     52            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
     53            $new_exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $new_name));
     54
     55            if ($old_exists && !$new_exists) {
     56                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table names are hardcoded above
     57                $wpdb->query("RENAME TABLE `{$old_name}` TO `{$new_name}`");
     58            } elseif ($old_exists && $new_exists) {
     59                // New table exists but may be empty — drop it and rename the old one with data
     60                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
     61                $new_count = (int) $wpdb->get_var("SELECT COUNT(*) FROM `{$new_name}`");
     62                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
     63                $old_count = (int) $wpdb->get_var("SELECT COUNT(*) FROM `{$old_name}`");
     64
     65                if ($old_count > 0 && $new_count === 0) {
     66                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
     67                    $wpdb->query("DROP TABLE `{$new_name}`");
     68                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
     69                    $wpdb->query("RENAME TABLE `{$old_name}` TO `{$new_name}`");
     70                }
     71            }
     72        }
     73
     74        // Migrate old option name
     75        $old_version = get_option('ept_db_version');
     76        if ($old_version !== false) {
     77            delete_option('ept_db_version');
    3178        }
    3279    }
  • epic-tracking/tags/1.3.6/src/Tracker.php

    r3480781 r3488532  
    4747        wp_localize_script('epictr-tracker', 'epictrConfig', [
    4848            'ajaxUrl' => admin_url('admin-ajax.php'),
    49             'nonce'   => wp_create_nonce('epictr_track'),
    5049            'pageUrl' => $pageUrl,
    5150            'events'  => array_map(function ($event) {
     
    5958    }
    6059
     60    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- public tracking endpoint, nonce breaks with page caching
    6161    public static function handleTrackVisit(): void
    6262    {
    63         if (!check_ajax_referer('epictr_track', 'nonce', false)) {
    64             wp_send_json_error(__('Invalid nonce', 'epic-tracking'), 403);
    65             return;
    66         }
    67 
    6863        $visitorId = sanitize_text_field(wp_unslash($_POST['visitor_id'] ?? ''));
    6964        $pageUrl   = sanitize_text_field(wp_unslash($_POST['page_url'] ?? ''));
     
    8883    }
    8984
     85    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- public tracking endpoint, nonce breaks with page caching
    9086    public static function handleTrackEvent(): void
    9187    {
    92         if (!check_ajax_referer('epictr_track', 'nonce', false)) {
    93             wp_send_json_error(__('Invalid nonce', 'epic-tracking'), 403);
    94             return;
    95         }
    96 
    9788        $eventId   = absint(wp_unslash($_POST['event_id'] ?? 0));
    9889        $visitorId = sanitize_text_field(wp_unslash($_POST['visitor_id'] ?? ''));
  • epic-tracking/trunk/assets/js/tracker.js

    r3480781 r3488532  
    2828        var formData = new FormData();
    2929        formData.append('action', action);
    30         formData.append('nonce', epictrConfig.nonce);
    3130        for (var key in data) {
    3231            formData.append(key, data[key]);
  • epic-tracking/trunk/epic-tracking.php

    r3480781 r3488532  
    1919}
    2020
    21 define('EPICTR_VERSION', '1.3.5');
     21define('EPICTR_VERSION', '1.3.6');
    2222define('EPICTR_PLUGIN_DIR', plugin_dir_path(__FILE__));
    2323define('EPICTR_PLUGIN_URL', plugin_dir_url(__FILE__));
  • epic-tracking/trunk/src/Database.php

    r3480781 r3488532  
    99class Database
    1010{
    11     const DB_VERSION = '1.2.0';
     11    const DB_VERSION = '1.3.0';
    1212    const DB_VERSION_OPTION = 'epictr_db_version';
    1313
     
    1919    public static function activate(): void
    2020    {
     21        self::migrateOldTables();
    2122        self::createTables();
    2223        update_option(self::DB_VERSION_OPTION, self::DB_VERSION);
     
    2728        $installed = get_option(self::DB_VERSION_OPTION, '0');
    2829        if (version_compare($installed, self::DB_VERSION, '<')) {
     30            self::migrateOldTables();
    2931            self::createTables();
    3032            update_option(self::DB_VERSION_OPTION, self::DB_VERSION);
     33        }
     34    }
     35
     36    /**
     37     * Migrate old ept_ prefixed tables to epictr_ prefix, preserving all data.
     38     */
     39    private static function migrateOldTables(): void
     40    {
     41        global $wpdb;
     42
     43        $old_tables = [
     44            "{$wpdb->prefix}ept_events"    => "{$wpdb->prefix}epictr_events",
     45            "{$wpdb->prefix}ept_visits"    => "{$wpdb->prefix}epictr_visits",
     46            "{$wpdb->prefix}ept_event_log" => "{$wpdb->prefix}epictr_event_log",
     47        ];
     48
     49        foreach ($old_tables as $old_name => $new_name) {
     50            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
     51            $old_exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $old_name));
     52            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
     53            $new_exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $new_name));
     54
     55            if ($old_exists && !$new_exists) {
     56                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table names are hardcoded above
     57                $wpdb->query("RENAME TABLE `{$old_name}` TO `{$new_name}`");
     58            } elseif ($old_exists && $new_exists) {
     59                // New table exists but may be empty — drop it and rename the old one with data
     60                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
     61                $new_count = (int) $wpdb->get_var("SELECT COUNT(*) FROM `{$new_name}`");
     62                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
     63                $old_count = (int) $wpdb->get_var("SELECT COUNT(*) FROM `{$old_name}`");
     64
     65                if ($old_count > 0 && $new_count === 0) {
     66                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
     67                    $wpdb->query("DROP TABLE `{$new_name}`");
     68                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
     69                    $wpdb->query("RENAME TABLE `{$old_name}` TO `{$new_name}`");
     70                }
     71            }
     72        }
     73
     74        // Migrate old option name
     75        $old_version = get_option('ept_db_version');
     76        if ($old_version !== false) {
     77            delete_option('ept_db_version');
    3178        }
    3279    }
  • epic-tracking/trunk/src/Tracker.php

    r3480781 r3488532  
    4747        wp_localize_script('epictr-tracker', 'epictrConfig', [
    4848            'ajaxUrl' => admin_url('admin-ajax.php'),
    49             'nonce'   => wp_create_nonce('epictr_track'),
    5049            'pageUrl' => $pageUrl,
    5150            'events'  => array_map(function ($event) {
     
    5958    }
    6059
     60    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- public tracking endpoint, nonce breaks with page caching
    6161    public static function handleTrackVisit(): void
    6262    {
    63         if (!check_ajax_referer('epictr_track', 'nonce', false)) {
    64             wp_send_json_error(__('Invalid nonce', 'epic-tracking'), 403);
    65             return;
    66         }
    67 
    6863        $visitorId = sanitize_text_field(wp_unslash($_POST['visitor_id'] ?? ''));
    6964        $pageUrl   = sanitize_text_field(wp_unslash($_POST['page_url'] ?? ''));
     
    8883    }
    8984
     85    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- public tracking endpoint, nonce breaks with page caching
    9086    public static function handleTrackEvent(): void
    9187    {
    92         if (!check_ajax_referer('epictr_track', 'nonce', false)) {
    93             wp_send_json_error(__('Invalid nonce', 'epic-tracking'), 403);
    94             return;
    95         }
    96 
    9788        $eventId   = absint(wp_unslash($_POST['event_id'] ?? 0));
    9889        $visitorId = sanitize_text_field(wp_unslash($_POST['visitor_id'] ?? ''));
Note: See TracChangeset for help on using the changeset viewer.