PluginProbe
QuadMenu – Mega Menu / 3.3.8
QuadMenu – Mega Menu v3.3.8
3.3.8 3.3.7 3.3.6 trunk 1.8.4 1.8.5 1.8.7 1.8.8 1.8.9 1.9.0 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 88 releases
quadmenu / redux / ReduxCore / inc / tracking.php

tracking.php in QuadMenu – Mega Menu 3.3.8, at redux/ReduxCore/inc/tracking.php

520 lines 19.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * @package ReduxLegacy_Tracking
5 */
6 if ( ! class_exists( 'ReduxFrameworkLegacy' ) ) {
7 return;
8 }
9
10 /**
11 * Class that creates the tracking functionality for Redux, as the core class might be used in more plugins,
12 * it's checked for existence first.
13 * NOTE: this functionality is opt-in. Disabling the tracking in the settings or saying no when asked will cause
14 * this file to not even be loaded.
15 */
16 if ( ! class_exists( 'ReduxLegacy_Tracking' ) ) {
17
18 /**
19 * class ReduxLegacy_Tracking
20 */
21 class ReduxLegacy_Tracking {
22
23 public $options = array();
24 public $parent;
25
26 /** Refers to a single instance of this class. */
27 private static $instance = null;
28
29 /**
30 * Creates or returns an instance of this class.
31 *
32 * @return ReduxLegacy_Tracking A single instance of this class.
33 */
34 public static function get_instance() {
35
36 if ( null == self::$instance ) {
37 self::$instance = new self();
38 }
39
40 return self::$instance;
41 }
42 // end get_instance;
43
44 /**
45 * Class constructor
46 */
47 function __construct() {
48 }
49
50 /**
51 * @param ReduxFrameworkLegacy $parent
52 */
53 public function load( $parent ) {
54 $this->parent = $parent;
55
56 $this->options = get_option( 'redux-framework-tracking' );
57 $this->options['dev_mode'] = $parent->args['dev_mode'];
58
59 if ( ! isset( $this->options['hash'] ) || ! $this->options['hash'] || empty( $this->options['hash'] ) ) {
60 $this->options['hash'] = md5( network_site_url() . '-' . $_SERVER['REMOTE_ADDR'] );
61 update_option( 'redux-framework-tracking', $this->options );
62 }
63
64 if ( isset( $_GET['redux_framework_disable_tracking'] ) && ! empty( $_GET['redux_framework_disable_tracking'] ) ) {
65 $this->options['allow_tracking'] = 'no';
66 update_option( 'redux-framework-tracking', $this->options );
67 }
68
69 if ( isset( $_GET['redux_framework_enable_tracking'] ) && ! empty( $_GET['redux_framework_enable_tracking'] ) ) {
70 $this->options['allow_tracking'] = 'yes';
71 update_option( 'redux-framework-tracking', $this->options );
72 }
73
74 if ( isset( $_GET['page'] ) && $_GET['page'] == $this->parent->args['page_slug'] ) {
75 if ( ! isset( $this->options['allow_tracking'] ) ) {
76 add_action( 'admin_enqueue_scripts', array( $this, '_enqueue_tracking' ) );
77 } elseif ( ! isset( $this->options['tour'] ) && ( $this->parent->args['dev_mode'] == 'true' || $this->parent->args['page_slug'] == 'redux_demo' ) ) {
78 add_action( 'admin_enqueue_scripts', array( $this, '_enqueue_newsletter' ) );
79 }
80 }
81
82 $hash = md5( trailingslashit( network_site_url() ) . '-redux' );
83 add_action( 'wp_ajax_nopriv_' . $hash, array( $this, 'tracking_arg' ) );
84 add_action( 'wp_ajax_' . $hash, array( $this, 'tracking_arg' ) );
85
86 $hash = md5( md5( ReduxLegacy_Helpers::get_auth_key_secret_key() . '-redux' ) . '-support' );
87 add_action( 'wp_ajax_nopriv_' . $hash, array( $this, 'support_args' ) );
88 add_action( 'wp_ajax_' . $hash, array( $this, 'support_args' ) );
89
90 if ( isset( $this->options['allow_tracking'] ) && $this->options['allow_tracking'] == 'yes' ) {
91 // The tracking checks daily, but only sends new data every 7 days.
92 if ( ! wp_next_scheduled( 'reduxlegacy_tracking' ) ) {
93 wp_schedule_event( time(), 'daily', 'reduxlegacy_tracking' );
94 }
95 add_action( 'reduxlegacy_tracking', array( $this, 'tracking' ) );
96 }
97 }
98
99 function _enqueue_tracking() {
100 wp_enqueue_style( 'wp-pointer' );
101 wp_enqueue_script( 'jquery' );
102 wp_enqueue_script( 'jquery-ui' );
103 wp_enqueue_script( 'wp-pointer' );
104 wp_enqueue_script( 'utils' );
105 add_action( 'admin_print_footer_scripts', array( $this, 'tracking_request' ) );
106 }
107
108 function _enqueue_newsletter() {
109 wp_enqueue_style( 'wp-pointer' );
110 wp_enqueue_script( 'jquery' );
111 wp_enqueue_script( 'jquery-ui' );
112 wp_enqueue_script( 'wp-pointer' );
113 wp_enqueue_script( 'utils' );
114 add_action( 'admin_print_footer_scripts', array( $this, 'newsletter_request' ) );
115 }
116
117 /**
118 * Shows a popup that asks for permission to allow tracking.
119 */
120 function tracking_request() {
121 $id = '#wpadminbar';
122 $nonce = wp_create_nonce( 'redux_activate_tracking' );
123
124 $content = '<h3>' . esc_html__( 'Help improve Our Panel', 'redux-framework' ) . '</h3>';
125 $content .= '<p>' . esc_html__( 'Please helps us improve our panel by allowing us to gather anonymous usage stats so we know which configurations, plugins and themes to test to ensure compatibility.', 'redux-framework' ) . '</p>';
126 $opt_arr = array(
127 'content' => $content,
128 'position' => array(
129 'edge' => 'top',
130 'align' => 'center',
131 ),
132 );
133 $button2 = esc_html__( 'Allow tracking', 'redux-framework' );
134
135 $function2 = 'redux_store_answer("yes","' . $nonce . '")';
136 $function1 = 'redux_store_answer("no","' . $nonce . '")';
137
138 $this->print_scripts( $id, $opt_arr, esc_html__( 'Do not allow tracking', 'redux-framework' ), $button2, $function2, $function1 );
139 }
140
141 /**
142 * Shows a popup that asks for permission to allow tracking.
143 */
144 function newsletter_request() {
145 $id = '#wpadminbar';
146 $nonce = wp_create_nonce( 'redux_activate_tracking' );
147
148 $content = '<h3>' . esc_html__( 'Welcome to the Redux Demo Panel', 'redux-framework' ) . '</h3>';
149 $content .= '<p><strong>' . esc_html__( 'Getting Started', 'redux-framework' ) . '</strong><br>' . sprintf( __( 'This panel demonstrates the many features of Redux. Before digging in, we suggest you get up to speed by reviewing %1$s.', 'redux-framework' ), '<a href="' . 'http://' . 'docs.ReduxFrameworkLegacy.com/redux-framework/getting-started/" target="_blank">' . esc_html__( 'our documentation', 'redux-framework' ) . '</a>' );
150 $content .= '<p><strong>' . esc_html__( 'Redux Generator', 'redux-framework' ) . '</strong><br>' . sprintf( __( 'Want to get a head start? Use the %1$s. It will create a customized boilerplate theme or a standalone admin folder complete with all things Redux (with the help of Underscores and TGM). Save yourself a headache and try it today.', 'redux-framework' ), '<a href="' . 'http://' . 'generate.ReduxFrameworkLegacy.com/" target="_blank">' . esc_html__( 'Redux Generator', 'redux-framework' ) . '</a>' );
151 $content .= '<p><strong>' . esc_html__( 'Redux Extensions', 'redux-framework' ) . '</strong><br>' . sprintf( __( 'Did you know we have extensions, which greatly enhance the features of Redux? Visit our %1$s to learn more!', 'redux-framework' ), '<a href="' . 'http://' . 'ReduxFrameworkLegacy.com/extensions/" target="_blank">' . esc_html__( 'extensions directory', 'redux-framework' ) . '</a>' );
152 $content .= '<p><strong>' . esc_html__( 'Like Redux?', 'redux-framework' ) . '</strong><br>' . sprintf( __( 'If so, please %1$s and consider making a %2$s to keep development of Redux moving forward.', 'redux-framework' ), '<a target="_blank" href="' . 'http://' . 'wordpress.org/support/view/plugin-reviews/redux-framework">' . esc_html__( 'leave us a favorable review on WordPress.org', 'redux-framework' ) . '</a>', '<a href="' . 'https://' . 'www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=N5AD7TSH8YA5U" target="_blank">' . esc_html__( 'donation', 'redux-framework' ) . '</a>' );
153 $content .= '<p><strong>' . esc_html__( 'Newsletter', 'redux-framework' ) . '</strong><br>' . esc_html__( 'If you\'d like to keep up to with all things Redux, please subscribe to our newsletter', 'redux-framework' ) . ':</p>';
154 $content .= '<form action="http://news.redux.io/subscribe" method="POST" target="_blank" accept-charset="utf-8" class="validate">
155 <p style="text-align: center;">
156 <label for="email">' . esc_html__( 'Email Address', 'redux-framework' ) . '</label>
157 <input type="email" name="email" class="required email" id="email"/>
158 <input type="hidden" name="list" value="9K1qDRvB8Ux0DqpEoQSEPA"/>
159 &nbsp;&nbsp;&nbsp;&nbsp;
160 <input type="submit" class="button button-primary" name="submit" value="' . esc_html__( 'Subscribe', 'redux-framework' ) . '" id="submit"/>
161 </p>
162 </form>';
163
164 $opt_arr = array(
165 'content' => $content,
166 'position' => array(
167 'edge' => 'top',
168 'align' => 'center',
169 ),
170 'pointerWidth' => 450,
171 );
172
173 $function1 = 'redux_store_answer("tour","' . $nonce . '")';
174
175 $this->print_scripts( $id, $opt_arr, esc_html__( 'Close', 'redux-framework' ), false, '', $function1 );
176 }
177
178 /**
179 * Prints the pointer script
180 *
181 * @param string $selector The CSS selector the pointer is attached to.
182 * @param array $options The options for the pointer.
183 * @param string $button1 Text for button 1
184 * @param string|bool $button2 Text for button 2 (or false to not show it, defaults to false)
185 * @param string $button2_function The JavaScript function to attach to button 2
186 * @param string $button1_function The JavaScript function to attach to button 1
187 */
188 function print_scripts( $selector, $options, $button1, $button2 = false, $button2_function = '', $button1_function = '' ) {
189 ?>
190 <script type="text/javascript">
191 //<![CDATA[
192 //
193 (function( $ ) {
194 $( document ).ready(
195 function() {
196 var redux_pointer_options = <?php echo json_encode( $options ); ?>, setup;
197
198 function redux_store_answer( input, nonce ) {
199 var reduxlegacy_tracking_data = {
200 action: 'redux_allow_tracking',
201 allow_tracking: input,
202 nonce: nonce
203 }
204 jQuery.post(
205 ajaxurl, reduxlegacy_tracking_data, function() {
206 jQuery( '#wp-pointer-0' ).remove();
207 }
208 );
209 }
210
211 redux_pointer_options = $.extend(
212 redux_pointer_options, {
213 buttons: function( event, t ) {
214 button = jQuery( '<a id="pointer-close" style="margin-left:5px" class="button-secondary">' + '<?php echo $button1; ?>' + '</a>' );
215 button.bind(
216 'click.pointer', function() {
217 t.element.pointer( 'close' );
218 //console.log( 'close button' );
219 }
220 );
221 return button;
222 },
223 close: function() {
224 }
225 }
226 );
227
228 setup = function() {
229 $( '<?php echo $selector; ?>' ).pointer( redux_pointer_options ).pointer( 'open' );
230 <?php if ( $button2 ) { ?>
231 jQuery( '#pointer-close' ).after( '<a id="pointer-primary" class="button-primary">' + '<?php echo $button2; ?>' + '</a>' );
232 jQuery( '#pointer-primary' ).click(
233 function() {
234 <?php echo $button2_function; ?>
235 }
236 );
237 jQuery( '#pointer-close' ).click(
238 function() {
239 <?php if ( $button1_function == '' ) { ?>
240 redux_store_answer( input, nonce )
241 //redux_setIgnore("tour", "wp-pointer-0", "<?php echo wp_create_nonce( 'redux-ignore' ); ?>");
242 <?php } else { ?>
243 <?php echo $button1_function; ?>
244 <?php } ?>
245 }
246 );
247 <?php } elseif ( $button1 && ! $button2 ) { ?>
248 jQuery( '#pointer-close' ).click(
249 function() {
250 <?php if ( $button1_function != '' ) { ?>
251 <?php echo $button1_function; ?>
252 <?php } ?>
253 }
254 );
255 <?php } ?>
256 };
257
258 if ( redux_pointer_options.position && redux_pointer_options.position.defer_loading )
259 $( window ).bind( 'load.wp-pointers', setup );
260 else
261 $( document ).ready( setup );
262 }
263 );
264 })( jQuery );
265 //]]>
266 </script>
267 <?php
268 }
269
270 function trackingObject() {
271 global $blog_id, $wpdb;
272 $pts = array();
273
274 foreach ( get_post_types( array( 'public' => true ) ) as $pt ) {
275 $count = wp_count_posts( $pt );
276 $pts[ $pt ] = $count->publish;
277 }
278
279 $comments_count = wp_count_comments();
280 $theme_data = wp_get_theme();
281 $theme = array(
282 'version' => $theme_data->Version,
283 'name' => $theme_data->Name,
284 'author' => $theme_data->Author,
285 'template' => $theme_data->Template,
286 );
287
288 if ( ! function_exists( 'get_plugin_data' ) ) {
289 require_once ABSPATH . 'wp-admin/includes/admin.php';
290 }
291
292 $plugins = array();
293 foreach ( get_option( 'active_plugins', array() ) as $plugin_path ) {
294 $plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin_path );
295
296 $slug = str_replace( '/' . basename( $plugin_path ), '', $plugin_path );
297 $plugins[ $slug ] = array(
298 'version' => $plugin_info['Version'],
299 'name' => $plugin_info['Name'],
300 'plugin_uri' => $plugin_info['PluginURI'],
301 'author' => $plugin_info['AuthorName'],
302 'author_uri' => $plugin_info['AuthorURI'],
303 );
304 }
305 if ( is_multisite() ) {
306 foreach ( get_option( 'active_sitewide_plugins', array() ) as $plugin_path ) {
307 $plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin_path );
308 $slug = str_replace( '/' . basename( $plugin_path ), '', $plugin_path );
309 $plugins[ $slug ] = array(
310 'version' => $plugin_info['Version'],
311 'name' => $plugin_info['Name'],
312 'plugin_uri' => $plugin_info['PluginURI'],
313 'author' => $plugin_info['AuthorName'],
314 'author_uri' => $plugin_info['AuthorURI'],
315 );
316 }
317 }
318
319 $version = explode( '.', PHP_VERSION );
320 $version = array(
321 'major' => $version[0],
322 'minor' => $version[0] . '.' . $version[1],
323 'release' => PHP_VERSION,
324 );
325
326 $user_query = new WP_User_Query(
327 array(
328 'blog_id' => $blog_id,
329 'count_total' => true,
330 )
331 );
332 $comments_query = new WP_Comment_Query();
333 $data = array(
334 '_id' => $this->options['hash'],
335 'localhost' => ( $_SERVER['REMOTE_ADDR'] === '127.0.0.1' ) ? 1 : 0,
336 'php' => $version,
337 'site' => array(
338 'hash' => $this->options['hash'],
339 'version' => get_bloginfo( 'version' ),
340 'multisite' => is_multisite(),
341 'users' => $user_query->get_total(),
342 'lang' => get_locale(),
343 'wp_debug' => ( defined( 'WP_DEBUG' ) ? WP_DEBUG ? true : false : false ),
344 'memory' => WP_MEMORY_LIMIT,
345 ),
346 'pts' => $pts,
347 'comments' => array(
348 'total' => $comments_count->total_comments,
349 'approved' => $comments_count->approved,
350 'spam' => $comments_count->spam,
351 'pings' => $comments_query->query(
352 array(
353 'count' => true,
354 'type' => 'pingback',
355 )
356 ),
357 ),
358 'options' => apply_filters( 'redux/tracking/options', array() ),
359 'theme' => $theme,
360 'redux' => array(
361 'mode' => ReduxFrameworkLegacy::$_is_plugin ? 'plugin' : 'theme',
362 'version' => ReduxFrameworkLegacy::$_version,
363 'demo_mode' => get_option( 'ReduxFrameworkPlugin' ),
364 ),
365 'developer' => apply_filters( 'redux/tracking/developer', array() ),
366 'plugins' => $plugins,
367 );
368
369 $parts = explode( ' ', $_SERVER['SERVER_SOFTWARE'] );
370 $software = array();
371 foreach ( $parts as $part ) {
372 if ( $part[0] == '(' ) {
373 continue;
374 }
375 if ( strpos( $part, '/' ) !== false ) {
376 $chunk = explode( '/', $part );
377 $software[ strtolower( $chunk[0] ) ] = $chunk[1];
378 }
379 }
380 $software['full'] = $_SERVER['SERVER_SOFTWARE'];
381 $data['environment'] = $software;
382 // if ( function_exists( 'mysql_get_server_info' ) ) {
383 // $data['environment']['mysql'] = mysql_get_server_info();
384 // }
385 $data['environment']['mysql'] = $wpdb->db_version();
386
387 if ( empty( $data['developer'] ) ) {
388 unset( $data['developer'] );
389 }
390
391 return $data;
392 }
393
394 /**
395 * Main tracking function.
396 */
397 function tracking() {
398 // Start of Metrics
399 global $blog_id, $wpdb;
400
401 $data = get_transient( 'reduxlegacy_tracking_cache' );
402 if ( ! $data ) {
403
404 $args = array(
405 'body' => $this->trackingObject(),
406 );
407
408 $response = wp_remote_post( 'https://redux-tracking.herokuapp.com', $args );
409
410 // Store for a week, then push data again.
411 set_transient( 'reduxlegacy_tracking_cache', true, WEEK_IN_SECONDS );
412 }
413 }
414
415 function tracking_arg() {
416 echo md5( ReduxLegacy_Helpers::get_auth_key_secret_key() . '-redux' );
417 die();
418 }
419
420 function support_args() {
421 header( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );
422 header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . 'GMT' );
423 header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
424 header( 'Cache-Control: no-store, no-cache, must-revalidate' );
425 header( 'Cache-Control: post-check=0, pre-check=0', false );
426 header( 'Pragma: no-cache' );
427 $instances = ReduxFrameworkInstancesLegacy::get_all_instances();
428
429 $array = array();
430
431 if ( isset( $_REQUEST['i'] ) && ! empty( $_REQUEST['i'] ) ) {
432 if ( is_array( $instances ) && ! empty( $instances ) ) {
433 foreach ( $instances as $opt_name => $data ) {
434 if ( md5( $opt_name . '-debug' ) == $_REQUEST['i'] ) {
435 $array = $instances[ $opt_name ];
436 }
437 }
438 }
439 if ( isset( $array ) ) {
440 if ( isset( $array->extensions ) && is_array( $array->extensions ) && ! empty( $array->extensions ) ) {
441 foreach ( $array->extensions as $key => $extension ) {
442 if ( isset( $extension->$version ) ) {
443 $array->extensions[ $key ] = $extension->$version;
444 } else {
445 $array->extensions[ $key ] = true;
446 }
447 }
448 }
449 if ( isset( $array->import_export ) ) {
450 unset( $array->import_export );
451 }
452 if ( isset( $array->debug ) ) {
453 unset( $array->debug );
454 }
455 } else {
456 die();
457 }
458 } else {
459 $array = $this->trackingObject();
460 if ( is_array( $instances ) && ! empty( $instances ) ) {
461 $array['instances'] = array();
462 foreach ( $instances as $opt_name => $data ) {
463 $array['instances'][] = $opt_name;
464 }
465 }
466 $array['key'] = md5( ReduxLegacy_Helpers::get_auth_key_secret_key() );
467 }
468
469 echo @json_encode( $array, true );
470 die();
471 }
472 }
473
474 ReduxLegacy_Tracking::get_instance();
475
476 /**
477 * Adds tracking parameters for Redux settings. Outside of the main class as the class could also be in use in other ways.
478 *
479 * @param array $options
480 *
481 * @return array
482 */
483 function reduxlegacy_tracking_additions( $options ) {
484 $opt = array();
485
486 $options['redux'] = array(
487 'demo_mode' => get_option( 'ReduxFrameworkPlugin' ),
488 );
489
490 return $options;
491 }
492
493 add_filter( 'redux/tracking/options', 'reduxlegacy_tracking_additions' );
494
495 function redux_allow_tracking_callback() {
496 // Verify that the incoming request is coming with the security nonce
497 if ( wp_verify_nonce( $_REQUEST['nonce'], 'redux_activate_tracking' ) ) {
498 $options = get_option( 'redux-framework-tracking' );
499
500 if ( $_REQUEST['allow_tracking'] == 'tour' ) {
501 $options['tour'] = 1;
502 } else {
503 $options['allow_tracking'] = $_REQUEST['allow_tracking'];
504 }
505
506 if ( update_option( 'redux-framework-tracking', $options ) ) {
507 die( '1' );
508 } else {
509 die( '0' );
510 }
511 } else {
512 // Send -1 if the attempt to save via Ajax was completed invalid.
513 die( '-1' );
514 } // end if
515 }
516
517 add_action( 'wp_ajax_redux_allow_tracking', 'redux_allow_tracking_callback' );
518
519 }
520