Plugin Directory

Changeset 3464601


Ignore:
Timestamp:
02/18/2026 07:10:37 PM (6 weeks ago)
Author:
maxwellfp
Message:

v0.3.1

Location:
firstpromoter
Files:
27 added
4 edited

Legend:

Unmodified
Added
Removed
  • firstpromoter/trunk/firstpromoter.php

    r3458122 r3464601  
    3232require_once FIRSTPROMOTER_PLUGIN_PATH . 'integrations/class-fp-integration-memberpress.php';
    3333require_once FIRSTPROMOTER_PLUGIN_PATH . 'integrations/class-fp-integration-customforms.php';
     34require_once FIRSTPROMOTER_PLUGIN_PATH . 'integrations/class-fp-integration-urlcapture.php';
    3435
    3536class FirstPromoter_Core
     
    242243        }
    243244
     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
    244253        do_action('firstpromoter_load_integrations', $integration_settings, $this->available_integrations);
    245254    }
  • firstpromoter/trunk/includes/class-fp-settings-page.php

    r3458128 r3464601  
    107107                'enabled_key' => 'custom_forms_enabled',
    108108            ],
    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.',
    112123        ];
    113124    }
     
    321332                                            </div>
    322333
    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"'; ?>>&times;</button>
    347361                                                                </div>
    348                                                                 <button type="button" class="fp-remove-form-row" title="Remove row"<?php if (!$has_multiple) echo ' style="display:none"'; ?>>&times;</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> &mdash; <code>.popup-email</code> / <code>form.popup-form</code>
     374                                                        </p>
    351375                                                    </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>
    357396                                                    </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> &mdash; <code>.popup-email</code> / <code>form.popup-form</code>
    362                                                     </p>
    363                                                 </div>
     397                                                <?php endif; ?>
    364398                                            <?php endif; ?>
    365399                                        </div>
     
    384418
    385419        // 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'];
    387421        foreach ($toggle_keys as $key) {
    388422            $sanitized[$key] = isset($input[$key]) ? 1 : 0;
     
    400434            $sanitized[$key] = isset($input[$key]) ? 1 : 0;
    401435        }
     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'] : '');
    402440
    403441        // Sanitize custom form selectors
  • firstpromoter/trunk/integrations/class-fp-integration-base.php

    r3458122 r3464601  
    101101     * @param mixed $userId
    102102     */
    103     private function enqueue_ajax_fallback($email, $userId)
     103    protected function enqueue_ajax_fallback($email, $userId)
    104104    {
    105105        $callback = function () use ($email, $userId) {
  • firstpromoter/trunk/readme.txt

    r3458128 r3464601  
    44Requires at least: 5.0
    55Tested up to: 6.9
    6 Stable tag: 0.3.0
     6Stable tag: 0.3.1
    77Requires PHP: 5.6
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1010
    11 Integrate FirstPromoter's affiliate tracking with WooCommerce, OptimizePress, Contact Form 7, and MemberPress.
     11Integrate FirstPromoter's affiliate tracking with WooCommerce, OptimizePress, Contact Form 7, MemberPress, and any custom form or thank you page.
    1212
    1313== Description ==
     
    2424* Contact Form 7 integration - track form submissions with email capture
    2525* 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
    2628* Cross-domain tracking support
    2729* Automatically send sales data to FirstPromoter (WooCommerce, MemberPress)
    2830* Automatic refund and cancellation tracking (WooCommerce)
    2931* Track recurring subscription payments (MemberPress)
     32* Force tracking bypass for privacy browsers and ad-blockers
    3033
    3134= WooCommerce Integration =
     
    6467**Important**: If you're using FirstPromoter's Stripe integration, only enable signup tracking. Leave sale tracking OFF to avoid duplicate sales.
    6568
     69= Custom Form Tracking =
     70
     71When 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
     82When 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
    6690
    6791== Installation ==
     
    1091333. **Contact Form 7 Integration**: Track contact form submissions with email capture
    1101344. **MemberPress Integration**: Track member signups, transactions, and recurring payments
     1355. **Custom Form Tracking**: Track email submissions from any form using CSS selectors
     1366. **URL Email Capture**: Capture referrals from thank you pages where the email is in the URL
    111137
    112138Enable the integrations that apply to your website and configure their specific settings.
     
    130156= Does this work with other plugins? =
    131157
    132 Currently, this plugin has specific integrations for WooCommerce, OptimizePress, Contact Form 7, and MemberPress. Additional integrations may be added in future updates.
     158The 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
     162Enable 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.
    133163
    134164= What information is sent to FirstPromoter? =
     
    150180
    151181== 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
    152186
    153187= 0.3.0 =
     
    202236== Upgrade Notice ==
    203237
     238= 0.3.1 =
     239New: URL Email Capture integration — track referrals from thank you pages where the customer email is in the URL.
     240
    204241= 0.3.0 =
    205242Removed 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.