Version Description
- SIDEKICK can now be embeded within other plugins!
- Custom walkthrough plans are now supported within MultiSite auto activation
- Wildcard compatibility matching added
- Captioning support added
- Fixes issues with general UI elements
- Fixes issues with walkthrough preview
- Fixes issues with Safari alignment on settings page
Download this release
Release Info
Developer | raptor235 |
Plugin | Sidekick |
Version | 2.2.0 |
Comparing to | |
See all releases |
Code changes from version 2.0.1 to 2.2.0
- js/sidekick_admin.js +270 -0
- libs/admin_page.php +6 -1
- libs/licensing.php +227 -166
- libs/mixpanel/Base/MixpanelBase.php +65 -0
- libs/mixpanel/ConsumerStrategies/AbstractConsumer.php +57 -0
- libs/mixpanel/ConsumerStrategies/CurlConsumer.php +221 -0
- libs/mixpanel/ConsumerStrategies/FileConsumer.php +38 -0
- libs/mixpanel/ConsumerStrategies/SocketConsumer.php +308 -0
- libs/mixpanel/Mixpanel.php +302 -0
- libs/mixpanel/Producers/MixpanelBaseProducer.php +229 -0
- libs/mixpanel/Producers/MixpanelEvents.php +164 -0
- libs/mixpanel/Producers/MixpanelPeople.php +147 -0
- libs/ms_admin_page.php +43 -9
- libs/sk_config_data.php +150 -155
- libs/walkthrough_config.php +4 -2
- readme.txt +16 -2
- sidekick.php +403 -354
- sidekick_embed.php +495 -0
js/sidekick_admin.js
ADDED
@@ -0,0 +1,270 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Single Site
|
2 |
+
|
3 |
+
var currently_disabled_wts;
|
4 |
+
var currently_disabled_network_wts;
|
5 |
+
var lastTimeout;
|
6 |
+
var loadCount = 0;
|
7 |
+
|
8 |
+
function sk_populate(data){
|
9 |
+
|
10 |
+
jQuery('.sk_walkthrough_list').html('');
|
11 |
+
|
12 |
+
_.each(data.products,function(item,key){
|
13 |
+
|
14 |
+
if (!item.cacheId) {
|
15 |
+
return false;
|
16 |
+
}
|
17 |
+
|
18 |
+
jQuery('.sk_walkthrough_list').append('<div class="sk_product" id="' + item.cacheId + '"><b>' + item.name + '</b> (<span class="select_all">Toggle All</span>)</div>');
|
19 |
+
|
20 |
+
|
21 |
+
if (sk_config.disable_wts) {
|
22 |
+
currently_disabled_wts = sk_config.disable_wts;
|
23 |
+
sk_config.disable_wts = null;
|
24 |
+
}
|
25 |
+
|
26 |
+
if (sk_config.disable_network_wts) {
|
27 |
+
currently_disabled_network_wts = sk_config.disable_network_wts;
|
28 |
+
sk_config.disable_network_wts = null;
|
29 |
+
}
|
30 |
+
|
31 |
+
jQuery.ajax({
|
32 |
+
url:sk_config.library + 'products/cache?cacheId=' + item.cacheId,
|
33 |
+
cacheId: item.cacheId,
|
34 |
+
success: function(data,cacheId){
|
35 |
+
|
36 |
+
// console.log('SUCCESS %o',arguments);
|
37 |
+
loadCount++;
|
38 |
+
|
39 |
+
if (data.payload && data.payload.buckets) {
|
40 |
+
|
41 |
+
// Clear out disabled wts so that compatibility doesn't screen out wts from this screen. Put it back after we're done.
|
42 |
+
|
43 |
+
console.groupCollapsed('Checking Compatibilities');
|
44 |
+
|
45 |
+
_.each(data.payload.buckets,function(bucket,key){
|
46 |
+
|
47 |
+
clearTimeout(lastTimeout);
|
48 |
+
lastTimeout = setTimeout(function(){setup_events();},1000);
|
49 |
+
|
50 |
+
if (typeof sk_config.disable_wts_in_root_bucket_ids !== 'undefined' && jQuery.inArray( bucket.id, sk_config.disable_wts_in_root_bucket_ids ) > -1) {
|
51 |
+
// Don't draw root bucket
|
52 |
+
return false;
|
53 |
+
}
|
54 |
+
|
55 |
+
jQuery('#' + item.cacheId).append("<li class='sk_bucket' id='sk_bucket_" + bucket.id + "'>" + bucket.name + " (<span class=\"select_all\">Toggle All</span>)<ul></ul></li>");
|
56 |
+
|
57 |
+
var pass_data = {
|
58 |
+
bucket_id: bucket.id,
|
59 |
+
all_walkthroughs: data.payload.walkthroughs
|
60 |
+
};
|
61 |
+
|
62 |
+
_.each(bucket.walkthroughs,function(walkthrough,key){
|
63 |
+
|
64 |
+
var pass = false;
|
65 |
+
|
66 |
+
if (typeof sk_ms_admin === 'undefined' || !sk_ms_admin && jQuery.inArray(parseInt(key,10),currently_disabled_network_wts) > -1) {
|
67 |
+
// If single site and network disabled walkthroughs then don't even show it.
|
68 |
+
return;
|
69 |
+
}
|
70 |
+
|
71 |
+
if (sidekick.compatibilityModel.check_compatiblity_array(this.all_walkthroughs[key]) || (typeof sk_ms_admin !== 'undefined' && sk_ms_admin)){
|
72 |
+
// Only check compatibilities for single sites not network admin page
|
73 |
+
pass = true;
|
74 |
+
}
|
75 |
+
|
76 |
+
if (pass){
|
77 |
+
var checked = false;
|
78 |
+
var selected = false;
|
79 |
+
|
80 |
+
if (jQuery.inArray(parseInt(key,10),currently_disabled_wts) > -1 || jQuery.inArray(parseInt(key,10),currently_disabled_network_wts) > -1) {
|
81 |
+
checked = 'CHECKED';
|
82 |
+
}
|
83 |
+
|
84 |
+
if (sk_config.autostart_walkthrough_id !== 'undefined' && sk_config.autostart_walkthrough_id == parseInt(key,10)) {
|
85 |
+
selected = 'SELECTED';
|
86 |
+
}
|
87 |
+
|
88 |
+
jQuery('#sk_bucket_' + this.bucket_id).find('ul').append("<li class=\" sk_walkthrough\"><span><input type=\"checkbox\" " + checked + " value='" + key + "' name=\"disable_wts[]\"></span><span class='title'>" + this.all_walkthroughs[key].title + "</span></li>");
|
89 |
+
jQuery('[name="sk_autostart_walkthrough_id"]').append('<option ' + selected + ' value="' + key + '">' + this.all_walkthroughs[key].title + '</option>');
|
90 |
+
|
91 |
+
}
|
92 |
+
clearTimeout(lastTimeout);
|
93 |
+
lastTimeout = setTimeout(function(){setup_events();},1000);
|
94 |
+
},pass_data);
|
95 |
+
|
96 |
+
}); //
|
97 |
+
|
98 |
+
jQuery('.configure').show(); //
|
99 |
+
|
100 |
+
console.groupEnd();//
|
101 |
+
|
102 |
+
} else { //
|
103 |
+
jQuery('#' + this.cacheId).remove();
|
104 |
+
}
|
105 |
+
|
106 |
+
}
|
107 |
+
});
|
108 |
+
}); //
|
109 |
+
} //
|
110 |
+
|
111 |
+
function setup_events(){
|
112 |
+
// console.log('setup_events');
|
113 |
+
|
114 |
+
jQuery('.select_all').click(function(){
|
115 |
+
var checkBoxes = jQuery(this).parent().find('input[type="checkbox"]');
|
116 |
+
|
117 |
+
_.each(checkBoxes,function(item,key){
|
118 |
+
jQuery(item).attr("checked", !jQuery(item).attr("checked"));
|
119 |
+
});
|
120 |
+
});
|
121 |
+
|
122 |
+
jQuery('[name="disable_wts[]"]').click(function(e){
|
123 |
+
|
124 |
+
if (e.currentTarget.checked) {
|
125 |
+
jQuery('input[value="' + e.currentTarget.value + '"]').attr('checked',true);
|
126 |
+
} else {
|
127 |
+
jQuery('input[value="' + e.currentTarget.value + '"]').attr('checked',false);
|
128 |
+
}
|
129 |
+
|
130 |
+
});
|
131 |
+
|
132 |
+
jQuery('.activate_all').click(function(){
|
133 |
+
jQuery('.activate_sk').each(function(key,item){
|
134 |
+
setTimeout(function() {
|
135 |
+
jQuery(item).trigger('click');
|
136 |
+
}, key*1000);
|
137 |
+
});
|
138 |
+
});
|
139 |
+
|
140 |
+
jQuery('.sk_bucket').not(':has(li)').remove();
|
141 |
+
jQuery('.sk_product').not(':has(li)').remove();
|
142 |
+
|
143 |
+
// Set the disable_wts back to original state
|
144 |
+
sk_config.disable_wts = currently_disabled_wts;
|
145 |
+
sk_config.disable_network_wts = currently_disabled_network_wts;
|
146 |
+
}
|
147 |
+
|
148 |
+
function load_sk_library($key){
|
149 |
+
|
150 |
+
// console.log('BBBB load_sk_library %o', $key);
|
151 |
+
var sk_url;
|
152 |
+
|
153 |
+
if (loadCount > 5) {
|
154 |
+
console.warn('Something is wrong...');
|
155 |
+
return false;
|
156 |
+
}
|
157 |
+
|
158 |
+
if ($key) {
|
159 |
+
sk_url = sk_config.library + 'domains/cache?domainKey=' + $key;
|
160 |
+
} else {
|
161 |
+
sk_url = sk_config.library + 'platform/cache?platformId=1';
|
162 |
+
}
|
163 |
+
|
164 |
+
loadCount++;
|
165 |
+
|
166 |
+
jQuery.ajax({
|
167 |
+
url: sk_url,
|
168 |
+
error: function(data){
|
169 |
+
jQuery('.sk_license_status span').html('Invalid Key').css({color: 'red'});
|
170 |
+
jQuery('.sk_upgrade').show();
|
171 |
+
load_sk_library();
|
172 |
+
},
|
173 |
+
success: function(data){
|
174 |
+
|
175 |
+
if (sk_config.library + 'domains/cache?domainKey=' + sk_config.activation_id == sk_url) {
|
176 |
+
if (!data.payload) {
|
177 |
+
jQuery('.sk_license_status').html('Invalid Key').css({color: 'red'});
|
178 |
+
} else {
|
179 |
+
jQuery('.sk_license_status').html('Valid').css({color: 'green'});
|
180 |
+
}
|
181 |
+
}
|
182 |
+
|
183 |
+
if (!data.payload) {
|
184 |
+
load_sk_library();
|
185 |
+
return false;
|
186 |
+
}
|
187 |
+
|
188 |
+
if (data.payload) {
|
189 |
+
sk_populate(data.payload);
|
190 |
+
}
|
191 |
+
}
|
192 |
+
});
|
193 |
+
}
|
194 |
+
|
195 |
+
jQuery(document).ready(function($) {
|
196 |
+
|
197 |
+
if (jQuery('.sidekick_admin').length === 0) {
|
198 |
+
return;
|
199 |
+
}
|
200 |
+
|
201 |
+
if (typeof sk_ms_admin !== 'undefined' && sk_ms_admin) {
|
202 |
+
|
203 |
+
// Multisite
|
204 |
+
|
205 |
+
var clicked_button;
|
206 |
+
|
207 |
+
if (typeof last_site_key !== 'undefined') {
|
208 |
+
load_sk_library(last_site_key);
|
209 |
+
} else {
|
210 |
+
jQuery('.sk_box.configure').html('Need to activate at least one site to configure walkthroughs').show();
|
211 |
+
}
|
212 |
+
|
213 |
+
jQuery('.activate_sk').click(function(){
|
214 |
+
|
215 |
+
clicked_button = this;
|
216 |
+
jQuery('.single_activation_error').html('');
|
217 |
+
|
218 |
+
var data = {
|
219 |
+
action: 'sk_activate_single',
|
220 |
+
blog_id: jQuery(this).data('blogid'),
|
221 |
+
user_id: jQuery(this).data('userid'),
|
222 |
+
domain: jQuery(this).data('domain'),
|
223 |
+
path: jQuery(this).data('path')
|
224 |
+
};
|
225 |
+
|
226 |
+
jQuery.post(ajaxurl, data, function(e){
|
227 |
+
|
228 |
+
if (!e.success) {
|
229 |
+
jQuery('.single_activation_error').html(e.message);
|
230 |
+
jQuery(clicked_button).parent().html('- <span class="not_active">Error Activating</span>');
|
231 |
+
} else if (e.success) {
|
232 |
+
jQuery(clicked_button).parent().html('- <span class="green">Activated</span>');
|
233 |
+
}
|
234 |
+
},'json');
|
235 |
+
|
236 |
+
});
|
237 |
+
|
238 |
+
if (jQuery('select[name="sk_selected_subscription"]').val().indexOf('roduct') > -1) {
|
239 |
+
jQuery('.walkthrough_library').show();
|
240 |
+
}
|
241 |
+
|
242 |
+
jQuery('select[name="sk_selected_subscription"]').on('change',function(){
|
243 |
+
if (jQuery('select[name="sk_selected_subscription"]').val().indexOf('roduct') > -1) {
|
244 |
+
jQuery('.walkthrough_library').show();
|
245 |
+
} else {
|
246 |
+
jQuery('.walkthrough_library').val(0);
|
247 |
+
jQuery('.walkthrough_library').hide();
|
248 |
+
}
|
249 |
+
});
|
250 |
+
|
251 |
+
} else {
|
252 |
+
jQuery(document).ready(function($) {
|
253 |
+
if (sk_config.activation_id) {
|
254 |
+
load_sk_library(sk_config.activation_id);
|
255 |
+
} else {
|
256 |
+
jQuery('.sk_upgrade').show();
|
257 |
+
}
|
258 |
+
|
259 |
+
jQuery('h3:contains(My Sidekick Account)').click(function(e){
|
260 |
+
if (e.shiftKey) {
|
261 |
+
jQuery('.advanced').show();
|
262 |
+
}
|
263 |
+
});
|
264 |
+
|
265 |
+
});
|
266 |
+
}
|
267 |
+
|
268 |
+
});
|
269 |
+
|
270 |
+
|
libs/admin_page.php
CHANGED
@@ -4,6 +4,11 @@
|
|
4 |
}
|
5 |
var last_site_key = null;
|
6 |
var sk_ms_admin = false;
|
|
|
|
|
|
|
|
|
|
|
7 |
</script>
|
8 |
|
9 |
<div class="page-header"><h2><a id="pluginlogo_32" class="header-icon32" href="http://www.sidekick.pro/modules/wordpress-core-module-premium/?utm_source=plugin&utm_medium=settings&utm_campaign=header" target="_blank"></a>Sidekick Dashboard</h2></div>
|
@@ -42,7 +47,7 @@
|
|
42 |
<tbody>
|
43 |
<tr valign="top">
|
44 |
<th scope="row" valign="top">Activation ID</th>
|
45 |
-
<?php if (defined('MULTISITE')): ?>
|
46 |
<?php if (isset($activation_id) && $activation_id): ?>
|
47 |
<td><input class='regular-text' style='color: gray;' type='text' name='activation_id' value='xxxxxxxx-xxxx-xxxx-xxxx-<?php echo substr($activation_id, 25,20) ?>'></input></td>
|
48 |
<?php else: ?>
|
4 |
}
|
5 |
var last_site_key = null;
|
6 |
var sk_ms_admin = false;
|
7 |
+
|
8 |
+
jQuery(document).ready(function($) {
|
9 |
+
mixpanel.track('Settings Page Visit - Plugin');
|
10 |
+
});
|
11 |
+
|
12 |
</script>
|
13 |
|
14 |
<div class="page-header"><h2><a id="pluginlogo_32" class="header-icon32" href="http://www.sidekick.pro/modules/wordpress-core-module-premium/?utm_source=plugin&utm_medium=settings&utm_campaign=header" target="_blank"></a>Sidekick Dashboard</h2></div>
|
47 |
<tbody>
|
48 |
<tr valign="top">
|
49 |
<th scope="row" valign="top">Activation ID</th>
|
50 |
+
<?php if (defined('MULTISITE') && MULTISITE): ?>
|
51 |
<?php if (isset($activation_id) && $activation_id): ?>
|
52 |
<td><input class='regular-text' style='color: gray;' type='text' name='activation_id' value='xxxxxxxx-xxxx-xxxx-xxxx-<?php echo substr($activation_id, 25,20) ?>'></input></td>
|
53 |
<?php else: ?>
|
libs/licensing.php
CHANGED
@@ -1,166 +1,192 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
-
// mlog('FUNCTION: activate');
|
7 |
|
8 |
-
|
9 |
|
10 |
-
|
|
|
11 |
|
12 |
-
$
|
13 |
-
$email = ($user) ? $user->user_email : 'unknown';
|
14 |
|
15 |
-
|
16 |
|
17 |
-
|
|
|
18 |
|
19 |
-
|
20 |
|
21 |
-
|
|
|
22 |
|
23 |
-
if (
|
24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
update_option('sk_activation_id',$result->payload->domainKey);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
}
|
|
|
|
|
|
|
|
|
27 |
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
|
|
32 |
|
33 |
-
|
34 |
-
} else {
|
35 |
-
update_option('sk_auto_activation_error',$result->message);
|
36 |
-
wp_mail( 'support@sidekick.pro', 'Failed Mass Domain Add', json_encode($result));
|
37 |
}
|
38 |
-
return $result;
|
39 |
}
|
40 |
-
return false;
|
41 |
-
}
|
42 |
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
|
59 |
-
|
60 |
// var_dump('send_request');
|
61 |
//var_dump("FUNCTION: send_request");
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
$url = $protocol . SK_API . $end_point;
|
70 |
-
$sk_token = get_transient('sk_token');
|
71 |
|
72 |
-
|
73 |
-
$this->login();
|
74 |
$sk_token = get_transient('sk_token');
|
75 |
-
}
|
76 |
|
77 |
-
|
|
|
|
|
|
|
78 |
|
79 |
-
|
80 |
-
$headers[] = "Authorization: $sk_token";
|
81 |
-
}
|
82 |
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
87 |
-
if ($data) {
|
88 |
-
curl_setopt($ch, CURLOPT_POSTFIELDS,json_encode($data));
|
89 |
-
}
|
90 |
-
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
91 |
-
$result = curl_exec($ch);
|
92 |
-
curl_close($ch);
|
93 |
-
|
94 |
-
// echo $result;
|
95 |
-
// var_dump($url);
|
96 |
-
// var_dump($headers);
|
97 |
-
// var_dump($data);
|
98 |
-
// var_dump($result);
|
99 |
-
// die();
|
100 |
-
|
101 |
-
if ($result == 'HTTP/1.1 401 Unauthorized' && !$second_attempt) {
|
102 |
-
// var_dump('Getting rid of token and trying again');
|
103 |
-
$this->login();
|
104 |
-
delete_transient('sk_token');
|
105 |
-
$this->send_request('post',$type,$data,true);
|
106 |
-
}
|
107 |
|
108 |
-
|
109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
|
111 |
-
|
112 |
-
add_submenu_page( 'settings.php', 'Sidekick - Licensing', 'Sidekick - Licensing', 'activate_plugins','sidekick-licensing', array(&$this,'admin_page'));
|
113 |
-
}
|
114 |
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
|
|
120 |
|
121 |
-
|
122 |
-
return false;
|
123 |
}
|
124 |
|
125 |
-
|
126 |
-
|
|
|
|
|
|
|
|
|
127 |
|
128 |
-
|
|
|
|
|
129 |
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
|
134 |
-
|
|
|
|
|
135 |
|
136 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
|
138 |
-
|
139 |
-
|
140 |
-
return array('error' => $result->message);
|
141 |
-
} else {
|
142 |
-
set_transient( 'sk_token', $result->payload->token->value, 24 * HOUR_IN_SECONDS );
|
143 |
-
$this->load_subscriptions($result->payload->token->value);
|
144 |
-
return array('success' => true);
|
145 |
}
|
146 |
-
}
|
147 |
|
148 |
-
|
149 |
-
|
150 |
-
|
|
|
|
|
|
|
151 |
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
if ($sub->
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
}
|
163 |
-
|
|
|
|
|
|
|
|
|
164 |
if (count($sub->Domains) > 0) {
|
165 |
foreach ($sub->Domains as &$domain) {
|
166 |
if (!$domain->DomainSubscription->end) {
|
@@ -171,68 +197,103 @@ class sidekickMassActivator{
|
|
171 |
}
|
172 |
}
|
173 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
} else {
|
175 |
$sub->activeDomainCount = 0;
|
176 |
}
|
177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
}
|
179 |
-
|
180 |
-
if (isset($current_subscription)) {
|
181 |
-
$data['current_subscription'] = $current_subscription;
|
182 |
-
} else {
|
183 |
-
delete_option('sk_auto_activations');
|
184 |
-
}
|
185 |
-
return $data;
|
186 |
}
|
187 |
-
return null;
|
188 |
-
}
|
189 |
|
190 |
-
|
191 |
-
|
|
|
|
|
|
|
|
|
192 |
|
193 |
-
|
194 |
-
|
195 |
-
|
|
|
|
|
|
|
|
|
196 |
|
197 |
-
|
198 |
-
|
199 |
|
200 |
-
update_option( 'sk_account', $_POST['sk_account'] );
|
201 |
-
update_option( 'sk_password', $encrypted_password );
|
202 |
-
$login_status = $this->login();
|
203 |
delete_option('sk_auto_activation_error');
|
204 |
-
|
205 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
}
|
207 |
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
}
|
213 |
-
}
|
214 |
|
215 |
-
|
216 |
-
if (!$sk_token) {
|
217 |
-
$login_status = $this->login();
|
218 |
}
|
219 |
-
$sk_subs = $this->load_subscriptions();
|
220 |
-
$user_data = $this->load_user_data();
|
221 |
-
$sk_auto_activations = get_option( 'sk_auto_activations');
|
222 |
-
$sk_auto_activation_error = get_option('sk_auto_activation_error');
|
223 |
-
$sk_selected_subscription = get_option('sk_selected_subscription');
|
224 |
-
$is_ms_admin = true;
|
225 |
-
$curl = function_exists('curl_version') ? true : false;
|
226 |
-
$fgets = file_get_contents(__FILE__) ? true : false;
|
227 |
-
$fgets_url = ini_get('allow_url_fopen') ? true : false;
|
228 |
-
|
229 |
-
// var_dump($sk_subs);
|
230 |
-
|
231 |
-
if ($curl && (!$fgets || !$fgets_url)) {
|
232 |
-
$error = "Sorry, SIDEKICK MultiSite activations require <b>CURL</b> or <b>file_get_contents</b> functions enabled in PHP.";
|
233 |
-
}
|
234 |
-
|
235 |
-
include('ms_admin_page.php');
|
236 |
}
|
237 |
}
|
238 |
|
|
1 |
<?php
|
2 |
|
3 |
+
// licensing.php
|
4 |
|
5 |
+
if (!class_exists('sidekickMassActivator')) {
|
|
|
6 |
|
7 |
+
class sidekickMassActivator{
|
8 |
|
9 |
+
function activate($blog_id, $user_id, $domain, $path){
|
10 |
+
// mlog('FUNCTION: activate');
|
11 |
|
12 |
+
$sk_auto_activations = get_option( 'sk_auto_activations');
|
|
|
13 |
|
14 |
+
if ($sk_auto_activations) {
|
15 |
|
16 |
+
$user = get_user_by('id',$user_id);
|
17 |
+
$email = ($user) ? $user->user_email : 'unknown';
|
18 |
|
19 |
+
// TODO: Send Domain for good measure
|
20 |
|
21 |
+
$sk_selected_subscription = get_option("sk_selected_subscription");
|
22 |
+
$sk_selected_product = get_option("sk_selected_product");
|
23 |
|
24 |
+
if (isset($sk_selected_product) && $sk_selected_product) {
|
25 |
+
$data = array('domainName' => $domain . $path, 'productId' => $sk_selected_product);
|
26 |
+
} else if (strpos($sk_selected_subscription,'subscription-') !== false) {
|
27 |
+
$sk_selected_subscription = explode('subscription-',$sk_selected_subscription);
|
28 |
+
$data = array('domainName' => $domain . $path, 'subscriptionId' => $sk_selected_subscription[1]);
|
29 |
+
}
|
30 |
+
|
31 |
+
$result = $this->send_request('post','/domains',$data);
|
32 |
+
|
33 |
+
if (isset($result->success) && $result->success == true && $result->payload->domainKey) {
|
34 |
+
|
35 |
+
if (!get_option('sk_activation_id')) {
|
36 |
+
// Use the first site's activation key for the network key
|
37 |
+
update_option('sk_activation_id',$result->payload->domainKey);
|
38 |
+
}
|
39 |
+
|
40 |
+
switch_to_blog($blog_id);
|
41 |
update_option('sk_activation_id',$result->payload->domainKey);
|
42 |
+
update_option('sk_email',$email);
|
43 |
+
restore_current_blog();
|
44 |
+
|
45 |
+
$this->track('Mass Activate',array('domain' => $domain,'email' => $email));
|
46 |
+
|
47 |
+
delete_option('sk_auto_activation_error');
|
48 |
+
} else {
|
49 |
+
|
50 |
+
$this->track('Mass Activate Error',array('domain' => $domain, 'message' => $result->message,'email' => $email));
|
51 |
+
update_option('sk_auto_activation_error',$result->message);
|
52 |
+
wp_mail( 'support@sidekick.pro', 'Failed Mass Domain Add', json_encode($result));
|
53 |
}
|
54 |
+
return $result;
|
55 |
+
}
|
56 |
+
return false;
|
57 |
+
}
|
58 |
|
59 |
+
function track($event,$data){
|
60 |
+
if (file_exists(realpath(dirname(__FILE__)) . '/mixpanel/Mixpanel.php')) {
|
61 |
+
require_once(realpath(dirname(__FILE__)) . '/mixpanel/Mixpanel.php');
|
62 |
+
$mp = Mixpanel::getInstance("965556434c5ae652a44f24b85b442263");
|
63 |
+
$domain = str_replace("http://","",$_SERVER["SERVER_NAME"]);
|
64 |
|
65 |
+
$mp->track($event, $data);
|
|
|
|
|
|
|
66 |
}
|
|
|
67 |
}
|
|
|
|
|
68 |
|
69 |
+
function activate_single(){
|
70 |
+
die(json_encode($this->activate($_POST['blog_id'], $_POST['user_id'], $_POST['domain'], $_POST['path'])));
|
71 |
+
}
|
72 |
|
73 |
+
function send_request_curl($url, $post){
|
74 |
+
$ch = curl_init($url);
|
75 |
+
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
76 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
77 |
+
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
|
78 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS,json_encode($post));
|
79 |
+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
80 |
+
$result = curl_exec($ch);
|
81 |
+
curl_close($ch);
|
82 |
+
return $result;
|
83 |
+
}
|
84 |
|
85 |
+
function send_request($type,$end_point, $data = null,$second_attempt = null){
|
86 |
// var_dump('send_request');
|
87 |
//var_dump("FUNCTION: send_request");
|
88 |
|
89 |
+
if (strpos($_SERVER['SERVER_PROTOCOL'], 'https') === false) {
|
90 |
+
$protocol = 'http:';
|
91 |
+
} else {
|
92 |
+
$protocol = 'https:';
|
93 |
+
}
|
|
|
|
|
|
|
94 |
|
95 |
+
$url = $protocol . SK_API . $end_point;
|
|
|
96 |
$sk_token = get_transient('sk_token');
|
|
|
97 |
|
98 |
+
if (!$sk_token && $end_point !== '/login') {
|
99 |
+
$this->login();
|
100 |
+
$sk_token = get_transient('sk_token');
|
101 |
+
}
|
102 |
|
103 |
+
$headers = array('Content-Type:application/json');
|
|
|
|
|
104 |
|
105 |
+
if ($sk_token && $end_point !== '/login') {
|
106 |
+
$headers[] = "Authorization: $sk_token";
|
107 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
|
109 |
+
$ch = curl_init($url);
|
110 |
+
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($type));
|
111 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
112 |
+
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
113 |
+
if ($data) {
|
114 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS,json_encode($data));
|
115 |
+
}
|
116 |
+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
117 |
+
$result = curl_exec($ch);
|
118 |
+
curl_close($ch);
|
119 |
|
120 |
+
// echo $result; var_dump($url); var_dump($headers); var_dump($data); var_dump($result); die();
|
|
|
|
|
121 |
|
122 |
+
if ($result == 'HTTP/1.1 401 Unauthorized' && !$second_attempt) {
|
123 |
+
// var_dump('Getting rid of token and trying again');
|
124 |
+
$this->login();
|
125 |
+
delete_transient('sk_token');
|
126 |
+
$this->send_request('post',$type,$data,true);
|
127 |
+
}
|
128 |
|
129 |
+
return json_decode($result);
|
|
|
130 |
}
|
131 |
|
132 |
+
function setup_menu(){
|
133 |
+
add_submenu_page( 'settings.php', 'Sidekick - Licensing', 'Sidekick - Licensing', 'activate_plugins','sidekick-licensing', array(&$this,'admin_page'));
|
134 |
+
}
|
135 |
+
|
136 |
+
function login(){
|
137 |
+
global $login_error;
|
138 |
|
139 |
+
$email = get_option('sk_account');
|
140 |
+
$password = get_option('sk_password');
|
141 |
+
delete_option('sk_auto_activation_error');
|
142 |
|
143 |
+
if (!$password || !$email) {
|
144 |
+
return false;
|
145 |
+
}
|
146 |
|
147 |
+
$string = $password;
|
148 |
+
$key = 'hash';
|
149 |
+
$decrypted_password = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($password), MCRYPT_MODE_CBC, md5(md5($key))), "\0");
|
150 |
|
151 |
+
$result = $this->send_request('post','/login',array('email' => $email, 'password' => $decrypted_password));
|
152 |
+
|
153 |
+
if (!isset($result) || !$result->success) {
|
154 |
+
delete_option( 'sk_token' );
|
155 |
+
return array('error' => $result->message);
|
156 |
+
} else {
|
157 |
+
set_transient( 'sk_token', $result->payload->token->value, 24 * HOUR_IN_SECONDS );
|
158 |
+
$this->load_subscriptions($result->payload->token->value);
|
159 |
+
return array('success' => true);
|
160 |
+
}
|
161 |
+
}
|
162 |
|
163 |
+
function load_user_data(){
|
164 |
+
return $this->send_request('get','/users/');
|
|
|
|
|
|
|
|
|
|
|
165 |
}
|
|
|
166 |
|
167 |
+
function load_subscriptions(){
|
168 |
+
|
169 |
+
$result = $this->send_request('get','/users/subscriptions');
|
170 |
+
$load_products = false;
|
171 |
+
|
172 |
+
if (isset($result->success) && isset($result->payload)) {
|
173 |
|
174 |
+
$sub = $result->payload[0];
|
175 |
+
|
176 |
+
if (isset($sub->Plan->CreatableProductType) && $sub->Plan->CreatableProductType->name == 'Public') {
|
177 |
+
$this->logout();
|
178 |
+
update_option( 'sk_auto_activation_error', 'Public accounts are not compatible with MultiSite activations.');
|
179 |
+
return false;
|
180 |
+
} if (isset($sub->Plan->CreatableProductType) && $sub->Plan->CreatableProductType->name == 'Private') {
|
181 |
+
update_option( 'sk_selected_subscription', 'product-' . $sub->id );
|
182 |
+
} else {
|
183 |
+
update_option( 'sk_selected_subscription', 'subscription-' . $sub->id );
|
184 |
}
|
185 |
+
|
186 |
+
if (isset($sub->Plan->CreatableProductType) && isset($sub->Plan->CreatableProductType->name) && $sub->Plan->CreatableProductType->name == 'Private') {
|
187 |
+
$load_products = true;
|
188 |
+
}
|
189 |
+
|
190 |
if (count($sub->Domains) > 0) {
|
191 |
foreach ($sub->Domains as &$domain) {
|
192 |
if (!$domain->DomainSubscription->end) {
|
197 |
}
|
198 |
}
|
199 |
}
|
200 |
+
} if (count($sub->PrivateProductSubscriptions) > 0) {
|
201 |
+
foreach ($sub->PrivateProductSubscriptions as &$domain) {
|
202 |
+
if (isset($sub->activeDomainCount)) {
|
203 |
+
$sub->activeDomainCount++;
|
204 |
+
} else {
|
205 |
+
$sub->activeDomainCount = 1;
|
206 |
+
}
|
207 |
+
}
|
208 |
} else {
|
209 |
$sub->activeDomainCount = 0;
|
210 |
}
|
211 |
|
212 |
+
$data['subscriptions'] = $result->payload;
|
213 |
+
|
214 |
+
if ($load_products) {
|
215 |
+
$data['products'] = $this->load_products();
|
216 |
+
}
|
217 |
+
|
218 |
+
return $data;
|
219 |
+
} else if (isset($result->message) && strpos($result->message, 'Invalid Token') !== false) {
|
220 |
+
$this->logout();
|
221 |
+
update_option( 'sk_auto_activation_error', 'Please authorize SIDEKICK by logging in.');
|
222 |
}
|
223 |
+
return null;
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
}
|
|
|
|
|
225 |
|
226 |
+
function logout(){
|
227 |
+
delete_option( 'sk_account');
|
228 |
+
delete_option( 'sk_password');
|
229 |
+
delete_option( 'sk_selected_subscription');
|
230 |
+
delete_option( 'sk_selected_product');
|
231 |
+
}
|
232 |
|
233 |
+
function load_products(){
|
234 |
+
$result = $this->send_request('get','/products');
|
235 |
+
if ($result->success) {
|
236 |
+
return $result->payload->products;
|
237 |
+
}
|
238 |
+
return null;
|
239 |
+
}
|
240 |
|
241 |
+
function admin_page(){
|
242 |
+
if (isset($_POST['sk_account'])) {
|
243 |
|
|
|
|
|
|
|
244 |
delete_option('sk_auto_activation_error');
|
245 |
+
|
246 |
+
if (isset($_POST['sk_password']) && $_POST['sk_password'] && isset($_POST['sk_account']) && $_POST['sk_account']) {
|
247 |
+
$key = 'hash';
|
248 |
+
$string = $_POST['sk_password'];
|
249 |
+
|
250 |
+
$encrypted_password = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key))));
|
251 |
+
$decrypted_password = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($encrypted_password), MCRYPT_MODE_CBC, md5(md5($key))), "\0");
|
252 |
+
|
253 |
+
update_option( 'sk_account', $_POST['sk_account'] );
|
254 |
+
update_option( 'sk_password', $encrypted_password );
|
255 |
+
$login_status = $this->login();
|
256 |
+
delete_option('sk_auto_activation_error');
|
257 |
+
} else {
|
258 |
+
update_option( 'sk_selected_subscription', $_POST['sk_selected_subscription'] );
|
259 |
+
}
|
260 |
+
|
261 |
+
if (isset($_POST['sk_auto_activations'])) {
|
262 |
+
update_option( 'sk_auto_activations', true );
|
263 |
+
} else {
|
264 |
+
delete_option( 'sk_auto_activations');
|
265 |
+
}
|
266 |
+
|
267 |
+
if (isset($_POST['sk_selected_product']) && $_POST['sk_selected_product'] !== '0' && isset($_POST['sk_selected_subscription']) && strpos($_POST['sk_selected_subscription'], 'product') !== false) {
|
268 |
+
update_option( 'sk_selected_product', $_POST['sk_selected_product'] );
|
269 |
+
} else {
|
270 |
+
delete_option( 'sk_selected_product');
|
271 |
+
}
|
272 |
+
|
273 |
}
|
274 |
|
275 |
+
$sk_token = get_transient('sk_token');
|
276 |
+
if (!$sk_token) {
|
277 |
+
$login_status = $this->login();
|
278 |
+
}
|
279 |
+
$sk_subs = $this->load_subscriptions();
|
280 |
+
$user_data = $this->load_user_data();
|
281 |
+
$sk_auto_activations = get_option( 'sk_auto_activations');
|
282 |
+
$sk_auto_activation_error = get_option('sk_auto_activation_error');
|
283 |
+
$sk_selected_subscription = get_option('sk_selected_subscription');
|
284 |
+
$sk_selected_product = get_option('sk_selected_product');
|
285 |
+
$is_ms_admin = true;
|
286 |
+
$curl = function_exists('curl_version') ? true : false;
|
287 |
+
$fgets = file_get_contents(__FILE__) ? true : false;
|
288 |
+
$fgets_url = ini_get('allow_url_fopen') ? true : false;
|
289 |
+
|
290 |
+
if ($curl && (!$fgets || !$fgets_url)) {
|
291 |
+
$error = "Sorry, SIDEKICK MultiSite activations require <b>CURL</b> or <b>file_get_contents</b> functions enabled in PHP.";
|
292 |
}
|
|
|
293 |
|
294 |
+
require_once('ms_admin_page.php');
|
|
|
|
|
295 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
296 |
}
|
297 |
}
|
298 |
|
299 |
+
// //licensing.php
|
libs/mixpanel/Base/MixpanelBase.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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" => false, // 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 |
+
}
|
libs/mixpanel/ConsumerStrategies/AbstractConsumer.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
}
|
libs/mixpanel/ConsumerStrategies/CurlConsumer.php
ADDED
@@ -0,0 +1,221 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
}
|
libs/mixpanel/ConsumerStrategies/FileConsumer.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
}
|
libs/mixpanel/ConsumerStrategies/SocketConsumer.php
ADDED
@@ -0,0 +1,308 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
}
|
libs/mixpanel/Mixpanel.php
ADDED
@@ -0,0 +1,302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
}
|
libs/mixpanel/Producers/MixpanelBaseProducer.php
ADDED
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
}
|
libs/mixpanel/Producers/MixpanelEvents.php
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
}
|
libs/mixpanel/Producers/MixpanelPeople.php
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
}
|
libs/ms_admin_page.php
CHANGED
@@ -1,9 +1,16 @@
|
|
|
|
|
|
1 |
<script type="text/javascript">
|
2 |
if (typeof ajax_url === 'undefined') {
|
3 |
ajax_url = '<?php echo admin_url() ?>admin-ajax.php';
|
4 |
}
|
5 |
var last_site_key = null;
|
6 |
var sk_ms_admin = true;
|
|
|
|
|
|
|
|
|
|
|
7 |
</script>
|
8 |
|
9 |
<div class="page-header"><h2><a id="pluginlogo_32" class="header-icon32" href="http://www.sidekick.pro" target="_blank"></a>Sidekick Licensing</h2></div>
|
@@ -40,8 +47,6 @@
|
|
40 |
</div>
|
41 |
<?php endif ?>
|
42 |
|
43 |
-
|
44 |
-
|
45 |
<div class="sidekick_admin">
|
46 |
|
47 |
<div class="sk_box left">
|
@@ -69,24 +74,32 @@
|
|
69 |
<input class='regular-text' type='password' name='sk_password' placeholder='********'></input>
|
70 |
</td>
|
71 |
</tr>
|
72 |
-
<tr valign="top">
|
73 |
<th scope="row" valign="top">Subscription</th>
|
74 |
<td>
|
75 |
<select name='sk_selected_subscription'>
|
76 |
<?php if (isset($sk_subs['subscriptions']) && count($sk_subs['subscriptions']) > 0): ?>
|
77 |
<?php foreach ($sk_subs['subscriptions'] as $key => $sub): ?>
|
78 |
<?php
|
79 |
-
if ($sub->PlanId !== 1) {
|
80 |
continue;
|
81 |
}
|
82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
$selected_sub = $sub;
|
84 |
$selected = 'SELECTED';
|
85 |
} else {
|
86 |
$selected = '';
|
87 |
}
|
88 |
?>
|
89 |
-
<option <?php echo $selected ?> value='<?php echo $sub->id ?>'><?php echo $sub->Plan->name . ' - ' . $sub->CurrentTier->name ?></option>
|
90 |
<?php endforeach ?>
|
91 |
<?php if (!isset($selected_sub)): ?>
|
92 |
<option value='0'>No Compatible Subscriptions</option>
|
@@ -97,17 +110,38 @@
|
|
97 |
</select>
|
98 |
</td>
|
99 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
<tr valign="top">
|
101 |
<th scope="row" valign="top">Enable Auto-Activations</th>
|
102 |
<td>
|
103 |
-
<?php if (!isset($selected_sub)): ?>
|
104 |
<input class='checkbox' type='checkbox' name='sk_auto_activations' DISABLED>
|
105 |
<?php else: ?>
|
106 |
<input class='checkbox' type='checkbox' name='sk_auto_activations' <?php echo ($sk_auto_activations) ? 'CHECKED' : '' ?>>
|
107 |
<?php endif ?>
|
108 |
</td>
|
109 |
</tr>
|
110 |
-
<?php
|
|
|
111 |
<tr>
|
112 |
<th scope="row" valign="top">Active Domains</th>
|
113 |
<td><?php echo $selected_sub->activeDomainCount ?>/ <?php echo ($selected_sub->CurrentTier->numberOfDomains == -1) ? 'Unlimited' : $selected_sub->CurrentTier->numberOfDomains ?> (<a href='https://www.sidekick.pro/profile/#/overview' target='_blank'>Manage</a>)
|
@@ -212,6 +246,6 @@
|
|
212 |
|
213 |
</div>
|
214 |
|
215 |
-
|
216 |
|
217 |
|
1 |
+
<!-- ms_admin_page.php -->
|
2 |
+
|
3 |
<script type="text/javascript">
|
4 |
if (typeof ajax_url === 'undefined') {
|
5 |
ajax_url = '<?php echo admin_url() ?>admin-ajax.php';
|
6 |
}
|
7 |
var last_site_key = null;
|
8 |
var sk_ms_admin = true;
|
9 |
+
|
10 |
+
jQuery(document).ready(function($) {
|
11 |
+
mixpanel.track('Network Settings Page Visit - Plugin');
|
12 |
+
});
|
13 |
+
|
14 |
</script>
|
15 |
|
16 |
<div class="page-header"><h2><a id="pluginlogo_32" class="header-icon32" href="http://www.sidekick.pro" target="_blank"></a>Sidekick Licensing</h2></div>
|
47 |
</div>
|
48 |
<?php endif ?>
|
49 |
|
|
|
|
|
50 |
<div class="sidekick_admin">
|
51 |
|
52 |
<div class="sk_box left">
|
74 |
<input class='regular-text' type='password' name='sk_password' placeholder='********'></input>
|
75 |
</td>
|
76 |
</tr>
|
77 |
+
<tr valign="top" style='display: none'>
|
78 |
<th scope="row" valign="top">Subscription</th>
|
79 |
<td>
|
80 |
<select name='sk_selected_subscription'>
|
81 |
<?php if (isset($sk_subs['subscriptions']) && count($sk_subs['subscriptions']) > 0): ?>
|
82 |
<?php foreach ($sk_subs['subscriptions'] as $key => $sub): ?>
|
83 |
<?php
|
84 |
+
if ($sub->PlanId !== 1 && $sub->Plan->CreatableProductType->name !== 'Private') {
|
85 |
continue;
|
86 |
}
|
87 |
+
|
88 |
+
if (isset($sub->Plan->CreatableProductType->name) && $sub->Plan->CreatableProductType->name == 'Private') {
|
89 |
+
$type = 'product';
|
90 |
+
} else {
|
91 |
+
$type = 'subscription';
|
92 |
+
}
|
93 |
+
|
94 |
+
|
95 |
+
if ($sk_selected_subscription == ($type . '-' . $sub->id) || !isset($selected_sub)) {
|
96 |
$selected_sub = $sub;
|
97 |
$selected = 'SELECTED';
|
98 |
} else {
|
99 |
$selected = '';
|
100 |
}
|
101 |
?>
|
102 |
+
<option <?php echo $selected ?> value='<?php echo (isset($sub->Plan->CreatableProductType->name) && $sub->Plan->CreatableProductType->name == 'Private') ? "product-" : "subscription-"; echo $sub->id ?>'><?php echo $sub->Plan->name . ' - ' . $sub->CurrentTier->name ?></option>
|
103 |
<?php endforeach ?>
|
104 |
<?php if (!isset($selected_sub)): ?>
|
105 |
<option value='0'>No Compatible Subscriptions</option>
|
110 |
</select>
|
111 |
</td>
|
112 |
</tr>
|
113 |
+
<?php if (isset($sk_subs['products'])): ?>
|
114 |
+
|
115 |
+
<tr valign="top" style='display: none' class='walkthrough_library'>
|
116 |
+
<th scope="row" valign="top">Library</th>
|
117 |
+
<td>
|
118 |
+
<select name='sk_selected_product'>
|
119 |
+
<?php if (isset($sk_subs['products']) && count($sk_subs['products']) > 0): ?>
|
120 |
+
<?php foreach ($sk_subs['products'] as $key => $product): ?>
|
121 |
+
<option <?php echo ($sk_selected_product == $product->id) ? 'SELECTED' : '' ?> value='<?php echo $product->id ?>'><?php echo $product->name ?></option>
|
122 |
+
<?php endforeach ?>
|
123 |
+
<?php else: ?>
|
124 |
+
<option style='color: red' value='0'>No Libraries Found!</option>
|
125 |
+
<?php $no_product = true; delete_option( 'sk_auto_activations') ?>
|
126 |
+
<?php endif ?>
|
127 |
+
</select>
|
128 |
+
</td>
|
129 |
+
</tr>
|
130 |
+
|
131 |
+
<?php endif ?>
|
132 |
+
|
133 |
<tr valign="top">
|
134 |
<th scope="row" valign="top">Enable Auto-Activations</th>
|
135 |
<td>
|
136 |
+
<?php if (!isset($selected_sub) || isset($no_product)): ?>
|
137 |
<input class='checkbox' type='checkbox' name='sk_auto_activations' DISABLED>
|
138 |
<?php else: ?>
|
139 |
<input class='checkbox' type='checkbox' name='sk_auto_activations' <?php echo ($sk_auto_activations) ? 'CHECKED' : '' ?>>
|
140 |
<?php endif ?>
|
141 |
</td>
|
142 |
</tr>
|
143 |
+
<?php //var_dump($selected_sub); ?>
|
144 |
+
<?php if (isset($selected_sub) && !isset($no_product)): ?>
|
145 |
<tr>
|
146 |
<th scope="row" valign="top">Active Domains</th>
|
147 |
<td><?php echo $selected_sub->activeDomainCount ?>/ <?php echo ($selected_sub->CurrentTier->numberOfDomains == -1) ? 'Unlimited' : $selected_sub->CurrentTier->numberOfDomains ?> (<a href='https://www.sidekick.pro/profile/#/overview' target='_blank'>Manage</a>)
|
246 |
|
247 |
</div>
|
248 |
|
249 |
+
<!-- //ms_admin_page.php -->
|
250 |
|
251 |
|
libs/sk_config_data.php
CHANGED
@@ -1,205 +1,200 @@
|
|
1 |
<?php
|
|
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
$site_url =
|
|
|
|
|
|
|
|
|
|
|
8 |
}
|
9 |
-
$site_url = str_replace(array("http://","https://"),array(""),$site_url);
|
10 |
-
return $site_url;
|
11 |
-
}
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
|
|
|
|
|
22 |
}
|
23 |
-
return $output;
|
24 |
-
}
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
|
41 |
-
|
|
|
|
|
42 |
}
|
43 |
-
return $output;
|
44 |
-
}
|
45 |
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
|
|
|
|
|
55 |
}
|
56 |
-
return $output;
|
57 |
-
}
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
|
|
|
|
76 |
}
|
77 |
-
return $output;
|
78 |
-
}
|
79 |
|
80 |
-
|
81 |
-
|
82 |
|
83 |
-
|
84 |
-
|
85 |
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
91 |
}
|
92 |
-
return $output;
|
93 |
-
}
|
94 |
|
95 |
-
|
96 |
-
|
97 |
|
98 |
-
|
99 |
|
100 |
-
|
101 |
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
|
|
108 |
}
|
|
|
109 |
}
|
110 |
-
break;
|
111 |
}
|
|
|
112 |
}
|
113 |
-
return $output;
|
114 |
-
}
|
115 |
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
|
|
128 |
}
|
129 |
-
}
|
130 |
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
|
|
|
|
135 |
}
|
136 |
-
return 'false';
|
137 |
-
}
|
138 |
-
|
139 |
-
function get_disabled_network_wts(){
|
140 |
-
$wts = str_replace('"', '', get_site_option('sk_disabled_wts'));
|
141 |
|
142 |
-
|
143 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
}
|
145 |
-
return 'false';
|
146 |
-
}
|
147 |
-
|
148 |
-
function get_plugins(){
|
149 |
-
$active_plugins = wp_get_active_and_valid_plugins();
|
150 |
-
$mu_plugins = get_mu_plugins();
|
151 |
-
|
152 |
-
$printed = false;
|
153 |
|
154 |
-
|
155 |
-
$count = 0;
|
156 |
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
|
|
167 |
}
|
168 |
-
}
|
169 |
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
$output .= "{'{$plugin['Name']}' : '{$plugin['Version']}'}";
|
176 |
-
$printed = true;
|
177 |
-
$count++;
|
178 |
}
|
|
|
179 |
}
|
180 |
-
$output .= ']';
|
181 |
-
return array('plugins' => $output, 'count' => $count);
|
182 |
-
}
|
183 |
|
184 |
-
|
185 |
-
|
186 |
|
187 |
-
|
188 |
-
return 'administrator';
|
189 |
-
}
|
190 |
-
|
191 |
-
if(!isset($current_user->caps) || count($current_user->caps) < 1){
|
192 |
-
// In MS in some specific pages current user is returning empty caps so this is a work around for that case.
|
193 |
-
if (current_user_can('activate_plugins')){
|
194 |
return 'administrator';
|
195 |
}
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
|
|
201 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
}
|
203 |
-
return $user_role;
|
204 |
}
|
205 |
-
}
|
|
|
|
1 |
<?php
|
2 |
+
// sk_config_data.php
|
3 |
|
4 |
+
if (!class_exists('sk_config_data')) {
|
5 |
+
|
6 |
+
class sk_config_data{
|
7 |
+
function get_domain(){
|
8 |
+
$site_url = get_site_url();
|
9 |
+
if(substr($site_url, -1) == '/') {
|
10 |
+
$site_url = substr($site_url, 0, -1);
|
11 |
+
}
|
12 |
+
$site_url = str_replace(array("http://","https://"),array(""),$site_url);
|
13 |
+
return $site_url;
|
14 |
}
|
|
|
|
|
|
|
15 |
|
16 |
+
function get_post_types(){
|
17 |
+
global $wpdb;
|
18 |
+
$query = "SELECT post_type, count(distinct ID) as count from {$wpdb->prefix}posts group by post_type";
|
19 |
+
$counts = $wpdb->get_results($query);
|
20 |
+
$output = '';
|
21 |
|
22 |
+
foreach ($counts as $key => $type) {
|
23 |
+
$type->post_type = str_replace('-', '_', $type->post_type);
|
24 |
+
$output .= "\n post_type_{$type->post_type} : $type->count,";
|
25 |
+
}
|
26 |
+
return $output;
|
27 |
}
|
|
|
|
|
28 |
|
29 |
+
function get_themes(){
|
30 |
+
$themes = wp_get_themes( array( 'allowed' => true ) );
|
31 |
+
return count($themes);
|
32 |
+
}
|
33 |
|
34 |
+
function get_post_types_and_statuses(){
|
35 |
+
global $wpdb;
|
36 |
+
$query = "SELECT post_type, post_status, count(distinct ID) as count from {$wpdb->prefix}posts group by post_type, post_status";
|
37 |
+
$counts = $wpdb->get_results($query);
|
38 |
+
$output = '';
|
39 |
|
40 |
+
foreach ($counts as $key => $type) {
|
41 |
+
$type->post_type = str_replace('-', '_', $type->post_type);
|
42 |
+
$type->post_status = str_replace('-', '_', $type->post_status);
|
43 |
|
44 |
+
$output .= "\n post_type_{$type->post_type}_{$type->post_status} : $type->count,";
|
45 |
+
}
|
46 |
+
return $output;
|
47 |
}
|
|
|
|
|
48 |
|
49 |
+
function get_taxonomies(){
|
50 |
+
global $wpdb;
|
51 |
+
$query = "SELECT count(distinct term_taxonomy_id) as count, taxonomy from {$wpdb->prefix}term_taxonomy group by taxonomy";
|
52 |
+
$counts = $wpdb->get_results($query);
|
53 |
+
$output = '';
|
54 |
|
55 |
+
foreach ($counts as $key => $taxonomy) {
|
56 |
+
$taxonomy->taxonomy = str_replace('-', '_', $taxonomy->taxonomy);
|
57 |
+
$output .= "\n taxonomy_{$taxonomy->taxonomy} : $taxonomy->count,";
|
58 |
+
}
|
59 |
+
return $output;
|
60 |
}
|
|
|
|
|
61 |
|
62 |
+
function get_comments(){
|
63 |
+
global $wpdb;
|
64 |
+
$query = "SELECT count(distinct comment_ID) as count from {$wpdb->prefix}comments";
|
65 |
+
$counts = $wpdb->get_var($query);
|
66 |
+
if (!$counts) $counts = 0;
|
67 |
+
return "\n comment_count : $counts,";
|
68 |
+
}
|
69 |
|
70 |
+
function get_post_statuses(){
|
71 |
+
global $wpdb;
|
72 |
+
$query = "SELECT post_status, count(ID) as count from {$wpdb->prefix}posts group by post_status";
|
73 |
+
$counts = $wpdb->get_results($query);
|
74 |
+
$output = '';
|
75 |
|
76 |
+
foreach ($counts as $key => $type) {
|
77 |
+
$type->post_status = str_replace('-', '_', $type->post_status);
|
78 |
+
$output .= "\n post_status_{$type->post_status} : $type->count,";
|
79 |
+
}
|
80 |
+
return $output;
|
81 |
}
|
|
|
|
|
82 |
|
83 |
+
function get_user_data(){
|
84 |
+
global $current_user;
|
85 |
|
86 |
+
$data = get_userdata($current_user->ID);
|
87 |
+
$output = "\n user_id : $current_user->ID,";
|
88 |
|
89 |
+
foreach ($data->allcaps as $cap => $val) {
|
90 |
+
$cap = sanitize_title($cap);
|
91 |
+
$cap = str_replace('-', '_', $cap);
|
92 |
+
if (!$val) $val = 0;
|
93 |
+
$output .= "\n cap_{$cap} : $val,";
|
94 |
+
}
|
95 |
+
return $output;
|
96 |
}
|
|
|
|
|
97 |
|
98 |
+
function get_framework(){
|
99 |
+
global $current_user;
|
100 |
|
101 |
+
$frameworks = array('genesis');
|
102 |
|
103 |
+
$output = "\n theme_framework : false,";
|
104 |
|
105 |
+
foreach ($frameworks as $framework) {
|
106 |
+
switch ($framework) {
|
107 |
+
case 'genesis':
|
108 |
+
if (function_exists( 'genesis' ) ) {
|
109 |
+
if (defined('PARENT_THEME_VERSION')) {
|
110 |
+
$output = "\n theme_framework : {name: '" . $framework . "', version: '" . PARENT_THEME_VERSION . "'},";
|
111 |
+
}
|
112 |
}
|
113 |
+
break;
|
114 |
}
|
|
|
115 |
}
|
116 |
+
return $output;
|
117 |
}
|
|
|
|
|
118 |
|
119 |
+
function get_current_url() {
|
120 |
+
if (isset($_SERVER['REQUEST_URI'])) {
|
121 |
+
return 'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
|
122 |
+
} else if (isset($_SERVER['PATH_INFO'])) {
|
123 |
+
return $_SERVER['PATH_INFO'];
|
124 |
+
} else {
|
125 |
+
$host = $_SERVER['HTTP_HOST'];
|
126 |
+
$port = $_SERVER['SERVER_PORT'];
|
127 |
+
$request = $_SERVER['PHP_SELF'];
|
128 |
+
$query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';
|
129 |
+
$toret = $protocol . '://' . $host . ($port == $protocol_port ? '' : ':' . $port) . $request . (empty($query) ? '' : '?' . $query);
|
130 |
+
return $toret;
|
131 |
+
}
|
132 |
}
|
|
|
133 |
|
134 |
+
function get_disabled_wts(){
|
135 |
+
$wts = str_replace('"', '', get_option('sk_disabled_wts'));
|
136 |
+
if ($wts) {
|
137 |
+
return $wts;
|
138 |
+
}
|
139 |
+
return 'false';
|
140 |
}
|
|
|
|
|
|
|
|
|
|
|
141 |
|
142 |
+
function get_disabled_network_wts(){
|
143 |
+
if (is_multisite()) {
|
144 |
+
$wts = str_replace('"', '', get_site_option('sk_disabled_wts'));
|
145 |
+
if ($wts) {
|
146 |
+
return $wts;
|
147 |
+
}
|
148 |
+
}
|
149 |
+
return 'false';
|
150 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
|
152 |
+
function get_plugins(){
|
|
|
153 |
|
154 |
+
$active_plugins = wp_get_active_and_valid_plugins();
|
155 |
+
$mu_plugins = get_mu_plugins();
|
156 |
+
$output = array();
|
157 |
|
158 |
+
if (is_array($active_plugins)) {
|
159 |
+
foreach ($active_plugins as $plugins_key => $plugin) {
|
160 |
+
$data = get_plugin_data( $plugin, false, false );
|
161 |
+
$slug = explode('/',plugin_basename($plugin));
|
162 |
+
$slug = str_replace('.php', '', $slug[1]);
|
163 |
+
$output[$slug] = $data['Version'];
|
164 |
+
}
|
165 |
}
|
|
|
166 |
|
167 |
+
if (is_array($mu_plugins)) {
|
168 |
+
foreach ($mu_plugins as $plugins_key => $plugin) {
|
169 |
+
$slug = str_replace('.php', '', $plugins_key);
|
170 |
+
$output[$slug] = '1.0.0';
|
171 |
+
}
|
|
|
|
|
|
|
172 |
}
|
173 |
+
return $output;
|
174 |
}
|
|
|
|
|
|
|
175 |
|
176 |
+
function get_user_role(){
|
177 |
+
global $current_user, $wp_roles;
|
178 |
|
179 |
+
if (is_super_admin($current_user->ID)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
return 'administrator';
|
181 |
}
|
182 |
+
|
183 |
+
if(!isset($current_user->caps) || count($current_user->caps) < 1){
|
184 |
+
// In MS in some specific pages current user is returning empty caps so this is a work around for that case.
|
185 |
+
if (current_user_can('activate_plugins')){
|
186 |
+
return 'administrator';
|
187 |
+
}
|
188 |
}
|
189 |
+
foreach($wp_roles->role_names as $role => $Role) {
|
190 |
+
if (array_key_exists($role, $current_user->caps)){
|
191 |
+
$user_role = $role;
|
192 |
+
break;
|
193 |
+
}
|
194 |
+
}
|
195 |
+
return $user_role;
|
196 |
}
|
|
|
197 |
}
|
198 |
+
}
|
199 |
+
|
200 |
+
// //sk_config_data.php
|
libs/walkthrough_config.php
CHANGED
@@ -19,9 +19,11 @@
|
|
19 |
|
20 |
<div class="sk_box configure">
|
21 |
<div class="well">
|
22 |
-
<h3>Configure - Turn Off Walkthroughs</h3>
|
23 |
-
|
24 |
<form method='post'>
|
|
|
|
|
|
|
|
|
25 |
<p>Below you can turn off specific Walkthroughs for this website.</p>
|
26 |
<p>Please note, incompatible multisite walkthroughs will be disabled automatically on individual sites already. Here you're being show the raw unfiltered list of all available walkthroughs.</p>
|
27 |
<div class='sk_walkthrough_list wrapper_wts'>
|
19 |
|
20 |
<div class="sk_box configure">
|
21 |
<div class="well">
|
|
|
|
|
22 |
<form method='post'>
|
23 |
+
|
24 |
+
<input class='top-right button button-primary alignright' type='submit' value='Save'/>
|
25 |
+
<h3>Configure - Turn Off Walkthroughs</h3>
|
26 |
+
|
27 |
<p>Below you can turn off specific Walkthroughs for this website.</p>
|
28 |
<p>Please note, incompatible multisite walkthroughs will be disabled automatically on individual sites already. Here you're being show the raw unfiltered list of all available walkthroughs.</p>
|
29 |
<div class='sk_walkthrough_list wrapper_wts'>
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: http://www.sidekick.pro
|
|
4 |
Tags: help, tutorial, training, learn, learning, sidekick, guide, teach, video, manual, videos, wphelp, support, instructions, question, questions, answers, answer, clippy, q&a, wpuniversity, helper, walkthrough
|
5 |
Requires at least: 3.7
|
6 |
Tested up to: 4.1
|
7 |
-
Stable tag: 2.0
|
8 |
License: GNU Version 2 or Any Later Version
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -130,7 +130,21 @@ Absolutely. In fact, we rely on users like you to tell us about things that nee
|
|
130 |
|
131 |
== Changelog ==
|
132 |
|
133 |
-
= 2.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
* Multisite Walkthrough Management Support
|
135 |
* Multisite Auto Activations
|
136 |
* Multisite Mass Activations
|
4 |
Tags: help, tutorial, training, learn, learning, sidekick, guide, teach, video, manual, videos, wphelp, support, instructions, question, questions, answers, answer, clippy, q&a, wpuniversity, helper, walkthrough
|
5 |
Requires at least: 3.7
|
6 |
Tested up to: 4.1
|
7 |
+
Stable tag: 2.2.0
|
8 |
License: GNU Version 2 or Any Later Version
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
130 |
|
131 |
== Changelog ==
|
132 |
|
133 |
+
= 2.2.0 =
|
134 |
+
* SIDEKICK can now be embeded within other plugins!
|
135 |
+
* Custom walkthrough plans are now supported within MultiSite auto activation
|
136 |
+
* Wildcard compatibility matching added
|
137 |
+
* Captioning support added
|
138 |
+
* Fixes issues with general UI elements
|
139 |
+
* Fixes issues with walkthrough preview
|
140 |
+
* Fixes issues with Safari alignment on settings page
|
141 |
+
|
142 |
+
= 2.1.1 =
|
143 |
+
* Added SIDEKICK version check
|
144 |
+
* Fixes issues with saving autostart walkthroughs
|
145 |
+
* Fixes issues with disabling walkthroughs
|
146 |
+
|
147 |
+
= 2.1.0 =
|
148 |
* Multisite Walkthrough Management Support
|
149 |
* Multisite Auto Activations
|
150 |
* Multisite Mass Activations
|
sidekick.php
CHANGED
@@ -4,436 +4,485 @@
|
|
4 |
Plugin Name: Sidekick
|
5 |
Plugin URL: http://wordpress.org/plugins/sidekick/
|
6 |
Description: Adds a real-time WordPress training walkthroughs right in your Dashboard
|
7 |
-
Requires at least:
|
8 |
-
Tested up to: 4.
|
9 |
-
Version: 2.0
|
10 |
Author: Sidekick.pro
|
11 |
Author URI: http://www.sidekick.pro
|
12 |
*/
|
13 |
|
14 |
|
15 |
-
if ( ! defined( '
|
16 |
-
if ( ! defined( '
|
17 |
-
if ( ! defined( '
|
18 |
-
if ( ! defined( '
|
19 |
-
if ( ! defined( '
|
20 |
-
if ( ! defined( 'SK_SL_PLUGIN_FILE' ) ) define( 'SK_SL_PLUGIN_FILE', __FILE__ );
|
21 |
if ( ! function_exists('mlog')) {
|
22 |
function mlog(){}
|
23 |
}
|
24 |
|
25 |
-
|
26 |
|
27 |
-
|
28 |
-
if (!defined('SK_TRACKING_API')) define('SK_TRACKING_API','//tracking.sidekick.pro/');
|
29 |
-
if (!defined('SK_COMPOSER_API')) define('SK_COMPOSER_API','//apiv2.sidekick.pro');
|
30 |
-
if (!defined('SK_API')) define('SK_API','//apiv2.sidekick.pro/');
|
31 |
-
if (!defined('SK_LIBRARY')) define('SK_LIBRARY','//librarycache.sidekick.pro/');
|
32 |
-
if (!defined('SK_ASSETS')) define('SK_ASSETS','//assets.sidekick.pro/');
|
33 |
-
if (!defined('SK_AUDIO')) define('SK_AUDIO','//audio.sidekick.pro/');
|
34 |
-
}
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
wp_enqueue_script('jquery-effects-scale' , null, array('jquery-ui-core') );
|
45 |
-
wp_enqueue_script('jquery-effects-highlight' , null, array('jquery-ui-core') );
|
46 |
-
wp_enqueue_script('sidekick-admin' ,plugins_url( '/js/sidekick_admin.js' , __FILE__ ),array( 'jquery' ));
|
47 |
-
}
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
55 |
-
}
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
72 |
}
|
73 |
-
}
|
74 |
|
75 |
-
|
76 |
-
if ( empty( $_POST ) || check_admin_referer( 'update_sk_settings' ) ) {
|
77 |
|
78 |
-
if (
|
79 |
|
80 |
-
if (isset($_POST['
|
81 |
-
$result = $this->activate(true);
|
82 |
-
} else if (isset($_POST['activation_id']) && strpos($_POST['activation_id'], '-xxxx-xxxx') === false) {
|
83 |
-
delete_option('sk_activation_id');
|
84 |
-
}
|
85 |
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
96 |
}
|
97 |
|
98 |
-
update_option( 'sk_activated', true );
|
99 |
-
die('<script>window.open("' . get_site_url() . '/wp-admin/options-general.php?page=sidekick","_self")</script>');
|
100 |
}
|
101 |
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
}
|
107 |
-
}
|
108 |
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
$error = null;
|
114 |
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
$status = 'Checking...';
|
119 |
-
}
|
120 |
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
}
|
125 |
|
126 |
-
|
127 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
}
|
129 |
|
130 |
-
|
131 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
}
|
133 |
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
<?php include('libs/admin_page.php') ?>
|
147 |
-
</div>
|
148 |
-
<?php
|
149 |
-
}
|
150 |
-
|
151 |
-
function set_disabled_wts(){
|
152 |
-
if (isset($_POST['disable_wts']) && $_POST['disable_wts']) {
|
153 |
-
update_option('sk_disabled_wts',json_encode($_POST['disable_wts']));
|
154 |
-
update_site_option('sk_disabled_wts',json_encode($_POST['disable_wts']));
|
155 |
-
} else {
|
156 |
-
delete_option('sk_disabled_wts');
|
157 |
-
delete_site_option('sk_disabled_wts');
|
158 |
}
|
159 |
-
}
|
160 |
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
delete_option('sk_autostart_walkthrough_id');
|
167 |
-
delete_site_option('sk_autostart_walkthrough_id');
|
168 |
}
|
169 |
-
}
|
170 |
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
|
|
|
|
|
207 |
|
|
|
|
|
|
|
|
|
208 |
|
|
|
|
|
|
|
|
|
209 |
|
210 |
-
|
211 |
-
|
|
|
212 |
|
213 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
214 |
|
215 |
-
|
216 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
|
218 |
-
|
|
|
|
|
|
|
|
|
219 |
|
220 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
|
222 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
<?php echo $post_statuses ?>
|
233 |
-
<?php echo $frameworks ?>
|
234 |
-
<?php echo $post_types_and_statuses ?>
|
235 |
-
installed_plugins: <?php echo $installed_plugins ?>,
|
236 |
-
plugin_count: <?php echo $plugin_count ?>,
|
237 |
-
is_multisite: <?php echo (is_multisite()) ? "true" : "false" ?>,
|
238 |
-
number_of_themes: <?php echo $number_of_themes ?>,
|
239 |
-
installed_theme: '<?php echo $theme->Name ?>',
|
240 |
-
main_soft_version: '<?php echo get_bloginfo("version") ?>',
|
241 |
-
theme_version: '<?php echo $theme->Version ?>',
|
242 |
-
user_level: '<?php echo $user_role ?>',
|
243 |
-
main_soft_name: 'WordPress',
|
244 |
-
role: '<?php echo $user_role ?>'
|
245 |
-
},
|
246 |
-
|
247 |
-
disable_wts: <?php echo $disabled_wts ?>,
|
248 |
-
disable_network_wts: <?php echo $disabled_network_wts ?>,
|
249 |
-
main_soft_name: 'WordPress',
|
250 |
-
|
251 |
-
// User Settings
|
252 |
-
activation_id: '<?php echo $activation_id ?>',
|
253 |
-
auto_open_root_bucket_id: 79,
|
254 |
-
auto_open_product: 'default',
|
255 |
-
disable_wts_in_root_bucket_ids: [5,87],
|
256 |
-
autostart_walkthrough_id: <?php echo $autostart_walkthrough_id ?>,
|
257 |
-
sk_composer_button: <?php echo ($sk_composer_button ? "true" : "false") ?>,
|
258 |
-
track_data: '<?php echo $sk_track_data ?>',
|
259 |
-
user_email: '<?php echo $user_email ?>',
|
260 |
-
custom_class: '<?php echo $custom_class ?>',
|
261 |
-
|
262 |
-
// Toggles
|
263 |
-
path_not_found_continue: true,
|
264 |
-
show_powered_by: true,
|
265 |
-
show_powered_by_link: true,
|
266 |
-
sk_autostart_only_once: true,
|
267 |
-
use_native_controls: false,
|
268 |
-
composer_upgrade_off: false,
|
269 |
-
basics_upgrade: true,
|
270 |
-
|
271 |
-
// Platform Info
|
272 |
-
library_version: 2,
|
273 |
-
platform_id: 1,
|
274 |
-
|
275 |
-
// Generic Info
|
276 |
-
just_activated: <?php echo ($sk_just_activated) ? "true" : "false" ?>,
|
277 |
-
platform_version: null,
|
278 |
-
plugin_version: '2.0.1',
|
279 |
-
show_login: <?php echo ($sk_just_activated) ? "true" : "false" ?>,
|
280 |
-
|
281 |
-
// SIDEKICK URLS
|
282 |
-
assets: '<?php echo SK_ASSETS ?>',
|
283 |
-
api: '<?php echo SK_API ?>',
|
284 |
-
tracking_api: '<?php echo SK_TRACKING_API ?>',
|
285 |
-
sk_path: '<?php echo PLAYER_PATH ?>',
|
286 |
-
audio: '<?php echo SK_AUDIO ?>',
|
287 |
-
library: '<?php echo SK_LIBRARY ?>',
|
288 |
-
|
289 |
-
// URLS
|
290 |
-
site_url: '<?php echo $site_url ?>',
|
291 |
-
domain: '<?php echo str_replace("http://","",$_SERVER["SERVER_NAME"]) ?>',
|
292 |
-
domain_used: '//player.sidekick.pro/',
|
293 |
-
plugin_url: '<?php echo admin_url("admin.php?page=sidekick") ?>',
|
294 |
-
base_url: '<?php echo site_url() ?>',
|
295 |
-
current_url: '<?php echo $current_url ?>',
|
296 |
-
// fallback_notfication_mp3: '//assets.sidekick.pro/fallback.mp3'
|
297 |
-
}
|
298 |
|
299 |
-
|
300 |
-
js: '//composer.sidekick.pro/<?php echo COMPOSER_PATH ?>/sidekick-composer.js',
|
301 |
-
css: '//composer.sidekick.pro/<?php echo COMPOSER_PATH ?>/sidekick-composer.css',
|
302 |
-
apiUrl: '<?php echo SK_COMPOSER_API ?>',
|
303 |
-
baseSiteUrl: sk_config.base_url,
|
304 |
-
platformId: 1,
|
305 |
-
compatibilities: sk_config.compatibilities,
|
306 |
-
audioBaseUrl: '<?php echo SK_AUDIO ?>',
|
307 |
-
audioPlaceholderUrl: '//assets.sidekick.pro/walkthrough-audio-placeholder.mp3',
|
308 |
-
siteAjaxUrl: window.ajaxurl || '',
|
309 |
-
trackingUrl: '//tracking.sidekick.pro/'
|
310 |
-
}
|
311 |
|
312 |
-
|
313 |
-
<?php endif ?>
|
314 |
|
315 |
-
|
316 |
-
}
|
317 |
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
'redirection' => 5,
|
323 |
-
'httpversion' => '1.0',
|
324 |
-
'blocking' => true,
|
325 |
-
'headers' => array(),
|
326 |
-
'body' => $data,
|
327 |
-
'cookies' => array()
|
328 |
-
)
|
329 |
-
);
|
330 |
-
}
|
331 |
|
332 |
-
|
333 |
-
|
334 |
-
update_option('sk_activation_id',$_POST['activation_id']);
|
335 |
-
}
|
336 |
-
}
|
337 |
|
338 |
-
|
339 |
-
|
340 |
-
update_option( 'sk_do_activation_redirect', true );
|
341 |
-
$data = array(
|
342 |
-
'source' => 'plugin',
|
343 |
-
'action' => 'track',
|
344 |
-
'type' => 'activate'
|
345 |
-
);
|
346 |
-
$this->track($data);
|
347 |
-
}
|
348 |
|
349 |
-
|
350 |
-
|
351 |
-
$timeout = 5;
|
352 |
-
curl_setopt($ch, CURLOPT_URL, $url);
|
353 |
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
354 |
-
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
|
355 |
-
$data = curl_exec($ch);
|
356 |
-
curl_close($ch);
|
357 |
-
return $data;
|
358 |
-
}
|
359 |
|
360 |
-
function redirect(){
|
361 |
-
if (get_option('sk_do_activation_redirect', false)) {
|
362 |
-
delete_option('sk_do_activation_redirect');
|
363 |
-
$siteurl = get_site_url();
|
364 |
-
wp_redirect($siteurl . "/wp-admin/options-general.php?page=sidekick");
|
365 |
die();
|
366 |
}
|
367 |
-
}
|
368 |
|
369 |
-
|
370 |
-
|
371 |
|
372 |
-
|
373 |
-
|
|
|
374 |
}
|
375 |
-
}
|
376 |
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
|
|
381 |
}
|
382 |
-
}
|
383 |
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
|
|
406 |
}
|
407 |
-
|
|
|
|
|
408 |
|
409 |
-
$sidekick
|
410 |
-
|
411 |
-
|
|
|
412 |
|
413 |
-
add_action('admin_menu', array($sidekick,'setup_menu'));
|
414 |
-
add_action('admin_init', array($sidekick,'redirect'));
|
415 |
-
add_action('wp_ajax_sk_activate', array($sidekick,'activate'));
|
416 |
-
add_action('wp_ajax_sk_save', array($sidekick,'ajax_save'));
|
417 |
-
add_action('admin_notices', array($sidekick,'admin_notice'));
|
418 |
-
add_action('admin_init', array($sidekick,'admin_notice_ignore'));
|
419 |
|
420 |
-
|
421 |
-
$sidekick
|
422 |
-
|
423 |
-
|
424 |
-
$sidekick
|
425 |
-
|
|
|
426 |
|
427 |
|
428 |
-
if (!defined('SK_PLUGIN_DEGBUG'))
|
429 |
-
|
430 |
|
431 |
-
if (!(isset($_GET['tab']) && $_GET['tab'] == 'plugin-information') && !defined('IFRAME_REQUEST')) {
|
432 |
-
|
433 |
-
|
|
|
434 |
}
|
435 |
|
436 |
|
|
|
437 |
// Multisite Licensing
|
438 |
|
439 |
if (defined('MULTISITE')) {
|
4 |
Plugin Name: Sidekick
|
5 |
Plugin URL: http://wordpress.org/plugins/sidekick/
|
6 |
Description: Adds a real-time WordPress training walkthroughs right in your Dashboard
|
7 |
+
Requires at least: 4.0
|
8 |
+
Tested up to: 4.1.1
|
9 |
+
Version: 2.2.0
|
10 |
Author: Sidekick.pro
|
11 |
Author URI: http://www.sidekick.pro
|
12 |
*/
|
13 |
|
14 |
|
15 |
+
if ( ! defined( 'PLAYER_DOMAIN' ) ) define( 'PLAYER_DOMAIN', 'player.sidekick.pro' );
|
16 |
+
if ( ! defined( 'PLAYER_PATH' ) ) define( 'PLAYER_PATH', 'tag/latest' );
|
17 |
+
if ( ! defined( 'PLAYER_FILE' ) ) define( 'PLAYER_FILE', 'sidekick.min.js' );
|
18 |
+
if ( ! defined( 'COMPOSER_DOMAIN' ) ) define( 'COMPOSER_DOMAIN', 'composer.sidekick.pro' );
|
19 |
+
if ( ! defined( 'COMPOSER_PATH' ) ) define( 'COMPOSER_PATH', 'tag/latest' );
|
|
|
20 |
if ( ! function_exists('mlog')) {
|
21 |
function mlog(){}
|
22 |
}
|
23 |
|
24 |
+
if (!class_exists('Sidekick')){
|
25 |
|
26 |
+
class Sidekick{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
+
function __construct(){
|
29 |
+
if (!defined('SK_TRACKING_API')) define('SK_TRACKING_API','//tracking.sidekick.pro/');
|
30 |
+
if (!defined('SK_COMPOSER_API')) define('SK_COMPOSER_API','//apiv2.sidekick.pro');
|
31 |
+
if (!defined('SK_API')) define('SK_API','//apiv2.sidekick.pro/');
|
32 |
+
if (!defined('SK_LIBRARY')) define('SK_LIBRARY','//librarycache.sidekick.pro/');
|
33 |
+
if (!defined('SK_ASSETS')) define('SK_ASSETS','//assets.sidekick.pro/');
|
34 |
+
if (!defined('SK_AUDIO')) define('SK_AUDIO','//audio.sidekick.pro/');
|
35 |
+
}
|
|
|
|
|
|
|
|
|
36 |
|
37 |
+
function enqueue_required(){
|
38 |
+
wp_enqueue_script('jquery' , null );
|
39 |
+
wp_enqueue_script('underscore' , null, array('underscore'));
|
40 |
+
wp_enqueue_script('backbone' , null, array('jquery','underscore'));
|
41 |
+
wp_enqueue_script('jquery-ui-core' , null, array('jquery') );
|
42 |
+
wp_enqueue_script('jquery-ui-position' , null, array('jquery-ui-core') );
|
43 |
+
wp_enqueue_script('jquery-ui-draggable' , null, array('jquery-ui-core') );
|
44 |
+
wp_enqueue_script('jquery-ui-droppable' , null, array('jquery-ui-core') );
|
45 |
+
wp_enqueue_script('jquery-effects-scale' , null, array('jquery-ui-core') );
|
46 |
+
wp_enqueue_script('jquery-effects-highlight' , null, array('jquery-ui-core') );
|
47 |
+
wp_enqueue_script('sidekick-admin' , '//assets.sidekick.pro/plugin/tag/latest/js/sidekick_admin.js',array( 'jquery' ));
|
48 |
}
|
|
|
49 |
|
50 |
+
function enqueue(){
|
51 |
+
wp_enqueue_script('sidekick' ,"//" . PLAYER_DOMAIN ."/" . PLAYER_PATH . "/" . PLAYER_FILE, array('backbone','jquery','underscore','jquery-effects-highlight'),null);
|
52 |
+
wp_enqueue_style('wp-pointer');
|
53 |
+
wp_enqueue_script('wp-pointer');
|
54 |
+
}
|
55 |
|
56 |
+
function setup_menu(){
|
57 |
+
add_submenu_page( 'options-general.php', 'Sidekick', 'Sidekick', 'activate_plugins','sidekick', array(&$this,'admin_page'));
|
58 |
+
}
|
59 |
|
60 |
+
function ajax_save(){
|
61 |
+
if (isset($_POST['sk_composer_button']) && $_POST['sk_composer_button'] == "true") {
|
62 |
+
update_option( 'sk_composer_button', true );
|
63 |
+
} elseif (isset($_POST['sk_composer_button']) && $_POST['sk_composer_button'] == "false") {
|
64 |
+
delete_option('sk_composer_button');
|
65 |
+
}
|
66 |
}
|
|
|
67 |
|
68 |
+
function admin_page(){
|
|
|
69 |
|
70 |
+
if ( empty( $_POST ) || check_admin_referer( 'update_sk_settings' ) ) {
|
71 |
|
72 |
+
if (isset($_POST['option_page']) && $_POST['option_page'] == 'sk_license') {
|
|
|
|
|
|
|
|
|
73 |
|
74 |
+
if (isset($_POST['activation_id']) && $_POST['activation_id'] && strpos($_POST['activation_id'], '-xxxx-xxxx') === false){
|
75 |
+
$result = $this->activate(true);
|
76 |
+
} else if (isset($_POST['activation_id']) && strpos($_POST['activation_id'], '-xxxx-xxxx') === false) {
|
77 |
+
delete_option('sk_activation_id');
|
78 |
+
}
|
79 |
+
|
80 |
+
if (isset($_POST['sk_composer_button'])) {
|
81 |
+
update_option( 'sk_composer_button', true );
|
82 |
+
} else {
|
83 |
+
delete_option('sk_composer_button');
|
84 |
+
}
|
85 |
|
86 |
+
if (isset($_POST['sk_track_data'])) {
|
87 |
+
update_option( 'sk_track_data', true );
|
88 |
+
} else {
|
89 |
+
delete_option('sk_track_data');
|
90 |
+
}
|
91 |
+
|
92 |
+
update_option( 'sk_activated', true );
|
93 |
+
die('<script>window.open("' . get_site_url() . '/wp-admin/options-general.php?page=sidekick","_self")</script>');
|
94 |
}
|
95 |
|
|
|
|
|
96 |
}
|
97 |
|
98 |
+
$activation_id = (get_option( "sk_activation_id" ) ? get_option( "sk_activation_id" ) : '');
|
99 |
+
$sk_track_data = get_option( 'sk_track_data' );
|
100 |
+
$current_user = wp_get_current_user();
|
101 |
+
$status = 'Free';
|
102 |
+
$error = null;
|
103 |
+
|
104 |
+
if (isset($SK_PAID_LIBRARY_FILE) && $activation_id) {
|
105 |
+
$_POST['activation_id'] = $activation_id;
|
106 |
+
$check_activation = $this->activate(true);
|
107 |
+
$status = 'Checking...';
|
108 |
}
|
|
|
109 |
|
110 |
+
global $wp_version;
|
111 |
+
if (version_compare($wp_version, '3.9', '<=')) {
|
112 |
+
$error = "Sorry, Sidekick requires WordPress 3.9 or higher to function.";
|
113 |
+
}
|
|
|
114 |
|
115 |
+
if (!$activation_id) {
|
116 |
+
$warn = "You're using the <b>free</b> version of Sidekick, to upgrade or get your license key, visit your <a target='_blank' href='http://www.sidekick.pro/plans/#/login?utm_source=plugin&utm_medium=settings&utm_campaign=upgrade_nag'>account page</a> or <a target='_blank' href='http://www.sidekick.pro/plans/?utm_source=plugin&utm_medium=settings&utm_campaign=upgrade_nag'>sign-up</a> for a paid plan.";
|
117 |
+
}
|
|
|
|
|
118 |
|
119 |
+
if(preg_match('/(?i)msie [6-8]/',$_SERVER['HTTP_USER_AGENT'])){
|
120 |
+
$error = "Sorry, Sidekick requires Internet Explorer 9 or higher to function.";
|
121 |
+
}
|
|
|
122 |
|
123 |
+
?>
|
124 |
+
|
125 |
+
<?php if (get_option('sk_firstuse') == true): ?>
|
126 |
+
<?php delete_option('sk_firstuse') ?>
|
127 |
+
<script type="text/javascript">
|
128 |
+
jQuery(document).ready(function($) {
|
129 |
+
jQuery('#sidekick #logo').trigger('click');
|
130 |
+
});
|
131 |
+
</script>
|
132 |
+
<?php endif ?>
|
133 |
+
|
134 |
+
<div class="wrap">
|
135 |
+
<?php include('libs/admin_page.php') ?>
|
136 |
+
</div>
|
137 |
+
<?php
|
138 |
}
|
139 |
|
140 |
+
function set_disabled_wts(){
|
141 |
+
if (isset($_POST['disable_wts']) && $_POST['disable_wts']) {
|
142 |
+
update_option('sk_disabled_wts',json_encode($_POST['disable_wts']));
|
143 |
+
if (is_network_admin()) {
|
144 |
+
update_site_option('sk_disabled_wts',json_encode($_POST['disable_wts']));
|
145 |
+
}
|
146 |
+
} else {
|
147 |
+
delete_option('sk_disabled_wts');
|
148 |
+
if (is_network_admin()) {
|
149 |
+
delete_site_option('sk_disabled_wts');
|
150 |
+
}
|
151 |
+
}
|
152 |
}
|
153 |
|
154 |
+
function set_autostart_wt(){
|
155 |
+
if (isset($_POST['sk_autostart_walkthrough_id']) && intval($_POST['sk_autostart_walkthrough_id']) > 0){
|
156 |
+
if (is_network_admin()) {
|
157 |
+
update_site_option('sk_autostart_walkthrough_id',$_POST['sk_autostart_walkthrough_id']);
|
158 |
+
}
|
159 |
+
update_option('sk_autostart_walkthrough_id',$_POST['sk_autostart_walkthrough_id']);
|
160 |
+
} else {
|
161 |
+
delete_option('sk_autostart_walkthrough_id');
|
162 |
+
if (is_network_admin()) {
|
163 |
+
delete_site_option('sk_autostart_walkthrough_id');
|
164 |
+
}
|
165 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
}
|
|
|
167 |
|
168 |
+
function set_api(){
|
169 |
+
if (isset($_POST['sk_api'])){
|
170 |
+
update_option('sk_api',$_POST['sk_api']);
|
171 |
+
update_site_option('sk_api',$_POST['sk_api']);
|
172 |
+
}
|
|
|
|
|
173 |
}
|
|
|
174 |
|
175 |
+
function footer(){
|
176 |
+
global $current_user;
|
177 |
+
|
178 |
+
require_once('libs/sk_config_data.php');
|
179 |
+
|
180 |
+
$sk_config_data = new sk_config_data;
|
181 |
+
$current_user = wp_get_current_user();
|
182 |
+
$sk_just_activated = get_option( 'sk_just_activated' );
|
183 |
+
$sk_track_data = get_option( 'sk_track_data' );
|
184 |
+
$sk_composer_button = get_option( 'sk_composer_button' );
|
185 |
+
$activation_id = (get_option( "sk_activation_id" ) ? get_option( "sk_activation_id" ) : '');
|
186 |
+
$autostart_network_walkthrough_id = (get_site_option('sk_autostart_walkthrough_id') ? get_site_option('sk_autostart_walkthrough_id') : 'null' );
|
187 |
+
$autostart_walkthrough_id = (get_option('sk_autostart_walkthrough_id') ? get_option('sk_autostart_walkthrough_id') : $autostart_network_walkthrough_id );
|
188 |
+
$custom_class = (get_option( "sk_custom_class" ) ? get_option( "sk_custom_class" ) : '');
|
189 |
+
$theme = wp_get_theme();
|
190 |
+
$not_supported_ie = false;
|
191 |
+
$user_email = '';
|
192 |
+
if ($sk_track_data) {
|
193 |
+
$user_email = $current_user->user_email;
|
194 |
+
}
|
195 |
|
196 |
+
$disabled_wts = (!is_network_admin()) ? $sk_config_data->get_disabled_wts() : '[]';
|
197 |
+
$user_role = $sk_config_data->get_user_role();
|
198 |
+
$site_url = $sk_config_data->get_domain();
|
199 |
+
$installed_plugins = $sk_config_data->get_plugins();
|
200 |
+
$plugin_count = (isset($plugins) && is_array($plugins)) ? count($plugins) : array();
|
201 |
+
$disabled_network_wts = $sk_config_data->get_disabled_network_wts();
|
202 |
+
$current_url = $sk_config_data->get_current_url();
|
203 |
+
$post_types = $sk_config_data->get_post_types();
|
204 |
+
$taxonomies = $sk_config_data->get_taxonomies();
|
205 |
+
$user_data = $sk_config_data->get_user_data();
|
206 |
+
$comments = $sk_config_data->get_comments();
|
207 |
+
$post_statuses = $sk_config_data->get_post_statuses();
|
208 |
+
$post_types_and_statuses = $sk_config_data->get_post_types_and_statuses();
|
209 |
+
$number_of_themes = $sk_config_data->get_themes();
|
210 |
+
$frameworks = $sk_config_data->get_framework();
|
211 |
+
|
212 |
+
delete_option( 'sk_just_activated' );
|
213 |
+
if(preg_match('/(?i)msie [6-8]/',$_SERVER['HTTP_USER_AGENT'])) $not_supported_ie = true;
|
214 |
+
|
215 |
+
?>
|
216 |
+
|
217 |
+
|
218 |
+
<?php if (!$not_supported_ie): ?>
|
219 |
+
|
220 |
+
<script type="text/javascript">
|
221 |
+
|
222 |
+
<?php if (is_network_admin()): ?>var is_network_admin = true; <?php endif ?>
|
223 |
+
|
224 |
+
var sk_config = {
|
225 |
+
// Compatibility
|
226 |
+
|
227 |
+
compatibilities: {
|
228 |
+
<?php echo $post_types ?>
|
229 |
+
<?php echo $taxonomies ?>
|
230 |
+
<?php echo $user_data ?>
|
231 |
+
<?php echo $comments ?>
|
232 |
+
<?php echo $post_statuses ?>
|
233 |
+
<?php echo $frameworks ?>
|
234 |
+
<?php echo $post_types_and_statuses ?>
|
235 |
+
installed_plugins: <?php echo json_encode($installed_plugins) ?>,
|
236 |
+
plugin_count: <?php echo ($plugin_count) ? $plugin_count : 0 ?>,
|
237 |
+
is_multisite: <?php echo (is_multisite()) ? "true" : "false" ?>,
|
238 |
+
number_of_themes: <?php echo $number_of_themes ?>,
|
239 |
+
installed_theme: {'<?php echo sanitize_title($theme->Name) ?>' : '<?php echo $theme->Version ?>'},
|
240 |
+
theme_version: '<?php echo $theme->Version ?>',
|
241 |
+
main_soft_version: '<?php echo get_bloginfo("version") ?>',
|
242 |
+
user_level: '<?php echo $user_role ?>',
|
243 |
+
main_soft_name: 'WordPress',
|
244 |
+
role: '<?php echo $user_role ?>'
|
245 |
+
},
|
246 |
+
|
247 |
+
disable_wts: <?php echo $disabled_wts ?>,
|
248 |
+
disable_network_wts: <?php echo $disabled_network_wts ?>,
|
249 |
+
main_soft_name: 'WordPress',
|
250 |
+
embeded: false,
|
251 |
+
|
252 |
+
// User Settings
|
253 |
+
activation_id: '<?php echo $activation_id ?>',
|
254 |
+
auto_open_root_bucket_id: 79,
|
255 |
+
auto_open_product: 'default',
|
256 |
+
disable_wts_in_root_bucket_ids: [5,87],
|
257 |
+
autostart_walkthrough_id: <?php echo $autostart_walkthrough_id ?>,
|
258 |
+
sk_composer_button: <?php echo ($sk_composer_button ? "true" : "false") ?>,
|
259 |
+
track_data: '<?php echo $sk_track_data ?>',
|
260 |
+
user_email: '<?php echo $user_email ?>',
|
261 |
+
custom_class: '<?php echo $custom_class ?>',
|
262 |
+
|
263 |
+
// Toggles
|
264 |
+
path_not_found_continue: true,
|
265 |
+
show_powered_by: true,
|
266 |
+
show_powered_by_link: true,
|
267 |
+
sk_autostart_only_once: true,
|
268 |
+
use_native_controls: false,
|
269 |
+
composer_upgrade_off: false,
|
270 |
+
basics_upgrade: true,
|
271 |
+
|
272 |
+
// Platform Info
|
273 |
+
library_version: 2,
|
274 |
+
platform_id: 1,
|
275 |
+
|
276 |
+
// Generic Info
|
277 |
+
just_activated: <?php echo ($sk_just_activated) ? "true" : "false" ?>,
|
278 |
+
platform_version: null,
|
279 |
+
plugin_version: '2.2.0',
|
280 |
+
show_login: <?php echo ($sk_just_activated) ? "true" : "false" ?>,
|
281 |
+
|
282 |
+
// SIDEKICK URLS
|
283 |
+
assets: '<?php echo SK_ASSETS ?>',
|
284 |
+
api: '<?php echo SK_API ?>',
|
285 |
+
tracking_api: '<?php echo SK_TRACKING_API ?>',
|
286 |
+
sk_path: '<?php echo PLAYER_PATH ?>',
|
287 |
+
audio: '<?php echo SK_AUDIO ?>',
|
288 |
+
library: '<?php echo SK_LIBRARY ?>',
|
289 |
+
|
290 |
+
// URLS
|
291 |
+
site_url: '<?php echo $site_url ?>',
|
292 |
+
domain: '<?php echo str_replace("http://","",$_SERVER["SERVER_NAME"]) ?>',
|
293 |
+
domain_used: '//<?php echo PLAYER_DOMAIN ?>/',
|
294 |
+
plugin_url: '<?php echo admin_url("admin.php?page=sidekick") ?>',
|
295 |
+
base_url: '<?php echo site_url() ?>',
|
296 |
+
current_url: '<?php echo $current_url ?>'
|
297 |
+
// fallback_notfication_mp3: '//assets.sidekick.pro/fallback.mp3'
|
298 |
+
}
|
299 |
+
|
300 |
+
var skc_config = {
|
301 |
+
audioPlaceholderUrl: '<?php echo SK_ASSETS ?>walkthrough-audio-placeholder.mp3',
|
302 |
+
audioBaseUrl: '<?php echo SK_AUDIO ?>',
|
303 |
+
apiUrl: '<?php echo SK_COMPOSER_API ?>',
|
304 |
+
trackingUrl: '<?php echo SK_TRACKING_API ?>',
|
305 |
+
js: '//<?php echo COMPOSER_DOMAIN ?>/<?php echo COMPOSER_PATH ?>/sidekick-composer.js',
|
306 |
+
css: '//<?php echo COMPOSER_DOMAIN ?>/<?php echo COMPOSER_PATH ?>/sidekick-composer.css',
|
307 |
+
baseSiteUrl: sk_config.base_url,
|
308 |
+
platformId: 1,
|
309 |
+
compatibilities: sk_config.compatibilities,
|
310 |
+
siteAjaxUrl: window.ajaxurl || ''
|
311 |
+
}
|
312 |
+
|
313 |
+
</script>
|
314 |
+
<?php endif ?>
|
315 |
+
|
316 |
+
<?php
|
317 |
+
}
|
318 |
|
319 |
+
function track($data){
|
320 |
+
mlog('track');
|
321 |
|
322 |
+
if (file_exists(realpath(dirname(__FILE__)) . '/libs/mixpanel/Mixpanel.php')) {
|
323 |
+
require_once(realpath(dirname(__FILE__)) . '/libs/mixpanel/Mixpanel.php');
|
324 |
+
$mp = Mixpanel::getInstance("965556434c5ae652a44f24b85b442263");
|
325 |
+
$domain = str_replace("http://","",$_SERVER["SERVER_NAME"]);
|
326 |
|
327 |
+
switch ($data['type']) {
|
328 |
+
case 'activate':
|
329 |
+
$mp->track("Activate - Plugin", array("domain" => $domain));
|
330 |
+
break;
|
331 |
|
332 |
+
case 'deactivate':
|
333 |
+
$mp->track("Deactivate - Plugin", array("domain" => $domain));
|
334 |
+
break;
|
335 |
|
336 |
+
default:
|
337 |
+
if (isset($data['event'])) {
|
338 |
+
$mp->track($data['event'], array("domain" => $domain));
|
339 |
+
}
|
340 |
+
break;
|
341 |
+
}
|
342 |
+
}
|
343 |
|
344 |
+
$response = wp_remote_post( SK_TRACKING_API . 'event', array(
|
345 |
+
'method' => 'POST',
|
346 |
+
'timeout' => 45,
|
347 |
+
'redirection' => 5,
|
348 |
+
'httpversion' => '1.0',
|
349 |
+
'blocking' => true,
|
350 |
+
'headers' => array(),
|
351 |
+
'body' => $data,
|
352 |
+
'cookies' => array()
|
353 |
+
)
|
354 |
+
);
|
355 |
+
}
|
356 |
|
357 |
+
function activate($return = false){
|
358 |
+
if (isset($_POST['activation_id'])) {
|
359 |
+
update_option('sk_activation_id',$_POST['activation_id']);
|
360 |
+
}
|
361 |
+
}
|
362 |
|
363 |
+
function activate_plugin(){
|
364 |
+
update_option( 'sk_firstuse', true );
|
365 |
+
update_option( 'sk_do_activation_redirect', true );
|
366 |
+
$data = array(
|
367 |
+
'source' => 'plugin',
|
368 |
+
'action' => 'track',
|
369 |
+
'type' => 'activate'
|
370 |
+
);
|
371 |
+
$this->track($data);
|
372 |
+
}
|
373 |
|
374 |
+
function curl_get_data($url){
|
375 |
+
$ch = curl_init();
|
376 |
+
$timeout = 5;
|
377 |
+
curl_setopt($ch, CURLOPT_URL, $url);
|
378 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
379 |
+
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
|
380 |
+
$data = curl_exec($ch);
|
381 |
+
curl_close($ch);
|
382 |
+
return $data;
|
383 |
+
}
|
384 |
|
385 |
+
function redirect(){
|
386 |
+
if (get_option('sk_do_activation_redirect', false)) {
|
387 |
+
delete_option('sk_do_activation_redirect');
|
388 |
+
$siteurl = get_site_url();
|
389 |
+
wp_redirect($siteurl . "/wp-admin/options-general.php?page=sidekick");
|
390 |
+
die();
|
391 |
+
}
|
392 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
393 |
|
394 |
+
function check_ver(){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
395 |
|
396 |
+
$data = json_encode('2.2.0');
|
|
|
397 |
|
398 |
+
if(array_key_exists('callback', $_GET)){
|
|
|
399 |
|
400 |
+
header('Content-Type: text/javascript; charset=utf8');
|
401 |
+
header('Access-Control-Allow-Origin: http://www.example.com/');
|
402 |
+
header('Access-Control-Max-Age: 3628800');
|
403 |
+
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
404 |
|
405 |
+
$callback = $_GET['callback'];
|
406 |
+
echo $callback.'('.$data.');';
|
|
|
|
|
|
|
407 |
|
408 |
+
}else{
|
409 |
+
header('Content-Type: application/json; charset=utf8');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
410 |
|
411 |
+
echo $data;
|
412 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
413 |
|
|
|
|
|
|
|
|
|
|
|
414 |
die();
|
415 |
}
|
|
|
416 |
|
417 |
+
function admin_notice() {
|
418 |
+
global $current_user ;
|
419 |
|
420 |
+
if ( ! get_user_meta($current_user->ID, 'sk_ignore_notice') ) {
|
421 |
+
printf ('<div class="updated"><p>Need help with WordPress? Click HELP ME in the bottom left corner to get started! <a href="%1$s">Hide</a></p></div>','?sk_ignore_notice=1');
|
422 |
+
}
|
423 |
}
|
|
|
424 |
|
425 |
+
function admin_notice_ignore() {
|
426 |
+
global $current_user;
|
427 |
+
if ( isset($_GET['sk_ignore_notice'])) {
|
428 |
+
add_user_meta($current_user->ID, 'sk_ignore_notice', true);
|
429 |
+
}
|
430 |
}
|
|
|
431 |
|
432 |
+
function deactivate_plugin(){
|
433 |
+
$data = array(
|
434 |
+
'source' => 'plugin',
|
435 |
+
'action' => 'track',
|
436 |
+
'type' => 'deactivate',
|
437 |
+
'user' => get_option( "activation_id" )
|
438 |
+
);
|
439 |
+
$this->track($data);
|
440 |
+
?>
|
441 |
+
<script type="text/javascript">
|
442 |
+
window._gaq = window._gaq || [];
|
443 |
+
window._gaq.push(['sk._setAccount', 'UA-39283622-1']);
|
444 |
+
|
445 |
+
(function() {
|
446 |
+
var ga_wpu = document.createElement('script'); ga_sk.type = 'text/javascript'; ga_sk.async = true;
|
447 |
+
ga_sk.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
448 |
+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga_wpu, s);
|
449 |
+
})();
|
450 |
+
window._gaq.push(['sk._trackEvent', 'Plugin - Deactivate', '', null, 0,true]);
|
451 |
+
</script>
|
452 |
+
<?php
|
453 |
+
delete_option( 'sk_activated' );
|
454 |
+
}
|
455 |
}
|
456 |
+
$sidekick = new Sidekick;
|
457 |
+
register_activation_hook( __FILE__, array($sidekick,'activate_plugin') );
|
458 |
+
register_deactivation_hook( __FILE__, array($sidekick,'deactivate_plugin') );
|
459 |
|
460 |
+
if (isset($_POST['sk_setting_disabled'])) $sidekick->set_disabled_wts();
|
461 |
+
if (isset($_POST['sk_setting_autostart'])) $sidekick->set_autostart_wt();
|
462 |
+
if (isset($_POST['sk_api'])) $sidekick->set_api();
|
463 |
+
if (isset($_GET['sk_ver_check'])) $sidekick->check_ver();
|
464 |
|
|
|
|
|
|
|
|
|
|
|
|
|
465 |
|
466 |
+
add_action('admin_menu', array($sidekick,'setup_menu'));
|
467 |
+
add_action('admin_init', array($sidekick,'redirect'));
|
468 |
+
add_action('wp_ajax_sk_activate', array($sidekick,'activate'));
|
469 |
+
add_action('wp_ajax_sk_save', array($sidekick,'ajax_save'));
|
470 |
+
add_action('admin_notices', array($sidekick,'admin_notice'));
|
471 |
+
add_action('admin_init', array($sidekick,'admin_notice_ignore'));
|
472 |
+
|
473 |
|
474 |
|
475 |
+
if (!defined('SK_PLUGIN_DEGBUG'))
|
476 |
+
require_once('sk_init.php');
|
477 |
|
478 |
+
if (!(isset($_GET['tab']) && $_GET['tab'] == 'plugin-information') && !defined('IFRAME_REQUEST')) {
|
479 |
+
add_action('admin_footer', array($sidekick,'footer'));
|
480 |
+
add_action('customize_controls_print_footer_scripts', array($sidekick,'footer'));
|
481 |
+
}
|
482 |
}
|
483 |
|
484 |
|
485 |
+
|
486 |
// Multisite Licensing
|
487 |
|
488 |
if (defined('MULTISITE')) {
|
sidekick_embed.php
ADDED
@@ -0,0 +1,495 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
Plugin Name: Sidekick
|
5 |
+
Plugin URL: http://wordpress.org/plugins/sidekick/
|
6 |
+
Description: Adds a real-time WordPress training walkthroughs right in your Dashboard
|
7 |
+
Requires at least: 4.0
|
8 |
+
Tested up to: 4.1.1
|
9 |
+
Version: %%version%%
|
10 |
+
Author: Sidekick.pro
|
11 |
+
Author URI: http://www.sidekick.pro
|
12 |
+
*/
|
13 |
+
|
14 |
+
|
15 |
+
if ( ! defined( 'PLAYER_DOMAIN' ) ) define( 'PLAYER_DOMAIN', 'player.sidekick.pro' );
|
16 |
+
if ( ! defined( 'PLAYER_PATH' ) ) define( 'PLAYER_PATH', 'tag/latest' );
|
17 |
+
if ( ! defined( 'PLAYER_FILE' ) ) define( 'PLAYER_FILE', 'sidekick.min.js' );
|
18 |
+
if ( ! defined( 'COMPOSER_DOMAIN' ) ) define( 'COMPOSER_DOMAIN', 'composer.sidekick.pro' );
|
19 |
+
if ( ! defined( 'COMPOSER_PATH' ) ) define( 'COMPOSER_PATH', 'tag/latest' );
|
20 |
+
if ( ! function_exists('mlog')) {
|
21 |
+
function mlog(){}
|
22 |
+
}
|
23 |
+
|
24 |
+
if (!class_exists('Sidekick')){
|
25 |
+
|
26 |
+
class Sidekick{
|
27 |
+
|
28 |
+
function __construct(){
|
29 |
+
if (!defined('SK_TRACKING_API')) define('SK_TRACKING_API','//tracking.sidekick.pro/');
|
30 |
+
if (!defined('SK_COMPOSER_API')) define('SK_COMPOSER_API','//apiv2.sidekick.pro');
|
31 |
+
if (!defined('SK_API')) define('SK_API','//apiv2.sidekick.pro/');
|
32 |
+
if (!defined('SK_LIBRARY')) define('SK_LIBRARY','//librarycache.sidekick.pro/');
|
33 |
+
if (!defined('SK_ASSETS')) define('SK_ASSETS','//assets.sidekick.pro/');
|
34 |
+
if (!defined('SK_AUDIO')) define('SK_AUDIO','//audio.sidekick.pro/');
|
35 |
+
}
|
36 |
+
|
37 |
+
function enqueue_required(){
|
38 |
+
wp_enqueue_script('jquery' , null );
|
39 |
+
wp_enqueue_script('underscore' , null, array('underscore'));
|
40 |
+
wp_enqueue_script('backbone' , null, array('jquery','underscore'));
|
41 |
+
wp_enqueue_script('jquery-ui-core' , null, array('jquery') );
|
42 |
+
wp_enqueue_script('jquery-ui-position' , null, array('jquery-ui-core') );
|
43 |
+
wp_enqueue_script('jquery-ui-draggable' , null, array('jquery-ui-core') );
|
44 |
+
wp_enqueue_script('jquery-ui-droppable' , null, array('jquery-ui-core') );
|
45 |
+
wp_enqueue_script('jquery-effects-scale' , null, array('jquery-ui-core') );
|
46 |
+
wp_enqueue_script('jquery-effects-highlight' , null, array('jquery-ui-core') );
|
47 |
+
wp_enqueue_script('sidekick-admin' , '//assets.sidekick.pro/plugin/tag/latest/js/sidekick_admin.js',array( 'jquery' ));
|
48 |
+
}
|
49 |
+
|
50 |
+
function enqueue(){
|
51 |
+
wp_enqueue_script('sidekick' ,"//" . PLAYER_DOMAIN ."/" . PLAYER_PATH . "/" . PLAYER_FILE, array('backbone','jquery','underscore','jquery-effects-highlight'),null);
|
52 |
+
wp_enqueue_style('wp-pointer');
|
53 |
+
wp_enqueue_script('wp-pointer');
|
54 |
+
}
|
55 |
+
|
56 |
+
function setup_menu(){
|
57 |
+
add_submenu_page( 'options-general.php', 'Sidekick', 'Sidekick', 'activate_plugins','sidekick', array(&$this,'admin_page'));
|
58 |
+
}
|
59 |
+
|
60 |
+
function ajax_save(){
|
61 |
+
if (isset($_POST['sk_composer_button']) && $_POST['sk_composer_button'] == "true") {
|
62 |
+
update_option( 'sk_composer_button', true );
|
63 |
+
} elseif (isset($_POST['sk_composer_button']) && $_POST['sk_composer_button'] == "false") {
|
64 |
+
delete_option('sk_composer_button');
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
function admin_page(){
|
69 |
+
|
70 |
+
if ( empty( $_POST ) || check_admin_referer( 'update_sk_settings' ) ) {
|
71 |
+
|
72 |
+
if (isset($_POST['option_page']) && $_POST['option_page'] == 'sk_license') {
|
73 |
+
|
74 |
+
if (isset($_POST['activation_id']) && $_POST['activation_id'] && strpos($_POST['activation_id'], '-xxxx-xxxx') === false){
|
75 |
+
$result = $this->activate(true);
|
76 |
+
} else if (isset($_POST['activation_id']) && strpos($_POST['activation_id'], '-xxxx-xxxx') === false) {
|
77 |
+
delete_option('sk_activation_id');
|
78 |
+
}
|
79 |
+
|
80 |
+
if (isset($_POST['sk_composer_button'])) {
|
81 |
+
update_option( 'sk_composer_button', true );
|
82 |
+
} else {
|
83 |
+
delete_option('sk_composer_button');
|
84 |
+
}
|
85 |
+
|
86 |
+
if (isset($_POST['sk_track_data'])) {
|
87 |
+
update_option( 'sk_track_data', true );
|
88 |
+
} else {
|
89 |
+
delete_option('sk_track_data');
|
90 |
+
}
|
91 |
+
|
92 |
+
update_option( 'sk_activated', true );
|
93 |
+
die('<script>window.open("' . get_site_url() . '/wp-admin/options-general.php?page=sidekick","_self")</script>');
|
94 |
+
}
|
95 |
+
|
96 |
+
}
|
97 |
+
|
98 |
+
$activation_id = (get_option( "sk_activation_id" ) ? get_option( "sk_activation_id" ) : '');
|
99 |
+
$sk_track_data = get_option( 'sk_track_data' );
|
100 |
+
$current_user = wp_get_current_user();
|
101 |
+
$status = 'Free';
|
102 |
+
$error = null;
|
103 |
+
|
104 |
+
if (isset($SK_PAID_LIBRARY_FILE) && $activation_id) {
|
105 |
+
$_POST['activation_id'] = $activation_id;
|
106 |
+
$check_activation = $this->activate(true);
|
107 |
+
$status = 'Checking...';
|
108 |
+
}
|
109 |
+
|
110 |
+
global $wp_version;
|
111 |
+
if (version_compare($wp_version, '3.9', '<=')) {
|
112 |
+
$error = "Sorry, Sidekick requires WordPress 3.9 or higher to function.";
|
113 |
+
}
|
114 |
+
|
115 |
+
if (!$activation_id) {
|
116 |
+
$warn = "You're using the <b>free</b> version of Sidekick, to upgrade or get your license key, visit your <a target='_blank' href='http://www.sidekick.pro/plans/#/login?utm_source=plugin&utm_medium=settings&utm_campaign=upgrade_nag'>account page</a> or <a target='_blank' href='http://www.sidekick.pro/plans/?utm_source=plugin&utm_medium=settings&utm_campaign=upgrade_nag'>sign-up</a> for a paid plan.";
|
117 |
+
}
|
118 |
+
|
119 |
+
if(preg_match('/(?i)msie [6-8]/',$_SERVER['HTTP_USER_AGENT'])){
|
120 |
+
$error = "Sorry, Sidekick requires Internet Explorer 9 or higher to function.";
|
121 |
+
}
|
122 |
+
|
123 |
+
?>
|
124 |
+
|
125 |
+
<?php if (get_option('sk_firstuse') == true): ?>
|
126 |
+
<?php delete_option('sk_firstuse') ?>
|
127 |
+
<script type="text/javascript">
|
128 |
+
jQuery(document).ready(function($) {
|
129 |
+
jQuery('#sidekick #logo').trigger('click');
|
130 |
+
});
|
131 |
+
</script>
|
132 |
+
<?php endif ?>
|
133 |
+
|
134 |
+
<div class="wrap">
|
135 |
+
<?php include('libs/admin_page.php') ?>
|
136 |
+
</div>
|
137 |
+
<?php
|
138 |
+
}
|
139 |
+
|
140 |
+
function set_disabled_wts(){
|
141 |
+
if (isset($_POST['disable_wts']) && $_POST['disable_wts']) {
|
142 |
+
update_option('sk_disabled_wts',json_encode($_POST['disable_wts']));
|
143 |
+
if (is_network_admin()) {
|
144 |
+
update_site_option('sk_disabled_wts',json_encode($_POST['disable_wts']));
|
145 |
+
}
|
146 |
+
} else {
|
147 |
+
delete_option('sk_disabled_wts');
|
148 |
+
if (is_network_admin()) {
|
149 |
+
delete_site_option('sk_disabled_wts');
|
150 |
+
}
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
function set_autostart_wt(){
|
155 |
+
if (isset($_POST['sk_autostart_walkthrough_id']) && intval($_POST['sk_autostart_walkthrough_id']) > 0){
|
156 |
+
if (is_network_admin()) {
|
157 |
+
update_site_option('sk_autostart_walkthrough_id',$_POST['sk_autostart_walkthrough_id']);
|
158 |
+
}
|
159 |
+
update_option('sk_autostart_walkthrough_id',$_POST['sk_autostart_walkthrough_id']);
|
160 |
+
} else {
|
161 |
+
delete_option('sk_autostart_walkthrough_id');
|
162 |
+
if (is_network_admin()) {
|
163 |
+
delete_site_option('sk_autostart_walkthrough_id');
|
164 |
+
}
|
165 |
+
}
|
166 |
+
}
|
167 |
+
|
168 |
+
function set_api(){
|
169 |
+
if (isset($_POST['sk_api'])){
|
170 |
+
update_option('sk_api',$_POST['sk_api']);
|
171 |
+
update_site_option('sk_api',$_POST['sk_api']);
|
172 |
+
}
|
173 |
+
}
|
174 |
+
|
175 |
+
function footer(){
|
176 |
+
global $current_user;
|
177 |
+
|
178 |
+
require_once('libs/sk_config_data.php');
|
179 |
+
|
180 |
+
$sk_config_data = new sk_config_data;
|
181 |
+
$current_user = wp_get_current_user();
|
182 |
+
$sk_just_activated = get_option( 'sk_just_activated' );
|
183 |
+
$sk_track_data = get_option( 'sk_track_data' );
|
184 |
+
$sk_composer_button = get_option( 'sk_composer_button' );
|
185 |
+
$activation_id = (get_option( "sk_activation_id" ) ? get_option( "sk_activation_id" ) : '');
|
186 |
+
$autostart_network_walkthrough_id = (get_site_option('sk_autostart_walkthrough_id') ? get_site_option('sk_autostart_walkthrough_id') : 'null' );
|
187 |
+
$autostart_walkthrough_id = (get_option('sk_autostart_walkthrough_id') ? get_option('sk_autostart_walkthrough_id') : $autostart_network_walkthrough_id );
|
188 |
+
$custom_class = (get_option( "sk_custom_class" ) ? get_option( "sk_custom_class" ) : '');
|
189 |
+
$theme = wp_get_theme();
|
190 |
+
$not_supported_ie = false;
|
191 |
+
$user_email = '';
|
192 |
+
if ($sk_track_data) {
|
193 |
+
$user_email = $current_user->user_email;
|
194 |
+
}
|
195 |
+
|
196 |
+
$disabled_wts = (!is_network_admin()) ? $sk_config_data->get_disabled_wts() : '[]';
|
197 |
+
$user_role = $sk_config_data->get_user_role();
|
198 |
+
$site_url = $sk_config_data->get_domain();
|
199 |
+
$installed_plugins = $sk_config_data->get_plugins();
|
200 |
+
$plugin_count = (isset($plugins) && is_array($plugins)) ? count($plugins) : array();
|
201 |
+
$disabled_network_wts = $sk_config_data->get_disabled_network_wts();
|
202 |
+
$current_url = $sk_config_data->get_current_url();
|
203 |
+
$post_types = $sk_config_data->get_post_types();
|
204 |
+
$taxonomies = $sk_config_data->get_taxonomies();
|
205 |
+
$user_data = $sk_config_data->get_user_data();
|
206 |
+
$comments = $sk_config_data->get_comments();
|
207 |
+
$post_statuses = $sk_config_data->get_post_statuses();
|
208 |
+
$post_types_and_statuses = $sk_config_data->get_post_types_and_statuses();
|
209 |
+
$number_of_themes = $sk_config_data->get_themes();
|
210 |
+
$frameworks = $sk_config_data->get_framework();
|
211 |
+
|
212 |
+
delete_option( 'sk_just_activated' );
|
213 |
+
if(preg_match('/(?i)msie [6-8]/',$_SERVER['HTTP_USER_AGENT'])) $not_supported_ie = true;
|
214 |
+
|
215 |
+
?>
|
216 |
+
|
217 |
+
|
218 |
+
<?php if (!$not_supported_ie): ?>
|
219 |
+
|
220 |
+
<script type="text/javascript">
|
221 |
+
|
222 |
+
<?php if (is_network_admin()): ?>var is_network_admin = true; <?php endif ?>
|
223 |
+
|
224 |
+
var sk_config = {
|
225 |
+
// Compatibility
|
226 |
+
|
227 |
+
compatibilities: {
|
228 |
+
<?php echo $post_types ?>
|
229 |
+
<?php echo $taxonomies ?>
|
230 |
+
<?php echo $user_data ?>
|
231 |
+
<?php echo $comments ?>
|
232 |
+
<?php echo $post_statuses ?>
|
233 |
+
<?php echo $frameworks ?>
|
234 |
+
<?php echo $post_types_and_statuses ?>
|
235 |
+
installed_plugins: <?php echo json_encode($installed_plugins) ?>,
|
236 |
+
plugin_count: <?php echo ($plugin_count) ? $plugin_count : 0 ?>,
|
237 |
+
is_multisite: <?php echo (is_multisite()) ? "true" : "false" ?>,
|
238 |
+
number_of_themes: <?php echo $number_of_themes ?>,
|
239 |
+
installed_theme: {'<?php echo sanitize_title($theme->Name) ?>' : '<?php echo $theme->Version ?>'},
|
240 |
+
theme_version: '<?php echo $theme->Version ?>',
|
241 |
+
main_soft_version: '<?php echo get_bloginfo("version") ?>',
|
242 |
+
user_level: '<?php echo $user_role ?>',
|
243 |
+
main_soft_name: 'WordPress',
|
244 |
+
role: '<?php echo $user_role ?>'
|
245 |
+
},
|
246 |
+
|
247 |
+
disable_wts: <?php echo $disabled_wts ?>,
|
248 |
+
disable_network_wts: <?php echo $disabled_network_wts ?>,
|
249 |
+
main_soft_name: 'WordPress',
|
250 |
+
embeded: false,
|
251 |
+
|
252 |
+
// User Settings
|
253 |
+
activation_id: '<?php echo $activation_id ?>',
|
254 |
+
auto_open_root_bucket_id: 79,
|
255 |
+
auto_open_product: 'default',
|
256 |
+
disable_wts_in_root_bucket_ids: [5,87],
|
257 |
+
autostart_walkthrough_id: <?php echo $autostart_walkthrough_id ?>,
|
258 |
+
sk_composer_button: <?php echo ($sk_composer_button ? "true" : "false") ?>,
|
259 |
+
track_data: '<?php echo $sk_track_data ?>',
|
260 |
+
user_email: '<?php echo $user_email ?>',
|
261 |
+
custom_class: '<?php echo $custom_class ?>',
|
262 |
+
|
263 |
+
// Toggles
|
264 |
+
path_not_found_continue: true,
|
265 |
+
show_powered_by: true,
|
266 |
+
show_powered_by_link: true,
|
267 |
+
sk_autostart_only_once: true,
|
268 |
+
use_native_controls: false,
|
269 |
+
composer_upgrade_off: false,
|
270 |
+
basics_upgrade: true,
|
271 |
+
|
272 |
+
// Platform Info
|
273 |
+
library_version: 2,
|
274 |
+
platform_id: 1,
|
275 |
+
|
276 |
+
// Generic Info
|
277 |
+
just_activated: <?php echo ($sk_just_activated) ? "true" : "false" ?>,
|
278 |
+
platform_version: null,
|
279 |
+
plugin_version: '%%version%%',
|
280 |
+
show_login: <?php echo ($sk_just_activated) ? "true" : "false" ?>,
|
281 |
+
|
282 |
+
// SIDEKICK URLS
|
283 |
+
assets: '<?php echo SK_ASSETS ?>',
|
284 |
+
api: '<?php echo SK_API ?>',
|
285 |
+
tracking_api: '<?php echo SK_TRACKING_API ?>',
|
286 |
+
sk_path: '<?php echo PLAYER_PATH ?>',
|
287 |
+
audio: '<?php echo SK_AUDIO ?>',
|
288 |
+
library: '<?php echo SK_LIBRARY ?>',
|
289 |
+
|
290 |
+
// URLS
|
291 |
+
site_url: '<?php echo $site_url ?>',
|
292 |
+
domain: '<?php echo str_replace("http://","",$_SERVER["SERVER_NAME"]) ?>',
|
293 |
+
domain_used: '//<?php echo PLAYER_DOMAIN ?>/',
|
294 |
+
plugin_url: '<?php echo admin_url("admin.php?page=sidekick") ?>',
|
295 |
+
base_url: '<?php echo site_url() ?>',
|
296 |
+
current_url: '<?php echo $current_url ?>'
|
297 |
+
// fallback_notfication_mp3: '//assets.sidekick.pro/fallback.mp3'
|
298 |
+
}
|
299 |
+
|
300 |
+
var skc_config = {
|
301 |
+
audioPlaceholderUrl: '<?php echo SK_ASSETS ?>walkthrough-audio-placeholder.mp3',
|
302 |
+
audioBaseUrl: '<?php echo SK_AUDIO ?>',
|
303 |
+
apiUrl: '<?php echo SK_COMPOSER_API ?>',
|
304 |
+
trackingUrl: '<?php echo SK_TRACKING_API ?>',
|
305 |
+
js: '//<?php echo COMPOSER_DOMAIN ?>/<?php echo COMPOSER_PATH ?>/sidekick-composer.js',
|
306 |
+
css: '//<?php echo COMPOSER_DOMAIN ?>/<?php echo COMPOSER_PATH ?>/sidekick-composer.css',
|
307 |
+
baseSiteUrl: sk_config.base_url,
|
308 |
+
platformId: 1,
|
309 |
+
compatibilities: sk_config.compatibilities,
|
310 |
+
siteAjaxUrl: window.ajaxurl || ''
|
311 |
+
}
|
312 |
+
|
313 |
+
</script>
|
314 |
+
<?php endif ?>
|
315 |
+
|
316 |
+
<?php
|
317 |
+
}
|
318 |
+
|
319 |
+
function track($data){
|
320 |
+
mlog('track');
|
321 |
+
|
322 |
+
if (file_exists(realpath(dirname(__FILE__)) . '/libs/mixpanel/Mixpanel.php')) {
|
323 |
+
require_once(realpath(dirname(__FILE__)) . '/libs/mixpanel/Mixpanel.php');
|
324 |
+
$mp = Mixpanel::getInstance("965556434c5ae652a44f24b85b442263");
|
325 |
+
$domain = str_replace("http://","",$_SERVER["SERVER_NAME"]);
|
326 |
+
|
327 |
+
switch ($data['type']) {
|
328 |
+
case 'activate':
|
329 |
+
$mp->track("Activate - Plugin", array("domain" => $domain));
|
330 |
+
break;
|
331 |
+
|
332 |
+
case 'deactivate':
|
333 |
+
$mp->track("Deactivate - Plugin", array("domain" => $domain));
|
334 |
+
break;
|
335 |
+
|
336 |
+
default:
|
337 |
+
if (isset($data['event'])) {
|
338 |
+
$mp->track($data['event'], array("domain" => $domain));
|
339 |
+
}
|
340 |
+
break;
|
341 |
+
}
|
342 |
+
}
|
343 |
+
|
344 |
+
$response = wp_remote_post( SK_TRACKING_API . 'event', array(
|
345 |
+
'method' => 'POST',
|
346 |
+
'timeout' => 45,
|
347 |
+
'redirection' => 5,
|
348 |
+
'httpversion' => '1.0',
|
349 |
+
'blocking' => true,
|
350 |
+
'headers' => array(),
|
351 |
+
'body' => $data,
|
352 |
+
'cookies' => array()
|
353 |
+
)
|
354 |
+
);
|
355 |
+
}
|
356 |
+
|
357 |
+
function activate($return = false){
|
358 |
+
if (isset($_POST['activation_id'])) {
|
359 |
+
update_option('sk_activation_id',$_POST['activation_id']);
|
360 |
+
}
|
361 |
+
}
|
362 |
+
|
363 |
+
function activate_plugin(){
|
364 |
+
update_option( 'sk_firstuse', true );
|
365 |
+
update_option( 'sk_do_activation_redirect', true );
|
366 |
+
$data = array(
|
367 |
+
'source' => 'plugin',
|
368 |
+
'action' => 'track',
|
369 |
+
'type' => 'activate'
|
370 |
+
);
|
371 |
+
$this->track($data);
|
372 |
+
}
|
373 |
+
|
374 |
+
function curl_get_data($url){
|
375 |
+
$ch = curl_init();
|
376 |
+
$timeout = 5;
|
377 |
+
curl_setopt($ch, CURLOPT_URL, $url);
|
378 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
379 |
+
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
|
380 |
+
$data = curl_exec($ch);
|
381 |
+
curl_close($ch);
|
382 |
+
return $data;
|
383 |
+
}
|
384 |
+
|
385 |
+
function redirect(){
|
386 |
+
if (get_option('sk_do_activation_redirect', false)) {
|
387 |
+
delete_option('sk_do_activation_redirect');
|
388 |
+
$siteurl = get_site_url();
|
389 |
+
wp_redirect($siteurl . "/wp-admin/options-general.php?page=sidekick");
|
390 |
+
die();
|
391 |
+
}
|
392 |
+
}
|
393 |
+
|
394 |
+
function check_ver(){
|
395 |
+
|
396 |
+
$data = json_encode('%%version%%');
|
397 |
+
|
398 |
+
if(array_key_exists('callback', $_GET)){
|
399 |
+
|
400 |
+
header('Content-Type: text/javascript; charset=utf8');
|
401 |
+
header('Access-Control-Allow-Origin: http://www.example.com/');
|
402 |
+
header('Access-Control-Max-Age: 3628800');
|
403 |
+
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
|
404 |
+
|
405 |
+
$callback = $_GET['callback'];
|
406 |
+
echo $callback.'('.$data.');';
|
407 |
+
|
408 |
+
}else{
|
409 |
+
header('Content-Type: application/json; charset=utf8');
|
410 |
+
|
411 |
+
echo $data;
|
412 |
+
}
|
413 |
+
|
414 |
+
die();
|
415 |
+
}
|
416 |
+
|
417 |
+
function admin_notice() {
|
418 |
+
global $current_user ;
|
419 |
+
|
420 |
+
if ( ! get_user_meta($current_user->ID, 'sk_ignore_notice') ) {
|
421 |
+
printf ('<div class="updated"><p>Need help with WordPress? Click HELP ME in the bottom left corner to get started! <a href="%1$s">Hide</a></p></div>','?sk_ignore_notice=1');
|
422 |
+
}
|
423 |
+
}
|
424 |
+
|
425 |
+
function admin_notice_ignore() {
|
426 |
+
global $current_user;
|
427 |
+
if ( isset($_GET['sk_ignore_notice'])) {
|
428 |
+
add_user_meta($current_user->ID, 'sk_ignore_notice', true);
|
429 |
+
}
|
430 |
+
}
|
431 |
+
|
432 |
+
function deactivate_plugin(){
|
433 |
+
$data = array(
|
434 |
+
'source' => 'plugin',
|
435 |
+
'action' => 'track',
|
436 |
+
'type' => 'deactivate',
|
437 |
+
'user' => get_option( "activation_id" )
|
438 |
+
);
|
439 |
+
$this->track($data);
|
440 |
+
?>
|
441 |
+
<script type="text/javascript">
|
442 |
+
window._gaq = window._gaq || [];
|
443 |
+
window._gaq.push(['sk._setAccount', 'UA-39283622-1']);
|
444 |
+
|
445 |
+
(function() {
|
446 |
+
var ga_wpu = document.createElement('script'); ga_sk.type = 'text/javascript'; ga_sk.async = true;
|
447 |
+
ga_sk.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
448 |
+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga_wpu, s);
|
449 |
+
})();
|
450 |
+
window._gaq.push(['sk._trackEvent', 'Plugin - Deactivate', '', null, 0,true]);
|
451 |
+
</script>
|
452 |
+
<?php
|
453 |
+
delete_option( 'sk_activated' );
|
454 |
+
}
|
455 |
+
}
|
456 |
+
$sidekick = new Sidekick;
|
457 |
+
register_activation_hook( __FILE__, array($sidekick,'activate_plugin') );
|
458 |
+
register_deactivation_hook( __FILE__, array($sidekick,'deactivate_plugin') );
|
459 |
+
|
460 |
+
if (isset($_POST['sk_setting_disabled'])) $sidekick->set_disabled_wts();
|
461 |
+
if (isset($_POST['sk_setting_autostart'])) $sidekick->set_autostart_wt();
|
462 |
+
if (isset($_POST['sk_api'])) $sidekick->set_api();
|
463 |
+
if (isset($_GET['sk_ver_check'])) $sidekick->check_ver();
|
464 |
+
|
465 |
+
|
466 |
+
add_action('admin_menu', array($sidekick,'setup_menu'));
|
467 |
+
add_action('admin_init', array($sidekick,'redirect'));
|
468 |
+
add_action('wp_ajax_sk_activate', array($sidekick,'activate'));
|
469 |
+
add_action('wp_ajax_sk_save', array($sidekick,'ajax_save'));
|
470 |
+
add_action('admin_notices', array($sidekick,'admin_notice'));
|
471 |
+
add_action('admin_init', array($sidekick,'admin_notice_ignore'));
|
472 |
+
|
473 |
+
|
474 |
+
|
475 |
+
if (!defined('SK_PLUGIN_DEGBUG'))
|
476 |
+
require_once('sk_init.php');
|
477 |
+
|
478 |
+
if (!(isset($_GET['tab']) && $_GET['tab'] == 'plugin-information') && !defined('IFRAME_REQUEST')) {
|
479 |
+
add_action('admin_footer', array($sidekick,'footer'));
|
480 |
+
add_action('customize_controls_print_footer_scripts', array($sidekick,'footer'));
|
481 |
+
}
|
482 |
+
}
|
483 |
+
|
484 |
+
|
485 |
+
|
486 |
+
// Multisite Licensing
|
487 |
+
|
488 |
+
if (defined('MULTISITE')) {
|
489 |
+
require_once('libs/licensing.php');
|
490 |
+
$sidekickMassActivator = new sidekickMassActivator;
|
491 |
+
add_action('wpmu_new_blog',array($sidekickMassActivator,'activate'),10,6);
|
492 |
+
add_action('network_admin_menu', array($sidekickMassActivator,'setup_menu'));
|
493 |
+
add_action('wp_ajax_sk_activate_single', array($sidekickMassActivator,'activate_single'));
|
494 |
+
}
|
495 |
+
|