Changeset 3464601
- Timestamp:
- 02/18/2026 07:10:37 PM (6 weeks ago)
- Location:
- firstpromoter
- Files:
-
- 27 added
- 4 edited
-
tags/0.3.1 (added)
-
tags/0.3.1/assets (added)
-
tags/0.3.1/assets/css (added)
-
tags/0.3.1/assets/css/admin.css (added)
-
tags/0.3.1/assets/css/index.php (added)
-
tags/0.3.1/assets/index.php (added)
-
tags/0.3.1/assets/js (added)
-
tags/0.3.1/assets/js/admin.js (added)
-
tags/0.3.1/assets/js/custom-forms.js (added)
-
tags/0.3.1/assets/js/index.php (added)
-
tags/0.3.1/firstpromoter.php (added)
-
tags/0.3.1/includes (added)
-
tags/0.3.1/includes/class-fp-helpers.php (added)
-
tags/0.3.1/includes/class-fp-settings-page.php (added)
-
tags/0.3.1/includes/index.php (added)
-
tags/0.3.1/index.php (added)
-
tags/0.3.1/integrations (added)
-
tags/0.3.1/integrations/class-fp-integration-base.php (added)
-
tags/0.3.1/integrations/class-fp-integration-contactform7.php (added)
-
tags/0.3.1/integrations/class-fp-integration-customforms.php (added)
-
tags/0.3.1/integrations/class-fp-integration-memberpress.php (added)
-
tags/0.3.1/integrations/class-fp-integration-optimizepress.php (added)
-
tags/0.3.1/integrations/class-fp-integration-urlcapture.php (added)
-
tags/0.3.1/integrations/class-fp-integration-woocommerce.php (added)
-
tags/0.3.1/integrations/index.php (added)
-
tags/0.3.1/readme.txt (added)
-
trunk/firstpromoter.php (modified) (2 diffs)
-
trunk/includes/class-fp-settings-page.php (modified) (4 diffs)
-
trunk/integrations/class-fp-integration-base.php (modified) (1 diff)
-
trunk/integrations/class-fp-integration-urlcapture.php (added)
-
trunk/readme.txt (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
firstpromoter/trunk/firstpromoter.php
r3458122 r3464601 32 32 require_once FIRSTPROMOTER_PLUGIN_PATH . 'integrations/class-fp-integration-memberpress.php'; 33 33 require_once FIRSTPROMOTER_PLUGIN_PATH . 'integrations/class-fp-integration-customforms.php'; 34 require_once FIRSTPROMOTER_PLUGIN_PATH . 'integrations/class-fp-integration-urlcapture.php'; 34 35 35 36 class FirstPromoter_Core … … 242 243 } 243 244 245 // URL Email Capture integration - always available (no plugin dependency) 246 if ( 247 isset($integration_settings['url_capture_enabled']) && 248 $integration_settings['url_capture_enabled'] 249 ) { 250 new FirstPromoter_Integration_UrlCapture($integration_settings); 251 } 252 244 253 do_action('firstpromoter_load_integrations', $integration_settings, $this->available_integrations); 245 254 } -
firstpromoter/trunk/includes/class-fp-settings-page.php
r3458128 r3464601 107 107 'enabled_key' => 'custom_forms_enabled', 108 108 ], 109 'options' => [], 110 'custom_content' => true, 111 'description' => 'Track email submissions from any form on your site using CSS selectors. Works with any form builder, custom HTML forms, or dynamically loaded popups.', 109 'options' => [], 110 'custom_content_type' => 'custom_forms', 111 'description' => 'Track email submissions from any form on your site using CSS selectors. Works with any form builder, custom HTML forms, or dynamically loaded popups.', 112 ]; 113 114 // URL Email Capture - always available (no plugin dependency) 115 $this->availableIntegrations['UrlCapture'] = [ 116 'title' => 'URL Email Capture', 117 'settings' => [ 118 'enabled_key' => 'url_capture_enabled', 119 ], 120 'options' => [], 121 'custom_content_type' => 'url_capture', 122 'description' => 'Capture referrals from thank you pages where the email (and optionally a user ID) is passed as a URL query parameter. Useful when your checkout or funnel redirects to a confirmation page with the email in the URL.', 112 123 ]; 113 124 } … … 321 332 </div> 322 333 323 <?php if (!empty($integration['custom_content'])): ?> 324 <?php 325 $saved_forms = isset($this->integration_settings['custom_forms']) ? $this->integration_settings['custom_forms'] : array(); 326 if (empty($saved_forms)) { 327 $saved_forms = array(array('email_selector' => '', 'submit_selector' => '')); 328 } 329 $has_multiple = count($saved_forms) > 1; 330 ?> 331 <div class="fp-custom-forms-repeater"> 332 <p class="firstpromoter_label" style="margin-top: 12px;">Form Selectors</p> 333 <div class="fp-custom-form-rows"> 334 <?php foreach ($saved_forms as $idx => $form_row): ?> 335 <div class="fp-custom-form-row"<?php if ($idx > 0 && !$has_multiple) echo ' style="display:none"'; ?>> 336 <div class="fp-custom-form-fields"> 337 <input type="text" 338 name="firstpromoter_integration_settings[custom_forms][<?php echo (int) $idx; ?>][email_selector]" 339 value="<?php echo esc_attr(isset($form_row['email_selector']) ? $form_row['email_selector'] : ''); ?>" 340 placeholder="Email input selector, e.g. #signup-email" 341 class="fp-input regular-text"> 342 <input type="text" 343 name="firstpromoter_integration_settings[custom_forms][<?php echo (int) $idx; ?>][submit_selector]" 344 value="<?php echo esc_attr(isset($form_row['submit_selector']) ? $form_row['submit_selector'] : ''); ?>" 345 placeholder="Submit selector, e.g. #signup-btn or form.my-form" 346 class="fp-input regular-text"> 334 <?php if (!empty($integration['custom_content_type'])): ?> 335 <?php if ($integration['custom_content_type'] === 'custom_forms'): ?> 336 <?php 337 $saved_forms = isset($this->integration_settings['custom_forms']) ? $this->integration_settings['custom_forms'] : array(); 338 if (empty($saved_forms)) { 339 $saved_forms = array(array('email_selector' => '', 'submit_selector' => '')); 340 } 341 $has_multiple = count($saved_forms) > 1; 342 ?> 343 <div class="fp-custom-forms-repeater"> 344 <p class="firstpromoter_label" style="margin-top: 12px;">Form Selectors</p> 345 <div class="fp-custom-form-rows"> 346 <?php foreach ($saved_forms as $idx => $form_row): ?> 347 <div class="fp-custom-form-row"<?php if ($idx > 0 && !$has_multiple) echo ' style="display:none"'; ?>> 348 <div class="fp-custom-form-fields"> 349 <input type="text" 350 name="firstpromoter_integration_settings[custom_forms][<?php echo (int) $idx; ?>][email_selector]" 351 value="<?php echo esc_attr(isset($form_row['email_selector']) ? $form_row['email_selector'] : ''); ?>" 352 placeholder="Email input selector, e.g. #signup-email" 353 class="fp-input regular-text"> 354 <input type="text" 355 name="firstpromoter_integration_settings[custom_forms][<?php echo (int) $idx; ?>][submit_selector]" 356 value="<?php echo esc_attr(isset($form_row['submit_selector']) ? $form_row['submit_selector'] : ''); ?>" 357 placeholder="Submit selector, e.g. #signup-btn or form.my-form" 358 class="fp-input regular-text"> 359 </div> 360 <button type="button" class="fp-remove-form-row" title="Remove row"<?php if (!$has_multiple) echo ' style="display:none"'; ?>>×</button> 347 361 </div> 348 <button type="button" class="fp-remove-form-row" title="Remove row"<?php if (!$has_multiple) echo ' style="display:none"'; ?>>×</button> 349 </div> 350 <?php endforeach; ?> 362 <?php endforeach; ?> 363 </div> 364 <div class="fp-multiple-forms-toggle" style="margin-top: 8px;"> 365 <label style="display: flex; align-items: center; gap: 8px; font-size: 14px; color: #374151;"> 366 <input type="checkbox" class="fp-multiple-forms-checkbox" <?php checked($has_multiple); ?>> 367 I have multiple forms to track 368 </label> 369 </div> 370 <button type="button" class="fp-add-form-row"<?php if (!$has_multiple) echo ' style="display:none"'; ?>>+ Add Another Form</button> 371 <p class="description" style="margin-top: 10px;"> 372 Enter a CSS selector for the email input and either a form element or submit button.<br> 373 Examples: <code>#signup-email</code> / <code>#signup-btn</code> — <code>.popup-email</code> / <code>form.popup-form</code> 374 </p> 351 375 </div> 352 <div class="fp-multiple-forms-toggle" style="margin-top: 8px;"> 353 <label style="display: flex; align-items: center; gap: 8px; font-size: 14px; color: #374151;"> 354 <input type="checkbox" class="fp-multiple-forms-checkbox" <?php checked($has_multiple); ?>> 355 I have multiple forms to track 356 </label> 376 <?php elseif ($integration['custom_content_type'] === 'url_capture'): ?> 377 <div class="fp-url-capture-fields" style="margin-top: 12px;"> 378 <div class="fp-form-field" style="margin-bottom: 12px;"> 379 <label class="firstpromoter_label">Email URL Parameter Key</label> 380 <input type="text" 381 name="firstpromoter_integration_settings[url_email_param]" 382 value="<?php echo esc_attr(isset($this->integration_settings['url_email_param']) ? $this->integration_settings['url_email_param'] : ''); ?>" 383 placeholder="e.g. email" 384 class="fp-input regular-text"> 385 <p class="description">The URL query parameter name that contains the email. For <code>?email=user@example.com</code> enter <code>email</code>.</p> 386 </div> 387 <div class="fp-form-field"> 388 <label class="firstpromoter_label">UID URL Parameter Key <span style="color:#888; font-weight:400;">(optional)</span></label> 389 <input type="text" 390 name="firstpromoter_integration_settings[url_uid_param]" 391 value="<?php echo esc_attr(isset($this->integration_settings['url_uid_param']) ? $this->integration_settings['url_uid_param'] : ''); ?>" 392 placeholder="e.g. uid" 393 class="fp-input regular-text"> 394 <p class="description">The URL query parameter name that contains the user ID, if applicable. For <code>?uid=12345</code> enter <code>uid</code>.</p> 395 </div> 357 396 </div> 358 <button type="button" class="fp-add-form-row"<?php if (!$has_multiple) echo ' style="display:none"'; ?>>+ Add Another Form</button> 359 <p class="description" style="margin-top: 10px;"> 360 Enter a CSS selector for the email input and either a form element or submit button.<br> 361 Examples: <code>#signup-email</code> / <code>#signup-btn</code> — <code>.popup-email</code> / <code>form.popup-form</code> 362 </p> 363 </div> 397 <?php endif; ?> 364 398 <?php endif; ?> 365 399 </div> … … 384 418 385 419 // Sanitize toggle checkboxes 386 $toggle_keys = ['woo_enabled', 'op_enabled', 'cf7_enabled', 'mepr_enabled', 'custom_forms_enabled' ];420 $toggle_keys = ['woo_enabled', 'op_enabled', 'cf7_enabled', 'mepr_enabled', 'custom_forms_enabled', 'url_capture_enabled']; 387 421 foreach ($toggle_keys as $key) { 388 422 $sanitized[$key] = isset($input[$key]) ? 1 : 0; … … 400 434 $sanitized[$key] = isset($input[$key]) ? 1 : 0; 401 435 } 436 437 // Sanitize URL capture params 438 $sanitized['url_email_param'] = sanitize_text_field(isset($input['url_email_param']) ? $input['url_email_param'] : ''); 439 $sanitized['url_uid_param'] = sanitize_text_field(isset($input['url_uid_param']) ? $input['url_uid_param'] : ''); 402 440 403 441 // Sanitize custom form selectors -
firstpromoter/trunk/integrations/class-fp-integration-base.php
r3458122 r3464601 101 101 * @param mixed $userId 102 102 */ 103 pr ivatefunction enqueue_ajax_fallback($email, $userId)103 protected function enqueue_ajax_fallback($email, $userId) 104 104 { 105 105 $callback = function () use ($email, $userId) { -
firstpromoter/trunk/readme.txt
r3458128 r3464601 4 4 Requires at least: 5.0 5 5 Tested up to: 6.9 6 Stable tag: 0.3. 06 Stable tag: 0.3.1 7 7 Requires PHP: 5.6 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html 10 10 11 Integrate FirstPromoter's affiliate tracking with WooCommerce, OptimizePress, Contact Form 7, and MemberPress.11 Integrate FirstPromoter's affiliate tracking with WooCommerce, OptimizePress, Contact Form 7, MemberPress, and any custom form or thank you page. 12 12 13 13 == Description == … … 24 24 * Contact Form 7 integration - track form submissions with email capture 25 25 * MemberPress integration - track member signups, transactions, and recurring payments 26 * Custom Form Tracking - track email submissions from any form using CSS selectors 27 * URL Email Capture - capture referrals from thank you pages where the email is in the URL 26 28 * Cross-domain tracking support 27 29 * Automatically send sales data to FirstPromoter (WooCommerce, MemberPress) 28 30 * Automatic refund and cancellation tracking (WooCommerce) 29 31 * Track recurring subscription payments (MemberPress) 32 * Force tracking bypass for privacy browsers and ad-blockers 30 33 31 34 = WooCommerce Integration = … … 64 67 **Important**: If you're using FirstPromoter's Stripe integration, only enable signup tracking. Leave sale tracking OFF to avoid duplicate sales. 65 68 69 = Custom Form Tracking = 70 71 When enabled, the Custom Form Tracking integration allows you to: 72 73 * Track email submissions from any form on your site — no plugin dependency required 74 * Works with any form builder, custom HTML forms, or dynamically loaded popups 75 * Configure CSS selector pairs: one for the email input, one for the submit button or form element 76 * Supports multiple forms with separate selector pairs 77 * Uses MutationObserver to handle dynamically loaded forms (popups, AJAX-injected content) 78 * AJAX fallback for ad-blocker bypass when force tracking is enabled 79 80 = URL Email Capture = 81 82 When enabled, the URL Email Capture integration allows you to: 83 84 * Track referrals from thank you pages where the email is passed as a URL query parameter 85 * Useful when your checkout, funnel, or external platform redirects to a confirmation page with the customer's email in the URL (e.g. `/thank-you?email=user@example.com`) 86 * Configure the URL parameter key for the email (e.g. `email`) 87 * Optionally configure a second parameter key for the user ID (e.g. `uid`) 88 * No plugin dependency required — works on any WordPress page 89 66 90 67 91 == Installation == … … 109 133 3. **Contact Form 7 Integration**: Track contact form submissions with email capture 110 134 4. **MemberPress Integration**: Track member signups, transactions, and recurring payments 135 5. **Custom Form Tracking**: Track email submissions from any form using CSS selectors 136 6. **URL Email Capture**: Capture referrals from thank you pages where the email is in the URL 111 137 112 138 Enable the integrations that apply to your website and configure their specific settings. … … 130 156 = Does this work with other plugins? = 131 157 132 Currently, this plugin has specific integrations for WooCommerce, OptimizePress, Contact Form 7, and MemberPress. Additional integrations may be added in future updates. 158 The plugin has specific integrations for WooCommerce, OptimizePress, Contact Form 7, and MemberPress. The Custom Form Tracking and URL Email Capture integrations work with any platform — no additional plugin required. 159 160 = How do I use URL Email Capture? = 161 162 Enable the "URL Email Capture" integration and enter the URL parameter name that contains the email on your thank you page. For example, if your thank you page URL looks like `/thank-you?email=user@example.com`, enter `email` in the Email URL Parameter Key field. Optionally enter a second parameter name for the user ID. 133 163 134 164 = What information is sent to FirstPromoter? = … … 150 180 151 181 == Changelog == 182 183 = 0.3.1 = 184 * New: URL Email Capture integration — capture referrals from thank you pages where the email (and optionally a user ID) is passed as a URL query parameter 185 * Configurable parameter key names for both email and UID 152 186 153 187 = 0.3.0 = … … 202 236 == Upgrade Notice == 203 237 238 = 0.3.1 = 239 New: URL Email Capture integration — track referrals from thank you pages where the customer email is in the URL. 240 204 241 = 0.3.0 = 205 242 Removed Guzzle dependency, now uses WordPress native HTTP functions. PHP requirement lowered to 5.6. Multiple bug fixes for WooCommerce double-tracking and OptimizePress JS errors.
Note: See TracChangeset
for help on using the changeset viewer.