Popup by Supsystic - Version 1.9.2

Version Description

/ 19.04.2017 * Added Age Verification templates detailed statistics * Fixed issue with propagandizing cached stats for AB Test PopUps * Fix small issue with ConstantContact subscribe service * Core code improvements and minor issues fix

Download this release

Release Info

Developer supsystic.com
Plugin Icon 128x128 Popup by Supsystic
Version 1.9.2
Comparing to
See all releases

Code changes from version 1.9.3 to 1.9.2

classes/html.php CHANGED
@@ -289,7 +289,7 @@ class htmlPps {
289
  static public function radiobutton($name, $params = array('attrs' => '', 'value' => '', 'checked' => '')) {
290
  $params['type'] = 'radio';
291
  $params['attrs'] = isset($params['attrs']) ? $params['attrs'] : '';
292
- if(isset($params['checked']) && $params['checked'])
293
  $params['attrs'] .= ' checked';
294
  return self::input($name, $params);
295
  }
289
  static public function radiobutton($name, $params = array('attrs' => '', 'value' => '', 'checked' => '')) {
290
  $params['type'] = 'radio';
291
  $params['attrs'] = isset($params['attrs']) ? $params['attrs'] : '';
292
+ if($params['checked'])
293
  $params['attrs'] .= ' checked';
294
  return self::input($name, $params);
295
  }
classes/response.php CHANGED
@@ -22,7 +22,7 @@ class responsePps {
22
  if(count($this->errors) > 0)
23
  $this->error = true;
24
  if($isAjax || $forceAjax)
25
- exit( json_encode_utf_normal($this) );
26
  /*if($redirect)
27
  redirectPps($redirect);*/
28
  return $this;
22
  if(count($this->errors) > 0)
23
  $this->error = true;
24
  if($isAjax || $forceAjax)
25
+ exit( json_encode($this) );
26
  /*if($redirect)
27
  redirectPps($redirect);*/
28
  return $this;
config.php CHANGED
@@ -48,7 +48,7 @@
48
  define('PPS_EOL', "\n");
49
 
50
  define('PPS_PLUGIN_INSTALLED', true);
51
- define('PPS_VERSION', '1.9.3');
52
  define('PPS_USER', 'user');
53
 
54
  define('PPS_CLASS_PREFIX', 'ppsc');
48
  define('PPS_EOL', "\n");
49
 
50
  define('PPS_PLUGIN_INSTALLED', true);
51
+ define('PPS_VERSION', '1.9.2');
52
  define('PPS_USER', 'user');
53
 
54
  define('PPS_CLASS_PREFIX', 'ppsc');
modules/options/mod.php CHANGED
@@ -40,7 +40,6 @@ class optionsPps extends modulePps {
40
  return $this->getView()->getAdminPage();
41
  } else {
42
  installerPps::setUsed(); // Show this welcome page - only one time
43
- framePps::_()->getModule('supsystic_promo')->getModel()->bigStatAdd('Welcome Show');
44
  return framePps::_()->getModule('supsystic_promo')->showWelcomePage();
45
  }
46
  }
40
  return $this->getView()->getAdminPage();
41
  } else {
42
  installerPps::setUsed(); // Show this welcome page - only one time
 
43
  return framePps::_()->getModule('supsystic_promo')->showWelcomePage();
44
  }
45
  }
modules/popup/models/popup.php CHANGED
@@ -143,7 +143,6 @@ class popupModelPps extends modelPps {
143
  if(!empty($d['original_id'])) {
144
  $original = $this->getById($d['original_id']);
145
  framePps::_()->getModule('supsystic_promo')->getModel()->saveUsageStat('create_from_tpl.'. strtolower(str_replace(' ', '-', $original['label'])));
146
- framePps::_()->getModule('supsystic_promo')->getModel()->bigStatAddCheck('Used Template', array('Selected Template' => $original['label']));
147
  unset($original['id']);
148
  $original['label'] = $d['label'];
149
  $original['original_id'] = $d['original_id'];
@@ -437,7 +436,6 @@ class popupModelPps extends modelPps {
437
  // Save main settings - as they should not influence for display settings
438
  $this->_assignKeyArr($currentPopup, $newTpl, 'params.main');
439
  framePps::_()->getModule('supsystic_promo')->getModel()->saveUsageStat('change_to_tpl.'. strtolower(str_replace(' ', '-', $newTpl['label'])));
440
- framePps::_()->getModule('supsystic_promo')->getModel()->bigStatAddCheck('Used Template', array('Changed to Template' => $newTpl['label']));
441
  $newTpl['original_id'] = $newTpl['id']; // It will be our new original
442
  $newTpl['id'] = $currentPopup['id'];
443
  $newTpl['label'] = $currentPopup['label'];
143
  if(!empty($d['original_id'])) {
144
  $original = $this->getById($d['original_id']);
145
  framePps::_()->getModule('supsystic_promo')->getModel()->saveUsageStat('create_from_tpl.'. strtolower(str_replace(' ', '-', $original['label'])));
 
146
  unset($original['id']);
147
  $original['label'] = $d['label'];
148
  $original['original_id'] = $d['original_id'];
436
  // Save main settings - as they should not influence for display settings
437
  $this->_assignKeyArr($currentPopup, $newTpl, 'params.main');
438
  framePps::_()->getModule('supsystic_promo')->getModel()->saveUsageStat('change_to_tpl.'. strtolower(str_replace(' ', '-', $newTpl['label'])));
 
439
  $newTpl['original_id'] = $newTpl['id']; // It will be our new original
440
  $newTpl['id'] = $currentPopup['id'];
441
  $newTpl['label'] = $currentPopup['label'];
modules/popup/views/popup.php CHANGED
@@ -306,15 +306,8 @@ class popupViewPps extends viewPps {
306
  uasort($tabs, array($this, 'sortEditPopupTabsClb'));
307
  $this->assign('tabs', $tabs);
308
  dispatcherPps::doAction('beforePopupEditRender', $popup);
309
- $this->_initBigDataStats();
310
  return parent::getContent('popupEditAdmin');
311
  }
312
- private function _initBigDataStats() {
313
- $canSend = (int) framePps::_()->getModule('options')->get('send_stats');
314
- if( $canSend ) {
315
- framePps::_()->getModule('supsystic_promo')->connectItemEditStats();
316
- }
317
- }
318
  public function showEditPopupFormControls() {
319
  parent::display('popupEditFormControls');
320
  }
306
  uasort($tabs, array($this, 'sortEditPopupTabsClb'));
307
  $this->assign('tabs', $tabs);
308
  dispatcherPps::doAction('beforePopupEditRender', $popup);
 
309
  return parent::getContent('popupEditAdmin');
310
  }
 
 
 
 
 
 
311
  public function showEditPopupFormControls() {
312
  parent::display('popupEditFormControls');
313
  }
modules/popup/views/tpl/popupEditAdmin.php CHANGED
@@ -1,6 +1,6 @@
1
  <div id="ppsPopupEditTabs">
2
  <section class="supsystic-bar supsystic-sticky sticky-padd-next sticky-save-width sticky-base-width-auto" data-prev-height="#supsystic-breadcrumbs" data-next-padding-add="15">
3
- <h3 class="nav-tab-wrapper ppsMainTabsNav" style="margin-bottom: 0px; margin-top: 12px;">
4
  <?php $i = 0;?>
5
  <?php foreach($this->tabs as $tKey => $tData) { ?>
6
  <?php
1
  <div id="ppsPopupEditTabs">
2
  <section class="supsystic-bar supsystic-sticky sticky-padd-next sticky-save-width sticky-base-width-auto" data-prev-height="#supsystic-breadcrumbs" data-next-padding-add="15">
3
+ <h3 class="nav-tab-wrapper" style="margin-bottom: 0px; margin-top: 12px;">
4
  <?php $i = 0;?>
5
  <?php foreach($this->tabs as $tKey => $tData) { ?>
6
  <?php
modules/supsystic_promo/controller.php CHANGED
@@ -118,14 +118,6 @@ class supsystic_promoControllerPps extends controllerPps {
118
  $res->pushError($this->getModel()->getErrors());
119
  $res->ajaxExec();
120
  }
121
- public function saveDeactivateData() {
122
- $res = new responsePps();
123
- if($this->getModel()->saveDeactivateData(reqPps::get('post'))) {
124
- $res->addMessage(__('Thank you for Feedback!', PPS_LANG_CODE));
125
- } else
126
- $res->pushError($this->getModel()->getErrors());
127
- $res->ajaxExec();
128
- }
129
  /**
130
  * @see controller::getPermissions();
131
  */
@@ -133,7 +125,7 @@ class supsystic_promoControllerPps extends controllerPps {
133
  return array(
134
  PPS_USERLEVELS => array(
135
  PPS_ADMIN => array('welcomePageSaveInfo', 'sendContact', 'addNoticeAction',
136
- 'addStep', 'closeTour', 'addTourFinish', 'saveDeactivateData')
137
  ),
138
  );
139
  }
118
  $res->pushError($this->getModel()->getErrors());
119
  $res->ajaxExec();
120
  }
 
 
 
 
 
 
 
 
121
  /**
122
  * @see controller::getPermissions();
123
  */
125
  return array(
126
  PPS_USERLEVELS => array(
127
  PPS_ADMIN => array('welcomePageSaveInfo', 'sendContact', 'addNoticeAction',
128
+ 'addStep', 'closeTour', 'addTourFinish')
129
  ),
130
  );
131
  }
modules/supsystic_promo/js/admin.item.edit.stats.js DELETED
@@ -1,72 +0,0 @@
1
- (function(e,a){if(!a.__SV){var b=window;try{var c,l,i,j=b.location,g=j.hash;c=function(a,b){return(l=a.match(RegExp(b+"=([^&]*)")))?l[1]:null};g&&c(g,"state")&&(i=JSON.parse(decodeURIComponent(c(g,"state"))),"mpeditor"===i.action&&(b.sessionStorage.setItem("_mpcehash",g),history.replaceState(i.desiredHash||"",e.title,j.pathname+j.search)))}catch(m){}var k,h;window.mixpanel=a;a._i=[];a.init=function(b,c,f){function e(b,a){var c=a.split(".");2==c.length&&(b=b[c[0]],a=c[1]);b[a]=function(){b.push([a].concat(Array.prototype.slice.call(arguments,
2
- 0)))}}var d=a;"undefined"!==typeof f?d=a[f]=[]:f="mixpanel";d.people=d.people||[];d.toString=function(b){var a="mixpanel";"mixpanel"!==f&&(a+="."+f);b||(a+=" (stub)");return a};d.people.toString=function(){return d.toString(1)+".people (stub)"};k="disable time_event track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config reset people.set people.set_once people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" ");
3
- for(h=0;h<k.length;h++)e(d,k[h]);a._i.push([b,c,f])};a.__SV=1.2;b=e.createElement("script");b.type="text/javascript";b.async=!0;b.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?MIXPANEL_CUSTOM_LIB_URL:"file:"===e.location.protocol&&"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)?"https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";c=e.getElementsByTagName("script")[0];c.parentNode.insertBefore(b,c)}})(document,window.mixpanel||[]);
4
- mixpanel.init("3cc36628768f1f84d4c6980d09ced036");
5
- jQuery(document).ready(function(){
6
- if(typeof(mixpanel) !== 'undefined') {
7
- // Main tabs navigation
8
- var $manTabsNav = jQuery('#ppsPopupEditTabs .ppsMainTabsNav');
9
- mixpanel.track('PopUp Edit Tab', {
10
- 'Active Tab': $manTabsNav.find('.nav-tab-active .ppsPopupTabTitle').text()
11
- });
12
- $manTabsNav.find('.nav-tab').click(function(){
13
- mixpanel.track('PopUp Edit Tab', {
14
- 'Active Tab': jQuery(this).find('.ppsPopupTabTitle').text()
15
- });
16
- });
17
- // Main opts stats collection
18
- _ppsBigDataMainOpt('params[main][show_on]', 'When to show PopUp');
19
- _ppsBigDataMainOpt('params[main][close_on]', 'When to close PopUp');
20
- _ppsBigDataMainOpt('params[main][show_pages]', 'Show on next pages');
21
- _ppsBigDataMainOpt('params[main][show_to]', 'Whom to show');
22
- // PRO version links clicks
23
- if(!PPS_DATA.isPro) {
24
- // Wait until all links will be inited
25
- setTimeout(function(){
26
- jQuery('a[href^="'+ PPS_DATA.mainLink+ '"]').click(function(){
27
- var href = jQuery(this).attr('href');
28
- if(href) {
29
- var urlQuery = href.split('?')
30
- , utmParam = '';
31
- if(urlQuery && urlQuery[ 1 ]) {
32
- var queryParams = parseStr( urlQuery[ 1 ] );
33
- if(queryParams && queryParams['utm_medium']) {
34
- utmParam = queryParams['utm_medium'];
35
- }
36
- }
37
- if(!utmParam) {
38
- utmParam = 'Not Specified';
39
- }
40
- mixpanel.track('Pro Link Click', {
41
- 'UTM Param': utmParam
42
- });
43
- }
44
- });
45
- }, 500);
46
- }
47
- }
48
- });
49
- function _ppsBigDataMainOpt( inpName, label ) {
50
- var $inp = jQuery('#ppsPopupEditForm [name="'+ inpName+ '"]');
51
- mixpanel.track(label, {
52
- 'Selected Opt': __ppsBigDataOptToLabel( $inp.filter(':checked') )
53
- });
54
- // Avoid auto startup changes trigger collection
55
- setTimeout(function(){
56
- $inp.change(function(){
57
- var $this = jQuery(this);
58
- if($this.prop('checked')) {
59
- mixpanel.track(label, {
60
- 'Selected Opt': __ppsBigDataOptToLabel( $this )
61
- });
62
- }
63
- });
64
- }, 500);
65
- }
66
- function __ppsBigDataOptToLabel( $opt ) {
67
- var $label = $opt.parents('label:first');
68
- if(!$label || !$label.size()) {
69
- $label = $opt.parents('.ppsPopupMainOptLbl:first');
70
- }
71
- return jQuery.trim($label.text());
72
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/supsystic_promo/js/admin.plugins.js DELETED
@@ -1,49 +0,0 @@
1
- jQuery(document).ready(function(){
2
- var $deactivateLnk = jQuery('#the-list tr[data-slug="'+ ppsPluginsData.plugSlug+ '"] .row-actions .deactivate a');
3
- if($deactivateLnk && $deactivateLnk.size()) {
4
- var $deactivateForm = jQuery('#ppsDeactivateForm');
5
- var $deactivateWnd = jQuery('#ppsDeactivateWnd').dialog({
6
- modal: true
7
- , autoOpen: false
8
- , width: 500
9
- , height: 390
10
- , buttons: {
11
- 'Submit & Deactivate': function() {
12
- $deactivateForm.submit();
13
- }
14
- }
15
- });
16
- var $wndButtonset = $deactivateWnd.parents('.ui-dialog:first')
17
- .find('.ui-dialog-buttonpane .ui-dialog-buttonset')
18
- , $deactivateDlgBtn = $deactivateWnd.find('.ppsDeactivateSkipDataBtn')
19
- , deactivateUrl = $deactivateLnk.attr('href');
20
- $deactivateDlgBtn.attr('href', deactivateUrl);
21
- $wndButtonset.append( $deactivateDlgBtn );
22
- $deactivateLnk.click(function(){
23
- $deactivateWnd.dialog('open');
24
- return false;
25
- });
26
-
27
- $deactivateForm.submit(function(){
28
- var $btn = $wndButtonset.find('button:first');
29
- $btn.width( $btn.width() ); // Ha:)
30
- $btn.showLoaderPps();
31
- jQuery(this).sendFormPps({
32
- btn: $btn
33
- , onSuccess: function(res) {
34
- toeRedirect( deactivateUrl );
35
- }
36
- });
37
- return false;
38
- });
39
- $deactivateForm.find('[name="deactivate_reason"]').change(function(){
40
- jQuery('.ppsDeactivateDescShell').slideUp( g_ppsAnimationSpeed );
41
- if(jQuery(this).prop('checked')) {
42
- var $descShell = jQuery(this).parents('.ppsDeactivateReasonShell:first').find('.ppsDeactivateDescShell');
43
- if($descShell && $descShell.size()) {
44
- $descShell.slideDown( g_ppsAnimationSpeed );
45
- }
46
- }
47
- });
48
- }
49
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/supsystic_promo/mod.php CHANGED
@@ -14,7 +14,6 @@ class supsystic_promoPps extends modulePps {
14
  if(is_admin()) {
15
  add_action('init', array($this, 'checkWelcome'));
16
  add_action('init', array($this, 'checkStatisticStatus'));
17
- add_action('admin_footer', array($this, 'checkPluginDeactivation'));
18
  }
19
  $this->weLoveYou();
20
  dispatcherPps::addFilter('mainAdminTabs', array($this, 'addAdminTab'));
@@ -191,8 +190,7 @@ class supsystic_promoPps extends modulePps {
191
  return $this->_preparePromoLink($link, $ref);
192
  }
193
  public function checkStatisticStatus(){
194
- // Not used for now - using big data methods
195
- /*$canSend = (int) framePps::_()->getModule('options')->get('send_stats');
196
  if($canSend && framePps::_()->getModule('user')->isAdmin()) {
197
  // Before this version we had many wrong data collected taht we don't need at all. Let's clear them.
198
  if(PPS_VERSION == '1.3.5') {
@@ -204,7 +202,7 @@ class supsystic_promoPps extends modulePps {
204
  }
205
  }
206
  $this->getModel()->checkAndSend();
207
- }*/
208
  }
209
  public function getMinStatSend() {
210
  return $this->_minDataInStatToSend;
@@ -212,7 +210,7 @@ class supsystic_promoPps extends modulePps {
212
  public function getMainLink() {
213
  if(empty($this->_mainLink)) {
214
  $affiliateQueryString = '';
215
- $this->_mainLink = 'https://supsystic.com/plugins/popup-plugin/' . $affiliateQueryString;
216
  }
217
  return $this->_mainLink ;
218
  }
@@ -555,23 +553,4 @@ array('label' => 'Lavender Mood', 'img_preview' => '2016-11-lavender-mood-prev.p
555
  public function showFeaturedPluginsPage() {
556
  return $this->getView()->showFeaturedPluginsPage();
557
  }
558
- public function checkPluginDeactivation() {
559
- if(function_exists('get_current_screen')) {
560
- $screen = get_current_screen();
561
- if($screen && isset($screen->base) && $screen->base == 'plugins') {
562
- framePps::_()->getModule('templates')->loadCoreJs();
563
- framePps::_()->getModule('templates')->loadCoreCss();
564
- framePps::_()->getModule('templates')->loadJqueryUi();
565
- framePps::_()->addScript('jquery-ui-dialog');
566
- framePps::_()->addScript(PPS_CODE. '.admin.plugins', $this->getModPath(). 'js/admin.plugins.js');
567
- framePps::_()->addJSVar(PPS_CODE. '.admin.plugins', 'ppsPluginsData', array(
568
- 'plugSlug' => PPS_PLUG_NAME,
569
- ));
570
- echo $this->getView()->getPluginDeactivation();
571
- }
572
- }
573
- }
574
- public function connectItemEditStats() {
575
- framePps::_()->addScript(PPS_CODE. '.admin.item.edit.stats', $this->getModPath(). 'js/admin.item.edit.stats.js');
576
- }
577
  }
14
  if(is_admin()) {
15
  add_action('init', array($this, 'checkWelcome'));
16
  add_action('init', array($this, 'checkStatisticStatus'));
 
17
  }
18
  $this->weLoveYou();
19
  dispatcherPps::addFilter('mainAdminTabs', array($this, 'addAdminTab'));
190
  return $this->_preparePromoLink($link, $ref);
191
  }
192
  public function checkStatisticStatus(){
193
+ $canSend = (int) framePps::_()->getModule('options')->get('send_stats');
 
194
  if($canSend && framePps::_()->getModule('user')->isAdmin()) {
195
  // Before this version we had many wrong data collected taht we don't need at all. Let's clear them.
196
  if(PPS_VERSION == '1.3.5') {
202
  }
203
  }
204
  $this->getModel()->checkAndSend();
205
+ }
206
  }
207
  public function getMinStatSend() {
208
  return $this->_minDataInStatToSend;
210
  public function getMainLink() {
211
  if(empty($this->_mainLink)) {
212
  $affiliateQueryString = '';
213
+ $this->_mainLink = 'http://supsystic.com/plugins/popup-plugin/' . $affiliateQueryString;
214
  }
215
  return $this->_mainLink ;
216
  }
553
  public function showFeaturedPluginsPage() {
554
  return $this->getView()->showFeaturedPluginsPage();
555
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
556
  }
modules/supsystic_promo/models/classes/lib/Base/MixpanelBase.php DELETED
@@ -1,65 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * This a Base class which all Mixpanel classes extend from to provide some very basic
5
- * debugging and logging functionality. It also serves to persist $_options across the library.
6
- *
7
- */
8
- class Base_MixpanelBase {
9
-
10
-
11
- /**
12
- * Default options that can be overridden via the $options constructor arg
13
- * @var array
14
- */
15
- private $_defaults = array(
16
- "max_batch_size" => 50, // the max batch size Mixpanel will accept is 50,
17
- "max_queue_size" => 1000, // the max num of items to hold in memory before flushing
18
- "debug" => true, // enable/disable debug mode
19
- "consumer" => "curl", // which consumer to use
20
- "host" => "api.mixpanel.com", // the host name for api calls
21
- "events_endpoint" => "/track", // host relative endpoint for events
22
- "people_endpoint" => "/engage", // host relative endpoint for people updates
23
- "use_ssl" => true, // use ssl when available
24
- "error_callback" => null // callback to use on consumption failures
25
- );
26
-
27
-
28
- /**
29
- * An array of options to be used by the Mixpanel library.
30
- * @var array
31
- */
32
- protected $_options = array();
33
-
34
-
35
- /**
36
- * Construct a new MixpanelBase object and merge custom options with defaults
37
- * @param array $options
38
- */
39
- public function __construct($options = array()) {
40
- $options = array_merge($this->_defaults, $options);
41
- $this->_options = $options;
42
- }
43
-
44
-
45
- /**
46
- * Log a message to PHP's error log
47
- * @param $msg
48
- */
49
- protected function _log($msg) {
50
- $arr = debug_backtrace();
51
- $class = $arr[0]['class'];
52
- $line = $arr[0]['line'];
53
- error_log ( "[ $class - line $line ] : " . $msg );
54
- }
55
-
56
-
57
- /**
58
- * Returns true if in debug mode, false if in production mode
59
- * @return bool
60
- */
61
- protected function _debug() {
62
- return array_key_exists("debug", $this->_options) && $this->_options["debug"] == true;
63
- }
64
-
65
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/supsystic_promo/models/classes/lib/ConsumerStrategies/AbstractConsumer.php DELETED
@@ -1,57 +0,0 @@
1
- <?php
2
- require_once(dirname(__FILE__) . "/../Base/MixpanelBase.php");
3
-
4
- /**
5
- * Provides some base methods for use by a Consumer implementation
6
- */
7
- abstract class ConsumerStrategies_AbstractConsumer extends Base_MixpanelBase {
8
-
9
- /**
10
- * Creates a new AbstractConsumer
11
- * @param array $options
12
- */
13
- function __construct($options = array()) {
14
-
15
- parent::__construct($options);
16
-
17
- if ($this->_debug()) {
18
- $this->_log("Instantiated new Consumer");
19
- }
20
-
21
- }
22
-
23
- /**
24
- * Encode an array to be persisted
25
- * @param array $params
26
- * @return string
27
- */
28
- protected function _encode($params) {
29
- return base64_encode(json_encode($params));
30
- }
31
-
32
- /**
33
- * Handles errors that occur in a consumer
34
- * @param $code
35
- * @param $msg
36
- */
37
- protected function _handleError($code, $msg) {
38
- if (isset($this->_options['error_callback'])) {
39
- $handler = $this->_options['error_callback'];
40
- call_user_func($handler, $code, $msg);
41
- }
42
-
43
- if ($this->_debug()) {
44
- $arr = debug_backtrace();
45
- $class = get_class($arr[0]['object']);
46
- $line = $arr[0]['line'];
47
- error_log ( "[ $class - line $line ] : " . print_r($msg, true) );
48
- }
49
- }
50
-
51
- /**
52
- * Persist a batch of messages in whatever way the implementer sees fit
53
- * @param array $batch an array of messages to consume
54
- * @return boolean success or fail
55
- */
56
- abstract function persist($batch);
57
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/supsystic_promo/models/classes/lib/ConsumerStrategies/CurlConsumer.php DELETED
@@ -1,221 +0,0 @@
1
- <?php
2
- require_once(dirname(__FILE__) . "/AbstractConsumer.php");
3
-
4
- /**
5
- * Consumes messages and sends them to a host/endpoint using cURL
6
- */
7
- class ConsumerStrategies_CurlConsumer extends ConsumerStrategies_AbstractConsumer {
8
-
9
- /**
10
- * @var string the host to connect to (e.g. api.mixpanel.com)
11
- */
12
- protected $_host;
13
-
14
-
15
- /**
16
- * @var string the host-relative endpoint to write to (e.g. /engage)
17
- */
18
- protected $_endpoint;
19
-
20
-
21
- /**
22
- * @var int connect_timeout The number of seconds to wait while trying to connect. Default is 5 seconds.
23
- */
24
- protected $_connect_timeout;
25
-
26
-
27
- /**
28
- * @var int timeout The maximum number of seconds to allow cURL call to execute. Default is 30 seconds.
29
- */
30
- protected $_timeout;
31
-
32
-
33
- /**
34
- * @var string the protocol to use for the cURL connection
35
- */
36
- protected $_protocol;
37
-
38
-
39
- /**
40
- * @var bool|null true to fork the cURL process (using exec) or false to use PHP's cURL extension. false by default
41
- */
42
- protected $_fork = null;
43
-
44
-
45
- /**
46
- * Creates a new CurlConsumer and assigns properties from the $options array
47
- * @param array $options
48
- * @throws Exception
49
- */
50
- function __construct($options) {
51
- parent::__construct($options);
52
-
53
- $this->_host = $options['host'];
54
- $this->_endpoint = $options['endpoint'];
55
- $this->_connect_timeout = array_key_exists('connect_timeout', $options) ? $options['connect_timeout'] : 5;
56
- $this->_timeout = array_key_exists('timeout', $options) ? $options['timeout'] : 30;
57
- $this->_protocol = array_key_exists('use_ssl', $options) && $options['use_ssl'] == true ? "https" : "http";
58
- $this->_fork = array_key_exists('fork', $options) ? ($options['fork'] == true) : false;
59
-
60
- // ensure the environment is workable for the given settings
61
- if ($this->_fork == true) {
62
- $exists = function_exists('exec');
63
- if (!$exists) {
64
- throw new Exception('The "exec" function must exist to use the cURL consumer in "fork" mode. Try setting fork = false or use another consumer.');
65
- }
66
- $disabled = explode(', ', ini_get('disable_functions'));
67
- $enabled = !in_array('exec', $disabled);
68
- if (!$enabled) {
69
- throw new Exception('The "exec" function must be enabled to use the cURL consumer in "fork" mode. Try setting fork = false or use another consumer.');
70
- }
71
- } else {
72
- if (!function_exists('curl_init')) {
73
- throw new Exception('The cURL PHP extension is required to use the cURL consumer with fork = false. Try setting fork = true or use another consumer.');
74
- }
75
- }
76
- }
77
-
78
-
79
- /**
80
- * Write to the given host/endpoint using either a forked cURL process or using PHP's cURL extension
81
- * @param array $batch
82
- * @return bool
83
- */
84
- public function persist($batch) {
85
- if (count($batch) > 0) {
86
- $data = "data=" . $this->_encode($batch);
87
- $url = $this->_protocol . "://" . $this->_host . $this->_endpoint;
88
- if ($this->_fork) {
89
- return $this->_execute_forked($url, $data);
90
- } else {
91
- return $this->_execute($url, $data);
92
- }
93
- } else {
94
- return true;
95
- }
96
- }
97
-
98
-
99
- /**
100
- * Write using the cURL php extension
101
- * @param $url
102
- * @param $data
103
- * @return bool
104
- */
105
- protected function _execute($url, $data) {
106
- if ($this->_debug()) {
107
- $this->_log("Making blocking cURL call to $url");
108
- }
109
-
110
- $ch = curl_init();
111
- curl_setopt($ch, CURLOPT_URL, $url);
112
- curl_setopt($ch, CURLOPT_HEADER, 0);
113
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->_connect_timeout);
114
- curl_setopt($ch, CURLOPT_TIMEOUT, $this->_timeout);
115
- curl_setopt($ch, CURLOPT_POST, 1);
116
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
117
- curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
118
- $response = curl_exec($ch);
119
- if (false === $response) {
120
- $curl_error = curl_error($ch);
121
- $curl_errno = curl_errno($ch);
122
- curl_close($ch);
123
- $this->_handleError($curl_errno, $curl_error);
124
- return false;
125
- } else {
126
- curl_close($ch);
127
- if (trim($response) == "1") {
128
- return true;
129
- } else {
130
- $this->_handleError(0, $response);
131
- return false;
132
- }
133
- }
134
- }
135
-
136
-
137
- /**
138
- * Write using a forked cURL process
139
- * @param $url
140
- * @param $data
141
- * @return bool
142
- */
143
- protected function _execute_forked($url, $data) {
144
-
145
- if ($this->_debug()) {
146
- $this->_log("Making forked cURL call to $url");
147
- }
148
-
149
- $exec = 'curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d ' . $data . ' "' . $url . '"';
150
-
151
- if(!$this->_debug()) {
152
- $exec .= " >/dev/null 2>&1 &";
153
- }
154
-
155
- exec($exec, $output, $return_var);
156
-
157
- if ($return_var != 0) {
158
- $this->_handleError($return_var, $output);
159
- }
160
-
161
- return $return_var == 0;
162
- }
163
-
164
- /**
165
- * @return int
166
- */
167
- public function getConnectTimeout()
168
- {
169
- return $this->_connect_timeout;
170
- }
171
-
172
- /**
173
- * @return string
174
- */
175
- public function getEndpoint()
176
- {
177
- return $this->_endpoint;
178
- }
179
-
180
- /**
181
- * @return bool|null
182
- */
183
- public function getFork()
184
- {
185
- return $this->_fork;
186
- }
187
-
188
- /**
189
- * @return string
190
- */
191
- public function getHost()
192
- {
193
- return $this->_host;
194
- }
195
-
196
- /**
197
- * @return array
198
- */
199
- public function getOptions()
200
- {
201
- return $this->_options;
202
- }
203
-
204
- /**
205
- * @return string
206
- */
207
- public function getProtocol()
208
- {
209
- return $this->_protocol;
210
- }
211
-
212
- /**
213
- * @return int
214
- */
215
- public function getTimeout()
216
- {
217
- return $this->_timeout;
218
- }
219
-
220
-
221
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/supsystic_promo/models/classes/lib/ConsumerStrategies/FileConsumer.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
- require_once(dirname(__FILE__) . "/AbstractConsumer.php");
3
- /**
4
- * Consumes messages and writes them to a file
5
- */
6
- class ConsumerStrategies_FileConsumer extends ConsumerStrategies_AbstractConsumer {
7
-
8
- /**
9
- * @var string path to a file that we want to write the messages to
10
- */
11
- private $_file;
12
-
13
-
14
- /**
15
- * Creates a new FileConsumer and assigns properties from the $options array
16
- * @param array $options
17
- */
18
- function __construct($options) {
19
- parent::__construct($options);
20
-
21
- // what file to write to?
22
- $this->_file = array_key_exists("file", $options) ? $options['file'] : dirname(__FILE__)."/../../messages.txt";
23
- }
24
-
25
-
26
- /**
27
- * Append $batch to a file
28
- * @param array $batch
29
- * @return bool
30
- */
31
- public function persist($batch) {
32
- if (count($batch) > 0) {
33
- return file_put_contents($this->_file, json_encode($batch)."\n", FILE_APPEND | LOCK_EX) !== false;
34
- } else {
35
- return true;
36
- }
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/supsystic_promo/models/classes/lib/ConsumerStrategies/SocketConsumer.php DELETED
@@ -1,308 +0,0 @@
1
- <?php
2
- /**
3
- * Portions of this class were borrowed from
4
- * https://github.com/segmentio/analytics-php/blob/master/lib/Analytics/Consumer/Socket.php.
5
- * Thanks for the work!
6
- *
7
- * WWWWWW||WWWWWW
8
- * W W W||W W W
9
- * ||
10
- * ( OO )__________
11
- * / | \
12
- * /o o| MIT \
13
- * \___/||_||__||_|| *
14
- * || || || ||
15
- * _||_|| _||_||
16
- * (__|__|(__|__|
17
- * (The MIT License)
18
- *
19
- * Copyright (c) 2013 Segment.io Inc. friends@segment.io
20
- *
21
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
22
- * documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the
23
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
24
- * permit persons to whom the Software is furnished to do so, subject to the following conditions:
25
- *
26
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
27
- * Software.
28
- *
29
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
30
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
31
- * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
32
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
- */
34
- require_once(dirname(__FILE__) . "/AbstractConsumer.php");
35
-
36
- /**
37
- * Consumes messages and writes them to host/endpoint using a persistent socket
38
- */
39
- class ConsumerStrategies_SocketConsumer extends ConsumerStrategies_AbstractConsumer {
40
-
41
- /**
42
- * @var string the host to connect to (e.g. api.mixpanel.com)
43
- */
44
- private $_host;
45
-
46
-
47
- /**
48
- * @var string the host-relative endpoint to write to (e.g. /engage)
49
- */
50
- private $_endpoint;
51
-
52
-
53
- /**
54
- * @var int connect_timeout the socket connection timeout in seconds
55
- */
56
- private $_connect_timeout;
57
-
58
-
59
- /**
60
- * @var string the protocol to use for the socket connection
61
- */
62
- private $_protocol;
63
-
64
-
65
- /**
66
- * @var resource holds the socket resource
67
- */
68
- private $_socket;
69
-
70
- /**
71
- * @var bool whether or not to wait for a response
72
- */
73
- private $_async;
74
-
75
-
76
- /**
77
- * Creates a new SocketConsumer and assigns properties from the $options array
78
- * @param array $options
79
- */
80
- public function __construct($options = array()) {
81
- parent::__construct($options);
82
-
83
-
84
- $this->_host = $options['host'];
85
- $this->_endpoint = $options['endpoint'];
86
- $this->_connect_timeout = array_key_exists('connect_timeout', $options) ? $options['connect_timeout'] : 5;
87
- $this->_async = array_key_exists('async', $options) && $options['async'] === false ? false : true;
88
-
89
- if (array_key_exists('use_ssl', $options) && $options['use_ssl'] == true) {
90
- $this->_protocol = "ssl";
91
- $this->_port = 443;
92
- } else {
93
- $this->_protocol = "tcp";
94
- $this->_port = 80;
95
- }
96
- }
97
-
98
-
99
- /**
100
- * Write using a persistent socket connection.
101
- * @param array $batch
102
- * @return bool
103
- */
104
- public function persist($batch) {
105
-
106
- $socket = $this->_getSocket();
107
- if (!is_resource($socket)) {
108
- return false;
109
- }
110
-
111
- $data = "data=".$this->_encode($batch);
112
-
113
- $body = "";
114
- $body.= "POST ".$this->_endpoint." HTTP/1.1\r\n";
115
- $body.= "Host: " . $this->_host . "\r\n";
116
- $body.= "Content-Type: application/x-www-form-urlencoded\r\n";
117
- $body.= "Accept: application/json\r\n";
118
- $body.= "Content-length: " . strlen($data) . "\r\n";
119
- $body.= "\r\n";
120
- $body.= $data;
121
-
122
- return $this->_write($socket, $body);
123
- }
124
-
125
-
126
- /**
127
- * Return cached socket if open or create a new persistent socket
128
- * @return bool|resource
129
- */
130
- private function _getSocket() {
131
- if(is_resource($this->_socket)) {
132
-
133
- if ($this->_debug()) {
134
- $this->_log("Using existing socket");
135
- }
136
-
137
- return $this->_socket;
138
- } else {
139
-
140
- if ($this->_debug()) {
141
- $this->_log("Creating new socket at ".time());
142
- }
143
-
144
- return $this->_createSocket();
145
- }
146
- }
147
-
148
- /**
149
- * Attempt to open a new socket connection, cache it, and return the resource
150
- * @param bool $retry
151
- * @return bool|resource
152
- */
153
- private function _createSocket($retry = true) {
154
- try {
155
- $socket = pfsockopen($this->_protocol . "://" . $this->_host, $this->_port, $err_no, $err_msg, $this->_connect_timeout);
156
-
157
- if ($this->_debug()) {
158
- $this->_log("Opening socket connection to " . $this->_protocol . "://" . $this->_host . ":" . $this->_port);
159
- }
160
-
161
- if ($err_no != 0) {
162
- $this->_handleError($err_no, $err_msg);
163
- return $retry == true ? $this->_createSocket(false) : false;
164
- } else {
165
- // cache the socket
166
- $this->_socket = $socket;
167
- return $socket;
168
- }
169
-
170
- } catch (Exception $e) {
171
- $this->_handleError($e->getCode(), $e->getMessage());
172
- return $retry == true ? $this->_createSocket(false) : false;
173
- }
174
- }
175
-
176
- /**
177
- * Attempt to close and dereference a socket resource
178
- */
179
- private function _destroySocket() {
180
- $socket = $this->_socket;
181
- $this->_socket = null;
182
- fclose($socket);
183
- }
184
-
185
-
186
- /**
187
- * Write $data through the given $socket
188
- * @param $socket
189
- * @param $data
190
- * @param bool $retry
191
- * @return bool
192
- */
193
- private function _write($socket, $data, $retry = true) {
194
-
195
- $bytes_sent = 0;
196
- $bytes_total = strlen($data);
197
- $socket_closed = false;
198
- $success = true;
199
- $max_bytes_per_write = 8192;
200
-
201
- // if we have no data to write just return true
202
- if ($bytes_total == 0) {
203
- return true;
204
- }
205
-
206
- // try to write the data
207
- while (!$socket_closed && $bytes_sent < $bytes_total) {
208
-
209
- try {
210
- $bytes = fwrite($socket, $data, $max_bytes_per_write);
211
-
212
- if ($this->_debug()) {
213
- $this->_log("Socket wrote ".$bytes." bytes");
214
- }
215
-
216
- // if we actually wrote data, then remove the written portion from $data left to write
217
- if ($bytes > 0) {
218
- $data = substr($data, $max_bytes_per_write);
219
- }
220
-
221
- } catch (Exception $e) {
222
- $this->_handleError($e->getCode(), $e->getMessage());
223
- $socket_closed = true;
224
- }
225
-
226
- if (isset($bytes) && $bytes) {
227
- $bytes_sent += $bytes;
228
- } else {
229
- $socket_closed = true;
230
- }
231
- }
232
-
233
- // create a new socket if the current one is closed and retry the message
234
- if ($socket_closed) {
235
-
236
- $this->_destroySocket();
237
-
238
- if ($retry) {
239
- if ($this->_debug()) {
240
- $this->_log("Retrying socket write...");
241
- }
242
- $socket = $this->_getSocket();
243
- if ($socket) return $this->_write($socket, $data, false);
244
- }
245
-
246
- return false;
247
- }
248
-
249
-
250
- // only wait for the response in debug mode or if we explicitly want to be synchronous
251
- if ($this->_debug() || !$this->_async) {
252
- $res = $this->handleResponse(fread($socket, 2048));
253
- if ($res["status"] != "200") {
254
- $this->_handleError($res["status"], $res["body"]);
255
- $success = false;
256
- }
257
- }
258
-
259
- return $success;
260
- }
261
-
262
-
263
- /**
264
- * Parse the response from a socket write (only used for debugging)
265
- * @param $response
266
- * @return array
267
- */
268
- private function handleResponse($response) {
269
-
270
- $lines = explode("\n", $response);
271
-
272
- // extract headers
273
- $headers = array();
274
- foreach($lines as $line) {
275
- $kvsplit = explode(":", $line);
276
- if (count($kvsplit) == 2) {
277
- $header = $kvsplit[0];
278
- $value = $kvsplit[1];
279
- $headers[$header] = trim($value);
280
- }
281
-
282
- }
283
-
284
- // extract status
285
- $line_one_exploded = explode(" ", $lines[0]);
286
- $status = $line_one_exploded[1];
287
-
288
- // extract body
289
- $body = $lines[count($lines) - 1];
290
-
291
- // if the connection has been closed lets kill the socket
292
- if ($headers['Connection'] == "close") {
293
- $this->_destroySocket();
294
- if ($this->_debug()) {
295
- $this->_log("Server told us connection closed so lets destroy the socket so it'll reconnect on next call");
296
- }
297
- }
298
-
299
- $ret = array(
300
- "status" => $status,
301
- "body" => $body,
302
- );
303
-
304
- return $ret;
305
- }
306
-
307
-
308
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/supsystic_promo/models/classes/lib/Mixpanel.php DELETED
@@ -1,302 +0,0 @@
1
- <?php
2
-
3
- require_once(dirname(__FILE__) . "/Base/MixpanelBase.php");
4
- require_once(dirname(__FILE__) . "/Producers/MixpanelPeople.php");
5
- require_once(dirname(__FILE__) . "/Producers/MixpanelEvents.php");
6
-
7
- /**
8
- * This is the main class for the Mixpanel PHP Library which provides all of the methods you need to track events and
9
- * create/update profiles.
10
- *
11
- * Architecture
12
- * -------------
13
- *
14
- * This library is built such that all messages are buffered in an in-memory "queue"
15
- * The queue will be automatically flushed at the end of every request. Alternatively, you can call "flush()" manually
16
- * at any time. Flushed messages will be passed to a Consumer's "persist" method. The library comes with a handful of
17
- * Consumers. The "CurlConsumer" is used by default which will send the messages to Mixpanel using forked cURL processes.
18
- * You can implement your own custom Consumer to customize how a message is sent to Mixpanel. This can be useful when
19
- * you want to put messages onto a distributed queue (such as ActiveMQ or Kestrel) instead of writing to Mixpanel in
20
- * the user thread.
21
- *
22
- * Options
23
- * -------------
24
- *
25
- * <table width="100%" cellpadding="5">
26
- * <tr>
27
- * <th>Option</th>
28
- * <th>Description</th>
29
- * <th>Default</th>
30
- * </tr>
31
- * <tr>
32
- * <td>max_queue_size</td>
33
- * <td>The maximum number of items to buffer in memory before flushing</td>
34
- * <td>1000</td>
35
- * </tr>
36
- * <tr>
37
- * <td>debug</td>
38
- * <td>Enable/disable debug mode</td>
39
- * <td>false</td>
40
- * </tr>
41
- * <tr>
42
- * <td>consumer</td>
43
- * <td>The consumer to use for writing messages</td>
44
- * <td>curl</td>
45
- * </tr>
46
- * <tr>
47
- * <td>consumers</td>
48
- * <td>An array of custom consumers in the format array(consumer_key => class_name)</td>
49
- * <td>null</td>
50
- * </tr>
51
- * <tr>
52
- * <td>host</td>
53
- * <td>The host name for api calls (used by some consumers)</td>
54
- * <td>api.mixpanel.com</td>
55
- * </tr>
56
- * <tr>
57
- * <td>events_endpoint</td>
58
- * <td>The endpoint for tracking events (relative to the host)</td>
59
- * <td>/events</td>
60
- * </tr>
61
- * <tr>
62
- * <td>people_endpoint</td>
63
- * <td>The endpoint for making people updates (relative to the host)</td>
64
- * <td>/engage</td>
65
- * </tr>
66
- * <tr>
67
- * <td>use_ssl</td>
68
- * <td>Tell the consumer whether or not to use ssl (when available)</td>
69
- * <td>true</td>
70
- * </tr>
71
- * <tr>
72
- * <td>error_callback</td>
73
- * <td>The name of a function to be called on consumption failures</td>
74
- * <td>null</td>
75
- * </tr>
76
- * <tr>
77
- * <td>connect_timeout</td>
78
- * <td>In both the SocketConsumer and CurlConsumer, this is used for the connection timeout (i.e. How long it has take to actually make a connection).
79
- * <td>5</td>
80
- * </tr>
81
- * <tr>
82
- * <td>timeout</td>
83
- * <td>In the CurlConsumer (non-forked), it is used to determine how long the cURL call has to execute.
84
- * <td>30</td>
85
- * </tr>
86
- * </table>
87
- *
88
- * Example: Tracking an Event
89
- * -------------
90
- *
91
- * $mp = Mixpanel::getInstance("MY_TOKEN");
92
- *
93
- * $mp->track("My Event");
94
- *
95
- * Example: Setting Profile Properties
96
- * -------------
97
- *
98
- * $mp = Mixpanel::getInstance("MY_TOKEN", array("use_ssl" => false));
99
- *
100
- * $mp->people->set(12345, array(
101
- * '$first_name' => "John",
102
- * '$last_name' => "Doe",
103
- * '$email' => "john.doe@example.com",
104
- * '$phone' => "5555555555",
105
- * 'Favorite Color' => "red"
106
- * ));
107
- *
108
- */
109
- class Mixpanel extends Base_MixpanelBase {
110
-
111
-
112
- /**
113
- * An instance of the MixpanelPeople class (used to create/update profiles)
114
- * @var MixpanelPeople
115
- */
116
- public $people;
117
-
118
-
119
- /**
120
- * An instance of the MixpanelEvents class
121
- * @var Producers_MixpanelEvents
122
- */
123
- private $_events;
124
-
125
-
126
- /**
127
- * An instance of the Mixpanel class (for singleton use)
128
- * @var Mixpanel
129
- */
130
- private static $_instance;
131
-
132
-
133
- /**
134
- * Instantiates a new Mixpanel instance.
135
- * @param $token
136
- * @param array $options
137
- */
138
- public function __construct($token, $options = array()) {
139
- parent::__construct($options);
140
- $this->people = new Producers_MixpanelPeople($token, $options);
141
- $this->_events = new Producers_MixpanelEvents($token, $options);
142
- }
143
-
144
-
145
- /**
146
- * Returns a singleton instance of Mixpanel
147
- * @param $token
148
- * @param array $options
149
- * @return Mixpanel
150
- */
151
- public static function getInstance($token, $options = array()) {
152
- if(!isset(self::$_instance)) {
153
- self::$_instance = new Mixpanel($token, $options);
154
- }
155
- return self::$_instance;
156
- }
157
-
158
-
159
- /**
160
- * Add an array representing a message to be sent to Mixpanel to the in-memory queue.
161
- * @param array $message
162
- */
163
- public function enqueue($message = array()) {
164
- $this->_events->enqueue($message);
165
- }
166
-
167
-
168
- /**
169
- * Add an array representing a list of messages to be sent to Mixpanel to a queue.
170
- * @param array $messages
171
- */
172
- public function enqueueAll($messages = array()) {
173
- $this->_events->enqueueAll($messages);
174
- }
175
-
176
-
177
- /**
178
- * Flush the events queue
179
- * @param int $desired_batch_size
180
- */
181
- public function flush($desired_batch_size = 50) {
182
- $this->_events->flush($desired_batch_size);
183
- }
184
-
185
-
186
- /**
187
- * Empty the events queue
188
- */
189
- public function reset() {
190
- $this->_events->reset();
191
- }
192
-
193
-
194
- /**
195
- * Identify the user you want to associate to tracked events
196
- * @param string|int $user_id
197
- */
198
- public function identify($user_id) {
199
- $this->_events->identify($user_id);
200
- }
201
-
202
- /**
203
- * Track an event defined by $event associated with metadata defined by $properties
204
- * @param string $event
205
- * @param array $properties
206
- */
207
- public function track($event, $properties = array()) {
208
- $this->_events->track($event, $properties);
209
- }
210
-
211
-
212
- /**
213
- * Register a property to be sent with every event.
214
- *
215
- * If the property has already been registered, it will be
216
- * overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class instance.
217
- * @param string $property
218
- * @param mixed $value
219
- */
220
- public function register($property, $value) {
221
- $this->_events->register($property, $value);
222
- }
223
-
224
-
225
- /**
226
- * Register multiple properties to be sent with every event.
227
- *
228
- * If any of the properties have already been registered,
229
- * they will be overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class
230
- * instance.
231
- * @param array $props_and_vals
232
- */
233
- public function registerAll($props_and_vals = array()) {
234
- $this->_events->registerAll($props_and_vals);
235
- }
236
-
237
-
238
- /**
239
- * Register a property to be sent with every event.
240
- *
241
- * If the property has already been registered, it will NOT be
242
- * overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class instance.
243
- * @param $property
244
- * @param $value
245
- */
246
- public function registerOnce($property, $value) {
247
- $this->_events->registerOnce($property, $value);
248
- }
249
-
250
-
251
- /**
252
- * Register multiple properties to be sent with every event.
253
- *
254
- * If any of the properties have already been registered,
255
- * they will NOT be overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class
256
- * instance.
257
- * @param array $props_and_vals
258
- */
259
- public function registerAllOnce($props_and_vals = array()) {
260
- $this->_events->registerAllOnce($props_and_vals);
261
- }
262
-
263
-
264
- /**
265
- * Un-register an property to be sent with every event.
266
- * @param string $property
267
- */
268
- public function unregister($property) {
269
- $this->_events->unregister($property);
270
- }
271
-
272
-
273
- /**
274
- * Un-register a list of properties to be sent with every event.
275
- * @param array $properties
276
- */
277
- public function unregisterAll($properties) {
278
- $this->_events->unregisterAll($properties);
279
- }
280
-
281
-
282
- /**
283
- * Get a property that is set to be sent with every event
284
- * @param string $property
285
- * @return mixed
286
- */
287
- public function getProperty($property)
288
- {
289
- return $this->_events->getProperty($property);
290
- }
291
-
292
-
293
- /**
294
- * Alias an existing id with a different unique id. This is helpful when you want to associate a generated id
295
- * (such as a session id) to a user id or username.
296
- * @param string|int $original_id
297
- * @param string|int $new_id
298
- */
299
- public function createAlias($original_id, $new_id) {
300
- $this->_events->createAlias($original_id, $new_id);
301
- }
302
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/supsystic_promo/models/classes/lib/Producers/MixpanelBaseProducer.php DELETED
@@ -1,229 +0,0 @@
1
- <?php
2
- require_once(dirname(__FILE__) . "/../Base/MixpanelBase.php");
3
- require_once(dirname(__FILE__) . "/../ConsumerStrategies/FileConsumer.php");
4
- require_once(dirname(__FILE__) . "/../ConsumerStrategies/CurlConsumer.php");
5
- require_once(dirname(__FILE__) . "/../ConsumerStrategies/SocketConsumer.php");
6
-
7
- if (!function_exists('json_encode')) {
8
- throw new Exception('The JSON PHP extension is required.');
9
- }
10
-
11
- /**
12
- * Provides some base methods for use by a message Producer
13
- */
14
- abstract class Producers_MixpanelBaseProducer extends Base_MixpanelBase {
15
-
16
-
17
- /**
18
- * @var string a token associated to a Mixpanel project
19
- */
20
- protected $_token;
21
-
22
-
23
- /**
24
- * @var array a queue to hold messages in memory before flushing in batches
25
- */
26
- private $_queue = array();
27
-
28
-
29
- /**
30
- * @var ConsumerStrategies_AbstractConsumer the consumer to use when flushing messages
31
- */
32
- private $_consumer = null;
33
-
34
-
35
- /**
36
- * @var array The list of available consumers
37
- */
38
- private $_consumers = array(
39
- "file" => "ConsumerStrategies_FileConsumer",
40
- "curl" => "ConsumerStrategies_CurlConsumer",
41
- "socket" => "ConsumerStrategies_SocketConsumer"
42
- );
43
-
44
-
45
- /**
46
- * If the queue reaches this size we'll auto-flush to prevent out of memory errors
47
- * @var int
48
- */
49
- protected $_max_queue_size = 1000;
50
-
51
-
52
- /**
53
- * Creates a new MixpanelBaseProducer, assings Mixpanel project token, registers custom Consumers, and instantiates
54
- * the desired consumer
55
- * @param $token
56
- * @param array $options
57
- */
58
- public function __construct($token, $options = array()) {
59
-
60
- parent::__construct($options);
61
-
62
- // register any customer consumers
63
- if (array_key_exists("consumers", $options)) {
64
- $this->_consumers = array_merge($this->_consumers, $options['consumers']);
65
- }
66
-
67
- // set max queue size
68
- if (array_key_exists("max_queue_size", $options)) {
69
- $this->_max_queue_size = $options['max_queue_size'];
70
- }
71
-
72
- // associate token
73
- $this->_token = $token;
74
-
75
- if ($this->_debug()) {
76
- $this->_log("Using token: ".$this->_token);
77
- }
78
-
79
- // instantiate the chosen consumer
80
- $this->_consumer = $this->_getConsumer();
81
-
82
- }
83
-
84
-
85
- /**
86
- * Flush the queue when we destruct the client with retries
87
- */
88
- public function __destruct() {
89
- $attempts = 0;
90
- $max_attempts = 10;
91
- $success = false;
92
- while (!$success && $attempts < $max_attempts) {
93
- if ($this->_debug()) {
94
- $this->_log("destruct flush attempt #".($attempts+1));
95
- }
96
- $success = $this->flush();
97
- $attempts++;
98
- }
99
- }
100
-
101
-
102
- /**
103
- * Iterate the queue and write in batches using the instantiated Consumer Strategy
104
- * @param int $desired_batch_size
105
- * @return bool whether or not the flush was successful
106
- */
107
- public function flush($desired_batch_size = 50) {
108
- $queue_size = count($this->_queue);
109
- $succeeded = true;
110
- if ($this->_debug()) {
111
- $this->_log("Flush called - queue size: ".$queue_size);
112
- }
113
-
114
- while($queue_size > 0 && $succeeded) {
115
- $batch_size = min(array($queue_size, $desired_batch_size, $this->_options['max_batch_size']));
116
- $batch = array_splice($this->_queue, 0, $batch_size);
117
- $succeeded = $this->_persist($batch);
118
-
119
- if (!$succeeded) {
120
- if ($this->_debug()) {
121
- $this->_log("Batch consumption failed!");
122
- }
123
- $this->_queue = array_merge($batch, $this->_queue);
124
-
125
- if ($this->_debug()) {
126
- $this->_log("added batch back to queue, queue size is now $queue_size");
127
- }
128
- }
129
-
130
- $queue_size = count($this->_queue);
131
-
132
- if ($this->_debug()) {
133
- $this->_log("Batch of $batch_size consumed, queue size is now $queue_size");
134
- }
135
- }
136
- return $succeeded;
137
- }
138
-
139
-
140
- /**
141
- * Empties the queue without persisting any of the messages
142
- */
143
- public function reset() {
144
- $this->_queue = array();
145
- }
146
-
147
-
148
- /**
149
- * Returns the in-memory queue
150
- * @return array
151
- */
152
- public function getQueue() {
153
- return $this->_queue;
154
- }
155
-
156
- /**
157
- * Returns the current Mixpanel project token
158
- * @return string
159
- */
160
- public function getToken() {
161
- return $this->_token;
162
- }
163
-
164
-
165
- /**
166
- * Given a strategy type, return a new PersistenceStrategy object
167
- * @return ConsumerStrategies_AbstractConsumer
168
- */
169
- protected function _getConsumer() {
170
- $key = $this->_options['consumer'];
171
- $Strategy = $this->_consumers[$key];
172
- if ($this->_debug()) {
173
- $this->_log("Using consumer: " . $key . " -> " . $Strategy);
174
- }
175
- $this->_options['endpoint'] = $this->_getEndpoint();
176
-
177
- return new $Strategy($this->_options);
178
- }
179
-
180
-
181
- /**
182
- * Add an array representing a message to be sent to Mixpanel to a queue.
183
- * @param array $message
184
- */
185
- public function enqueue($message = array()) {
186
- array_push($this->_queue, $message);
187
-
188
- // force a flush if we've reached our threshold
189
- if (count($this->_queue) > $this->_max_queue_size) {
190
- $this->flush();
191
- }
192
-
193
- if ($this->_debug()) {
194
- $this->_log("Queued message: ".json_encode($message));
195
- }
196
- }
197
-
198
-
199
- /**
200
- * Add an array representing a list of messages to be sent to Mixpanel to a queue.
201
- * @param array $messages
202
- */
203
- public function enqueueAll($messages = array()) {
204
- foreach($messages as $message) {
205
- $this->enqueue($message);
206
- }
207
-
208
- }
209
-
210
-
211
- /**
212
- * Given an array of messages, persist it with the instantiated Persistence Strategy
213
- * @param $message
214
- * @return mixed
215
- */
216
- protected function _persist($message) {
217
- return $this->_consumer->persist($message);
218
- }
219
-
220
-
221
-
222
-
223
- /**
224
- * Return the endpoint that should be used by a consumer that consumes messages produced by this producer.
225
- * @return string
226
- */
227
- abstract function _getEndpoint();
228
-
229
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/supsystic_promo/models/classes/lib/Producers/MixpanelEvents.php DELETED
@@ -1,164 +0,0 @@
1
- <?php
2
- require_once(dirname(__FILE__) . "/MixpanelBaseProducer.php");
3
- require_once(dirname(__FILE__) . "/MixpanelPeople.php");
4
- require_once(dirname(__FILE__) . "/../ConsumerStrategies/CurlConsumer.php");
5
-
6
- /**
7
- * Provides an API to track events on Mixpanel
8
- */
9
- class Producers_MixpanelEvents extends Producers_MixpanelBaseProducer {
10
-
11
- /**
12
- * An array of properties to attach to every tracked event
13
- * @var array
14
- */
15
- private $_super_properties = array("mp_lib" => "php");
16
-
17
-
18
- /**
19
- * Track an event defined by $event associated with metadata defined by $properties
20
- * @param string $event
21
- * @param array $properties
22
- */
23
- public function track($event, $properties = array()) {
24
-
25
- // if no token is passed in, use current token
26
- if (!array_key_exists("token", $properties)) $properties['token'] = $this->_token;
27
-
28
- // if no time is passed in, use the current time
29
- if (!array_key_exists('time', $properties)) $properties['time'] = time();
30
-
31
- $params['event'] = $event;
32
- $params['properties'] = array_merge($this->_super_properties, $properties);
33
-
34
- $this->enqueue($params);
35
- }
36
-
37
-
38
- /**
39
- * Register a property to be sent with every event. If the property has already been registered, it will be
40
- * overwritten.
41
- * @param string $property
42
- * @param mixed $value
43
- */
44
- public function register($property, $value) {
45
- $this->_super_properties[$property] = $value;
46
- }
47
-
48
-
49
- /**
50
- * Register multiple properties to be sent with every event. If any of the properties have already been registered,
51
- * they will be overwritten.
52
- * @param array $props_and_vals
53
- */
54
- public function registerAll($props_and_vals = array()) {
55
- foreach($props_and_vals as $property => $value) {
56
- $this->register($property, $value);
57
- }
58
- }
59
-
60
-
61
- /**
62
- * Register a property to be sent with every event. If the property has already been registered, it will NOT be
63
- * overwritten.
64
- * @param $property
65
- * @param $value
66
- */
67
- public function registerOnce($property, $value) {
68
- if (!isset($this->_super_properties[$property])) {
69
- $this->register($property, $value);
70
- }
71
- }
72
-
73
-
74
- /**
75
- * Register multiple properties to be sent with every event. If any of the properties have already been registered,
76
- * they will NOT be overwritten.
77
- * @param array $props_and_vals
78
- */
79
- public function registerAllOnce($props_and_vals = array()) {
80
- foreach($props_and_vals as $property => $value) {
81
- if (!isset($this->_super_properties[$property])) {
82
- $this->register($property, $value);
83
- }
84
- }
85
- }
86
-
87
-
88
- /**
89
- * Un-register an property to be sent with every event.
90
- * @param string $property
91
- */
92
- public function unregister($property) {
93
- unset($this->_super_properties[$property]);
94
- }
95
-
96
-
97
- /**
98
- * Un-register a list of properties to be sent with every event.
99
- * @param array $properties
100
- */
101
- public function unregisterAll($properties) {
102
- foreach($properties as $property) {
103
- $this->unregister($property);
104
- }
105
- }
106
-
107
-
108
- /**
109
- * Get a property that is set to be sent with every event
110
- * @param string $property
111
- * @return mixed
112
- */
113
- public function getProperty($property) {
114
- return $this->_super_properties[$property];
115
- }
116
-
117
-
118
- /**
119
- * Identify the user you want to associate to tracked events
120
- * @param string|int $user_id
121
- */
122
- public function identify($user_id) {
123
- $this->register("distinct_id", $user_id);
124
- }
125
-
126
-
127
- /**
128
- * Alias an existing id with a different unique id. This is helpful when you want to associate a generated id to
129
- * a username or e-mail address.
130
- *
131
- * Because aliasing can be extremely vulnerable to race conditions and ordering issues, we'll make a synchronous
132
- * call directly to Mixpanel when this method is called. If it fails we'll throw an Exception as subsequent
133
- * events are likely to be incorrectly tracked.
134
- * @param string|int $original_id
135
- * @param string|int $new_id
136
- * @return array $msg
137
- * @throws Exception
138
- */
139
- public function createAlias($original_id, $new_id) {
140
- $msg = array(
141
- "event" => '$create_alias',
142
- "properties" => array("distinct_id" => $original_id, "alias" => $new_id, "token" => $this->_token)
143
- );
144
-
145
- $options = array_merge($this->_options, array("endpoint" => $this->_getEndpoint(), "fork" => false));
146
- $curlConsumer = new ConsumerStrategies_CurlConsumer($options);
147
- $success = $curlConsumer->persist(array($msg));
148
- if (!$success) {
149
- error_log("Creating Mixpanel Alias (original id: $original_id, new id: $new_id) failed");
150
- throw new Exception("Tried to create an alias but the call was not successful");
151
- } else {
152
- return $msg;
153
- }
154
- }
155
-
156
-
157
- /**
158
- * Returns the "events" endpoint
159
- * @return string
160
- */
161
- function _getEndpoint() {
162
- return $this->_options['events_endpoint'];
163
- }
164
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/supsystic_promo/models/classes/lib/Producers/MixpanelPeople.php DELETED
@@ -1,147 +0,0 @@
1
- <?php
2
- require_once(dirname(__FILE__) . "/MixpanelBaseProducer.php");
3
-
4
- /**
5
- * Provides an API to create/update profiles on Mixpanel
6
- */
7
- class Producers_MixpanelPeople extends Producers_MixpanelBaseProducer {
8
-
9
- /**
10
- * Internal method to prepare a message given the message data
11
- * @param $distinct_id
12
- * @param $operation
13
- * @param $value
14
- * @param null $ip
15
- * @return array
16
- */
17
- private function _constructPayload($distinct_id, $operation, $value, $ip = null, $ignore_time = false) {
18
- $payload = array(
19
- '$token' => $this->_token,
20
- '$distinct_id' => $distinct_id,
21
- $operation => $value
22
- );
23
- if ($ip !== null) $payload['$ip'] = $ip;
24
- if ($ignore_time === true) $payload['$ignore_time'] = true;
25
- return $payload;
26
- }
27
-
28
- /**
29
- * Set properties on a user record. If the profile does not exist, it creates it with these properties.
30
- * If it does exist, it sets the properties to these values, overwriting existing values.
31
- * @param string|int $distinct_id the distinct_id or alias of a user
32
- * @param array $props associative array of properties to set on the profile
33
- * @param string|null $ip the ip address of the client (used for geo-location)
34
- * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
35
- */
36
- public function set($distinct_id, $props, $ip = null, $ignore_time = false) {
37
- $payload = $this->_constructPayload($distinct_id, '$set', $props, $ip, $ignore_time);
38
- $this->enqueue($payload);
39
- }
40
-
41
- /**
42
- * Set properties on a user record. If the profile does not exist, it creates it with these properties.
43
- * If it does exist, it sets the properties to these values but WILL NOT overwrite existing values.
44
- * @param string|int $distinct_id the distinct_id or alias of a user
45
- * @param array $props associative array of properties to set on the profile
46
- * @param string|null $ip the ip address of the client (used for geo-location)
47
- * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
48
- */
49
- public function setOnce($distinct_id, $props, $ip = null, $ignore_time = false) {
50
- $payload = $this->_constructPayload($distinct_id, '$set_once', $props, $ip, $ignore_time);
51
- $this->enqueue($payload);
52
- }
53
-
54
- /**
55
- * Unset properties on a user record. If the profile does not exist, it creates it with no properties.
56
- * If it does exist, it unsets these properties. NOTE: In other libraries we use 'unset' which is
57
- * a reserved word in PHP.
58
- * @param string|int $distinct_id the distinct_id or alias of a user
59
- * @param array $props associative array of properties to unset on the profile
60
- * @param string|null $ip the ip address of the client (used for geo-location)
61
- * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
62
- */
63
- public function remove($distinct_id, $props, $ip = null, $ignore_time = false) {
64
- $payload = $this->_constructPayload($distinct_id, '$unset', $props, $ip, $ignore_time);
65
- $this->enqueue($payload);
66
- }
67
-
68
- /**
69
- * Increments the value of a property on a user record. If the profile does not exist, it creates it and sets the
70
- * property to the increment value.
71
- * @param string|int $distinct_id the distinct_id or alias of a user
72
- * @param $prop string the property to increment
73
- * @param int $val the amount to increment the property by
74
- * @param string|null $ip the ip address of the client (used for geo-location)
75
- * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
76
- */
77
- public function increment($distinct_id, $prop, $val, $ip = null, $ignore_time = false) {
78
- $payload = $this->_constructPayload($distinct_id, '$add', array("$prop" => $val), $ip, $ignore_time);
79
- $this->enqueue($payload);
80
- }
81
-
82
- /**
83
- * Adds $val to a list located at $prop. If the property does not exist, it will be created. If $val is a string
84
- * and the list is empty or does not exist, a new list with one value will be created.
85
- * @param string|int $distinct_id the distinct_id or alias of a user
86
- * @param string $prop the property that holds the list
87
- * @param string|array $val items to add to the list
88
- * @param string|null $ip the ip address of the client (used for geo-location)
89
- * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
90
- */
91
- public function append($distinct_id, $prop, $val, $ip = null, $ignore_time = false) {
92
- $operation = gettype($val) == "array" ? '$union' : '$append';
93
- $payload = $this->_constructPayload($distinct_id, $operation, array("$prop" => $val), $ip, $ignore_time);
94
- $this->enqueue($payload);
95
- }
96
-
97
- /**
98
- * Adds a transaction to the user's profile for revenue tracking
99
- * @param string|int $distinct_id the distinct_id or alias of a user
100
- * @param string $amount the transaction amount e.g. "20.50"
101
- * @param null $timestamp the timestamp of when the transaction occurred (default to current timestamp)
102
- * @param string|null $ip the ip address of the client (used for geo-location)
103
- * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
104
- */
105
- public function trackCharge($distinct_id, $amount, $timestamp = null, $ip = null, $ignore_time = false) {
106
- $timestamp = $timestamp == null ? time() : $timestamp;
107
- $date_iso = date("c", $timestamp);
108
- $transaction = array(
109
- '$time' => $date_iso,
110
- '$amount' => $amount
111
- );
112
- $val = array('$transactions' => $transaction);
113
- $payload = $this->_constructPayload($distinct_id, '$append', $val, $ip, $ignore_time);
114
- $this->enqueue($payload);
115
- }
116
-
117
- /**
118
- * Clear all transactions stored on a user's profile
119
- * @param string|int $distinct_id the distinct_id or alias of a user
120
- * @param string|null $ip the ip address of the client (used for geo-location)
121
- * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
122
- */
123
- public function clearCharges($distinct_id, $ip = null, $ignore_time = false) {
124
- $payload = $this->_constructPayload($distinct_id, '$set', array('$transactions' => array()), $ip, $ignore_time);
125
- $this->enqueue($payload);
126
- }
127
-
128
- /**
129
- * Delete this profile from Mixpanel
130
- * @param string|int $distinct_id the distinct_id or alias of a user
131
- * @param string|null $ip the ip address of the client (used for geo-location)
132
- * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
133
- */
134
- public function deleteUser($distinct_id, $ip = null, $ignore_time = false) {
135
- $payload = $this->_constructPayload($distinct_id, '$delete', "", $ip, $ignore_time);
136
- $this->enqueue($payload);
137
- }
138
-
139
- /**
140
- * Returns the "engage" endpoint
141
- * @return string
142
- */
143
- function _getEndpoint() {
144
- return $this->_options['people_endpoint'];
145
- }
146
-
147
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/supsystic_promo/models/supsystic_promo.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
  class supsystic_promoModelPps extends modelPps {
3
  private $_apiUrl = '';
4
- private $_bigCli = null;
5
  private function _getApiUrl() {
6
  if(empty($this->_apiUrl)) {
7
  $this->_initApiUrl();
@@ -118,64 +117,4 @@ class supsystic_promoModelPps extends modelPps {
118
  $this->setTourHst( $hst );
119
  $this->saveUsageStat('tour_finished_on_'. $pointKey);
120
  }
121
- private function _getBigStatClient() {
122
- if(!$this->_bigCli) {
123
- if(!class_exists('Mixpanel')) {
124
- require_once($this->getModule()->getModDir(). 'models'. DS. 'classes'. DS. 'lib'. DS. 'Mixpanel.php');
125
- }
126
- $opts = array();
127
- if(!function_exists('curl_init')) {
128
- $opts['consumer'] = 'socket';
129
- }
130
- if(class_exists('Mixpanel')) {
131
- $this->_bigCli = Mixpanel::getInstance("3cc36628768f1f84d4c6980d09ced036", $opts);
132
- /*$bigCliId = (int) get_option(PPS_CODE. '_big_cli_id');
133
- if(!$bigCliId) {
134
- $bigCliId = mt_rand(1, 9999999999);
135
- update_option(PPS_CODE. '_big_cli_id', $bigCliId);
136
- }
137
- $this->_bigCli->identify( $bigCliId );*/
138
- }
139
- }
140
- return $this->_bigCli;
141
- }
142
- public function bigStatAdd( $key, $properties = array() ) {
143
- if(function_exists('json_encode')) {
144
- $this->_getBigStatClient();
145
- if($this->_bigCli) {
146
- $this->_bigCli->track( $key, $properties );
147
- }
148
- }
149
- }
150
- public function bigStatAddCheck( $key, $properties = array() ) {
151
- $canSend = (int) framePps::_()->getModule('options')->get('send_stats');
152
- if( $canSend ) {
153
- $this->bigStatAdd( $key, $properties );
154
- }
155
- }
156
- public function saveDeactivateData( $d ) {
157
- $deactivateParams = array();
158
- $reasonsLabels = array(
159
- 'not_working' => 'Not working',
160
- 'found_better' => 'Found better',
161
- 'not_need' => 'Not need',
162
- 'temporary' => 'Temporary',
163
- 'other' => 'Other',
164
- );
165
- $deactivateParams['Reason'] = isset($d['deactivate_reason']) && $d['deactivate_reason']
166
- ? $reasonsLabels[ $d['deactivate_reason'] ]
167
- : 'No reason';
168
- if(isset($d['deactivate_reason']) && $d['deactivate_reason']) {
169
- switch( $d['deactivate_reason'] ) {
170
- case 'found_better':
171
- $deactivateParams['Better plugin'] = $d['better_plugin'];
172
- break;
173
- case 'other':
174
- $deactivateParams['Other'] = $d['other'];
175
- break;
176
- }
177
- }
178
- $this->bigStatAdd('Deactivated', $deactivateParams);
179
- return true;
180
- }
181
  }
1
  <?php
2
  class supsystic_promoModelPps extends modelPps {
3
  private $_apiUrl = '';
 
4
  private function _getApiUrl() {
5
  if(empty($this->_apiUrl)) {
6
  $this->_initApiUrl();
117
  $this->setTourHst( $hst );
118
  $this->saveUsageStat('tour_finished_on_'. $pointKey);
119
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  }
modules/supsystic_promo/views/supsystic_promo.php CHANGED
@@ -148,7 +148,4 @@ Here you can edit css style of the pop-up window.', PPS_LANG_CODE),
148
  $this->assign('bundleUrl', $siteUrl. 'product/plugins-bundle/'. '?utm_source=plugin&utm_medium=featured_plugins&utm_campaign='. $promoCampaign);
149
  return parent::getContent('featuredPlugins');
150
  }
151
- public function getPluginDeactivation() {
152
- return parent::getContent('pluginDeactivation');
153
- }
154
  }
148
  $this->assign('bundleUrl', $siteUrl. 'product/plugins-bundle/'. '?utm_source=plugin&utm_medium=featured_plugins&utm_campaign='. $promoCampaign);
149
  return parent::getContent('featuredPlugins');
150
  }
 
 
 
151
  }
modules/supsystic_promo/views/tpl/pluginDeactivation.php DELETED
@@ -1,78 +0,0 @@
1
- <style type="text/css">
2
- .ppsDeactivateDescShell {
3
- display: none;
4
- margin-left: 25px;
5
- margin-top: 5px;
6
- }
7
- .ppsDeactivateReasonShell {
8
- display: block;
9
- margin-bottom: 10px;
10
- }
11
- #ppsDeactivateWnd input[type="text"],
12
- #ppsDeactivateWnd textarea {
13
- width: 100%;
14
- }
15
- #ppsDeactivateWnd h4 {
16
- line-height: 1.53em;
17
- }
18
- #ppsDeactivateWnd + .ui-dialog-buttonpane .ui-dialog-buttonset {
19
- float: none;
20
- }
21
- .ppsDeactivateSkipDataBtn {
22
- float: right;
23
- margin-top: 15px;
24
- text-decoration: none;
25
- color: #777 !important;
26
- }
27
- </style>
28
- <div id="ppsDeactivateWnd" style="display: none;" title="<?php _e('Your Feedback', PPS_LANG_CODE)?>">
29
- <h4><?php printf(__('If you have a moment, please share why you are deactivating %s', PPS_LANG_CODE), PPS_WP_PLUGIN_NAME)?></h4>
30
- <form id="ppsDeactivateForm">
31
- <label class="ppsDeactivateReasonShell">
32
- <?php echo htmlPps::radiobutton('deactivate_reason', array(
33
- 'value' => 'not_working',
34
- ))?>
35
- <?php _e('Couldn\'t get the plugin to work', PPS_LANG_CODE)?>
36
- <div class="ppsDeactivateDescShell">
37
- <?php printf(__('If you have a question, <a href="%s" target="_blank">contact us</a> and will do our best to help you'), 'https://supsystic.com/contact-us/?utm_source=plugin&utm_medium=deactivated_contact&utm_campaign=popup')?>
38
- </div>
39
- </label>
40
- <label class="ppsDeactivateReasonShell">
41
- <?php echo htmlPps::radiobutton('deactivate_reason', array(
42
- 'value' => 'found_better',
43
- ))?>
44
- <?php _e('I found a better plugin', PPS_LANG_CODE)?>
45
- <div class="ppsDeactivateDescShell">
46
- <?php echo htmlPps::text('better_plugin', array(
47
- 'placeholder' => __('If it\'s possible, specify plugin name', PPS_LANG_CODE),
48
- ))?>
49
- </div>
50
- </label>
51
- <label class="ppsDeactivateReasonShell">
52
- <?php echo htmlPps::radiobutton('deactivate_reason', array(
53
- 'value' => 'not_need',
54
- ))?>
55
- <?php _e('I no longer need the plugin', PPS_LANG_CODE)?>
56
- </label>
57
- <label class="ppsDeactivateReasonShell">
58
- <?php echo htmlPps::radiobutton('deactivate_reason', array(
59
- 'value' => 'temporary',
60
- ))?>
61
- <?php _e('It\'s a temporary deactivation', PPS_LANG_CODE)?>
62
- </label>
63
- <label class="ppsDeactivateReasonShell">
64
- <?php echo htmlPps::radiobutton('deactivate_reason', array(
65
- 'value' => 'other',
66
- ))?>
67
- <?php _e('Other', PPS_LANG_CODE)?>
68
- <div class="ppsDeactivateDescShell">
69
- <?php echo htmlPps::text('other', array(
70
- 'placeholder' => __('What is the reason?', PPS_LANG_CODE),
71
- ))?>
72
- </div>
73
- </label>
74
- <?php echo htmlPps::hidden('mod', array('value' => 'supsystic_promo'))?>
75
- <?php echo htmlPps::hidden('action', array('value' => 'saveDeactivateData'))?>
76
- </form>
77
- <a href="" class="ppsDeactivateSkipDataBtn"><?php _e('Skip & Deactivate', PPS_LANG_CODE)?></a>
78
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/templates/mod.php CHANGED
@@ -86,7 +86,6 @@ class templatesPps extends modulePps {
86
  );
87
  if(is_admin()) {
88
  $jsData['isPro'] = framePps::_()->getModule('supsystic_promo')->isPro();
89
- $jsData['mainLink'] = framePps::_()->getModule('supsystic_promo')->getMainLink();
90
  }
91
  $jsData = dispatcherPps::applyFilters('jsInitVariables', $jsData);
92
  framePps::_()->addJSVar('corePps', 'PPS_DATA', $jsData);
86
  );
87
  if(is_admin()) {
88
  $jsData['isPro'] = framePps::_()->getModule('supsystic_promo')->isPro();
 
89
  }
90
  $jsData = dispatcherPps::applyFilters('jsInitVariables', $jsData);
91
  framePps::_()->addJSVar('corePps', 'PPS_DATA', $jsData);
pps.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Popup by Supsystic
4
  * Plugin URI: https://supsystic.com/plugins/popup-plugin/
5
  * Description: The Best WordPress popup plugin to help you gain more subscribers, social followers or advertisement. Responsive popups with friendly options
6
- * Version: 1.9.3
7
  * Author: supsystic.com
8
  * Author URI: https://supsystic.com
9
  **/
3
  * Plugin Name: Popup by Supsystic
4
  * Plugin URI: https://supsystic.com/plugins/popup-plugin/
5
  * Description: The Best WordPress popup plugin to help you gain more subscribers, social followers or advertisement. Responsive popups with friendly options
6
+ * Version: 1.9.2
7
  * Author: supsystic.com
8
  * Author URI: https://supsystic.com
9
  **/
readme.txt CHANGED
@@ -2,29 +2,18 @@
2
  Contributors: supsystic.com
3
  Donate link: https://supsystic.com/plugins/popup-plugin
4
  Tags: popup, full screen popup, html popup, wordpress popup, popup contact form, popup builder, modal popup, video popup, youtube popup, social popup, facebook popup, christmas
5
- Tested up to: 4.7.4
6
- Stable tag: 1.9.3
7
 
8
- Popup by Supsystic the best way to convert visitors into subscribers, followers & customers. Create any type of popup with popup builder templates
9
 
10
  == Description ==
11
 
12
- [Popup by Supsystic](https://supsystic.com/plugins/popup-plugin?utm_source=wordpress&utm_medium=description&utm_campaign=popup "Popup WordPress Plugin") with Popup Builder help you to get newsletter subscribers, promote new products, deliver special offers and get more social followers. Popup maker loaded with full range of features:
13
 
14
- = Main Features =
15
-
16
- * 30+ Mobile-ready [Popup Templates](https://supsystic.com/popup-examples/ "WordPress Plugin Popup Templates")
17
- * [Popup Triggers](https://supsystic.com/displaying-popup-configuration/ "Popup Triggers"). When to show / close popup, whom to show, show on next pages, time to display
18
- * Different Popup types
19
- * [Popup Placement](https://supsystic.com/popup-placement/ "Popup Placement"). Modal Popup, Fullscreen Popup, Info Bar, Fly-in, Slide In Popup
20
-
21
- = More Popup Options =
22
 
23
- * [Optin, Social and Link Locks](https://supsystic.com/lock-content/ "Content Lock")
24
- * Subscription Services Integration (WordPress, MailChimp, Aweber and more)
25
- * [A/B Split Tests](https://supsystic.com/what-is-ab-testing/ "A / B Split Test")
26
- * [Real Time Statistic](https://supsystic.com/statistics/ "Real Time Popup Statistic")
27
- * [20+ Popup Opening Animations](https://supsystic.com/popup-opening-animations/ "Popup Openin Animation")
28
 
29
  Popup types:
30
 
@@ -38,9 +27,24 @@ Popup types:
38
  * [Notification Bar](https://supsystic.com/plugins/popup-plugin/#ppsShowPopUp_157 "Notification Bar")
39
  * [Age Verivication](https://supsystic.com/plugins/popup-plugin/#ppsShowPopUp_158 "Age Verification Popup")
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  = Popup Builder =
42
 
43
- What makes people buy up? Firstly emotions. Use Popup builder to popup people's emotions and up your purchases. By Supsystic team Popup you can easily customize any popup window to your site design attracting users popuply. Popup plugin allows to create magnetizing popup by customizing sizes, attracting visitors attention to bonuses and discounts with popups. Many other various promotion offers becomes more effective by popouping them on the site.
44
 
45
  [youtube http://www.youtube.com/watch?v=-Q9-tWi-lQE]
46
 
@@ -220,21 +224,21 @@ Yes. Light compliant Popup plugin backup can close the Popup window, just set th
220
 
221
  == Screenshots ==
222
 
223
- 1. Subscription popup templates. All [Popup Examples](https://supsystic.com/popup-examples?utm_source=wordpress&utm_medium=second_screenshot&utm_campaign=popup "Popup Examples")
224
 
225
- 2. Facebook like popup
226
 
227
- 3. Popup with YouTube video
228
 
229
- 4. PopUp Login / Registration Style
230
 
231
- 5. PopUp with google map and contact form
232
 
233
- 6. Social Buttons and contact form with popup
234
 
235
- 7. [Popup WordPress plugin](https://supsystic.com/plugins/popup-plugin?utm_source=wordpress&utm_medium=first_screenshot&utm_campaign=popup "Popup WordPress plugin")
236
 
237
- 8. [Christmas popup templates pack](https://supsystic.com/blog/christmas-popup-templates-pack "Christmas popup templates")
238
 
239
  == Other Notes ==
240
 
@@ -267,7 +271,7 @@ Perform your site in candy attraction resource with Video Popup Builder features
267
  = Facebook Like Popup =
268
 
269
  More then 50% of population of the Earth is addicted to the internet and social share resources. Make them involved in your products/ services with Popup plugin. Or just become popular offering to share your site along the FB, Twitter, Linkedin etc. by Facebook Like Popup. Installing of the Popup Builder doesn’t take much time or effort than to drink coffee or tea.
270
- Facebook Like Popup is the most gentle way to welcome your visitors for website interaction. Try simple Facebook Like Popup by Supsystic in the box to show your social sites profile.
271
 
272
  = Age Verification Popup =
273
 
@@ -275,11 +279,6 @@ Working with adult site content, sometimes is needed to be sure kids not watchin
275
 
276
  == Changelog ==
277
 
278
- = 1.9.3 / 24.04.2017
279
- * Additional feedback improvements
280
- * Fix issue with some non-latin characters in PopUp Labels
281
- * Additional core improvements
282
-
283
  = 1.9.2 / 19.04.2017
284
  * Added Age Verification templates detailed statistics
285
  * Fixed issue with propagandizing cached stats for AB Test PopUps
2
  Contributors: supsystic.com
3
  Donate link: https://supsystic.com/plugins/popup-plugin
4
  Tags: popup, full screen popup, html popup, wordpress popup, popup contact form, popup builder, modal popup, video popup, youtube popup, social popup, facebook popup, christmas
5
+ Tested up to: 4.7.3
6
+ Stable tag: 1.9.2
7
 
8
+ Popup by Supsystic the best way to convert visitors into subscribers, followers & customers. Create any type of popup with preset popup builder templates
9
 
10
  == Description ==
11
 
12
+ [Popup by Supsystic](https://supsystic.com/plugins/popup-plugin?utm_source=wordpress&utm_medium=description&utm_campaign=popup "Popup WordPress Plugin") get more newsletter subscribers, promote new products, deliver special offers anf get more social followers.
13
 
14
+ = Christmas special popup templates pack! =
 
 
 
 
 
 
 
15
 
16
+ Grab visitors attention with Christmas templates. The highest conversion with positive amotions. More about [Christmas popup templates](https://supsystic.com/blog/christmas-popup-templates-pack "Christmas popup templates").
 
 
 
 
17
 
18
  Popup types:
19
 
27
  * [Notification Bar](https://supsystic.com/plugins/popup-plugin/#ppsShowPopUp_157 "Notification Bar")
28
  * [Age Verivication](https://supsystic.com/plugins/popup-plugin/#ppsShowPopUp_158 "Age Verification Popup")
29
 
30
+ = Main Features =
31
+
32
+ * 30+ Mobile-ready [Popup Templates](https://supsystic.com/popup-examples/ "WordPress Plugin Popup Templates")
33
+ * [Popup Placement](https://supsystic.com/popup-placement/ "Popup Placement"). Modal Popup, Fullscreen Popup, Info Bar, Fly-in, Slide In Popup
34
+ * [Popup Triggers](https://supsystic.com/displaying-popup-configuration/ "Popup Triggers"). When to show / close popup, whom to show, show on next pages, time to display
35
+ * Different Popup types. Subscriptions, Contact Form, YouTube Popup, Google Maps, Full Screen, Image Popup, Login/Registration, Age Verification
36
+
37
+ = More Popup Options =
38
+
39
+ * [Optin, Social and Link Locks](https://supsystic.com/lock-content/ "Content Lock")
40
+ * Subscription Services Integration (WordPress, MailChimp, Aweber and more)
41
+ * [A/B Split Tests](https://supsystic.com/what-is-ab-testing/ "A / B Split Test")
42
+ * [Real Time Statistic](https://supsystic.com/statistics/ "Real Time Popup Statistic")
43
+ * [20+ Popup Opening Animations](https://supsystic.com/popup-opening-animations/ "Popup Openin Animation")
44
+
45
  = Popup Builder =
46
 
47
+ What makes people buy up? Firstly emotions. Use Popup builder to pop up people's emotions and up your purchases. By Supsystic team Popup you can easily customize any popup window to your site design attracting users popuply. Popup plugin allows to create magnetizing popup by customizing sizes, attracting visitors attention to bonuses and discounts with popups. Many other various promotion offers becomes more effective by popouping them on the site.
48
 
49
  [youtube http://www.youtube.com/watch?v=-Q9-tWi-lQE]
50
 
224
 
225
  == Screenshots ==
226
 
227
+ 1. [Christmas popup templates pack](https://supsystic.com/blog/christmas-popup-templates-pack "Christmas popup templates")
228
 
229
+ 2. Subscription popup templates. All [Popup Examples](https://supsystic.com/popup-examples?utm_source=wordpress&utm_medium=second_screenshot&utm_campaign=popup "Popup Examples")
230
 
231
+ 3. Facebook like popup
232
 
233
+ 4. popup with YouTube video
234
 
235
+ 5. PopUp Login / Registration Style
236
 
237
+ 6. PopUp with google map and contact form
238
 
239
+ 7. Social Buttons and contact form with popup
240
 
241
+ 8. [Popup WordPress plugin](https://supsystic.com/plugins/popup-plugin?utm_source=wordpress&utm_medium=first_screenshot&utm_campaign=popup "Popup WordPress plugin")
242
 
243
  == Other Notes ==
244
 
271
  = Facebook Like Popup =
272
 
273
  More then 50% of population of the Earth is addicted to the internet and social share resources. Make them involved in your products/ services with Popup plugin. Or just become popular offering to share your site along the FB, Twitter, Linkedin etc. by Facebook Like Popup. Installing of the Popup Builder doesn’t take much time or effort than to drink coffee or tea.
274
+ Facebook Like Popup is the most gentle way to welcome your visitors for website interaction.Try simple Facebook Like Popup by Supsystic in the box to show your social sites profile.
275
 
276
  = Age Verification Popup =
277
 
279
 
280
  == Changelog ==
281
 
 
 
 
 
 
282
  = 1.9.2 / 19.04.2017
283
  * Added Age Verification templates detailed statistics
284
  * Fixed issue with propagandizing cached stats for AB Test PopUps