Plugin Directory

Changeset 2383010


Ignore:
Timestamp:
09/16/2020 03:40:21 PM (6 years ago)
Author:
clickervolt
Message:

1.166

  • Added template for Awin affiliate network
  • Added support for vendors' sales notifications in WarriorPlus IPN
  • Added [geo-country-code] dynamic token
  • Added [session] dynamic token for email marketers. A session can be restored by appending session=XXX to your tracking links, where XXX is the session value returned by [session]
  • Added handling of parallel tracking for Microsoft Ads traffic (you must enable auto-tagging in your MS Ads account: https://help.ads.microsoft.com/#apex/3/en/60000/2)
Location:
clickervolt/trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • clickervolt/trunk/admin/js/affiliate-networks.js

    r2357258 r2383010  
    8080            AffiliateNetworkHelper.registerNetwork(new AffiliateNetwork("Affise", "sub2", "{sub2}", "{status}-{transactionid}", "{sum}"));
    8181            AffiliateNetworkHelper.registerNetwork(new AffiliateNetwork("AIVIX", "aff_sub", "{aff_sub}", "{transaction_id}", "{cost}"));
     82            AffiliateNetworkHelper.registerNetwork(new AffiliateNetwork("Awin", "clickref", "!!!clickRef!!!", "!!!transactionId!!!", "!!!commission!!!"));
    8283            AffiliateNetworkHelper.registerNetwork(new AffiliateNetwork("BeeOption", "aff_sub", "{aff_sub}", "{transaction_id}", "{payout}"));
    8384            AffiliateNetworkHelper.registerNetwork(new AffiliateNetwork("Big Bang Ads", "aff_sub", "{aff_sub}", "{transaction_id}", "{payout}"));
  • clickervolt/trunk/clickervolt.php

    r2357258 r2383010  
    55 * Plugin URI:  https://clickervolt.com/
    66 * Description: Advanced click tracking, link cloaking and affiliate campaigns management made easy.
    7  * Version:     1.163
     7 * Version:     1.166
    88 * Author:      ClickerVolt.com
    99 * License:     GPLv3
    1010 * License URI: https://www.gnu.org/licenses/gpl-3.0.html
    1111 *
    12   */
    13 
     12 */
    1413namespace ClickerVolt;
    1514
     
    2524// TODO: add pause time to time tracking (when tab not visible)
    2625// TODO: for future traffic source auto-optim, check if these sources have API: propellerads, popads, popcash, plugrush
    27 
    28 if (!defined('ABSPATH')) {
     26if ( !defined( 'ABSPATH' ) ) {
    2927    exit;
    3028}
    3129
    32 if (function_exists('\ClickerVolt\cli_fs')) {
    33     cli_fs()->set_basename(true, __FILE__);
     30if ( function_exists( '\\ClickerVolt\\cli_fs' ) ) {
     31    cli_fs()->set_basename( false, __FILE__ );
    3432    return;
    3533}
     
    5452require_once __DIR__ . '/db/tableSourceTemplates.php';
    5553require_once __DIR__ . '/utils/dataProxy.php';
    56 
    57 add_action('plugins_loaded', ['ClickerVolt\\Setup', 'onLoaded']);
    58 add_action('rest_api_init', ['ClickerVolt\\Api', 'registerRoutes']);
    59 
    60 add_action('rest_api_init', function () {
     54add_action( 'plugins_loaded', [ 'ClickerVolt\\Setup', 'onLoaded' ] );
     55add_action( 'rest_api_init', [ 'ClickerVolt\\Api', 'registerRoutes' ] );
     56add_action( 'rest_api_init', function () {
    6157    // We want to register 'wp_unique_post_slug' early to be able to intercept post inserts/updates
    62     add_filter('wp_unique_post_slug', function ($slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug) {
    63         $link = DataProxy::getLink($slug);
    64         if ($link != null) {
    65             if ($post_status != AjaxLinks::STATUS_SLUG_CHECKING || $link->getId() != $post_ID) {
     58    add_filter(
     59        'wp_unique_post_slug',
     60        function (
     61        $slug,
     62        $post_ID,
     63        $post_status,
     64        $post_type,
     65        $post_parent,
     66        $original_slug
     67    ) {
     68        $link = DataProxy::getLink( $slug );
     69        if ( $link != null ) {
     70            if ( $post_status != AjaxLinks::STATUS_SLUG_CHECKING || $link->getId() != $post_ID ) {
    6671                // A link with this slug already exists... can't create post with that one.
    6772                // Generate a random slug instead.
     
    7075        }
    7176        return $slug;
    72     }, 10, 6);
    73 });
     77    },
     78        10,
     79        6
     80    );
     81} );
    7482
    75 if (is_admin() || defined('DOING_AJAX') || defined('DOING_CRON')) {
    76 
    77     register_activation_hook(__FILE__, ['ClickerVolt\\Setup', 'onActivate']);
    78     register_deactivation_hook(__FILE__, ['ClickerVolt\\Setup', 'onDeactivate']);
    79     register_uninstall_hook(__FILE__, ['ClickerVolt\\Setup', 'onDelete']);
    80 
    81     add_action('admin_enqueue_scripts', ['ClickerVolt\\Setup', 'enqueueScripts']);
    82     add_action('admin_menu', ['ClickerVolt\\Setup', 'addMainMenu']);
    83     add_action('in_admin_footer', ['ClickerVolt\\Setup', 'addFooterElements']);
    84 
     83if ( is_admin() || defined( 'DOING_AJAX' ) || defined( 'DOING_CRON' ) ) {
     84    register_activation_hook( __FILE__, [ 'ClickerVolt\\Setup', 'onActivate' ] );
     85    register_deactivation_hook( __FILE__, [ 'ClickerVolt\\Setup', 'onDeactivate' ] );
     86    register_uninstall_hook( __FILE__, [ 'ClickerVolt\\Setup', 'onDelete' ] );
     87    add_action( 'admin_enqueue_scripts', [ 'ClickerVolt\\Setup', 'enqueueScripts' ] );
     88    add_action( 'admin_menu', [ 'ClickerVolt\\Setup', 'addMainMenu' ] );
     89    add_action( 'in_admin_footer', [ 'ClickerVolt\\Setup', 'addFooterElements' ] );
    8590    // Ajax actions
    86 
    87     add_action('wp_ajax_clickervolt_save_link', ['ClickerVolt\\AjaxLinks', 'saveLinkAjax']);
    88     add_action('wp_ajax_clickervolt_get_link', ['ClickerVolt\\AjaxLinks', 'getLinkAjax']);
    89     add_action('wp_ajax_clickervolt_get_link_by_slug', ['ClickerVolt\\AjaxLinks', 'getLinkBySlugAjax']);
    90     add_action('wp_ajax_clickervolt_delete_link_by_slug', ['ClickerVolt\\AjaxLinks', 'deleteLinkBySlugAjax']);
    91     add_action('wp_ajax_clickervolt_get_all_slugs', ['ClickerVolt\\AjaxLinks', 'getAllSlugsAjax']);
    92     add_action('wp_ajax_clickervolt_get_aida_script_template', ['ClickerVolt\\AjaxLinks', 'getAIDAScriptTemplateAjax']);
    93     add_action('wp_ajax_clickervolt_save_source_template', ['ClickerVolt\\AjaxSources', 'saveSourceAjax']);
    94     add_action('wp_ajax_clickervolt_get_sources', ['ClickerVolt\\AjaxSources', 'getAllSourcesAjax']);
    95     add_action('wp_ajax_clickervolt_delete_source_template', ['ClickerVolt\\AjaxSources', 'deleteSourceAjax']);
    96     add_action('wp_ajax_clickervolt_process_clicks_queue', ['ClickerVolt\\AjaxStats', 'processClicksQueueAjax']);
    97     add_action('wp_ajax_clickervolt_get_stats', ['ClickerVolt\\AjaxStats', 'getStatsAjax']);
    98     add_action('wp_ajax_clickervolt_get_clicklog', ['ClickerVolt\\AjaxStats', 'getClickLogAjax']);
    99     add_action('wp_ajax_clickervolt_get_all_custom_reports', ['ClickerVolt\\AjaxStats', 'getAllCustomReportsAjax']);
    100     add_action('wp_ajax_clickervolt_save_custom_report', ['ClickerVolt\\AjaxStats', 'saveCustomReportsAjax']);
    101     add_action('wp_ajax_clickervolt_delete_custom_report', ['ClickerVolt\\AjaxStats', 'deleteCustomReportAjax']);
    102     add_action('wp_ajax_clickervolt_purge_all_stats', ['ClickerVolt\\AjaxStats', 'purgeAllStatsAjax']);
    103     add_action('wp_ajax_clickervolt_purge_raw_clicks', ['ClickerVolt\\AjaxStats', 'purgeRAWClicksAjax']);
    104     add_action('wp_ajax_clickervolt_search_isps', ['ClickerVolt\\AjaxSearches', 'searchISPsAjax']);
    105     add_action('wp_ajax_clickervolt_search_regions', ['ClickerVolt\\AjaxSearches', 'searchRegionsAjax']);
    106     add_action('wp_ajax_clickervolt_search_cities', ['ClickerVolt\\AjaxSearches', 'searchCitiesAjax']);
    107     add_action('wp_ajax_clickervolt_search_device_names', ['ClickerVolt\\AjaxSearches', 'searchDeviceNamesAjax']);
    108     add_action('wp_ajax_clickervolt_save_settings', ['ClickerVolt\\AjaxCVSettings', 'saveAjax']);
    109     add_action('wp_ajax_clickervolt_load_rss', ['ClickerVolt\\AjaxFeed', 'loadRSSAjax']);
    110 
     91    add_action( 'wp_ajax_clickervolt_save_link', [ 'ClickerVolt\\AjaxLinks', 'saveLinkAjax' ] );
     92    add_action( 'wp_ajax_clickervolt_get_link', [ 'ClickerVolt\\AjaxLinks', 'getLinkAjax' ] );
     93    add_action( 'wp_ajax_clickervolt_get_link_by_slug', [ 'ClickerVolt\\AjaxLinks', 'getLinkBySlugAjax' ] );
     94    add_action( 'wp_ajax_clickervolt_delete_link_by_slug', [ 'ClickerVolt\\AjaxLinks', 'deleteLinkBySlugAjax' ] );
     95    add_action( 'wp_ajax_clickervolt_get_all_slugs', [ 'ClickerVolt\\AjaxLinks', 'getAllSlugsAjax' ] );
     96    add_action( 'wp_ajax_clickervolt_get_aida_script_template', [ 'ClickerVolt\\AjaxLinks', 'getAIDAScriptTemplateAjax' ] );
     97    add_action( 'wp_ajax_clickervolt_save_source_template', [ 'ClickerVolt\\AjaxSources', 'saveSourceAjax' ] );
     98    add_action( 'wp_ajax_clickervolt_get_sources', [ 'ClickerVolt\\AjaxSources', 'getAllSourcesAjax' ] );
     99    add_action( 'wp_ajax_clickervolt_delete_source_template', [ 'ClickerVolt\\AjaxSources', 'deleteSourceAjax' ] );
     100    add_action( 'wp_ajax_clickervolt_process_clicks_queue', [ 'ClickerVolt\\AjaxStats', 'processClicksQueueAjax' ] );
     101    add_action( 'wp_ajax_clickervolt_get_stats', [ 'ClickerVolt\\AjaxStats', 'getStatsAjax' ] );
     102    add_action( 'wp_ajax_clickervolt_get_clicklog', [ 'ClickerVolt\\AjaxStats', 'getClickLogAjax' ] );
     103    add_action( 'wp_ajax_clickervolt_get_all_custom_reports', [ 'ClickerVolt\\AjaxStats', 'getAllCustomReportsAjax' ] );
     104    add_action( 'wp_ajax_clickervolt_save_custom_report', [ 'ClickerVolt\\AjaxStats', 'saveCustomReportsAjax' ] );
     105    add_action( 'wp_ajax_clickervolt_delete_custom_report', [ 'ClickerVolt\\AjaxStats', 'deleteCustomReportAjax' ] );
     106    add_action( 'wp_ajax_clickervolt_purge_all_stats', [ 'ClickerVolt\\AjaxStats', 'purgeAllStatsAjax' ] );
     107    add_action( 'wp_ajax_clickervolt_purge_raw_clicks', [ 'ClickerVolt\\AjaxStats', 'purgeRAWClicksAjax' ] );
     108    add_action( 'wp_ajax_clickervolt_search_isps', [ 'ClickerVolt\\AjaxSearches', 'searchISPsAjax' ] );
     109    add_action( 'wp_ajax_clickervolt_search_regions', [ 'ClickerVolt\\AjaxSearches', 'searchRegionsAjax' ] );
     110    add_action( 'wp_ajax_clickervolt_search_cities', [ 'ClickerVolt\\AjaxSearches', 'searchCitiesAjax' ] );
     111    add_action( 'wp_ajax_clickervolt_search_device_names', [ 'ClickerVolt\\AjaxSearches', 'searchDeviceNamesAjax' ] );
     112    add_action( 'wp_ajax_clickervolt_save_settings', [ 'ClickerVolt\\AjaxCVSettings', 'saveAjax' ] );
     113    add_action( 'wp_ajax_clickervolt_load_rss', [ 'ClickerVolt\\AjaxFeed', 'loadRSSAjax' ] );
    111114    // Crons
    112 
    113     add_filter('cron_schedules', function ($schedules) {
    114 
     115    add_filter( 'cron_schedules', function ( $schedules ) {
    115116        $schedules['clickervolt_one_minute'] = array(
    116117            'interval' => 60,
    117             'display'  => esc_html__('Each Minute'),
     118            'display'  => esc_html__( 'Each Minute' ),
    118119        );
    119 
    120120        $schedules['clickervolt_once_per_week'] = array(
    121121            'interval' => 60 * 60 * 24 * 7,
    122             'display'  => esc_html__('Once per Week'),
     122            'display'  => esc_html__( 'Once per Week' ),
    123123        );
    124 
    125124        return $schedules;
    126     });
    127 
    128     add_action('clickervolt_cron_clicks_queue', ['ClickerVolt\\Cron', 'processClicksQueue']);
    129     if (!wp_next_scheduled('clickervolt_cron_clicks_queue')) {
    130         wp_schedule_event(time(), 'clickervolt_one_minute', 'clickervolt_cron_clicks_queue');
     125    } );
     126    add_action( 'clickervolt_cron_clicks_queue', [ 'ClickerVolt\\Cron', 'processClicksQueue' ] );
     127    if ( !wp_next_scheduled( 'clickervolt_cron_clicks_queue' ) ) {
     128        wp_schedule_event( time(), 'clickervolt_one_minute', 'clickervolt_cron_clicks_queue' );
    131129    }
    132 
    133     add_action('clickervolt_cron_maxmind_update_dbs', ['ClickerVolt\\Cron', 'maxmindUpdate']);
    134     if (!wp_next_scheduled('clickervolt_cron_maxmind_update_dbs')) {
    135         wp_schedule_event(time(), 'clickervolt_once_per_week', 'clickervolt_cron_maxmind_update_dbs');
     130    add_action( 'clickervolt_cron_maxmind_update_dbs', [ 'ClickerVolt\\Cron', 'maxmindUpdate' ] );
     131    if ( !wp_next_scheduled( 'clickervolt_cron_maxmind_update_dbs' ) ) {
     132        wp_schedule_event( time(), 'clickervolt_once_per_week', 'clickervolt_cron_maxmind_update_dbs' );
    136133    }
    137134}
  • clickervolt/trunk/db/db.php

    r2357258 r2383010  
    1111class DB
    1212{
    13     const VERSION = 1.163;
     13    const VERSION = 1.166;
    1414
    1515    const OPTION_VERSION = 'clickervolt-version';
  • clickervolt/trunk/db/objects/parallelId.php

    r2164283 r2383010  
    1616    static $urlTriggerVars = [
    1717        'gclid',
     18        'msclkid',
    1819    ];
    1920
  • clickervolt/trunk/db/tablePurgeable.php

    r2314546 r2383010  
    77abstract class TablePurgeable extends Table
    88{
    9     function purge()
     9    function purge($restricToColumnName = null, $restrictToColumnValue = null)
    1010    {
    1111        global $wpdb;
    1212        $tableName = $this->wpTableName($this->getName());
    13         $wpdb->query("truncate table {$tableName}");
     13        if ($restricToColumnName !== null && $restrictToColumnValue !== null) {
     14            $wpdb->query("delete from {$tableName} where {$restricToColumnName} = '{$restrictToColumnValue}'");
     15        } else {
     16            $wpdb->query("truncate table {$tableName}");
     17        }
    1418    }
    1519}
  • clickervolt/trunk/pixel/ipn/warriorplus.php

    r2357258 r2383010  
    1515    static function getVendorSaleProcessor()
    1616    {
    17         return new IPNConversionProcessor('WP_SALE', 'WP_SALE_AMOUNT', 'WP_HOP_SID');
     17        return new IPNConversionProcessor('WP_SALE', 'WP_SALE_EARNINGS_VENDOR', 'WP_HOP_SID');
    1818    }
    1919}
  • clickervolt/trunk/readme.txt

    r2357291 r2383010  
    11=== ClickerVolt - Affiliate Links & Click Tracking for Performance Marketers ===
    2 Contributors: clickervolt
     2Contributors: clickervolt, freemius
    33Tags: affiliate, affiliate link management, link, link cloaker, link redirect, affiliate links, click tracking, link tracking, shortlink, url, page cloaker, cloaker, cloaking, redirect, redirection, drilldown, stats, statistics, marketing, aida
    44Requires at least: 4.9
     
    9999* etc...
    100100
    101 ClickerVolt works with the new Google Ads parallel tracking out of the box. It is actually one of the only trackers working with Google Ads parallel tracking.
     101ClickerVolt works with the new Google Ads and Microsoft Ads parallel tracking out of the box. It is actually one of the only trackers working with parallel tracking.
    102102
    103103== AIDA Metrics: Our Unique Selling Point ==
     
    196196* Affise
    197197* AIVIX
     198* Awin
    198199* BeeOption
    199200* Big Bang Ads
     
    284285
    285286== Changelog ==
     287= 1.166 =
     288* Added template for Awin affiliate network
     289* Added support for vendors' sales notifications in WarriorPlus IPN
     290* Added [geo-country-code] dynamic token
     291* Added [session] dynamic token for email marketers. A session can be restored by appending session=XXX to your tracking links, where XXX is the session value returned by [session]
     292* Added handling of parallel tracking for Microsoft Ads traffic (you must enable auto-tagging in your MS Ads account: https://help.ads.microsoft.com/#apex/3/en/60000/2)
     293
    286294= 1.163 =
    287295* All dynamic tokens such as [geo-country] can now be used in HTML/Javascript and PHP hooks
  • clickervolt/trunk/redirect/dynamicTokens.php

    r2314546 r2383010  
    88{
    99    const TOKEN_CID = '[cid]';
     10    const TOKEN_COUNTRY_CODE = '[geo-country-code]';
    1011    const TOKEN_COUNTRY = '[geo-country]';
    1112    const TOKEN_REGION = '[geo-region]';
     
    3738    const TOKEN_V10 = '[v10]';
    3839    const TOKEN_EXTERNAL_ID = '[external-id]';
     40    const TOKEN_SESSION = '[session]';
    3941
    4042    const TOKENS = [
    4143        self::TOKEN_CID,
     44        self::TOKEN_COUNTRY_CODE,
    4245        self::TOKEN_COUNTRY,
    4346        self::TOKEN_REGION,
     
    6972        self::TOKEN_V10,
    7073        self::TOKEN_EXTERNAL_ID,
     74        self::TOKEN_SESSION,
    7175    ];
    7276
     
    9397                            break;
    9498
     99                        case self::TOKEN_COUNTRY_CODE: {
     100                                $geoIp = $this->getGeoIP();
     101                                $replacePairs[$token] = $geoIp->getCountryCode();
     102                            }
     103                            break;
     104
    95105                        case self::TOKEN_COUNTRY: {
    96106                                require_once __DIR__ . '/../utils/countryCodes.php';
     
    252262                        case self::TOKEN_EXTERNAL_ID: {
    253263                                $replacePairs[$token] = $clickInfo->getExternalId();
     264                            }
     265                            break;
     266
     267                        case self::TOKEN_SESSION: {
     268                                $replacePairs[$token] = Session::getSessionId();
    254269                            }
    255270                            break;
  • clickervolt/trunk/redirect/session/session.php

    r2164283 r2383010  
    2929    function __construct()
    3030    {
    31         if (session_status() == PHP_SESSION_NONE) {
    32             $sessionId = null;
     31        if (!self::$sessionId && session_status() == PHP_SESSION_NONE) {
     32            self::$sessionId = null;
    3333
    3434            require_once __DIR__ . '/../../db/objects/parallelId.php';
    3535            $pidParam = ParallelId::fromURLOrParams(null, $_GET);
    3636            if ($pidParam) {
    37                 $sessionId = md5($pidParam->getValue());
     37                self::$sessionId = md5($pidParam->getValue());
    3838            }
    3939
    40             if (!$sessionId) {
     40            if (!self::$sessionId) {
    4141                if (isset($_GET[self::URL_SESSION_KEY])) {
    42                     $sessionId = $_GET[self::URL_SESSION_KEY];
     42                    self::$sessionId = $_GET[self::URL_SESSION_KEY];
    4343                } else {
    44                     $sessionId = filter_input(INPUT_COOKIE, self::COOKIE_NAME);
     44                    self::$sessionId = filter_input(INPUT_COOKIE, self::COOKIE_NAME);
    4545                }
    4646            }
    4747
    48             if (!$sessionId) {
     48            if (!self::$sessionId) {
    4949                require_once __DIR__ . '/../../utils/ipTools.php';
    5050                $footprints = [];
     
    5252                $footprints[] = empty($_SERVER['HTTP_USER_AGENT']) ? '' : $_SERVER['HTTP_USER_AGENT'];
    5353                $footprints[] = empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? '' : $_SERVER['HTTP_ACCEPT_LANGUAGE'];
    54                 $sessionId = md5(implode('|', $footprints));
     54                self::$sessionId = md5(implode('|', $footprints));
    5555            }
    5656
    57             if ($sessionId) {
    58                 session_id($sessionId);
     57            if (self::$sessionId) {
     58                session_id(self::$sessionId);
    5959            }
    6060
     
    6868        }
    6969    }
     70
     71    static function getSessionId()
     72    {
     73        return self::$sessionId;
     74    }
     75
     76    static private $sessionId = null;
    7077}
  • clickervolt/trunk/utils/remote.php

    r2241036 r2383010  
    4949
    5050        require_once __DIR__ . '/fileTools.php';
     51        require_once __DIR__ . '/urlTools.php';
    5152
    5253        $c = curl_init();
Note: See TracChangeset for help on using the changeset viewer.