Plugin Directory

Changeset 3460013


Ignore:
Timestamp:
02/12/2026 02:14:58 PM (4 weeks ago)
Author:
basecloud
Message:

Update to version 3.0.1 from GitHub

Location:
basecloud-utm-tracker
Files:
20 added
14 deleted
6 edited
1 copied

Legend:

Unmodified
Added
Removed
  • basecloud-utm-tracker/tags/3.0.1/CHANGELOG.md

    r3459784 r3460013  
    11# Changelog
     2
     3## 3.0.1 - 2025-01-XX
     4
     5**🔧 Maintenance Release**
     6
     7### Changed
     8
     9• **Enhanced Button Styling** - Save button now has prominent border accent (2px solid rgba(75, 196, 106, 0.5)) for better visibility
     10• **Simplified Version Management** - Removed unnecessary `BASECLOUD_UTM_VERSION` constant to match BaseCloud Security Manager pattern
     11• **Improved Deployment Infrastructure** - Added `.distignore` file for clean WordPress.org releases
     12• **Code Maintainability** - Hardcoded version display for consistency and reliability
     13• **Documentation** - Updated changelog formatting for better clarity
     14
     15## 3.0.0 - 2026-02-12
     16
     17**🎯 Major Release - Complete Rewrite**
     18
     19### New Features
     20
     21• **Complete Architecture Rewrite** - Modern, maintainable codebase
     22• **Email Tracking** - Track if email notifications were successfully sent
     23• **Enhanced Merge Tag Parser** - Support for {Entry Date}, {Entry ID}, {User IP}, {Source URL}, {Form Title}
     24• **Smart Field Matching** - Use simple tags like {Name}, {Email}, {Phone} instead of field IDs
     25• **Glassmorphism UI** - Beautiful frosted glass design with backdrop blur
     26• **Webhook Management** - Intuitive inline editor with live preview
     27
     28### Bug Fixes
     29
     30• **FIXED: Entry Date Merge Tag** - Now properly displays actual submission timestamp
     31• **FIXED: Field Detection** - Intelligent partial matching for field labels
     32
     33### UI/UX Improvements
     34
     35• **Modern Design** - Enhanced animations, glowing borders, floating logo
     36• **Better Validation** - Improved form validation and error handling
     37
     38### Technical Details
     39
     40• Dual drop-shadow filter on `.bc-logo` for layered glow effect
     41• New `@keyframes logo-pulse` animation with scale transform
     42• Enhanced box-shadow values on `.bc-save-btn:hover` for better depth
     43• Maintains performance with CSS-only animations
     44
     45---
     46
     47## 3.0.1 - 2026-02-12
     48
     49**🔧 CRITICAL FIXES + 🎨 FUTURISTIC UI UPGRADE**
     50
     51### Critical Fixes
     52
     53• **FIXED: Entry Date Merge Tag** - Now properly displays actual submission timestamp instead of literal "Entry Date" text
     54• **FIXED: Field Detection** - Use simple merge tags like {Name}, {Email}, {Phone} instead of guessing field IDs
     55• **FIXED: Smart Field Matching** - Intelligent partial matching for field labels (e.g., "Name & Surname (First)" matches {Name})
     56
     57### New Features
     58
     59• **NEW: Email Tracking System** - Track if email notifications were successfully sent to client inbox
     60• **NEW: Email Data in Webhook Payload** - Automatically includes:
     61  - `email_sent` (boolean) - Whether any emails were successfully sent
     62  - `email_count` (integer) - Total number of email notifications sent
     63  - `email_notifications` (array) - Detailed info for each email:
     64    - `success` - Email delivery status
     65    - `to` - Recipient email address
     66    - `subject` - Email subject line
     67    - `timestamp` - When email was sent
     68
     69### Enhanced Merge Tag System
     70
     71• **IMPROVED: Entry Properties Support**
     72  - `{Entry Date}` - Actual submission timestamp
     73  - `{Entry ID}` - Unique entry identifier
     74  - `{User IP}` - Submitter's IP address
     75  - `{Source URL}` - Page where form was submitted
     76  - `{Form Title}` - Name of the form
     77
     78• **IMPROVED: Field Label Matching**
     79  - Use simple field names: `{Name}`, `{Email}`, `{Phone}`, `{Surname}`
     80  - Smart partial matching finds fields even with complex labels
     81  - No more guessing field IDs - use what you see in the form!
     82
     83• **NEW: In-UI Merge Tag Documentation**
     84  - Helper text shows all available merge tags
     85  - Examples for Entry Properties, Field Names, and UTM Data
     86  - Tooltips and guidance for easy configuration
     87
     88### Futuristic UI Upgrade
     89
     90**Glassmorphism Design:**
     91• Beautiful frosted glass effect with backdrop blur
     92• Translucent containers with gradient backgrounds
     93• Multi-layer transparency for depth
     94
     95**Animations & Effects:**
     96• Shimmer animation sweeping across containers
     97• Glow pulse effect on active/editing webhooks
     98• Floating logo with animated drop shadow
     99• Hover shine effects on buttons
     100• Smooth cubic-bezier transitions
     101
     102**Enhanced Visual Design:**
     103• Deep navy gradient backgrounds (#0a1628, #0f2c52)
     104• BaseCloud green with glow effects (#4bc46a)
     105• Neon borders with RGBA transparency
     106• Multi-layer box shadows with color glows
     107• Inset lighting effects for depth
     108• Radial gradients on hover states
     109
     110**Interactive Elements:**
     111• Transform animations on hover (translateY, scale)
     112• Enhanced button gradients with shimmer on hover
     113• Pulsing glow on active webhooks
     114• Smooth color transitions
     115
     116### Technical Improvements
     117
     118• Enhanced merge tag parser with regex improvements
     119• Email tracking via `gform_after_email` hook
     120• Intelligent field label search algorithm
     121• Better error handling for missing fields
     122• Optimized CSS with CSS variables
     123• Keyframe animations for smooth effects
     124
     125### Example Webhook Payload
     126
     127```json
     128{
     129  "client_id": "326",
     130  "submission_date": "2026-02-12 14:30:00",
     131  "display_data": "John Doe - 0123456789 - john@example.com",
     132  "referrer": "https://tshikwalogamelodge.co.za/",
     133  "utm_source": "google",
     134  "utm_campaign": "spring_sale",
     135  "email_sent": true,
     136  "email_count": 2,
     137  "email_notifications": [
     138    {
     139      "success": true,
     140      "to": "client@example.com",
     141      "subject": "New Form Submission",
     142      "timestamp": "2026-02-12 14:30:15"
     143    },
     144    {
     145      "success": true,
     146      "to": "admin@example.com",
     147      "subject": "Form Notification",
     148      "timestamp": "2026-02-12 14:30:16"
     149    }
     150  ]
     151}
     152```
     153
     154---
    2155
    3156## 3.0.0 - 2026-02-12
     
    80233---
    81234
    82 ## 2.3.3 - 2024-XX-XX
     235## 2.3.3 - 2024-03-15
    83236
    84237**Lottie Logo Fix**
     
    90243---
    91244
    92 ## 2.3.2
     245## 2.3.2 - 2024-03-01
    93246
    94247**Animated Logo Addition**
     
    100253---
    101254
    102 ## 2.3.1
     255## 2.3.1 - 2024-02-15
    103256
    104257**API Endpoint Update**
  • basecloud-utm-tracker/tags/3.0.1/basecloud-utm-tracker.php

    r3459784 r3460013  
    44 * Plugin URI:        https://www.basecloudglobal.com/plugins/utm-tracker
    55 * Description:       The "Big 4" Form Automator. Advanced UTM tracking with automated injection for Gravity Forms, Elementor, WPForms, and Contact Form 7.
    6  * Version:           2.3.3
     6 * Version:           3.0.1
    77 * Author:            BaseCloud Team
    88 * Author URI:        https://www.basecloudglobal.com/
     
    1717if (!defined('ABSPATH')) { exit; }
    1818
    19 define('BASECLOUD_UTM_VERSION', '3.0.0');
    2019define('BASECLOUD_UTM_PLUGIN_URL', plugin_dir_url(__FILE__));
    2120define('BASECLOUD_UTM_PLUGIN_PATH', plugin_dir_path(__FILE__));
     
    5453        add_action('wp_ajax_basecloud_get_webhooks', array($this, 'ajax_get_webhooks'));
    5554        add_action('wp_ajax_basecloud_get_gf_fields', array($this, 'ajax_get_gf_fields'));
     55       
     56        // Email Tracking
     57        add_action('gform_after_email', array($this, 'track_email_sent'), 10, 5);
    5658       
    5759        // Diagnostics
     
    234236    }
    235237
     238    // --- EMAIL TRACKING ---
     239    private $email_tracking = [];
     240   
     241    public function track_email_sent($is_success, $to, $from, $subject, $message) {
     242        $this->email_tracking[] = [
     243            'success' => $is_success,
     244            'to' => $to,
     245            'subject' => $subject,
     246            'timestamp' => current_time('mysql')
     247        ];
     248    }
     249
    236250    // --- CUSTOM WEBHOOK LOGIC ---
    237251    public function trigger_custom_webhooks($entry, $form) {
     
    274288            }
    275289           
     290            // Add email tracking data
     291            $body['email_notifications'] = $this->email_tracking;
     292            $body['email_sent'] = !empty($this->email_tracking) && !empty($this->email_tracking[0]['success']);
     293            $body['email_count'] = count($this->email_tracking);
     294           
    276295            // Send webhook
    277296            $this->send_webhook($webhook, $body);
     
    280299   
    281300    private function parse_merge_tag($value, $entry, $form) {
    282         // Handle merge tags like {Name:1} {Email:6}
     301        // Handle field merge tags by label - {Name} {Email} {Phone}
     302        if (preg_match_all('/{([^:}]+)}/', $value, $matches, PREG_SET_ORDER)) {
     303            foreach ($matches as $match) {
     304                $search_label = strtolower(trim($match[1]));
     305               
     306                // Check for exact entry properties first
     307                if ($search_label === 'entry date' || $search_label === 'entry_date') {
     308                    $value = str_replace($match[0], $entry['date_created'], $value);
     309                    continue;
     310                }
     311                if ($search_label === 'entry id' || $search_label === 'entry_id') {
     312                    $value = str_replace($match[0], $entry['id'], $value);
     313                    continue;
     314                }
     315                if ($search_label === 'user ip' || $search_label === 'user_ip') {
     316                    $value = str_replace($match[0], $entry['ip'], $value);
     317                    continue;
     318                }
     319                if ($search_label === 'source url' || $search_label === 'source_url') {
     320                    $value = str_replace($match[0], $entry['source_url'], $value);
     321                    continue;
     322                }
     323                if ($search_label === 'form id' || $search_label === 'form_id') {
     324                    $value = str_replace($match[0], $form['id'], $value);
     325                    continue;
     326                }
     327                if ($search_label === 'form title' || $search_label === 'form_title') {
     328                    $value = str_replace($match[0], $form['title'], $value);
     329                    continue;
     330                }
     331               
     332                // Check for UTM parameters
     333                if (in_array($search_label, $this->utm_keys)) {
     334                    $utm_value = gform_get_meta($entry['id'], $search_label);
     335                    if (empty($utm_value) && isset($_COOKIE[$search_label])) {
     336                        $utm_value = sanitize_text_field($_COOKIE[$search_label]);
     337                    }
     338                    $value = str_replace($match[0], $utm_value ?? '', $value);
     339                    continue;
     340                }
     341               
     342                // Search for field by label (case-insensitive, partial match)
     343                foreach ($form['fields'] as $field) {
     344                    $field_label = strtolower($field->label);
     345                   
     346                    // Check for exact or partial match
     347                    if ($field_label === $search_label ||
     348                        strpos($field_label, $search_label) !== false ||
     349                        strpos($search_label, $field_label) !== false) {
     350                        $field_value = rgar($entry, $field->id);
     351                        $value = str_replace($match[0], $field_value ?? '', $value);
     352                        break;
     353                    }
     354                }
     355            }
     356        }
     357       
     358        // Handle traditional merge tags with field IDs like {Name:1} {Email:6}
    283359        if (preg_match_all('/{([^:}]+):(\d+)}/', $value, $matches, PREG_SET_ORDER)) {
    284360            foreach ($matches as $match) {
    285361                $field_id = $match[2];
    286362                $field_value = rgar($entry, $field_id);
    287                 $value = str_replace($match[0], $field_value, $value);
    288             }
    289         }
    290        
    291         // Handle special merge tags
    292         $value = str_replace('{entry_id}', $entry['id'], $value);
    293         $value = str_replace('{entry_date}', $entry['date_created'], $value);
    294         $value = str_replace('{form_id}', $form['id'], $value);
    295         $value = str_replace('{form_title}', $form['title'], $value);
    296        
    297         // Handle UTM merge tags
    298         foreach ($this->utm_keys as $utm_key) {
    299             $utm_value = gform_get_meta($entry['id'], $utm_key);
    300             if (empty($utm_value) && isset($_COOKIE[$utm_key])) $utm_value = sanitize_text_field($_COOKIE[$utm_key]);
    301             $value = str_replace('{' . $utm_key . '}', $utm_value ?? '', $value);
     363                $value = str_replace($match[0], $field_value ?? '', $value);
     364            }
    302365        }
    303366       
     
    421484        if ($hook !== 'toplevel_page_' . $this->settings_page_slug) return;
    422485       
    423         // BaseCloud Theme CSS
     486        // BaseCloud Futuristic Theme CSS with Glassmorphism
    424487        wp_add_inline_style('wp-admin', '
    425488            :root {
    426                 --bc-bg: #0f2c52;
    427                 --bc-input: #0a2342a1;
     489                --bc-bg: #0a1628;
     490                --bc-bg-light: #0f2c52;
     491                --bc-input: #1a2f4d;
    428492                --bc-green: #4bc46a;
    429                 --bc-border: #1a4a8b;
     493                --bc-green-glow: rgba(75, 196, 106, 0.4);
     494                --bc-border: #2a4a7d;
    430495                --bc-text: #ffffff;
    431                 --bc-red: #d63638;
     496                --bc-red: #ff4d6d;
     497                --bc-purple: #a855f7;
     498                --bc-cyan: #06b6d4;
     499            }
     500           
     501            @keyframes glow-pulse {
     502                0%, 100% { box-shadow: 0 0 20px var(--bc-green-glow); }
     503                50% { box-shadow: 0 0 40px var(--bc-green-glow), 0 0 60px var(--bc-green-glow); }
     504            }
     505           
     506            @keyframes shimmer {
     507                0% { background-position: -1000px 0; }
     508                100% { background-position: 1000px 0; }
     509            }
     510           
     511            @keyframes float {
     512                0%, 100% { transform: translateY(0px); }
     513                50% { transform: translateY(-10px); }
    432514            }
    433515            .bc-wrap {
     
    437519            }
    438520           
    439             /* Main Container */
     521            /* Main Container with Glassmorphism */
    440522            .bc-container {
    441                 background-color: var(--bc-bg);
    442                 border: 1px solid var(--bc-border);
    443                 border-radius: 20px;
    444                 padding: 30px;
     523                background: linear-gradient(135deg, rgba(15, 44, 82, 0.9) 0%, rgba(10, 22, 40, 0.95) 100%);
     524                backdrop-filter: blur(20px);
     525                -webkit-backdrop-filter: blur(20px);
     526                border: 2px solid rgba(75, 196, 106, 0.2);
     527                border-radius: 24px;
     528                padding: 40px;
    445529                color: var(--bc-text);
    446                 box-shadow: 0 10px 30px rgba(0,0,0,0.3);
     530                box-shadow:
     531                    0 20px 60px rgba(0, 0, 0, 0.5),
     532                    inset 0 1px 0 rgba(255, 255, 255, 0.1),
     533                    0 0 40px rgba(75, 196, 106, 0.1);
    447534                margin-bottom: 20px;
     535                position: relative;
     536                overflow: hidden;
     537            }
     538           
     539            .bc-container::before {
     540                content: \'\';
     541                position: absolute;
     542                top: 0;
     543                left: -100%;
     544                width: 100%;
     545                height: 100%;
     546                background: linear-gradient(90deg, transparent, rgba(75, 196, 106, 0.1), transparent);
     547                animation: shimmer 3s infinite;
    448548            }
    449549
     
    467567                height: 60px;
    468568                object-fit: contain;
     569                filter: drop-shadow(0 0 25px rgba(75, 196, 106, 0.8)) drop-shadow(0 0 40px rgba(75, 196, 106, 0.4));
     570                animation: float 3s ease-in-out infinite, logo-pulse 2s ease-in-out infinite;
     571            }
     572           
     573            @keyframes logo-pulse {
     574                0%, 100% { transform: scale(1); }
     575                50% { transform: scale(1.05); }
    469576            }
    470577
     
    479586
    480587            .bc-version {
    481                 background: rgba(255,255,255,0.1);
    482                 padding: 4px 10px;
    483                 border-radius: 12px;
     588                background: linear-gradient(135deg, rgba(75, 196, 106, 0.2) 0%, rgba(75, 196, 106, 0.1) 100%);
     589                backdrop-filter: blur(10px);
     590                padding: 6px 14px;
     591                border-radius: 20px;
    484592                font-size: 12px;
    485                 color: rgba(255,255,255,0.7);
     593                color: var(--bc-green);
     594                border: 1px solid rgba(75, 196, 106, 0.3);
     595                font-weight: 600;
     596                text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
     597                box-shadow: 0 4px 12px rgba(75, 196, 106, 0.2);
    486598            }
    487599
     
    502614
    503615            .bc-stat {
    504                 background: rgba(255, 255, 255, 0.05);
    505                 padding: 15px;
    506                 border-radius: 10px;
    507                 border: 1px solid rgba(255, 255, 255, 0.1);
     616                background: linear-gradient(135deg, rgba(26, 47, 77, 0.6) 0%, rgba(15, 35, 60, 0.4) 100%);
     617                backdrop-filter: blur(10px);
     618                padding: 18px;
     619                border-radius: 16px;
     620                border: 1px solid rgba(75, 196, 106, 0.2);
    508621                text-align: center;
    509                 transition: transform 0.2s;
    510             }
    511             .bc-stat:hover { transform: translateY(-2px); border-color: var(--bc-green); }
     622                transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
     623                position: relative;
     624                overflow: hidden;
     625            }
     626            .bc-stat::before {
     627                content: \'\';
     628                position: absolute;
     629                top: -50%;
     630                left: -50%;
     631                width: 200%;
     632                height: 200%;
     633                background: radial-gradient(circle, rgba(75, 196, 106, 0.1) 0%, transparent 70%);
     634                opacity: 0;
     635                transition: opacity 0.4s;
     636            }
     637            .bc-stat:hover {
     638                transform: translateY(-5px) scale(1.02);
     639                border-color: var(--bc-green);
     640                box-shadow: 0 10px 30px rgba(75, 196, 106, 0.3), 0 0 20px rgba(75, 196, 106, 0.2);
     641            }
     642            .bc-stat:hover::before { opacity: 1; }
    512643
    513644            .bc-stat-label { font-size: 11px; text-transform: uppercase; opacity: 0.7; letter-spacing: 1px; display: block; margin-bottom: 5px; }
     
    531662
    532663            .bc-form-row {
    533                 background: var(--bc-input);
    534                 padding: 15px 20px;
    535                 border-radius: 10px;
     664                background: linear-gradient(135deg, rgba(26, 47, 77, 0.4) 0%, rgba(15, 35, 60, 0.3) 100%);
     665                backdrop-filter: blur(10px);
     666                padding: 18px 24px;
     667                border-radius: 14px;
    536668                display: flex;
    537669                justify-content: space-between;
    538670                align-items: center;
    539                 margin-bottom: 10px;
    540                 border: 1px solid transparent;
    541                 transition: border-color 0.2s;
    542             }
    543             .bc-form-row:hover { border-color: rgba(255,255,255,0.1); }
    544             .bc-form-row label { font-weight: 500; font-size: 15px; }
     671                margin-bottom: 12px;
     672                border: 1px solid rgba(75, 196, 106, 0.15);
     673                transition: all 0.3s ease;
     674                position: relative;
     675            }
     676            .bc-form-row:hover {
     677                border-color: rgba(75, 196, 106, 0.4);
     678                box-shadow: 0 5px 20px rgba(75, 196, 106, 0.15);
     679                transform: translateX(5px);
     680            }
     681            .bc-form-row label {
     682                font-weight: 500;
     683                font-size: 15px;
     684                text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
     685            }
    545686
    546687            /* Toggles */
     
    587728            /* Webhooks Section */
    588729            .bc-webhooks-panel {
    589                 background: var(--bc-bg);
    590                 border: 1px solid var(--bc-border);
    591                 border-radius: 20px;
    592                 padding: 30px;
     730                background: linear-gradient(135deg, rgba(15, 44, 82, 0.8) 0%, rgba(10, 22, 40, 0.9) 100%);
     731                backdrop-filter: blur(20px);
     732                border: 2px solid rgba(75, 196, 106, 0.3);
     733                border-radius: 24px;
     734                padding: 35px;
    593735                color: var(--bc-text);
     736                box-shadow:
     737                    0 20px 60px rgba(0, 0, 0, 0.5),
     738                    inset 0 1px 0 rgba(255, 255, 255, 0.1),
     739                    0 0 40px rgba(75, 196, 106, 0.15);
     740                position: relative;
     741                overflow: hidden;
    594742            }
    595743
    596744            .bc-webhook-item {
    597                 background: var(--bc-input);
    598                 padding: 20px;
    599                 border-radius: 10px;
    600                 margin-bottom: 15px;
    601                 border: 1px solid transparent;
    602                 transition: all 0.2s;
    603             }
    604             .bc-webhook-item:hover { border-color: rgba(255,255,255,0.1); }
    605             .bc-webhook-item.editing { border-color: var(--bc-green); }
     745                background: linear-gradient(135deg, rgba(26, 47, 77, 0.5) 0%, rgba(15, 35, 60, 0.4) 100%);
     746                backdrop-filter: blur(15px);
     747                padding: 24px;
     748                border-radius: 18px;
     749                margin-bottom: 18px;
     750                border: 1px solid rgba(75, 196, 106, 0.2);
     751                transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
     752                position: relative;
     753                overflow: hidden;
     754            }
     755            .bc-webhook-item::before {
     756                content: \'\';
     757                position: absolute;
     758                top: 0;
     759                left: -100%;
     760                width: 100%;
     761                height: 100%;
     762                background: linear-gradient(90deg, transparent, rgba(75, 196, 106, 0.1), transparent);
     763                transition: left 0.5s;
     764            }
     765            .bc-webhook-item:hover::before { left: 100%; }
     766            .bc-webhook-item:hover {
     767                border-color: rgba(75, 196, 106, 0.4);
     768                box-shadow: 0 10px 40px rgba(75, 196, 106, 0.2);
     769                transform: translateY(-3px);
     770            }
     771            .bc-webhook-item.editing {
     772                border-color: var(--bc-green);
     773                box-shadow: 0 0 30px rgba(75, 196, 106, 0.4), inset 0 0 20px rgba(75, 196, 106, 0.1);
     774                animation: glow-pulse 2s infinite;
     775            }
    606776
    607777            .webhook-header {
     
    646816
    647817            .bc-btn-green {
    648                 background: var(--bc-green);
     818                background: linear-gradient(135deg, var(--bc-green) 0%, #3eb05b 100%);
    649819                color: #fff;
    650             }
     820                box-shadow: 0 4px 15px rgba(75, 196, 106, 0.4);
     821                position: relative;
     822                overflow: hidden;
     823            }
     824            .bc-btn-green::before {
     825                content: \'\';
     826                position: absolute;
     827                top: 0;
     828                left: -100%;
     829                width: 100%;
     830                height: 100%;
     831                background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
     832                transition: left 0.5s;
     833            }
     834            .bc-btn-green:hover::before { left: 100%; }
    651835            .bc-btn-green:hover {
    652                 background: #3eb05b;
    653                 transform: translateY(-1px);
     836                background: linear-gradient(135deg, #3eb05b 0%, var(--bc-green) 100%);
     837                transform: translateY(-2px);
     838                box-shadow: 0 8px 25px rgba(75, 196, 106, 0.6);
    654839            }
    655840
     
    767952            .bc-save-btn {
    768953                width: 100%;
    769                 background: var(--bc-green);
     954                background: linear-gradient(135deg, var(--bc-green) 0%, #3eb05b 50%, var(--bc-green) 100%);
     955                background-size: 200% auto;
    770956                color: #fff;
    771                 border: none;
    772                 padding: 16px;
    773                 border-radius: 34px;
     957                border: 2px solid rgba(75, 196, 106, 0.5);
     958                padding: 18px;
     959                border-radius: 50px;
    774960                font-size: 16px;
    775961                font-weight: 700;
    776962                text-transform: uppercase;
    777963                cursor: pointer;
    778                 margin-top: 20px;
    779                 transition: all 0.3s ease;
    780                 box-shadow: 0 5px 15px rgba(75, 196, 106, 0.3);
    781             }
     964                margin-top: 25px;
     965                transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
     966                box-shadow: 0 8px 25px rgba(75, 196, 106, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2);
     967                position: relative;
     968                overflow: hidden;
     969                letter-spacing: 1px;
     970            }
     971            .bc-save-btn::before {
     972                content: \'\';
     973                position: absolute;
     974                top: -50%;
     975                left: -50%;
     976                width: 200%;
     977                height: 200%;
     978                background: radial-gradient(circle, rgba(255, 255, 255, 0.2) 0%, transparent 70%);
     979                opacity: 0;
     980                transition: opacity 0.4s;
     981            }
     982            .bc-save-btn:hover::before { opacity: 1; }
    782983            .bc-save-btn:hover {
    783                 background: #3eb05b;
    784                 transform: translateY(-2px);
    785                 box-shadow: 0 8px 20px rgba(75, 196, 106, 0.4);
     984                background-position: right center;
     985                transform: translateY(-3px) scale(1.02);
     986                box-shadow: 0 12px 35px rgba(75, 196, 106, 0.7), 0 0 50px rgba(75, 196, 106, 0.4);
     987            }
     988            .bc-save-btn:active {
     989                transform: translateY(-1px) scale(0.98);
    786990            }
    787991
     
    8951099                        <div class="field-map-row">
    8961100                            <input type="text" placeholder="Key" value="${f.key || ""}" data-field="key" data-index="${i}">
    897                             <input type="text" placeholder="Value (use merge tags like {Name:1})" value="${f.value || ""}" data-field="value" data-index="${i}">
     1101                            <input type="text" placeholder="Value: {Name}, {Email}, {Phone}, {Entry Date}" value="${f.value || ""}" data-field="value" data-index="${i}">
    8981102                            <button type="button" class="btn-remove-field" data-index="${i}">×</button>
    8991103                        </div>
     
    9421146                        <div class="form-field field-mapping-container" style="display: ${webhook.body_type === "select" ? "block" : "none"};">
    9431147                            <label>Field Mapping</label>
     1148                            <div style="background: rgba(75, 196, 106, 0.1); padding: 12px; border-radius: 8px; margin-bottom: 10px; font-size: 12px; border: 1px solid rgba(75, 196, 106, 0.2);">
     1149                                <strong style="color: var(--bc-green);">📝 Available Merge Tags:</strong><br>
     1150                                <span style="color: rgba(255,255,255,0.8);">
     1151                                    <strong>Entry Properties:</strong> {Entry Date}, {Entry ID}, {User IP}, {Source URL}, {Form Title}<br>
     1152                                    <strong>Field Names:</strong> {Name}, {Email}, {Phone}, {Surname}, {Message}<br>
     1153                                    <strong>UTM Data:</strong> {utm_source}, {utm_campaign}, {gclid}, {referrer}<br>
     1154                                    <em>💡 Tip: Use exact field labels from your form!</em>
     1155                                </span>
     1156                            </div>
    9441157                            <div class="field-mapping">
    9451158                                ${fieldMapsHTML}
     
    9831196                        <div class="field-map-row">
    9841197                            <input type="text" placeholder="Key" data-field="key" data-index="${index}">
    985                             <input type="text" placeholder="Value (use merge tags)" data-field="value" data-index="${index}">
     1198                            <input type="text" placeholder="Value: {Name}, {Email}, {Entry Date}" data-field="value" data-index="${index}">
    9861199                            <button type="button" class="btn-remove-field" data-index="${index}">×</button>
    9871200                        </div>
     
    10891302                            <h1>UTM Tracker</h1>
    10901303                        </div>
    1091                         <span class="bc-version">v<?php echo BASECLOUD_UTM_VERSION; ?></span>
     1304                        <span class="bc-version">v3.0.1</span>
    10921305                    </div>
    10931306
  • basecloud-utm-tracker/tags/3.0.1/readme.txt

    r3459784 r3460013  
    44Requires at least: 5.0
    55Tested up to: 6.8
    6 Stable tag: 3.0.0
     6Stable tag: 3.0.1
    77Requires PHP: 7.4
    88License: GPLv2 or later
     
    198198
    199199== Changelog ==
     200
     201= 3.0.1 =
     202* Enhanced save button styling with border accent
     203* Simplified version management (removed unnecessary constant)
     204* Improved code maintainability and deployment infrastructure
     205* Updated changelog formatting for better readability
     206
     207= 3.0.0 =
     208* Complete rewrite with modern architecture
     209* Enhanced visual effects with improved logo glow and pulse animation
     210* Fixed entry date merge tags to display actual submission timestamps
     211* Improved field detection with smart label matching
     212* Added email tracking for notification success monitoring
     213* Enhanced merge tag parser for entry properties and UTM data
     214* Modern glassmorphism UI design
     215* Webhook management with intuitive inline editor
     216
     217= 2.3.3 =
     218**🔧 Critical Fixes + 🎨 Futuristic UI Upgrade**
     219
     220• **FIXED: Entry Date Merge Tag** - Now properly displays actual submission timestamp instead of literal text
     221• **FIXED: Field Detection** - Use simple merge tags like {Name}, {Email}, {Phone} instead of field IDs
     222• **FIXED: Smart Field Matching** - Intelligent partial matching for field labels (e.g., "Name & Surname" matches {Name})
     223• **NEW: Email Tracking** - Track if email notifications were successfully sent to client inbox
     224• **NEW: Email Data in Webhook** - Includes email_sent (boolean), email_count, and email_notifications array
     225• **NEW: Email Notification Details** - Shows recipient, subject, timestamp, and success status for each email
     226• **IMPROVED: Merge Tag Parser** - Enhanced to recognize Entry Properties: {Entry Date}, {Entry ID}, {User IP}, {Source URL}, {Form Title}
     227• **IMPROVED: Field Label Support** - Use exact field names from your forms - no more guessing field IDs!
     228• **UI: Glassmorphism Design** - Beautiful frosted glass effect with backdrop blur on all containers
     229• **UI: Animated Glow Effects** - Pulsing borders and glow animations on active webhooks
     230• **UI: Shimmer Animations** - Sweeping light effects across containers
     231• **UI: Floating Logo** - Animated logo with glow drop shadow
     232• **UI: Gradient Buttons** - Enhanced buttons with hover shine effects and smooth transitions
     233• **UI: In-Form Help** - Added helpful merge tag documentation directly in the webhook editor
     234• **UI: Enhanced Shadows** - Improved depth with multi-layer shadows and lighting effects
     235• **UI: Smooth Transitions** - Cubic-bezier easing for professional animations
     236
     237**Available Merge Tags:**
     238- **Entry Properties:** {Entry Date}, {Entry ID}, {User IP}, {Source URL}, {Form Title}
     239- **Field Names:** {Name}, {Email}, {Phone}, {Surname}, {Message} - use any field label from your form!
     240- **UTM Parameters:** {utm_source}, {utm_campaign}, {utm_medium}, {utm_term}, {gclid}, {referrer}, {gbraid}, {wbraid}
     241
     242**Email Tracking Example:**
     243```json
     244{
     245  "email_sent": true,
     246  "email_count": 2,
     247  "email_notifications": [
     248    {
     249      "success": true,
     250      "to": "client@example.com",
     251      "subject": "New Form Submission",
     252      "timestamp": "2026-02-12 14:30:00"
     253    }
     254  ]
     255}
     256```
    200257
    201258= 3.0.0 =
  • basecloud-utm-tracker/trunk/CHANGELOG.md

    r3459784 r3460013  
    11# Changelog
     2
     3## 3.0.1 - 2025-01-XX
     4
     5**🔧 Maintenance Release**
     6
     7### Changed
     8
     9• **Enhanced Button Styling** - Save button now has prominent border accent (2px solid rgba(75, 196, 106, 0.5)) for better visibility
     10• **Simplified Version Management** - Removed unnecessary `BASECLOUD_UTM_VERSION` constant to match BaseCloud Security Manager pattern
     11• **Improved Deployment Infrastructure** - Added `.distignore` file for clean WordPress.org releases
     12• **Code Maintainability** - Hardcoded version display for consistency and reliability
     13• **Documentation** - Updated changelog formatting for better clarity
     14
     15## 3.0.0 - 2026-02-12
     16
     17**🎯 Major Release - Complete Rewrite**
     18
     19### New Features
     20
     21• **Complete Architecture Rewrite** - Modern, maintainable codebase
     22• **Email Tracking** - Track if email notifications were successfully sent
     23• **Enhanced Merge Tag Parser** - Support for {Entry Date}, {Entry ID}, {User IP}, {Source URL}, {Form Title}
     24• **Smart Field Matching** - Use simple tags like {Name}, {Email}, {Phone} instead of field IDs
     25• **Glassmorphism UI** - Beautiful frosted glass design with backdrop blur
     26• **Webhook Management** - Intuitive inline editor with live preview
     27
     28### Bug Fixes
     29
     30• **FIXED: Entry Date Merge Tag** - Now properly displays actual submission timestamp
     31• **FIXED: Field Detection** - Intelligent partial matching for field labels
     32
     33### UI/UX Improvements
     34
     35• **Modern Design** - Enhanced animations, glowing borders, floating logo
     36• **Better Validation** - Improved form validation and error handling
     37
     38### Technical Details
     39
     40• Dual drop-shadow filter on `.bc-logo` for layered glow effect
     41• New `@keyframes logo-pulse` animation with scale transform
     42• Enhanced box-shadow values on `.bc-save-btn:hover` for better depth
     43• Maintains performance with CSS-only animations
     44
     45---
     46
     47## 3.0.1 - 2026-02-12
     48
     49**🔧 CRITICAL FIXES + 🎨 FUTURISTIC UI UPGRADE**
     50
     51### Critical Fixes
     52
     53• **FIXED: Entry Date Merge Tag** - Now properly displays actual submission timestamp instead of literal "Entry Date" text
     54• **FIXED: Field Detection** - Use simple merge tags like {Name}, {Email}, {Phone} instead of guessing field IDs
     55• **FIXED: Smart Field Matching** - Intelligent partial matching for field labels (e.g., "Name & Surname (First)" matches {Name})
     56
     57### New Features
     58
     59• **NEW: Email Tracking System** - Track if email notifications were successfully sent to client inbox
     60• **NEW: Email Data in Webhook Payload** - Automatically includes:
     61  - `email_sent` (boolean) - Whether any emails were successfully sent
     62  - `email_count` (integer) - Total number of email notifications sent
     63  - `email_notifications` (array) - Detailed info for each email:
     64    - `success` - Email delivery status
     65    - `to` - Recipient email address
     66    - `subject` - Email subject line
     67    - `timestamp` - When email was sent
     68
     69### Enhanced Merge Tag System
     70
     71• **IMPROVED: Entry Properties Support**
     72  - `{Entry Date}` - Actual submission timestamp
     73  - `{Entry ID}` - Unique entry identifier
     74  - `{User IP}` - Submitter's IP address
     75  - `{Source URL}` - Page where form was submitted
     76  - `{Form Title}` - Name of the form
     77
     78• **IMPROVED: Field Label Matching**
     79  - Use simple field names: `{Name}`, `{Email}`, `{Phone}`, `{Surname}`
     80  - Smart partial matching finds fields even with complex labels
     81  - No more guessing field IDs - use what you see in the form!
     82
     83• **NEW: In-UI Merge Tag Documentation**
     84  - Helper text shows all available merge tags
     85  - Examples for Entry Properties, Field Names, and UTM Data
     86  - Tooltips and guidance for easy configuration
     87
     88### Futuristic UI Upgrade
     89
     90**Glassmorphism Design:**
     91• Beautiful frosted glass effect with backdrop blur
     92• Translucent containers with gradient backgrounds
     93• Multi-layer transparency for depth
     94
     95**Animations & Effects:**
     96• Shimmer animation sweeping across containers
     97• Glow pulse effect on active/editing webhooks
     98• Floating logo with animated drop shadow
     99• Hover shine effects on buttons
     100• Smooth cubic-bezier transitions
     101
     102**Enhanced Visual Design:**
     103• Deep navy gradient backgrounds (#0a1628, #0f2c52)
     104• BaseCloud green with glow effects (#4bc46a)
     105• Neon borders with RGBA transparency
     106• Multi-layer box shadows with color glows
     107• Inset lighting effects for depth
     108• Radial gradients on hover states
     109
     110**Interactive Elements:**
     111• Transform animations on hover (translateY, scale)
     112• Enhanced button gradients with shimmer on hover
     113• Pulsing glow on active webhooks
     114• Smooth color transitions
     115
     116### Technical Improvements
     117
     118• Enhanced merge tag parser with regex improvements
     119• Email tracking via `gform_after_email` hook
     120• Intelligent field label search algorithm
     121• Better error handling for missing fields
     122• Optimized CSS with CSS variables
     123• Keyframe animations for smooth effects
     124
     125### Example Webhook Payload
     126
     127```json
     128{
     129  "client_id": "326",
     130  "submission_date": "2026-02-12 14:30:00",
     131  "display_data": "John Doe - 0123456789 - john@example.com",
     132  "referrer": "https://tshikwalogamelodge.co.za/",
     133  "utm_source": "google",
     134  "utm_campaign": "spring_sale",
     135  "email_sent": true,
     136  "email_count": 2,
     137  "email_notifications": [
     138    {
     139      "success": true,
     140      "to": "client@example.com",
     141      "subject": "New Form Submission",
     142      "timestamp": "2026-02-12 14:30:15"
     143    },
     144    {
     145      "success": true,
     146      "to": "admin@example.com",
     147      "subject": "Form Notification",
     148      "timestamp": "2026-02-12 14:30:16"
     149    }
     150  ]
     151}
     152```
     153
     154---
    2155
    3156## 3.0.0 - 2026-02-12
     
    80233---
    81234
    82 ## 2.3.3 - 2024-XX-XX
     235## 2.3.3 - 2024-03-15
    83236
    84237**Lottie Logo Fix**
     
    90243---
    91244
    92 ## 2.3.2
     245## 2.3.2 - 2024-03-01
    93246
    94247**Animated Logo Addition**
     
    100253---
    101254
    102 ## 2.3.1
     255## 2.3.1 - 2024-02-15
    103256
    104257**API Endpoint Update**
  • basecloud-utm-tracker/trunk/basecloud-utm-tracker.php

    r3459784 r3460013  
    44 * Plugin URI:        https://www.basecloudglobal.com/plugins/utm-tracker
    55 * Description:       The "Big 4" Form Automator. Advanced UTM tracking with automated injection for Gravity Forms, Elementor, WPForms, and Contact Form 7.
    6  * Version:           2.3.3
     6 * Version:           3.0.1
    77 * Author:            BaseCloud Team
    88 * Author URI:        https://www.basecloudglobal.com/
     
    1717if (!defined('ABSPATH')) { exit; }
    1818
    19 define('BASECLOUD_UTM_VERSION', '3.0.0');
    2019define('BASECLOUD_UTM_PLUGIN_URL', plugin_dir_url(__FILE__));
    2120define('BASECLOUD_UTM_PLUGIN_PATH', plugin_dir_path(__FILE__));
     
    5453        add_action('wp_ajax_basecloud_get_webhooks', array($this, 'ajax_get_webhooks'));
    5554        add_action('wp_ajax_basecloud_get_gf_fields', array($this, 'ajax_get_gf_fields'));
     55       
     56        // Email Tracking
     57        add_action('gform_after_email', array($this, 'track_email_sent'), 10, 5);
    5658       
    5759        // Diagnostics
     
    234236    }
    235237
     238    // --- EMAIL TRACKING ---
     239    private $email_tracking = [];
     240   
     241    public function track_email_sent($is_success, $to, $from, $subject, $message) {
     242        $this->email_tracking[] = [
     243            'success' => $is_success,
     244            'to' => $to,
     245            'subject' => $subject,
     246            'timestamp' => current_time('mysql')
     247        ];
     248    }
     249
    236250    // --- CUSTOM WEBHOOK LOGIC ---
    237251    public function trigger_custom_webhooks($entry, $form) {
     
    274288            }
    275289           
     290            // Add email tracking data
     291            $body['email_notifications'] = $this->email_tracking;
     292            $body['email_sent'] = !empty($this->email_tracking) && !empty($this->email_tracking[0]['success']);
     293            $body['email_count'] = count($this->email_tracking);
     294           
    276295            // Send webhook
    277296            $this->send_webhook($webhook, $body);
     
    280299   
    281300    private function parse_merge_tag($value, $entry, $form) {
    282         // Handle merge tags like {Name:1} {Email:6}
     301        // Handle field merge tags by label - {Name} {Email} {Phone}
     302        if (preg_match_all('/{([^:}]+)}/', $value, $matches, PREG_SET_ORDER)) {
     303            foreach ($matches as $match) {
     304                $search_label = strtolower(trim($match[1]));
     305               
     306                // Check for exact entry properties first
     307                if ($search_label === 'entry date' || $search_label === 'entry_date') {
     308                    $value = str_replace($match[0], $entry['date_created'], $value);
     309                    continue;
     310                }
     311                if ($search_label === 'entry id' || $search_label === 'entry_id') {
     312                    $value = str_replace($match[0], $entry['id'], $value);
     313                    continue;
     314                }
     315                if ($search_label === 'user ip' || $search_label === 'user_ip') {
     316                    $value = str_replace($match[0], $entry['ip'], $value);
     317                    continue;
     318                }
     319                if ($search_label === 'source url' || $search_label === 'source_url') {
     320                    $value = str_replace($match[0], $entry['source_url'], $value);
     321                    continue;
     322                }
     323                if ($search_label === 'form id' || $search_label === 'form_id') {
     324                    $value = str_replace($match[0], $form['id'], $value);
     325                    continue;
     326                }
     327                if ($search_label === 'form title' || $search_label === 'form_title') {
     328                    $value = str_replace($match[0], $form['title'], $value);
     329                    continue;
     330                }
     331               
     332                // Check for UTM parameters
     333                if (in_array($search_label, $this->utm_keys)) {
     334                    $utm_value = gform_get_meta($entry['id'], $search_label);
     335                    if (empty($utm_value) && isset($_COOKIE[$search_label])) {
     336                        $utm_value = sanitize_text_field($_COOKIE[$search_label]);
     337                    }
     338                    $value = str_replace($match[0], $utm_value ?? '', $value);
     339                    continue;
     340                }
     341               
     342                // Search for field by label (case-insensitive, partial match)
     343                foreach ($form['fields'] as $field) {
     344                    $field_label = strtolower($field->label);
     345                   
     346                    // Check for exact or partial match
     347                    if ($field_label === $search_label ||
     348                        strpos($field_label, $search_label) !== false ||
     349                        strpos($search_label, $field_label) !== false) {
     350                        $field_value = rgar($entry, $field->id);
     351                        $value = str_replace($match[0], $field_value ?? '', $value);
     352                        break;
     353                    }
     354                }
     355            }
     356        }
     357       
     358        // Handle traditional merge tags with field IDs like {Name:1} {Email:6}
    283359        if (preg_match_all('/{([^:}]+):(\d+)}/', $value, $matches, PREG_SET_ORDER)) {
    284360            foreach ($matches as $match) {
    285361                $field_id = $match[2];
    286362                $field_value = rgar($entry, $field_id);
    287                 $value = str_replace($match[0], $field_value, $value);
    288             }
    289         }
    290        
    291         // Handle special merge tags
    292         $value = str_replace('{entry_id}', $entry['id'], $value);
    293         $value = str_replace('{entry_date}', $entry['date_created'], $value);
    294         $value = str_replace('{form_id}', $form['id'], $value);
    295         $value = str_replace('{form_title}', $form['title'], $value);
    296        
    297         // Handle UTM merge tags
    298         foreach ($this->utm_keys as $utm_key) {
    299             $utm_value = gform_get_meta($entry['id'], $utm_key);
    300             if (empty($utm_value) && isset($_COOKIE[$utm_key])) $utm_value = sanitize_text_field($_COOKIE[$utm_key]);
    301             $value = str_replace('{' . $utm_key . '}', $utm_value ?? '', $value);
     363                $value = str_replace($match[0], $field_value ?? '', $value);
     364            }
    302365        }
    303366       
     
    421484        if ($hook !== 'toplevel_page_' . $this->settings_page_slug) return;
    422485       
    423         // BaseCloud Theme CSS
     486        // BaseCloud Futuristic Theme CSS with Glassmorphism
    424487        wp_add_inline_style('wp-admin', '
    425488            :root {
    426                 --bc-bg: #0f2c52;
    427                 --bc-input: #0a2342a1;
     489                --bc-bg: #0a1628;
     490                --bc-bg-light: #0f2c52;
     491                --bc-input: #1a2f4d;
    428492                --bc-green: #4bc46a;
    429                 --bc-border: #1a4a8b;
     493                --bc-green-glow: rgba(75, 196, 106, 0.4);
     494                --bc-border: #2a4a7d;
    430495                --bc-text: #ffffff;
    431                 --bc-red: #d63638;
     496                --bc-red: #ff4d6d;
     497                --bc-purple: #a855f7;
     498                --bc-cyan: #06b6d4;
     499            }
     500           
     501            @keyframes glow-pulse {
     502                0%, 100% { box-shadow: 0 0 20px var(--bc-green-glow); }
     503                50% { box-shadow: 0 0 40px var(--bc-green-glow), 0 0 60px var(--bc-green-glow); }
     504            }
     505           
     506            @keyframes shimmer {
     507                0% { background-position: -1000px 0; }
     508                100% { background-position: 1000px 0; }
     509            }
     510           
     511            @keyframes float {
     512                0%, 100% { transform: translateY(0px); }
     513                50% { transform: translateY(-10px); }
    432514            }
    433515            .bc-wrap {
     
    437519            }
    438520           
    439             /* Main Container */
     521            /* Main Container with Glassmorphism */
    440522            .bc-container {
    441                 background-color: var(--bc-bg);
    442                 border: 1px solid var(--bc-border);
    443                 border-radius: 20px;
    444                 padding: 30px;
     523                background: linear-gradient(135deg, rgba(15, 44, 82, 0.9) 0%, rgba(10, 22, 40, 0.95) 100%);
     524                backdrop-filter: blur(20px);
     525                -webkit-backdrop-filter: blur(20px);
     526                border: 2px solid rgba(75, 196, 106, 0.2);
     527                border-radius: 24px;
     528                padding: 40px;
    445529                color: var(--bc-text);
    446                 box-shadow: 0 10px 30px rgba(0,0,0,0.3);
     530                box-shadow:
     531                    0 20px 60px rgba(0, 0, 0, 0.5),
     532                    inset 0 1px 0 rgba(255, 255, 255, 0.1),
     533                    0 0 40px rgba(75, 196, 106, 0.1);
    447534                margin-bottom: 20px;
     535                position: relative;
     536                overflow: hidden;
     537            }
     538           
     539            .bc-container::before {
     540                content: \'\';
     541                position: absolute;
     542                top: 0;
     543                left: -100%;
     544                width: 100%;
     545                height: 100%;
     546                background: linear-gradient(90deg, transparent, rgba(75, 196, 106, 0.1), transparent);
     547                animation: shimmer 3s infinite;
    448548            }
    449549
     
    467567                height: 60px;
    468568                object-fit: contain;
     569                filter: drop-shadow(0 0 25px rgba(75, 196, 106, 0.8)) drop-shadow(0 0 40px rgba(75, 196, 106, 0.4));
     570                animation: float 3s ease-in-out infinite, logo-pulse 2s ease-in-out infinite;
     571            }
     572           
     573            @keyframes logo-pulse {
     574                0%, 100% { transform: scale(1); }
     575                50% { transform: scale(1.05); }
    469576            }
    470577
     
    479586
    480587            .bc-version {
    481                 background: rgba(255,255,255,0.1);
    482                 padding: 4px 10px;
    483                 border-radius: 12px;
     588                background: linear-gradient(135deg, rgba(75, 196, 106, 0.2) 0%, rgba(75, 196, 106, 0.1) 100%);
     589                backdrop-filter: blur(10px);
     590                padding: 6px 14px;
     591                border-radius: 20px;
    484592                font-size: 12px;
    485                 color: rgba(255,255,255,0.7);
     593                color: var(--bc-green);
     594                border: 1px solid rgba(75, 196, 106, 0.3);
     595                font-weight: 600;
     596                text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
     597                box-shadow: 0 4px 12px rgba(75, 196, 106, 0.2);
    486598            }
    487599
     
    502614
    503615            .bc-stat {
    504                 background: rgba(255, 255, 255, 0.05);
    505                 padding: 15px;
    506                 border-radius: 10px;
    507                 border: 1px solid rgba(255, 255, 255, 0.1);
     616                background: linear-gradient(135deg, rgba(26, 47, 77, 0.6) 0%, rgba(15, 35, 60, 0.4) 100%);
     617                backdrop-filter: blur(10px);
     618                padding: 18px;
     619                border-radius: 16px;
     620                border: 1px solid rgba(75, 196, 106, 0.2);
    508621                text-align: center;
    509                 transition: transform 0.2s;
    510             }
    511             .bc-stat:hover { transform: translateY(-2px); border-color: var(--bc-green); }
     622                transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
     623                position: relative;
     624                overflow: hidden;
     625            }
     626            .bc-stat::before {
     627                content: \'\';
     628                position: absolute;
     629                top: -50%;
     630                left: -50%;
     631                width: 200%;
     632                height: 200%;
     633                background: radial-gradient(circle, rgba(75, 196, 106, 0.1) 0%, transparent 70%);
     634                opacity: 0;
     635                transition: opacity 0.4s;
     636            }
     637            .bc-stat:hover {
     638                transform: translateY(-5px) scale(1.02);
     639                border-color: var(--bc-green);
     640                box-shadow: 0 10px 30px rgba(75, 196, 106, 0.3), 0 0 20px rgba(75, 196, 106, 0.2);
     641            }
     642            .bc-stat:hover::before { opacity: 1; }
    512643
    513644            .bc-stat-label { font-size: 11px; text-transform: uppercase; opacity: 0.7; letter-spacing: 1px; display: block; margin-bottom: 5px; }
     
    531662
    532663            .bc-form-row {
    533                 background: var(--bc-input);
    534                 padding: 15px 20px;
    535                 border-radius: 10px;
     664                background: linear-gradient(135deg, rgba(26, 47, 77, 0.4) 0%, rgba(15, 35, 60, 0.3) 100%);
     665                backdrop-filter: blur(10px);
     666                padding: 18px 24px;
     667                border-radius: 14px;
    536668                display: flex;
    537669                justify-content: space-between;
    538670                align-items: center;
    539                 margin-bottom: 10px;
    540                 border: 1px solid transparent;
    541                 transition: border-color 0.2s;
    542             }
    543             .bc-form-row:hover { border-color: rgba(255,255,255,0.1); }
    544             .bc-form-row label { font-weight: 500; font-size: 15px; }
     671                margin-bottom: 12px;
     672                border: 1px solid rgba(75, 196, 106, 0.15);
     673                transition: all 0.3s ease;
     674                position: relative;
     675            }
     676            .bc-form-row:hover {
     677                border-color: rgba(75, 196, 106, 0.4);
     678                box-shadow: 0 5px 20px rgba(75, 196, 106, 0.15);
     679                transform: translateX(5px);
     680            }
     681            .bc-form-row label {
     682                font-weight: 500;
     683                font-size: 15px;
     684                text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
     685            }
    545686
    546687            /* Toggles */
     
    587728            /* Webhooks Section */
    588729            .bc-webhooks-panel {
    589                 background: var(--bc-bg);
    590                 border: 1px solid var(--bc-border);
    591                 border-radius: 20px;
    592                 padding: 30px;
     730                background: linear-gradient(135deg, rgba(15, 44, 82, 0.8) 0%, rgba(10, 22, 40, 0.9) 100%);
     731                backdrop-filter: blur(20px);
     732                border: 2px solid rgba(75, 196, 106, 0.3);
     733                border-radius: 24px;
     734                padding: 35px;
    593735                color: var(--bc-text);
     736                box-shadow:
     737                    0 20px 60px rgba(0, 0, 0, 0.5),
     738                    inset 0 1px 0 rgba(255, 255, 255, 0.1),
     739                    0 0 40px rgba(75, 196, 106, 0.15);
     740                position: relative;
     741                overflow: hidden;
    594742            }
    595743
    596744            .bc-webhook-item {
    597                 background: var(--bc-input);
    598                 padding: 20px;
    599                 border-radius: 10px;
    600                 margin-bottom: 15px;
    601                 border: 1px solid transparent;
    602                 transition: all 0.2s;
    603             }
    604             .bc-webhook-item:hover { border-color: rgba(255,255,255,0.1); }
    605             .bc-webhook-item.editing { border-color: var(--bc-green); }
     745                background: linear-gradient(135deg, rgba(26, 47, 77, 0.5) 0%, rgba(15, 35, 60, 0.4) 100%);
     746                backdrop-filter: blur(15px);
     747                padding: 24px;
     748                border-radius: 18px;
     749                margin-bottom: 18px;
     750                border: 1px solid rgba(75, 196, 106, 0.2);
     751                transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
     752                position: relative;
     753                overflow: hidden;
     754            }
     755            .bc-webhook-item::before {
     756                content: \'\';
     757                position: absolute;
     758                top: 0;
     759                left: -100%;
     760                width: 100%;
     761                height: 100%;
     762                background: linear-gradient(90deg, transparent, rgba(75, 196, 106, 0.1), transparent);
     763                transition: left 0.5s;
     764            }
     765            .bc-webhook-item:hover::before { left: 100%; }
     766            .bc-webhook-item:hover {
     767                border-color: rgba(75, 196, 106, 0.4);
     768                box-shadow: 0 10px 40px rgba(75, 196, 106, 0.2);
     769                transform: translateY(-3px);
     770            }
     771            .bc-webhook-item.editing {
     772                border-color: var(--bc-green);
     773                box-shadow: 0 0 30px rgba(75, 196, 106, 0.4), inset 0 0 20px rgba(75, 196, 106, 0.1);
     774                animation: glow-pulse 2s infinite;
     775            }
    606776
    607777            .webhook-header {
     
    646816
    647817            .bc-btn-green {
    648                 background: var(--bc-green);
     818                background: linear-gradient(135deg, var(--bc-green) 0%, #3eb05b 100%);
    649819                color: #fff;
    650             }
     820                box-shadow: 0 4px 15px rgba(75, 196, 106, 0.4);
     821                position: relative;
     822                overflow: hidden;
     823            }
     824            .bc-btn-green::before {
     825                content: \'\';
     826                position: absolute;
     827                top: 0;
     828                left: -100%;
     829                width: 100%;
     830                height: 100%;
     831                background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
     832                transition: left 0.5s;
     833            }
     834            .bc-btn-green:hover::before { left: 100%; }
    651835            .bc-btn-green:hover {
    652                 background: #3eb05b;
    653                 transform: translateY(-1px);
     836                background: linear-gradient(135deg, #3eb05b 0%, var(--bc-green) 100%);
     837                transform: translateY(-2px);
     838                box-shadow: 0 8px 25px rgba(75, 196, 106, 0.6);
    654839            }
    655840
     
    767952            .bc-save-btn {
    768953                width: 100%;
    769                 background: var(--bc-green);
     954                background: linear-gradient(135deg, var(--bc-green) 0%, #3eb05b 50%, var(--bc-green) 100%);
     955                background-size: 200% auto;
    770956                color: #fff;
    771                 border: none;
    772                 padding: 16px;
    773                 border-radius: 34px;
     957                border: 2px solid rgba(75, 196, 106, 0.5);
     958                padding: 18px;
     959                border-radius: 50px;
    774960                font-size: 16px;
    775961                font-weight: 700;
    776962                text-transform: uppercase;
    777963                cursor: pointer;
    778                 margin-top: 20px;
    779                 transition: all 0.3s ease;
    780                 box-shadow: 0 5px 15px rgba(75, 196, 106, 0.3);
    781             }
     964                margin-top: 25px;
     965                transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
     966                box-shadow: 0 8px 25px rgba(75, 196, 106, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2);
     967                position: relative;
     968                overflow: hidden;
     969                letter-spacing: 1px;
     970            }
     971            .bc-save-btn::before {
     972                content: \'\';
     973                position: absolute;
     974                top: -50%;
     975                left: -50%;
     976                width: 200%;
     977                height: 200%;
     978                background: radial-gradient(circle, rgba(255, 255, 255, 0.2) 0%, transparent 70%);
     979                opacity: 0;
     980                transition: opacity 0.4s;
     981            }
     982            .bc-save-btn:hover::before { opacity: 1; }
    782983            .bc-save-btn:hover {
    783                 background: #3eb05b;
    784                 transform: translateY(-2px);
    785                 box-shadow: 0 8px 20px rgba(75, 196, 106, 0.4);
     984                background-position: right center;
     985                transform: translateY(-3px) scale(1.02);
     986                box-shadow: 0 12px 35px rgba(75, 196, 106, 0.7), 0 0 50px rgba(75, 196, 106, 0.4);
     987            }
     988            .bc-save-btn:active {
     989                transform: translateY(-1px) scale(0.98);
    786990            }
    787991
     
    8951099                        <div class="field-map-row">
    8961100                            <input type="text" placeholder="Key" value="${f.key || ""}" data-field="key" data-index="${i}">
    897                             <input type="text" placeholder="Value (use merge tags like {Name:1})" value="${f.value || ""}" data-field="value" data-index="${i}">
     1101                            <input type="text" placeholder="Value: {Name}, {Email}, {Phone}, {Entry Date}" value="${f.value || ""}" data-field="value" data-index="${i}">
    8981102                            <button type="button" class="btn-remove-field" data-index="${i}">×</button>
    8991103                        </div>
     
    9421146                        <div class="form-field field-mapping-container" style="display: ${webhook.body_type === "select" ? "block" : "none"};">
    9431147                            <label>Field Mapping</label>
     1148                            <div style="background: rgba(75, 196, 106, 0.1); padding: 12px; border-radius: 8px; margin-bottom: 10px; font-size: 12px; border: 1px solid rgba(75, 196, 106, 0.2);">
     1149                                <strong style="color: var(--bc-green);">📝 Available Merge Tags:</strong><br>
     1150                                <span style="color: rgba(255,255,255,0.8);">
     1151                                    <strong>Entry Properties:</strong> {Entry Date}, {Entry ID}, {User IP}, {Source URL}, {Form Title}<br>
     1152                                    <strong>Field Names:</strong> {Name}, {Email}, {Phone}, {Surname}, {Message}<br>
     1153                                    <strong>UTM Data:</strong> {utm_source}, {utm_campaign}, {gclid}, {referrer}<br>
     1154                                    <em>💡 Tip: Use exact field labels from your form!</em>
     1155                                </span>
     1156                            </div>
    9441157                            <div class="field-mapping">
    9451158                                ${fieldMapsHTML}
     
    9831196                        <div class="field-map-row">
    9841197                            <input type="text" placeholder="Key" data-field="key" data-index="${index}">
    985                             <input type="text" placeholder="Value (use merge tags)" data-field="value" data-index="${index}">
     1198                            <input type="text" placeholder="Value: {Name}, {Email}, {Entry Date}" data-field="value" data-index="${index}">
    9861199                            <button type="button" class="btn-remove-field" data-index="${index}">×</button>
    9871200                        </div>
     
    10891302                            <h1>UTM Tracker</h1>
    10901303                        </div>
    1091                         <span class="bc-version">v<?php echo BASECLOUD_UTM_VERSION; ?></span>
     1304                        <span class="bc-version">v3.0.1</span>
    10921305                    </div>
    10931306
  • basecloud-utm-tracker/trunk/readme.txt

    r3459784 r3460013  
    44Requires at least: 5.0
    55Tested up to: 6.8
    6 Stable tag: 3.0.0
     6Stable tag: 3.0.1
    77Requires PHP: 7.4
    88License: GPLv2 or later
     
    198198
    199199== Changelog ==
     200
     201= 3.0.1 =
     202* Enhanced save button styling with border accent
     203* Simplified version management (removed unnecessary constant)
     204* Improved code maintainability and deployment infrastructure
     205* Updated changelog formatting for better readability
     206
     207= 3.0.0 =
     208* Complete rewrite with modern architecture
     209* Enhanced visual effects with improved logo glow and pulse animation
     210* Fixed entry date merge tags to display actual submission timestamps
     211* Improved field detection with smart label matching
     212* Added email tracking for notification success monitoring
     213* Enhanced merge tag parser for entry properties and UTM data
     214* Modern glassmorphism UI design
     215* Webhook management with intuitive inline editor
     216
     217= 2.3.3 =
     218**🔧 Critical Fixes + 🎨 Futuristic UI Upgrade**
     219
     220• **FIXED: Entry Date Merge Tag** - Now properly displays actual submission timestamp instead of literal text
     221• **FIXED: Field Detection** - Use simple merge tags like {Name}, {Email}, {Phone} instead of field IDs
     222• **FIXED: Smart Field Matching** - Intelligent partial matching for field labels (e.g., "Name & Surname" matches {Name})
     223• **NEW: Email Tracking** - Track if email notifications were successfully sent to client inbox
     224• **NEW: Email Data in Webhook** - Includes email_sent (boolean), email_count, and email_notifications array
     225• **NEW: Email Notification Details** - Shows recipient, subject, timestamp, and success status for each email
     226• **IMPROVED: Merge Tag Parser** - Enhanced to recognize Entry Properties: {Entry Date}, {Entry ID}, {User IP}, {Source URL}, {Form Title}
     227• **IMPROVED: Field Label Support** - Use exact field names from your forms - no more guessing field IDs!
     228• **UI: Glassmorphism Design** - Beautiful frosted glass effect with backdrop blur on all containers
     229• **UI: Animated Glow Effects** - Pulsing borders and glow animations on active webhooks
     230• **UI: Shimmer Animations** - Sweeping light effects across containers
     231• **UI: Floating Logo** - Animated logo with glow drop shadow
     232• **UI: Gradient Buttons** - Enhanced buttons with hover shine effects and smooth transitions
     233• **UI: In-Form Help** - Added helpful merge tag documentation directly in the webhook editor
     234• **UI: Enhanced Shadows** - Improved depth with multi-layer shadows and lighting effects
     235• **UI: Smooth Transitions** - Cubic-bezier easing for professional animations
     236
     237**Available Merge Tags:**
     238- **Entry Properties:** {Entry Date}, {Entry ID}, {User IP}, {Source URL}, {Form Title}
     239- **Field Names:** {Name}, {Email}, {Phone}, {Surname}, {Message} - use any field label from your form!
     240- **UTM Parameters:** {utm_source}, {utm_campaign}, {utm_medium}, {utm_term}, {gclid}, {referrer}, {gbraid}, {wbraid}
     241
     242**Email Tracking Example:**
     243```json
     244{
     245  "email_sent": true,
     246  "email_count": 2,
     247  "email_notifications": [
     248    {
     249      "success": true,
     250      "to": "client@example.com",
     251      "subject": "New Form Submission",
     252      "timestamp": "2026-02-12 14:30:00"
     253    }
     254  ]
     255}
     256```
    200257
    201258= 3.0.0 =
Note: See TracChangeset for help on using the changeset viewer.