PluginProbe
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) / trunk
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) vtrunk
9.1.2 9.1.1 9.1.0 9.0.2 9.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.1.0 1.1.1 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 All 153 releases
← All changes | wp-analytify.php +1936 -869 1.0.3trunk View file →
@@ -1,869 +1,1936 @@
1 -<?php
2 -/*
3 -* Plugin Name: Analytify - Google Analytics Dashboard
4 -* Plugin URI: hhttp://wp-analytify.com/details
5 -* Description: Analytify brings a brand new and modern feeling Google Analytics superbly integrated with WordPress Dashboard. It presents the statistics in a beautiful way under the WordPress Posts/Pages at front end, backend and in its own Dashboard. This provides Stats from Country, Referrers, Social media, General stats, New visitors, Returning visitors, Exit pages, Browser wise and Top keywords. This plugin provides the RealTime statistics in a new UI which is easy to understand and looks good.
6 -* Version: 1.0.3
7 -* Author: WPBrigade
8 -* Author URI: http://wpbrigade.com/
9 -* License: GPLv2+
10 -* Text Domain: wp-analytify
11 -* Min WP Version: 3.0.1
12 -* Max WP Version: 4.1.1
13 -* Domain Path: /lang
14 -*/
15 -
16 -// Exit if accessed directly
17 -if ( !defined( 'ABSPATH' ) ) exit;
18 -
19 -ini_set( 'include_path', dirname(__FILE__) . '/lib/' );
20 -
21 -if ( !class_exists( 'WP_Analytify' ) ) {
22 -
23 - if ( !class_exists( 'Analytify_General_FREE' ) ){
24 -
25 - require_once WP_PLUGIN_DIR .'/wp-analytify/analytify-general.php';
26 - }
27 -
28 -class WP_Analytify extends Analytify_General_FREE{
29 -
30 - public $token = false;
31 - public $client = null;
32 -
33 - // Constructor
34 - function __construct() {
35 -
36 - parent::__construct();
37 -
38 - if ( !class_exists( 'Analytify_Google_Client' ) ) {
39 -
40 - require_once ANALYTIFY_LIB_PATH . 'Google/Client.php';
41 - require_once ANALYTIFY_LIB_PATH . 'Google/Service/Analytics.php';
42 - }
43 -
44 - add_action( 'plugin_action_links', array(
45 - $this,
46 - 'pa_plugin_links'
47 - ),10,2);
48 -
49 - add_action( 'plugin_row_meta', array(
50 - $this,
51 - 'analytify_plugin_row_meta'
52 - ),10,2);
53 -
54 - add_action( 'admin_enqueue_scripts', array(
55 - $this,
56 - 'pa_scripts'
57 - ));
58 - add_action( 'admin_enqueue_scripts', array(
59 - $this,
60 - 'pa_styles'
61 - ));
62 -
63 -
64 - add_action( 'wp_enqueue_scripts', array(
65 - $this,
66 - 'pa_front_scripts'
67 - ));
68 - add_action( 'wp_enqueue_scripts', array(
69 - $this,
70 - 'pa_front_styles'
71 - ));
72 -
73 - add_action( 'admin_menu', array(
74 - $this,
75 - 'wpa_add_menu'
76 - ));
77 -
78 - // Insert Google Analytics Code
79 - if( get_option( 'analytify_code') == 1 ) {
80 -
81 - add_action( 'wp_head', array(
82 - $this,
83 - 'analytify_add_analytics_code'
84 - ));
85 - }
86 -
87 - add_action( 'wp_ajax_nopriv_get_ajax_single_admin_analytics', array(
88 - $this,
89 - 'get_ajax_single_admin_analytics'
90 - ));
91 -
92 - add_action( 'wp_ajax_get_ajax_single_admin_analytics', array(
93 - $this,
94 - 'get_ajax_single_admin_analytics'
95 - ));
96 -
97 - add_action( 'wp_ajax_get_ajax_secret_keys', array(
98 - $this,
99 - 'get_ajax_secret_keys'
100 - ));
101 -
102 - if( get_option( 'analytify_disable_front') == 0 ) {
103 -
104 - add_filter( 'the_content', array(
105 - $this,
106 - 'get_single_front_analytics'
107 - ));
108 - }
109 -
110 - /*
111 - * load Analytics under the EDIT POST Screen
112 - * add action runs only for admin section and load metabox.
113 - */
114 -
115 - if ( is_admin() ) {
116 - add_action( 'load-post.php', array(
117 - $this,
118 - 'load_metaboxes'
119 - ));
120 - }
121 -
122 - // Show welcome message when user activate plugin.
123 - if ( get_option( 'pa_welcome_message' ) == 0 ) {
124 -
125 - add_action( 'admin_print_footer_scripts', array(
126 - $this,
127 - 'pa_welcome_message'
128 - ) );
129 - }
130 -
131 - /*
132 - * localization language file filter
133 - */
134 -
135 - add_action( 'init', array(
136 - $this,
137 - 'analytify_textdomain') );
138 -
139 - //add_action( 'admin_footer', array( &$this, 'profile_warning' ) );
140 -
141 - register_activation_hook( __FILE__, array( $this, 'install' ) );
142 - register_deactivation_hook( __FILE__, array( $this, 'uninstall' ) );
143 - }
144 -
145 - /*
146 - * Set plugin language/localizations files directory
147 - */
148 - public function analytify_textdomain() {
149 -
150 - $plugin_dir = basename( dirname(__FILE__) );
151 - load_plugin_textdomain( 'wp-analytify', false , $plugin_dir . '/lang/');
152 -
153 - }
154 -
155 - /*
156 - * Show analytics sections under the posts/pages in the metabox.
157 - */
158 -
159 - function load_metaboxes() {
160 -
161 - add_action( 'add_meta_boxes', array(
162 - $this,
163 - 'show_admin_single_analytics_add_metabox'
164 - ));
165 - }
166 -
167 - /*
168 - * Show metabox under each Post type to display Analytics of single post/page in wp-admin
169 - */
170 - public function show_admin_single_analytics_add_metabox() {
171 -
172 - $post_types = get_option( 'analytify_posts_stats' );
173 -
174 - // Don't load boxes/sections if no any post type is selected.
175 - if( !empty($post_types))
176 - foreach ( $post_types as $post_type ) {
177 -
178 - add_meta_box('pa-single-admin-analytics', // $id
179 - 'Analytify: Google Analytics of this page.', // $title
180 - array(
181 - 'WP_Analytify',
182 - 'show_admin_single_analytics'
183 - ), // $callback
184 -
185 - $post_type, // $posts
186 - 'normal', // $context
187 - 'high' // $priority
188 - );
189 - } //$post_types as $post_type
190 - }
191 -
192 -
193 - public static function get_ajax_secret_keys(){
194 -
195 - $response = wp_remote_get( "http://wp-analytify.com/secret/keys.json" );
196 - if( is_wp_error( $response ) ) {
197 - $error_message = $response->get_error_message();
198 - echo "Something went wrong: $error_message";
199 - } else {
200 - print_r($response['body']);
201 - }
202 - die();
203 - }
204 -
205 - /*
206 - * Show Analytics of single post/page in wp-admin under EDIT screen.
207 - */
208 - public static function show_admin_single_analytics() {
209 -
210 - global $post;
211 -
212 - $back_exclude_posts = explode( ',', get_option( 'post_analytics_exclude_posts_back' ));
213 -
214 - if ( is_array( $back_exclude_posts ) ) {
215 -
216 - if ( in_array( $post->ID, $back_exclude_posts ) ) {
217 -
218 - _e('This post is excluded and will not show Analytics.');
219 -
220 - return;
221 - }
222 - }
223 -
224 - $urlPost = '';
225 - $wp_analytify = new WP_Analytify();
226 - $urlPost = parse_url( get_permalink( $post->ID ) );
227 - $start_date = ''; $end_date = ''; $urlpost = '' ;
228 - $is_access_level = get_option( 'post_analytics_access_back' );
229 -
230 - if( $wp_analytify->pa_check_roles( $is_access_level ) ){ ?>
231 -
232 - <div class="pa-filter">
233 - <table cellspacing="0" cellpadding="0" width="400">
234 - <tbody>
235 - <tr>
236 - <td width="0">
237 - <input type="text" id="start_date" name="start_date">
238 - </td>
239 - <td width="0">
240 - <input type="text" id="end_date" name="end_date">
241 - </td>
242 - <input type="hidden" name="urlpost" id="urlpost" value="<?php echo $urlPost['path']; ?>">
243 - <td width="0">
244 - <input type="button" id="view_analytics" name="view_analytics" value="View Analytics" class="button-primary btn-green">
245 - </td>
246 - </tr>
247 - </tbody>
248 - </table>
249 - </div>
250 - <div class="loading" style="display:none">
251 - <img src="<?php echo plugins_url('images/loading.gif', __FILE__);?>">
252 - </div>
253 - <div class="show-hide">
254 - <?php $wp_analytify->get_single_admin_analytics( $start_date, $end_date, $post->ID, 0 ); ?>
255 - </div>
256 - <?php
257 - }
258 - else{
259 - echo _e( 'You are not allowed to see stats', 'wp-analytify' );
260 - }
261 - }
262 -
263 - // Add Google Analytics JS code
264 - public function analytify_add_analytics_code() {
265 -
266 - global $current_user;
267 -
268 - $roles = $current_user->roles;
269 -
270 - if ( isset( $roles[0] ) and in_array( $roles[0], get_option( 'display_tracking_code' ) )) {
271 -
272 - }
273 - else{
274 -
275 - echo '<!-- This code is added by Analytify v - ' . ANALYTIFY_VERSION . ' http://wp-analytify.com/ !--> ';
276 -
277 - if ( get_option( 'analytify_tracking_code' ) == 'universal' ) { ?>
278 -
279 - <script>
280 - (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
281 - (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
282 - m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
283 - })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
284 - ga('create', '<?php echo get_option( "webPropertyId" );?>', 'auto');
285 - ga('send', 'pageview');
286 - </script>
287 -
288 - <?php
289 - }
290 -
291 - if ( get_option( 'analytify_tracking_code' ) == 'ga' ) { ?>
292 -
293 - <script type="text/javascript">//<![CDATA[
294 - var _gaq = _gaq || [];
295 - _gaq.push(['_setAccount', '<?php echo get_option( "webPropertyId" );?>']);
296 - _gaq.push(['_trackPageview']);
297 - (function () {
298 - var ga = document.createElement('script');
299 - ga.type = 'text/javascript';
300 - ga.async = true;
301 - ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
302 - var s = document.getElementsByTagName('script')[0];
303 - s.parentNode.insertBefore(ga, s);
304 - })();
305 - //]]>
306 - </script>
307 -
308 - <?php
309 - }
310 -
311 - echo '<!-- This code is added by Analytify v - ' . ANALYTIFY_VERSION . ' !-->';
312 - }
313 - }
314 -
315 - /**
316 - * Add a link to the settings page to the plugins list
317 - */
318 - public function pa_plugin_links( $links, $file ) {
319 -
320 - static $this_plugin;
321 -
322 - if ( empty( $this_plugin ) ){
323 -
324 - $this_plugin = 'wp-analytify/wp-analytify.php';
325 - }
326 -
327 - if ( $file == $this_plugin ) {
328 -
329 - $settings_link = '<a href="' . admin_url("admin.php?page=analytify-settings") . '">' . __( 'Settings', 'wp-analytify' ) . '</a> | <a href="' . admin_url("admin.php?page=analytify-dashboard") . '">' . __( 'Dashboard', 'wp-analytify' ) . '</a>';
330 - array_unshift( $links, $settings_link );
331 - }
332 -
333 - return $links;
334 - }
335 -
336 - /**
337 - * Plugin row meta links
338 - *
339 - * @since 1.1
340 - * @param array $input already defined meta links
341 - * @param string $file plugin file path and name being processed
342 - * @return array $input
343 - */
344 - function analytify_plugin_row_meta( $input, $file ) {
345 - if ( $file != 'wp-analytify/wp-analytify.php' )
346 - return $input;
347 -
348 - $links = array(
349 - '<a href="http://wp-analytify.com/">' . esc_html__( 'Buy Pro Version', 'edd' ) . '</a>',
350 - '<a href="http://wp-analytify.com/add-ons/">' . esc_html__( 'Add Ons', 'edd' ) . '</a>',
351 - );
352 -
353 - $input = array_merge( $input, $links );
354 -
355 - return $input;
356 - }
357 -
358 -
359 - /**
360 - * Display warning if profiles are not selected.
361 - */
362 - public function pa_check_warnings(){
363 -
364 - add_action( 'admin_footer', array(
365 - &$this,
366 - 'profile_warning'
367 - ));
368 - }
369 -
370 - /**
371 - * Get current screen details
372 - */
373 - public static function pa_page_file_path() {
374 -
375 - $screen = get_current_screen();
376 -
377 - if ( strpos( $screen->base, 'analytify-settings' ) !== false ) {
378 - include( ANALYTIFY_ROOT_PATH . '/inc/analytify-settings.php' );
379 - }
380 - else {
381 - include( ANALYTIFY_ROOT_PATH . '/inc/analytify-dashboard.php' );
382 - }
383 - }
384 -
385 - /**
386 - * Styling: loading stylesheets for the plugin.
387 - */
388 - public function pa_styles( $page ) {
389 -
390 - wp_enqueue_style( 'wp-analytify-style', plugins_url('css/wp-analytify-style.css', __FILE__));
391 -
392 - // wp_enqueue_style( 'ui-css', plugins_url('jquery-ui-theme/jquery-ui.css', __FILE__));
393 - wp_enqueue_style( 'chosen', plugins_url('css/chosen.css', __FILE__));
394 - // wp_enqueue_style( 'jquery-ui-tooltip-css', plugins_url('css/jquery.ui.tooltip.html.css', __FILE__) );
395 -
396 - if ( get_option( 'pa_welcome_message' ) == '0' ) {
397 -
398 - wp_enqueue_style( 'wp-pointer' );
399 -
400 - }
401 - }
402 -
403 - public function pa_front_styles( $page ) {
404 -
405 - if( get_option( 'analytify_disable_front') == 0 ) {
406 -
407 - wp_enqueue_style( 'front-end-style', plugins_url('css/frontend_styles.css', __FILE__),false,ANALYTIFY_VERSION);
408 - }
409 - }
410 -
411 - /**
412 - * Loading scripts js for the plugin.
413 - */
414 - public function pa_scripts( $page ) {
415 -
416 - wp_enqueue_script ( 'jquery' );
417 - wp_enqueue_script ( 'charts_api_js', 'https://www.google.com/jsapi', false, ANALYTIFY_VERSION );
418 - wp_enqueue_script ( 'chosen-js', plugins_url('js/chosen.jquery.js', __FILE__), false, ANALYTIFY_VERSION );
419 - wp_enqueue_script ( 'script-js', plugins_url('js/wp-analytify.js', __FILE__), false, ANALYTIFY_VERSION );
420 - wp_enqueue_script ( 'jquery-ui-tooltip' );
421 - wp_enqueue_script ( 'jquery-ui-datepicker');
422 -
423 - if ( get_option( 'pa_welcome_message' ) == '0' ) {
424 -
425 - wp_enqueue_script( 'wp-pointer' );
426 - }
427 - }
428 -
429 - /**
430 - * Loading scripts js for the plugin.
431 - */
432 - public function pa_front_scripts( $page ) {
433 -
434 - if( get_option( 'analytify_disable_front') == 0 ){
435 -
436 - wp_enqueue_script ('jquery');
437 - wp_enqueue_script ('analytify-classie', plugins_url('js/classie.js', __FILE__), false, ANALYTIFY_VERSION);
438 - wp_enqueue_script ('analytify-selectfx', plugins_url('js/selectFx.js', __FILE__), false, ANALYTIFY_VERSION);
439 - wp_enqueue_script ('analytify-script', plugins_url('js/script.js', __FILE__), false, ANALYTIFY_VERSION);
440 -
441 - }
442 - }
443 -
444 - /**
445 - * Create Analytics menu at the left side of dashboard
446 - */
447 - public static function wpa_add_menu() {
448 -
449 - add_menu_page( ANALYTIFY_NICK, 'Analytify', 'manage_options', 'analytify-dashboard', array(
450 - __CLASS__,
451 - 'pa_page_file_path'
452 - ), plugins_url('images/wp-analytics-logo.png', __FILE__),'2.1.9');
453 -
454 - add_submenu_page( 'analytify-dashboard', ANALYTIFY_NICK . ' Dashboard', ' Dashboard', 'manage_options', 'analytify-dashboard', array(
455 - __CLASS__,
456 - 'pa_page_file_path'
457 - ));
458 -
459 - add_submenu_page( 'analytify-dashboard', ANALYTIFY_NICK . ' Settings', '<b style="color:#f9845b">Settings</b>', 'manage_options', 'analytify-settings', array(
460 - __CLASS__,
461 - 'pa_page_file_path'
462 - ));
463 - }
464 -
465 - /**
466 - * Creating tabs for settings
467 - * @since 1.0
468 - */
469 -
470 - public function pa_settings_tabs( $current = 'authentication' ) {
471 -
472 - $tabs = array( 'authentication' => 'Authentication',
473 - 'profile' => 'Profile',
474 -
475 - 'admin' => 'Admin'
476 - );
477 -
478 - echo '<div class="left-area">';
479 -
480 - echo '<div id="icon-themes" class="icon32"><br></div>';
481 - echo '<h2 class="nav-tab-wrapper">';
482 -
483 - foreach( $tabs as $tab => $name ) {
484 -
485 - $class = ( $tab == $current ) ? ' nav-tab-active' : '';
486 - echo "<a class='nav-tab$class' href='?page=analytify-settings&tab=$tab'>$name</a>";
487 - }
488 -
489 - echo '</h2>';
490 - }
491 -
492 - /**
493 - * Get profiles from user Google Analytics account profiles.
494 - */
495 - public function pt_get_analytics_accounts() {
496 -
497 - try {
498 -
499 - if( get_option( 'pa_google_token' ) !='' ) {
500 - $profiles = $this->service->management_profiles->listManagementProfiles( "~all", "~all" );
501 - return $profiles;
502 - }
503 -
504 - else{
505 - echo '<br /><p class="description">' . __( 'You must authenticate to access your web profiles.', 'wp-analytify' ) . '</p>';
506 - }
507 -
508 - }
509 -
510 - catch (Exception $e) {
511 - die('An error occured: ' . $e->getMessage() . '\n');
512 - }
513 - }
514 -
515 - public function pa_setting_url() {
516 -
517 - return admin_url('admin.php?page=analytify-settings');
518 -
519 - }
520 -
521 -
522 - public function pt_save_data( $key_google_token ) {
523 -
524 - update_option( 'post_analytics_token', $key_google_token );
525 - $this->pa_connect();
526 -
527 - return true;
528 - }
529 -
530 - /**
531 - * Warning messages.
532 - */
533 - public function profile_warning() {
534 -
535 - $profile_id = get_option( "pt_webprofile" );
536 - $acces_token = get_option( "post_analytics_token" );
537 -
538 - if (! isset( $acces_token ) || empty( $acces_token )) {
539 -
540 - echo "<div id='message' class='error'><p><strong>" . __( "Analytify is not active. Please <a href='" . menu_page_url ( 'analytify-settings', false ) ."'>Authenticate</a> in order to get started using this plugin.", 'wp-analytify' )."</p></div>";
541 - }
542 - else{
543 -
544 - if (! isset( $profile_id ) || empty( $profile_id )){
545 - echo '<div class="error"><p><strong>' . __( 'Google Analytics Profile is not set. Set the <a href="' . menu_page_url ( 'analytify-settings', false ) . '&tab=profile">Profile</a> ', 'wp-analytify' ) . '</p></div>';
546 - }
547 - }
548 - }
549 -
550 -
551 - public function get_single_front_analytics( $content ) {
552 -
553 - global $post, $wp_analytify;
554 -
555 - $front_access = get_option( 'post_analytics_access' );
556 -
557 - if ( is_single() || is_page() ) {
558 -
559 - $post_type = get_post_type( $post->ID );
560 -
561 - if( strlen( get_option( 'analytify_posts_stats_front' ) < 3) ) {
562 - return $content;
563 - }
564 -
565 - if( is_array( get_option( 'analytify_posts_stats_front' )) and !in_array( $post_type, get_option( 'analytify_posts_stats_front' ) ) ) {
566 -
567 - return $content;
568 - }
569 -
570 - if ( is_array( get_option( 'post_analytics_exclude_posts_front' ) ) ) {
571 -
572 - if ( in_array( get_the_ID(), get_option( 'post_analytics_exclude_posts_front' ) ) ) {
573 -
574 - return $content;
575 - }
576 - }
577 -
578 - // Showing stats to guests
579 - if ( $front_access[0] == 'every-one' || $this->pa_check_roles( $front_access )) {
580 -
581 - $post_analytics_settings_front = array();
582 - $post_analytics_settings_front = get_option( 'post_analytics_settings_front' );
583 -
584 - $urlPost = parse_url( get_permalink( $post->ID ) );
585 -
586 - if ( $urlPost['host'] == 'localhost' )
587 - $filter = 'ga:pagePath==/'; //.$u_post['path'];
588 - else
589 - $filter = 'ga:pagePath==' .$urlPost['path']. '';
590 -
591 - if( get_the_time('Y', $post->ID) < 2005 ) {
592 -
593 - $start_date = '2005-01-01';
594 - }
595 - else {
596 -
597 - $start_date = get_the_time('Y-m-d', $post->ID);
598 - }
599 -
600 - $end_date = date('Y-m-d');
601 -
602 - ob_start();
603 -
604 - include ANALYTIFY_ROOT_PATH . '/inc/front-menus.php';
605 -
606 - if(! empty( $post_analytics_settings_front )){
607 -
608 - if (is_array( $post_analytics_settings_front )){
609 -
610 - $stats = $this->pa_get_analytics( 'ga:sessions,ga:bounces,ga:newUsers,ga:entrances,ga:pageviews,ga:sessionDuration,ga:avgSessionDuration,ga:users',$start_date, $end_date, false, false, $filter);
611 -
612 - if ( isset( $stats->totalsForAllResults ) ) {
613 -
614 - include ANALYTIFY_ROOT_PATH . '/views/front/general-stats.php';
615 - pa_include_general( $this, $stats);
616 - }
617 - }
618 - }
619 -
620 - $content .= ob_get_contents();
621 - ob_get_clean();
622 - }
623 -
624 - }
625 -
626 - return $content;
627 -
628 - }
629 -
630 - /*
631 - * get the Analytics data from ajax() call
632 - *
633 - */
634 -
635 - public function get_ajax_single_admin_analytics() {
636 -
637 - $startDate = '';
638 - $endDate = '';
639 - $postID = 0 ;
640 - $startDate = $_POST['start_date'];
641 - $endDate = $_POST['end_date'];
642 - $postID = $_POST['post_id'];
643 - $this->get_single_admin_analytics( $startDate, $endDate, $postID, 1 );
644 -
645 - die();
646 - }
647 -
648 - /*
649 - * get the Analytics data for wp-admin posts/pages.
650 - *
651 - */
652 - public function get_single_admin_analytics( $start_date = '', $end_date = '', $postID = 0, $ajax = 0 ) {
653 -
654 - global $post;
655 -
656 - //$urlPost = parse_url( get_permalink( $post->ID ) );
657 -
658 - if ( $postID == 0 ) {
659 - $u_post = '/'; //$urlPost['path'];
660 - }
661 - else{
662 - $u_post = parse_url( get_permalink( $postID ) );
663 - }
664 -
665 - if ( $u_post['host'] == 'localhost' )
666 - $filter = false;
667 - else
668 - $filter = 'ga:pagePath==' .$u_post['path']. '';
669 -
670 -
671 - if ( $start_date == '' ) {
672 -
673 - $s_date = get_the_time('Y-m-d', $post->ID);
674 - if(get_the_time('Y', $post->ID) < 2005){
675 - $s_date = '2005-01-01';
676 - }
677 - }
678 - else{
679 - $s_date = $start_date;
680 - }
681 -
682 - if ( $end_date == '' ) {
683 - $e_date = date('Y-m-d');
684 - }
685 - else{
686 - $e_date = $end_date;
687 - }
688 -
689 - $show_settings = array();
690 - $show_settings = get_option('post_analytics_settings_back');
691 -
692 - // Stop here, if user has disable backend analytics i.e OFF
693 - if ( get_option( 'post_analytics_disable_back' ) == 1 and $ajax == 0) {
694 - return;
695 - }
696 -
697 - echo '<p> Displaying Analytics of this page from ' . date("jS F, Y", strtotime($s_date)) . ' to '. date("jS F, Y", strtotime($e_date)) . '</p>';
698 -
699 - if( !empty( $show_settings )){
700 -
701 - if (is_array( $show_settings )){
702 -
703 - if (in_array( 'show-overall-back', $show_settings )) {
704 -
705 - $stats = $this->pa_get_analytics( 'ga:sessions,ga:bounces,ga:newUsers,ga:entrances,ga:pageviews,ga:sessionDuration,ga:avgSessionDuration,ga:users',$s_date, $e_date, false, false, $filter);
706 -
707 - if ( isset( $stats->totalsForAllResults ) ) {
708 -
709 - include ANALYTIFY_ROOT_PATH . '/views/admin/single-general-stats.php';
710 - wpa_single_include_general( $this, $stats);
711 - }
712 - }
713 - }
714 - }
715 - }
716 -
717 -
718 - /*
719 - * Pretty numbers
720 - */
721 - function wpa_pretty_numbers( $num ) {
722 -
723 - return round(($num/1000),2).'k';
724 - }
725 -
726 - /*
727 - * format numbers
728 - */
729 - function wpa_number_format( $num ) {
730 -
731 - return number_format($num);
732 - }
733 -
734 - /*
735 - * Pretty time to display
736 - */
737 - function pa_pretty_time( $time ) {
738 -
739 - // Check if numeric
740 - if ( is_numeric($time) ) {
741 -
742 - $value = array(
743 - "years" => '00',
744 - "days" => '00',
745 - "hours" => '',
746 - "minutes" => '',
747 - "seconds" => ''
748 - );
749 -
750 - if ($time >= 31556926) {
751 - $value["years"] = floor($time / 31556926);
752 - $time = ($time % 31556926);
753 - } //$time >= 31556926
754 -
755 - if ($time >= 86400)
756 - {
757 - $value["days"] = floor($time / 86400);
758 - $time = ($time % 86400);
759 - } //$time >= 86400
760 - if ($time >= 3600)
761 - {
762 - $value["hours"] = str_pad(floor($time / 3600), 1, 0, STR_PAD_LEFT);
763 - $time = ($time % 3600);
764 - } //$time >= 3600
765 - if ($time >= 60)
766 - {
767 - $value["minutes"] = str_pad(floor($time / 60), 1, 0, STR_PAD_LEFT);
768 - $time = ($time % 60);
769 - } //$time >= 60
770 - $value["seconds"] = str_pad(floor($time), 1, 0, STR_PAD_LEFT);
771 - # Get the hour:minute:second version
772 - if($value['hours']!=''){
773 - $attach_hours='<sub>h</sub> ';
774 - }
775 - if($value['minutes']!=''){
776 - $attach_min='<sub>min</sub> ';
777 - }
778 - if($value['seconds']!=''){
779 - $attach_sec='<sub>sec</sub>';
780 - }
781 - return $value['hours'] .@$attach_hours. $value['minutes'] .@$attach_min. $value['seconds'].$attach_sec;
782 - //return $value['hours'] . ':' . $value['minutes'] . ':' . $value['seconds'];
783 - } //is_numeric($time)
784 - else
785 - {
786 - return false;
787 - }
788 - }
789 -
790 -
791 - public function pa_check_roles( $access_level ) {
792 -
793 - if ( is_user_logged_in () && isset ( $access_level ) ) {
794 -
795 - global $current_user;
796 - $roles = $current_user->roles;
797 -
798 - /*if ( ( current_user_can ( 'manage_options' ) ) ) {
799 -
800 - return true;
801 - }*/
802 -
803 - if ( in_array ( $roles[0], $access_level ) ) {
804 -
805 - return true;
806 - }
807 - else {
808 -
809 - return false;
810 - }
811 - }
812 - }
813 -
814 - public function pa_welcome_message() {
815 -
816 - $pointer_content = '<h3>Analytify - Google Analytics for WordPress.</h3>';
817 - $pointer_content .= '<p>Thank you for activating Analytify Plugin. Enjoy Google Analytics for everything in WordPress.</p>';
818 - ?>
819 -
820 - <script type="text/javascript">
821 - //<![CDATA[
822 - jQuery(document).ready( function($) {
823 -
824 - $('#toplevel_page_pa-dashboard').pointer({
825 - content: '<?php echo $pointer_content; ?>',
826 - position: 'left',
827 - close: function() {
828 - <?php update_option("pa_welcome_message",1) ?>
829 - }
830 - }).pointer('open');
831 - });
832 - //]]>
833 - </script>
834 -
835 - <?php
836 - }
837 -
838 - /*
839 - * Activate options by default on installing the plugin.
840 - */
841 - static function install() {
842 -
843 - update_option( 'analytify_posts_stats', array( 'post','page' ));
844 - update_option( 'post_analytics_disable_back' , 1 );
845 - update_option( 'analytify_code' , 1 );
846 - update_option( 'post_analytics_settings_back' , array( 'show-overall-back' ) );
847 - update_option( 'post_analytics_access_back' , array( 'editor','administrator' ) );
848 - update_option( 'display_tracking_code' , array( 'administrator' ) );
849 -
850 -
851 - }
852 -
853 - static function uninstall() {
854 -
855 - delete_option( 'analytify_posts_stats' );
856 - delete_option( 'pa_google_token' );
857 - delete_option( 'pa_welcome_message' );
858 - delete_option( 'post_analytics_token' );
859 -
860 - }
861 -
862 -}
863 -
864 -$wp_analytify = new WP_Analytify();
865 -
866 -$wp_analytify->pa_check_warnings();
867 -
868 -} //end if
869 -?>
1 +<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 +/**
3 + * Plugin Name: Analytify Dashboard
4 + * Plugin URI: https://analytify.io/?ref=27&utm_source=wp-org&utm_medium=plugin-header&utm_campaign=pro-upgrade&utm_content=plugin-uri
5 + * Description: Analytify brings a brand new and modern feeling of Google Analytics superbly integrated within the WordPress.
6 + * Version: 9.1.2
7 + * Author: Analytify
8 + * Author URI: https://analytify.io/?ref=27&utm_source=wp-org&utm_medium=plugin-header&utm_campaign=pro-upgrade&utm_content=author-uri
9 + * License: GPLv3
10 + * Text Domain: wp-analytify
11 + * Requires at least: 4.0
12 + * Tested up to: 7.0
13 + * Domain Path: /languages
14 + * GitHub Plugin URI: https://github.com/WPBrigade/wp-analytify
15 + *
16 + * @package WP_ANALYTIFY
17 + */
18 +if ( ! defined( 'ABSPATH' ) ) {
19 + exit;
20 +}
21 +
22 +if ( ! function_exists( 'wa_wpb78834179' ) ) {
23 + /**
24 + * Create a helper function for easy SDK access.
25 + *
26 + * @return mixed
27 + */
28 + function wa_wpb78834179() {
29 + global $wa_wpb78834179;
30 +
31 + if ( ! isset( $wa_wpb78834179 ) || ! is_array( $wa_wpb78834179 ) ) {
32 + require_once __DIR__ . '/lib/wpb-sdk/start.php';
33 +
34 + /**
35 + * Initialize WPB SDK.
36 + *
37 + * @phpstan-ignore-next-line
38 + */
39 + $wa_wpb78834179 = wpb_sdk_dynamic_init(
40 + array(
41 + 'id' => '7',
42 + 'slug' => 'wp-analytify',
43 + 'type' => 'plugin',
44 + 'plugin_file' => __FILE__,
45 + 'sdk_views_dir' => __DIR__ . '/lib/wpb-sdk/views',
46 + 'public_key' => '1|4aOA8EuyIN4pi2miMvC23LLpnHbBZFNki9R9pVmwd673d3c8',
47 + 'secret_key' => 'sk_b36c525848fee035',
48 + 'is_premium' => false,
49 + 'has_addons' => false,
50 + 'has_paid_plans' => false,
51 + 'optin_user_meta' => array(
52 + 'token' => '_analytify_verification_token',
53 + 'email_verified' => '_analytify_email_verified',
54 + ),
55 + 'lifecycle' => array(
56 + 'class' => 'Analytify_Plugin_Lifecycle',
57 + 'bootstrap_files' => array(
58 + 'inc/analytify-constants.php',
59 + 'inc/plugin-lifecycle.php',
60 + ),
61 + 'uninstall_requires' => 'classes/analytify-utils.php',
62 + 'constructor_args' => array( null ),
63 + ),
64 + 'telemetry' => array(
65 + 'user_info_format' => 'laravel',
66 + 'optout_submit_key' => 'analytify-submit-optout',
67 + ),
68 + 'optin' => array(
69 + 'option_name' => '_analytify_optin',
70 + 'verify_query_arg' => 'wp-analytify_optin_verify',
71 + 'settings_page' => 'analytify-settings',
72 + 'optin_page' => 'analytify-optin',
73 + 'use_site_option' => true,
74 + 'guard_pages' => array(
75 + 'analytify-settings',
76 + 'analytify-dashboard',
77 + 'analytify-pmpro',
78 + 'analytify-learndash',
79 + 'analytify-lifterlms',
80 + 'analytify-woocommerce',
81 + 'analytify-addons',
82 + ),
83 + ),
84 + 'menu' => array(
85 + 'slug' => 'wp-analytify',
86 + 'account' => false,
87 + 'support' => false,
88 + ),
89 + 'settings' => array(
90 + 'wp_analytify_modules' => '',
91 + 'wp-analytify-tracking' => '',
92 + 'wp-analytify-email' => '',
93 + 'wp-analytify-events-tracking' => '',
94 + 'wp-analytify-front' => '',
95 + 'wp-analytify-custom-dimensions' => '',
96 + 'wp-analytify-forms' => '',
97 + 'analytify_widget_date_differ' => '',
98 + 'wp-analytify-profile' => '',
99 + 'wp-analytify-admin' => '',
100 + 'wp-analytify-dashboard' => '',
101 + 'wp-analytify-advanced' => '',
102 + 'analytify_ua_code' => '',
103 + 'analytify_date_differ' => '',
104 + 'wp_analytify_review_dismiss' => '',
105 + 'analytify_date_start' => '',
106 + 'analytify_date_end' => '',
107 + 'wp_analytify_review_dismiss_4_1_8' => '',
108 + 'wpanalytify_settings' => '',
109 + 'analytify_license_key' => '',
110 + 'analytify_license_status' => '',
111 + 'analytify_campaigns_license_status' => '',
112 + 'analytify_campaigns_license_key' => '',
113 + 'analytify_goals_license_status' => '',
114 + 'analytify_goals_license_key' => '',
115 + 'Analytify_Addon_Forms_license_status' => '',
116 + 'analytify_forms_license_key' => '',
117 + 'analytify_authors_license_status' => '',
118 + 'analytify_authors_license_key' => '',
119 + 'analytify_woo_license_status' => '',
120 + 'analytify_woo_license_key' => '',
121 + 'analytify_email_license_status' => '',
122 + 'analytify_email_license_key' => '',
123 + 'analytify-google-ads-tracking' => '',
124 + '_analytify_optin' => '',
125 + 'analytify_cache_timeout' => '',
126 + 'analytify_csv_data' => '',
127 + 'analytify_active_date' => '',
128 + 'analytify_edd_license_status' => '',
129 + 'analytify_edd_license_key' => '',
130 + '_transient_timeout_analytify_api_addons' => '',
131 + '_transient_analytify_api_addons' => '',
132 + 'analytify_ga4_exceptions' => '',
133 + 'analytify-ga-properties-summery' => '',
134 + 'analytify_ga4-streams' => '',
135 + 'analytify_tracking_property_info' => '',
136 + 'analytify_reporting_property_info' => '',
137 + 'analytify_gtag_move_to_notice' => '',
138 + 'analytify_current_version' => '',
139 + 'analytify_logs_setup' => '',
140 + 'analytify_pro_default_settings' => '',
141 + 'analytify_pro_active_date' => '',
142 + 'analytify_pro_upgrade_routine' => '',
143 + 'analytify_pro_current_version' => '',
144 + 'WP_ANALYTIFY_PRO_PLUGIN_VERSION' => '',
145 + 'wp-analytify-license' => '',
146 + 'analytify_authentication_date' => '',
147 + 'WP_ANALYTIFY_PLUGIN_VERSION_OLD' => '',
148 + 'WP_ANALYTIFY_PRO_PLUGIN_VERSION_OLD' => '',
149 + 'analytify_default_settings' => '',
150 + 'analytify_free_upgrade_routine' => '',
151 + 'WP_ANALYTIFY_PLUGIN_VERSION' => '',
152 + 'wp_analytify_active_time' => '',
153 + 'wp-analytify-authentication' => '',
154 + 'wp-analytify-help' => '',
155 + 'WP_ANALYTIFY_NEW_LOGIN' => '',
156 + 'profiles_list_summary' => '',
157 + 'pa_google_token' => '',
158 + 'post_analytics_token' => '',
159 + ),
160 + )
161 + );
162 + }
163 +
164 + return $wa_wpb78834179;
165 + }
166 +
167 + wa_wpb78834179();
168 + do_action( 'wa_wpb78834179_loaded' );
169 +}
170 +
171 +require_once __DIR__ . '/inc/analytify-constants.php';
172 +
173 +if ( ! class_exists( 'Analytify_General' ) ) {
174 + require_once 'analytify-general.php';
175 +}
176 +
177 +if ( ! class_exists( 'WP_Analytify' ) ) {
178 + /**
179 + * Main WP_Analytify class.
180 + *
181 + * @since 1.0.0
182 + */
183 + // phpcs:ignore Universal.Files.SeparateFunctionsFromOO.Mixed,Squiz.Commenting.ClassComment.Missing
184 + class WP_Analytify extends Analytify_General {
185 +
186 + /**
187 + * Plugin instance.
188 + *
189 + * @var WP_Analytify $instance The one true WP_Analytify
190 + * @since 1.2.2
191 + */
192 + private static $instance = null;
193 +
194 + /**
195 + * Token data.
196 + *
197 + * @var mixed
198 + */
199 + public $token = false;
200 + /**
201 + * Client instance.
202 + *
203 + * @var mixed
204 + */
205 + public $client = null;
206 +
207 + /**
208 + * Post stats disable flag.
209 + *
210 + * @var mixed
211 + */
212 + protected $disable_post_stats;
213 +
214 + /**
215 + * Settings data.
216 + *
217 + * @var mixed
218 + */
219 + public $settings;
220 +
221 + /**
222 + * Component loader instance
223 + *
224 + * @var Analytify_Loader
225 + */
226 + private $loader;
227 +
228 + /**
229 + * Measurement ID for gtag when consent-deferred (any CMP that opts in via filters).
230 + *
231 + * @var string|null
232 + */
233 + private $consent_deferred_gtag_ua_code = null;
234 +
235 + /**
236 + * Whether the wp_footer handler for consent-deferred gtag was registered.
237 + *
238 + * @var bool
239 + */
240 + private $consent_deferred_gtag_hooked = false;
241 +
242 + /**
243 + * Filter applied to deferred gtag markup ({@see 'analytify_ga_script'} or {@see 'analytify_gtag_script'}).
244 + *
245 + * @var string
246 + */
247 + private $consent_deferred_gtag_filter = 'analytify_ga_script';
248 +
249 + /**
250 + * When true, {@see self::output_gtag_code()} emits immediate async gtag only (for footer base64 payload).
251 + *
252 + * @var bool
253 + */
254 + private $output_gtag_for_footer_payload = false;
255 +
256 + // ========================================.
257 + // CONSTRUCTOR & CORE METHODS START.
258 + // ========================================.
259 +
260 + /**
261 + * Constructor.
262 + *
263 + * @since 1.2.2
264 + */
265 + public function __construct() {
266 + parent::__construct();
267 + $this->setup_constants();
268 + $this->includes();
269 + $this->disable_post_stats = $this->settings->get_option( 'enable_back_end', 'wp-analytify-admin' );
270 + $this->hooks();
271 + }
272 +
273 + /**
274 + * Get active instance.
275 + *
276 + * @access public
277 + * @since 1.2.2
278 + * @return object self::$instance The one true WP_Analytify
279 + */
280 + public static function get_instance() {
281 + if ( ! self::$instance ) {
282 + self::$instance = new WP_Analytify();
283 + }
284 +
285 + return self::$instance;
286 + }
287 +
288 + /**
289 + * Setup plugin constants
290 + *
291 + * @access private
292 + * @since 1.2.2
293 + * @return void
294 + */
295 + private function setup_constants() {
296 +
297 + $upload_dir = wp_upload_dir( null, false );
298 + }
299 +
300 + /**
301 + * Define constant if not already set
302 + *
303 + * @since 1.2.4
304 + * @param string $name contanst name.
305 + * @param string|bool $value constant value.
306 + * @return void
307 + */
308 + private function define( $name, $value ) {
309 + if ( ! defined( $name ) ) {
310 + define( $name, $value );
311 + }
312 + }
313 +
314 + /**
315 + * What type of request is this?
316 + *
317 + * @since 1.2.4
318 + * @param string $type ajax, frontend or admin.
319 + * @return bool
320 + */
321 + private function is_request( $type ) {
322 + switch ( $type ) {
323 + case 'admin':
324 + return is_admin();
325 + case 'ajax':
326 + return defined( 'DOING_AJAX' );
327 + case 'cron':
328 + return defined( 'DOING_CRON' );
329 + case 'frontend':
330 + return ( ! is_admin() || defined( 'DOING_AJAX' ) ) && ! defined( 'DOING_CRON' );
331 + default:
332 + return false;
333 + }
334 + }
335 +
336 +
337 + /**
338 + * Include necessary files
339 + *
340 + * @access private
341 + * @since 1.2.2
342 + * @return void
343 + */
344 + private function includes() {
345 + $files = array(
346 + WP_ANALYTIFY_LIB_PATH . 'logs/class-analytify-log-handler-interface.php',
347 + WP_ANALYTIFY_LIB_PATH . 'logs/class-analytify-logger-interface.php',
348 + WP_ANALYTIFY_LIB_PATH . 'logs/class-analytify-log-levels.php',
349 + WP_ANALYTIFY_LIB_PATH . 'logs/class-analytify-logger.php',
350 + WP_ANALYTIFY_LIB_PATH . 'logs/abstract-analytify-log-handler.php',
351 + WP_ANALYTIFY_LIB_PATH . 'logs/class-analytify-log-handler-file.php',
352 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-logs.php',
353 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-sanitize.php',
354 + WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytify-core-functions.php',
355 + WP_ANALYTIFY_PLUGIN_DIR . '/inc/class-analytify-adminbar.php',
356 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/abstracts/analytify-report-abstract.php',
357 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/abstracts/analytify-host-analytics-abstract.php',
358 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-host-analytics.php',
359 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-report-core.php',
360 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-rest-api.php',
361 + WP_ANALYTIFY_PLUGIN_DIR . '/inc/class-analytify-ajax.php',
362 + WP_ANALYTIFY_PLUGIN_DIR . '/inc/class-analytify-post-columns.php',
363 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/class-wp-analytify-compatibility-upgrade.php',
364 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-dashboard-widget.php',
365 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/class-analytify-user-optout.php',
366 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/class-analytify-gdpr-compliance.php',
367 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-email.php',
368 + WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-settings.php',
369 + );
370 +
371 + foreach ( $files as $file ) {
372 + if ( file_exists( $file ) ) {
373 + include_once $file;
374 + } else {
375 +
376 + echo '<div class="notice notice-error"><p>' . esc_html__( 'A critical file is missing:', 'wp-analytify' ) . ' ' . esc_html( $file ) . '. ' . esc_html__( 'The Analytify plugin needs to be deactivated && re-installed.', 'wp-analytify' ) . '</p></div>';
377 + return;
378 + }
379 + }
380 +
381 + if ( file_exists( WP_ANALYTIFY_PLUGIN_DIR . '/inc/class-analytify-loader.php' ) ) {
382 + require_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/class-analytify-loader.php';
383 + if ( class_exists( 'Analytify_Loader' ) ) {
384 + $this->loader = new Analytify_Loader( $this );
385 + }
386 + }
387 + }
388 +
389 + // ========================================.
390 + // CONSTRUCTOR & CORE METHODS END.
391 + // ========================================.
392 +
393 + // ========================================.
394 + // WordPress HOOKS & ACTIONS START.
395 + // ========================================.
396 +
397 + /**
398 + * Run action && filter hooks
399 + *
400 + * @access private
401 + * @since 1.2.2
402 + * @return void
403 + */
404 + private function hooks() {
405 +
406 + add_action( 'init', array( $this, 'load_textdomain' ) ); // Hook load_textdomain.
407 + add_action( 'admin_init', array( $this, '_save_core_version' ) );
408 + add_action( 'admin_init', array( $this, 'wpa_check_authentication' ) );
409 + add_action( 'admin_init', array( $this, 'logout' ), 1 );
410 + add_filter( 'removable_query_args', array( $this, 'Analytify_remove_query' ) );
411 + add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
412 +
413 + add_action( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 4 );
414 + add_filter( 'wpb_sdk_plugin_action_links', array( $this, 'wp_analytify_plugin_action_links' ), 10, 3 );
415 +
416 + add_action( 'wp_head', array( $this, 'analytify_add_analytics_code' ) );
417 + add_action( 'wp_head', array( $this, 'analytify_add_manual_analytics_code' ) );
418 +
419 + add_filter( 'admin_footer_text', 'wpa_admin_rate_footer_text', 1 );
420 + add_action( 'admin_footer', 'wpa_print_js', 25 );
421 +
422 + add_action( 'admin_init', array( $this, 'redirect_optin' ) );
423 + add_action( 'admin_init', array( $this, 'block_subscriber_analytify_access' ) );
424 +
425 + add_action( 'analytify_cleanup_logs', array( $this, 'analytify_cleanup_logs' ) );
426 + add_action(
427 + 'init',
428 + function () {
429 + if ( WPANALYTIFY_Utils::get_option( 'locally_host_analytics', 'wp-analytify-advanced', false ) && ! wp_next_scheduled( 'analytify_analytics_lib_cron' ) ) {
430 + wp_schedule_event( time(), 'daily', 'analytify_analytics_lib_cron' );
431 + }
432 + }
433 + );
434 +
435 + add_action(
436 + 'analytify_analytics_lib_cron',
437 + function () {
438 + if ( class_exists( 'Analytify_Host_Analytics' ) ) {
439 + new Analytify_Host_Analytics( 'gtag', true );
440 + }
441 + }
442 + );
443 + }
444 +
445 + /**
446 + * Redirect to Welcome page.
447 + *
448 + * @since 2.0.14
449 + * @return void
450 + */
451 + public function redirect_optin() {
452 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading URL parameter for display purposes
453 + $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
454 +
455 + if ( $page && ( 'analytify-settings' === $page || 'analytify-dashboard' === $page || 'analytify-pmpro' === $page || 'analytify-learndash' === $page || 'analytify-lifterlms' === $page || 'analytify-woocommerce' === $page || 'analytify-addons' === $page ) ) {
456 + if ( ! get_site_option( '_analytify_optin' ) ) {
457 + wp_safe_redirect( admin_url( 'admin.php?page=analytify-optin' ) );
458 + exit;
459 + }
460 + }
461 + }
462 +
463 +
464 + /**
465 + * Internationalization.
466 + *
467 + * @access public
468 + * @since 1.2.2
469 + * @return void
470 + */
471 + public function load_textdomain() {
472 + $plugin_dir = basename( __DIR__ );
473 + load_plugin_textdomain( 'wp-analytify', false, $plugin_dir . '/languages/' );
474 + }
475 +
476 + /**
477 + *
478 + * Save Authentication code on return
479 + * && nonce verification
480 + *
481 + * @return void
482 + */
483 + public function wpa_check_authentication() {
484 +
485 + $state = isset( $_GET['state'] ) ? json_decode( urldecode( sanitize_text_field( wp_unslash( $_GET['state'] ) ) ), true ) : null;
486 +
487 + if ( isset( $_GET['code'] ) && isset( $_GET['page'] ) && 'analytify-settings' === sanitize_text_field( wp_unslash( $_GET['page'] ) ) ) {
488 + $get_nonce = isset( $_GET['nonce'] ) ? sanitize_text_field( wp_unslash( $_GET['nonce'] ) ) : null;
489 + $nonce = isset( $state['nonce'] ) ? $state['nonce'] : $get_nonce;
490 +
491 + if ( wp_verify_nonce( $nonce, 'analytify_analytics_login' ) ) {
492 +
493 + $key_google_token = sanitize_text_field( wp_unslash( $_GET['code'] ) );
494 + update_option( 'WP_ANALYTIFY_NEW_LOGIN', 'yes' );
495 + delete_transient( 'analytify_google_userinfo_probe_skip' );
496 + self::pt_save_data( $key_google_token );
497 + wp_safe_redirect( admin_url( 'admin.php?page=analytify-settings' ) . '#wp-analytify-profile' );
498 + exit;
499 +
500 + } else {
501 + $plugin_page_url = admin_url( 'plugins.php' );
502 + wp_die(
503 + sprintf( // translators: Nonce verification failed.
504 + esc_html__( 'Sorry, you are not allowed as nonce verification failed. %1$sClick here to return to the Dashboard%2$s.', 'wp-analytify' ),
505 + '<a href="' . esc_url( $plugin_page_url ) . '">',
506 + '</a>'
507 + )
508 + );
509 + }
510 + }
511 + }
512 +
513 + /**
514 + * Save version number of the plugin && show a custom message for users
515 + *
516 + * @since 1.3
517 + * @return void
518 + */
519 + public function _save_core_version() { // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore -- Underscore prefix is intentional for internal method
520 + if ( ANALYTIFY_VERSION !== get_option( 'WP_ANALYTIFY_PLUGIN_VERSION' ) ) {
521 + update_option( 'WP_ANALYTIFY_PLUGIN_VERSION_OLD', get_option( 'WP_ANALYTIFY_PLUGIN_VERSION' ), true ); // saving old plugin version.
522 + update_option( 'WP_ANALYTIFY_PLUGIN_VERSION', ANALYTIFY_VERSION );
523 + }
524 + }
525 +
526 +
527 +
528 +
529 +
530 + // ========================================.
531 + // GOOGLE ANALYTICS TRACKING CODE START.
532 + // ========================================.
533 +
534 + /**
535 + * Add Google Analytics JS code
536 + *
537 + * @since 1.0.0
538 + * @version 7.0.4
539 + * @return bool|void Returns false if tracking is blocked/skipped, true if code is output, void otherwise.
540 + */
541 + public function analytify_add_analytics_code() {
542 + if ( WPANALYTIFY_Utils::skip_page_tracking() ) {
543 + return false;
544 + }
545 +
546 + // Check for GDPR compliance.
547 + if ( Analytify_GDPR_Compliance::is_gdpr_compliance_blocking() ) {
548 + return false;
549 + }
550 +
551 + if ( 'on' === $this->settings->get_option( 'install_ga_code', 'wp-analytify-profile', 'off' ) ) {
552 + global $current_user;
553 +
554 + $roles = $current_user->roles;
555 +
556 + if ( isset( $roles[0] ) && in_array( $roles[0], $this->settings->get_option( 'exclude_users_tracking', 'wp-analytify-profile', array() ), true ) ) {
557 + echo '<!-- This user is disabled from tracking by Analytify !-->';
558 + return false;
559 + } else {
560 + if ( ! $this->settings->get_option( 'profile_for_posts', 'wp-analytify-profile' ) ) {
561 + return false;
562 + }
563 +
564 + $ua_code = WP_ANALYTIFY_FUNCTIONS::get_UA_code();
565 +
566 + // Validate UA code before outputting tracking code.
567 + if ( empty( $ua_code ) ) {
568 + // Add a comment in HTML for debugging.
569 + echo '<!-- Analytify: No tracking code - check profile selection or OAuth connection -->';
570 + return false;
571 + }
572 +
573 + if ( 'gtag' === WP_ANALYTIFY_TRACKING_MODE && $this->maybe_schedule_consent_deferred_gtag( $ua_code, 'analytify_ga_script' ) ) {
574 + return false;
575 + }
576 +
577 + if ( 'gtag' === WP_ANALYTIFY_TRACKING_MODE ) {
578 + $ga_code = $this->output_gtag_code( $ua_code );
579 + } else {
580 + $ga_code = $this->output_ga_code( $ua_code );
581 + }
582 +
583 + echo apply_filters( 'analytify_ga_script', $ga_code ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JavaScript code needs to be output directly
584 + return true;
585 + }
586 + }
587 + }
588 +
589 + /**
590 + * Add Google Manual Analytics JS code
591 + *
592 + * @return void
593 + */
594 + public function analytify_add_manual_analytics_code() {
595 + if ( get_option( 'pa_google_token' ) ) {
596 + return;
597 + }
598 +
599 + $manual_ua_code = $this->settings->get_option( 'manual_ua_code', 'wp-analytify-authentication', false );
600 +
601 + if ( ! $manual_ua_code ) {
602 + return;
603 + }
604 +
605 + if ( class_exists( 'WPANALYTIFY_Utils' ) && WPANALYTIFY_Utils::skip_page_tracking() ) {
606 + return;
607 + }
608 +
609 + if ( Analytify_GDPR_Compliance::is_gdpr_compliance_blocking() ) {
610 + return;
611 + }
612 +
613 + global $current_user;
614 + $roles = $current_user->roles;
615 +
616 + if ( in_array( 'administrator', $roles, true ) ) {
617 + echo '<!-- This user is disabled from tracking by Analytify !-->';
618 + } elseif ( apply_filters( 'analytify_manaul_ga_script', false ) ) {
619 + echo apply_filters( 'analytify_ga_script', $this->output_ga_code( $manual_ua_code ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JavaScript code needs to be output directly
620 + } elseif ( $this->maybe_schedule_consent_deferred_gtag( $manual_ua_code, 'analytify_gtag_script' ) ) {
621 + return;
622 + } else {
623 + echo apply_filters( 'analytify_gtag_script', $this->output_gtag_code( $manual_ua_code ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JavaScript code needs to be output directly
624 + }
625 + }
626 +
627 + /**
628 + * Schedule gtag for wp_footer when consent-deferred mode is on (any compatible cookie plugin).
629 + *
630 + * @since 9.0.0
631 + * @param string $ua_code Measurement ID (or legacy property id).
632 + * @param string $result_filter Filter name for the deferred markup.
633 + * @return bool True when deferred (no head output).
634 + */
635 + private function maybe_schedule_consent_deferred_gtag( $ua_code, $result_filter = 'analytify_ga_script' ) {
636 +
637 + if ( ! class_exists( 'Class_Analytify_GDPR_Compliance' ) ) {
638 + return false;
639 + }
640 +
641 + if ( ! Class_Analytify_GDPR_Compliance::is_consent_deferred_gtag_enabled() ) {
642 + return false;
643 + }
644 +
645 + if ( ! defined( 'WP_ANALYTIFY_TRACKING_MODE' ) || 'gtag' !== WP_ANALYTIFY_TRACKING_MODE ) {
646 + return false;
647 + }
648 +
649 + $ua_code = is_string( $ua_code ) ? trim( $ua_code ) : '';
650 + if ( '' === $ua_code ) {
651 + return false;
652 + }
653 +
654 + $allowed_filters = array( 'analytify_ga_script', 'analytify_gtag_script' );
655 + if ( ! in_array( $result_filter, $allowed_filters, true ) ) {
656 + $result_filter = 'analytify_ga_script';
657 + }
658 +
659 + if ( $this->consent_deferred_gtag_hooked ) {
660 + return true;
661 + }
662 +
663 + $this->consent_deferred_gtag_filter = $result_filter;
664 + $this->consent_deferred_gtag_ua_code = $ua_code;
665 + $this->consent_deferred_gtag_hooked = true;
666 + add_action( 'wp_footer', array( $this, 'analytify_print_consent_deferred_gtag' ), 1 );
667 +
668 + return true;
669 + }
670 +
671 + /**
672 + * Print base64 gtag payload and loader for consent-deferred integrations.
673 + *
674 + * Listens to DOM events from {@see Class_Analytify_GDPR_Compliance::get_consent_ready_dom_events()}
675 + * and exposes {@see Class_Analytify_GDPR_Compliance::get_consent_deferred_js_loader_name()} on window.
676 + *
677 + * @since 9.0.0
678 + * @return void
679 + */
680 + public function analytify_print_consent_deferred_gtag() {
681 +
682 + if ( null === $this->consent_deferred_gtag_ua_code ) {
683 + return;
684 + }
685 +
686 + if ( class_exists( 'WPANALYTIFY_Utils' ) && WPANALYTIFY_Utils::skip_page_tracking() ) {
687 + return;
688 + }
689 +
690 + if ( Analytify_GDPR_Compliance::is_gdpr_compliance_blocking() ) {
691 + return;
692 + }
693 +
694 + global $current_user;
695 + $roles = $current_user->roles;
696 +
697 + if ( isset( $roles[0] ) && in_array( $roles[0], $this->settings->get_option( 'exclude_users_tracking', 'wp-analytify-profile', array() ), true ) ) {
698 + return;
699 + }
700 +
701 + $ua = $this->consent_deferred_gtag_ua_code;
702 +
703 + $this->output_gtag_for_footer_payload = true;
704 + $markup = $this->output_gtag_code( $ua );
705 + $this->output_gtag_for_footer_payload = false;
706 + if ( '' === $markup ) {
707 + return;
708 + }
709 +
710 + $markup = apply_filters( $this->consent_deferred_gtag_filter, $markup ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Core plugin filter.
711 +
712 + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Deferred gtag payload for atob(); not obfuscation.
713 + $b64 = base64_encode( $markup );
714 +
715 + $dom_events = class_exists( 'Class_Analytify_GDPR_Compliance' )
716 + ? Class_Analytify_GDPR_Compliance::get_consent_ready_dom_events()
717 + : array( 'analytifyConsentGranted' );
718 +
719 + $js_global = class_exists( 'Class_Analytify_GDPR_Compliance' )
720 + ? Class_Analytify_GDPR_Compliance::get_consent_deferred_js_loader_name()
721 + : 'analytifyLoadGtagAfterConsent';
722 +
723 + ?>
724 + <script type="text/plain" id="analytify-consent-deferred-gtag-b64" style="display:none;"><?php echo esc_html( $b64 ); ?></script>
725 + <script>
726 + (function () {
727 + var events = <?php echo wp_json_encode( $dom_events ); ?>;
728 + var globalName = <?php echo wp_json_encode( $js_global ); ?>;
729 + function analytifyConsentDeferredInjectGtag() {
730 + if (window.__analytifyConsentDeferredGtagDone) {
731 + return;
732 + }
733 + var el = document.getElementById('analytify-consent-deferred-gtag-b64');
734 + if (!el || !el.textContent) {
735 + return;
736 + }
737 + var html;
738 + try {
739 + html = atob(el.textContent.replace(/\s/g, ''));
740 + } catch (e) {
741 + return;
742 + }
743 + window.__analytifyConsentDeferredGtagDone = true;
744 + var doc = new DOMParser().parseFromString(html, 'text/html');
745 + var nodes = doc.querySelectorAll('script');
746 + for (var i = 0; i < nodes.length; i++) {
747 + var oldScript = nodes[i];
748 + var s = document.createElement('script');
749 + if (oldScript.src) {
750 + s.src = oldScript.src;
751 + s.async = true;
752 + } else {
753 + s.textContent = oldScript.textContent;
754 + }
755 + document.head.appendChild(s);
756 + }
757 + }
758 + if (events && events.length) {
759 + for (var j = 0; j < events.length; j++) {
760 + document.addEventListener(events[j], analytifyConsentDeferredInjectGtag, false);
761 + }
762 + }
763 + if (globalName && typeof globalName === 'string' && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(globalName)) {
764 + window[globalName] = analytifyConsentDeferredInjectGtag;
765 + }
766 + })();
767 + </script>
768 + <?php
769 + }
770 +
771 + /**
772 + * Back-compat alias for {@see self::analytify_print_consent_deferred_gtag()}.
773 + *
774 + * @since 9.0.0
775 + * @return void
776 + */
777 + public function analytify_print_ccv_deferred_gtag() {
778 +
779 + $this->analytify_print_consent_deferred_gtag();
780 + }
781 +
782 + /**
783 + * Generate gtag code.
784 + *
785 + * @param string $ua_code Google Analytics UA code.
786 + * @since 3.0
787 + * @version 9.1.0
788 + * @return $gtag_code
789 + */
790 + private function output_gtag_code( $ua_code ) {
791 + ob_start();
792 +
793 + $local_analytics_file = class_exists( 'Analytify_Host_Analytics' ) ? ( new Analytify_Host_Analytics( 'gtag', false ) )->local_analytics_file_url() : false;
794 +
795 + if ( false !== apply_filters( 'analytify_tracking_code_comments', true ) ) {
796 + printf( // translators: Tracking code comments.
797 + esc_html__( '%2$s This code is added by Analytify (%1$s) %4$s %3$s', 'wp-analytify' ),
798 + esc_html( ANALYTIFY_VERSION ),
799 + '<!--',
800 + '!-->',
801 + 'https://analytify.io/'
802 + );
803 + }
804 +
805 + $allow_display_features = ( 'on' === $this->settings->get_option( 'demographic_interest_tracking', 'wp-analytify-advanced' ) ) ? 'true' : 'false';
806 + $linker_cross_domain_tracking = ( 'on' === $this->settings->get_option( 'linker_cross_domain_tracking', 'wp-analytify-advanced' ) ) ? true : false;
807 + $linked_domains = array();
808 +
809 + if ( $linker_cross_domain_tracking ) {
810 + $all_linked_domains = $this->settings->get_option( 'linked_domain', 'wp-analytify-advanced' );
811 + $all_linked_domains = trim( $all_linked_domains ? $all_linked_domains : '' );
812 +
813 + if ( ! empty( $all_linked_domains ) ) {
814 + $all_linked_domains = str_replace( "'", '', $all_linked_domains );
815 + $all_linked_domains = str_replace( '"', '', $all_linked_domains );
816 +
817 + $all_linked_domains = preg_replace( '/\s+/', '', $all_linked_domains );
818 +
819 + $list_linked_domains = explode( ',', $all_linked_domains );
820 + $number_of_linked_domains = count( $list_linked_domains );
821 +
822 + if ( $number_of_linked_domains > 0 ) {
823 + $linked_domains = array_filter(
824 + (array) $list_linked_domains,
825 + function ( $value ) {
826 + return strlen( $value ) > 0;
827 + }
828 + );
829 + } else {
830 + $linked_domains = (array) $all_linked_domains;
831 + }
832 + } else {
833 + $linker_cross_domain_tracking = false;
834 + }
835 + }
836 +
837 + $configuration = array(
838 +
839 + 'allow_display_features' => $allow_display_features,
840 + );
841 +
842 + if ( $linker_cross_domain_tracking ) {
843 + $configuration['linker'] = array(
844 + 'domains' => $linked_domains,
845 + );
846 + }
847 +
848 + $debug_mode = apply_filters( 'analytify_debug_mode', false );
849 +
850 + if ( $debug_mode ) {
851 + $configuration['debug_mode'] = true;
852 + }
853 +
854 + if ( 'on' === $this->settings->get_option( 'track_user_id', 'wp-analytify-advanced' ) && is_user_logged_in() ) {
855 + $configuration['user_id'] = esc_html( (string) get_current_user_id() );
856 + }
857 +
858 + $configuration = apply_filters( 'analytify_gtag_configuration', $configuration );
859 + $configuration_json = wp_json_encode( $configuration, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT );
860 +
861 + // Build the script src URL correctly.
862 + $script_src = $local_analytics_file ?? 'https://www.googletagmanager.com/gtag/js';
863 + $script_src .= ( strpos( $script_src, '?' ) !== false ? '&' : '?' ) . 'id=' . esc_attr( $ua_code );
864 +
865 + // Excluded query parameters: strip only these query keys from page_location (path and hash unchanged).
866 + $exclude_params = 'on' === $this->settings->get_option( 'exclude_query_params', 'wp-analytify-advanced' );
867 + $params_list = $this->settings->get_option( 'query_params_to_exclude', 'wp-analytify-advanced' );
868 + $params_list = is_string( $params_list ) ? $params_list : '';
869 +
870 + $js_location_logic = '';
871 + if ( $exclude_params && '' !== $params_list ) {
872 + $params_array = analytify_query_params_to_exclude_keys_array( $params_list );
873 + if ( ! empty( $params_array ) ) {
874 + $params_json = wp_json_encode( $params_array );
875 +
876 + // Strip only query keys (case-insensitive); path and hash are not altered; no query string / repeated params are safe.
877 + $js_location_logic = "
878 + try {
879 + var wa_loc = window.location.href;
880 + var wa_url = new URL(wa_loc);
881 + var wa_params = $params_json;
882 + var keysToRemove = [];
883 + wa_url.searchParams.forEach(function(val, key) {
884 + if (wa_params.indexOf(key.toLowerCase()) !== -1) { keysToRemove.push(key); }
885 + });
886 + keysToRemove.forEach(function(k) { wa_url.searchParams.delete(k); });
887 + configuration.page_location = wa_url.toString();
888 + } catch (e) {}
889 + ";
890 + }
891 + }
892 +
893 + $gdpr_class = 'Class_Analytify_GDPR_Compliance';
894 + $has_gdpr_class = class_exists( $gdpr_class );
895 + $consent_params = $has_gdpr_class ? Class_Analytify_GDPR_Compliance::get_gtag_consent_default_params() : array();
896 + $has_consent_line = $has_gdpr_class
897 + && Class_Analytify_GDPR_Compliance::should_output_gtag_consent_defaults()
898 + && ! empty( $consent_params );
899 + $use_defer_gtag = $has_gdpr_class
900 + && Class_Analytify_GDPR_Compliance::is_consent_deferred_gtag_enabled()
901 + && ! $this->output_gtag_for_footer_payload;
902 + $defer_events = $has_gdpr_class ? Class_Analytify_GDPR_Compliance::get_consent_ready_dom_events() : array();
903 + if ( $use_defer_gtag && empty( $defer_events ) ) {
904 + $use_defer_gtag = false;
905 + }
906 + $split_gtag_markup = $has_consent_line || $use_defer_gtag;
907 + $defer_pageview_cmp = $has_gdpr_class
908 + && ! $use_defer_gtag
909 + && Class_Analytify_GDPR_Compliance::should_defer_gtag_pageview_until_cmp_consent();
910 + $consent_json = wp_json_encode(
911 + $consent_params,
912 + JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT
913 + );
914 + $defer_events_json = wp_json_encode( array_values( $defer_events ) );
915 + $script_src_json = wp_json_encode( $script_src );
916 + $loader_name = $use_defer_gtag ? Class_Analytify_GDPR_Compliance::get_consent_deferred_js_loader_name() : '';
917 + ?>
918 +
919 + <?php if ( $split_gtag_markup ) : ?>
920 + <script>
921 + window.dataLayer = window.dataLayer || [];
922 + function gtag(){dataLayer.push(arguments);}
923 + <?php if ( $has_consent_line ) : ?>
924 + gtag('consent', 'default', <?php echo $consent_json; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JSON from sanitized consent params. ?>);
925 + <?php endif; ?>
926 + </script>
927 + <?php endif; ?>
928 +
929 + <?php if ( ! $use_defer_gtag ) : ?>
930 + <?php // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript -- Inline gtag script must be output directly in the page head. ?>
931 + <script async src="<?php echo esc_url( $script_src ); ?>"></script>
932 + <?php endif; ?>
933 +
934 + <script>
935 + <?php if ( ! $split_gtag_markup ) : ?>
936 + window.dataLayer = window.dataLayer || [];
937 + function gtag(){dataLayer.push(arguments);}
938 + <?php endif; ?>
939 + <?php if ( ! $use_defer_gtag ) : ?>
940 + gtag('js', new Date());
941 + <?php endif; ?>
942 +
943 + const configuration = <?php echo $configuration_json; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- wp_json_encode() with JSON_HEX flags already escapes JSON safely for JavaScript context. ?>;
944 + const gaID = '<?php echo esc_js( $ua_code ); ?>';
945 +
946 + <?php if ( $use_defer_gtag ) : ?>
947 + (function() {
948 + var gtagSrc = <?php echo $script_src_json; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- wp_json_encode() on URL. ?>;
949 + var consentEvents = <?php echo $defer_events_json; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- wp_json_encode() on validated event names. ?>;
950 + var injectFired = false;
951 + function analytifyInjectGtagAfterConsent() {
952 + if (injectFired) {
953 + return;
954 + }
955 + injectFired = true;
956 + var s = document.createElement('script');
957 + s.async = true;
958 + s.src = gtagSrc;
959 + s.onload = function() {
960 + gtag('js', new Date());
961 + <?php do_action( 'analytify_tracking_code_before_pageview' ); ?>
962 + <?php
963 + if ( ! empty( $js_location_logic ) ) {
964 + echo $js_location_logic; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JS logic constructed internally with safe JSON.
965 + }
966 + ?>
967 + gtag('config', gaID, configuration);
968 + <?php
969 + if ( $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' ) ) {
970 + $custom_js = $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' );
971 + if ( ! empty( $custom_js ) ) {
972 + echo wp_kses_post( $custom_js );
973 + }
974 + }
975 + do_action( 'ga_ecommerce_js' );
976 + do_action( 'analytify_tracking_code_after_pageview' );
977 + ?>
978 + };
979 + document.head.appendChild(s);
980 + }
981 + if (consentEvents.length) {
982 + consentEvents.forEach(function(evName) {
983 + document.addEventListener(evName, analytifyInjectGtagAfterConsent);
984 + });
985 + }
986 + <?php if ( '' !== $loader_name ) : ?>
987 + window['<?php echo esc_js( $loader_name ); ?>'] = analytifyInjectGtagAfterConsent;
988 + <?php endif; ?>
989 + })();
990 + <?php else : ?>
991 + <?php if ( $defer_pageview_cmp ) : ?>
992 + (function() {
993 + var fired = false;
994 + function firePageview() {
995 + if (fired) { return; }
996 + fired = true;
997 + <?php do_action( 'analytify_tracking_code_before_pageview' ); ?>
998 + <?php
999 + if ( ! empty( $js_location_logic ) ) {
1000 + echo $js_location_logic; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JS logic constructed internally with safe JSON.
1001 + }
1002 + ?>
1003 + gtag('config', gaID, configuration);
1004 + <?php
1005 + if ( $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' ) ) {
1006 + $custom_js = $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' );
1007 + if ( ! empty( $custom_js ) ) {
1008 + echo wp_kses_post( $custom_js );
1009 + }
1010 + }
1011 + do_action( 'ga_ecommerce_js' );
1012 + do_action( 'analytify_tracking_code_after_pageview' );
1013 + ?>
1014 + }
1015 + function onAnalyticsGranted() {
1016 + gtag('consent', 'update', {
1017 + analytics_storage: 'granted',
1018 + personalization_storage: 'granted'
1019 + });
1020 + firePageview();
1021 + }
1022 + document.addEventListener('cookieyes_consent_update', function(evt) {
1023 + var accepted = evt.detail && evt.detail.accepted;
1024 + if (accepted && -1 !== accepted.indexOf('analytics')) {
1025 + onAnalyticsGranted();
1026 + }
1027 + });
1028 + document.addEventListener('cookieyes_banner_load', function() {
1029 + if ('function' === typeof window.getCkyConsent && getCkyConsent().categories.analytics) {
1030 + onAnalyticsGranted();
1031 + }
1032 + });
1033 + document.addEventListener('cookielawinfo-consent', onAnalyticsGranted);
1034 + })();
1035 + <?php else : ?>
1036 + <?php do_action( 'analytify_tracking_code_before_pageview' ); ?>
1037 + <?php
1038 + if ( ! empty( $js_location_logic ) ) {
1039 + echo $js_location_logic; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JS logic constructed internally with safe JSON.
1040 + }
1041 + ?>
1042 +
1043 + gtag('config', gaID, configuration);
1044 +
1045 + <?php
1046 + if ( $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' ) ) {
1047 + $custom_js = $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' );
1048 +
1049 + if ( ! empty( $custom_js ) ) {
1050 + echo wp_kses_post( $custom_js );
1051 + }
1052 + }
1053 +
1054 + do_action( 'ga_ecommerce_js' );
1055 + do_action( 'analytify_tracking_code_after_pageview' );
1056 + ?>
1057 + <?php endif; ?>
1058 + <?php endif; ?>
1059 +
1060 + </script>
1061 +
1062 + <?php
1063 + if ( false !== apply_filters( 'analytify_tracking_code_comments', true ) ) {
1064 + printf( // translators: Tracking code comments.
1065 + esc_html__( '%2$s This code is added by Analytify (%1$s) %3$s', 'wp-analytify' ),
1066 + esc_html( ANALYTIFY_VERSION ),
1067 + '<!--',
1068 + '!-->'
1069 + );
1070 + }
1071 +
1072 + $gtag_code = ob_get_contents();
1073 + ob_end_clean();
1074 + return $gtag_code ? $gtag_code : '';
1075 + }
1076 +
1077 + /**
1078 + * Generate gtag code.
1079 + *
1080 + * @param string $ua_code Google Analytics UA code.
1081 + * @since 3.0
1082 + * @return string
1083 + */
1084 + public function output_ga_code( $ua_code ) {
1085 + ob_start();
1086 +
1087 + $src = apply_filters( 'analytify_output_ga_js_src', '//www.google-analytics.com/analytics.js' );
1088 +
1089 + if ( false !== apply_filters( 'analytify_tracking_code_comments', true ) ) {
1090 + printf( // translators: Tracking code comments.
1091 + esc_html__( '%2$s This code is added by Analytify (%1$s) %4$s %3$s', 'wp-analytify' ),
1092 + esc_html( ANALYTIFY_VERSION ),
1093 + '<!--',
1094 + '!-->',
1095 + 'https://analytify.io/'
1096 + );
1097 + }
1098 + ?>
1099 +
1100 + <script>
1101 + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
1102 + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
1103 + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
1104 + })
1105 +
1106 + (window,document,'script','<?php echo esc_url( $src ); ?>','ga');
1107 +
1108 + <?php
1109 + if ( 'on' === $this->settings->get_option( 'linker_cross_domain_tracking', 'wp-analytify-advanced' ) ) {
1110 + echo " ga('create', '" . esc_js( $ua_code ) . "', 'auto', {'allowLinker': true});";
1111 + echo "ga('require', 'linker');";
1112 + } else {
1113 + echo " ga('create', '" . esc_js( $ua_code ) . "', 'auto');";
1114 + }
1115 +
1116 + if ( 'on' === $this->settings->get_option( 'track_user_id', 'wp-analytify-advanced' ) && is_user_logged_in() ) {
1117 + echo "ga('set', 'userId', " . esc_html( (string) get_current_user_id() ) . ');';
1118 + }
1119 +
1120 + if ( 'on' === $this->settings->get_option( 'demographic_interest_tracking', 'wp-analytify-advanced' ) ) {
1121 + echo "ga('require', 'displayfeatures');";
1122 + }
1123 +
1124 + if ( $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' ) ) {
1125 +
1126 + $custom_js = $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' );
1127 +
1128 + if ( $custom_js && false !== $custom_js ) {
1129 + $custom_js = wp_kses(
1130 + $custom_js,
1131 + array(
1132 + 'script' => array(),
1133 + 'noscript' => array(),
1134 + 'div' => array(
1135 + 'id' => array(),
1136 + 'class' => array(),
1137 + ),
1138 + 'span' => array(
1139 + 'id' => array(),
1140 + 'class' => array(),
1141 + ),
1142 + )
1143 + );
1144 + echo '<script type="text/javascript">' . esc_js( wp_strip_all_tags( $custom_js ) ) . '</script>';
1145 + }
1146 + }
1147 +
1148 + do_action( 'ga_ecommerce_js' );
1149 + do_action( 'analytify_tracking_code_before_pageview' );
1150 + echo "ga('send', 'pageview');";
1151 + ?>
1152 +
1153 + </script>
1154 +
1155 + <?php
1156 + if ( false !== apply_filters( 'analytify_tracking_code_comments', true ) ) {
1157 + printf( // translators: Tracking code comments.
1158 + esc_html__( '%2$s This code is added by Analytify (%1$s) %3$s', 'wp-analytify' ),
1159 + esc_html( ANALYTIFY_VERSION ),
1160 + '<!--',
1161 + '!-->'
1162 + );
1163 + }
1164 +
1165 + $ga_code = ob_get_contents();
1166 + ob_end_clean();
1167 + return $ga_code ? $ga_code : '';
1168 + }
1169 +
1170 + // ========================================.
1171 + // GOOGLE ANALYTICS TRACKING CODE END.
1172 + // ========================================.
1173 +
1174 +
1175 + /**
1176 + * Adds Analytify-specific action links on the Plugins screen (Settings, Pro notices).
1177 + *
1178 + * Opt In / Opt Out are registered by the bundled WPB SDK only.
1179 + *
1180 + * @param array<int|string, string> $links Plugin row action links.
1181 + * @param string $slug Product slug from the SDK.
1182 + * @param array<string, mixed> $module Module definition from the SDK.
1183 + * @return array<int|string, string>
1184 + */
1185 + public function wp_analytify_plugin_action_links( $links, $slug = '', $module = array() ) {
1186 + if ( '' !== $slug && 'wp-analytify' !== $slug ) {
1187 + return $links;
1188 + }
1189 + $settings_link = '';
1190 + if ( class_exists( 'WP_Analytify_Pro' ) ) {
1191 + // Remove deactivate link if Pro is active, and add a message that it's required by Pro.
1192 + $settings_link .= sprintf(
1193 + /* translators: %1$s: opening span tag, %2$s: closing span tag. */
1194 + esc_html__( '%1$s Required by Analytify Pro %2$s | ', 'wp-analytify' ),
1195 + '<span style="color:#32373c">',
1196 + '</span>'
1197 + );
1198 + unset( $links['deactivate'] );
1199 + } elseif ( class_exists( 'Analytify_Dashboard_Addon' ) ) {
1200 + // Remove deactivate link if Widget is active, and add a message that it's required by Widget.
1201 + $settings_link .= sprintf(
1202 + /* translators: %1$s: opening span tag, %2$s: closing span tag. */
1203 + esc_html__( '%1$s Required by Analytify Dashboard Widget %2$s | ', 'wp-analytify' ),
1204 + '<span style="color:#32373c">',
1205 + '</span>'
1206 + );
1207 + unset( $links['deactivate'] );
1208 + }
1209 +
1210 + if ( ! class_exists( 'WP_Analytify_Pro' ) ) {
1211 + $settings_link .= sprintf(
1212 + /* translators: %1$s opening link tag, %2$s closing link tag */
1213 + esc_html__( '%1$s Get Analytify Pro %2$s | ', 'wp-analytify' ),
1214 + '<a href="' . esc_url( 'https://analytify.io/pricing/?utm_source=analytify-lite&utm_medium=plugin-action-link&utm_campaign=pro-upgrade&utm_content=Get+Analytify+Pro' ) . '" target="_blank" rel="noopener noreferrer" style="color:#3db634;">',
1215 + '</a>'
1216 + );
1217 + }
1218 +
1219 + $settings_link .= sprintf(
1220 + /* translators: %1$s opening link tag, %2$s closing link tag */
1221 + esc_html__( '%1$s Settings %2$s', 'wp-analytify' ),
1222 + '<a href="' . esc_url( admin_url( 'admin.php?page=analytify-settings' ) ) . '">',
1223 + '</a>'
1224 + );
1225 +
1226 + array_unshift( $links, $settings_link );
1227 + return $links;
1228 + }
1229 +
1230 + /**
1231 + * Plugin row meta links
1232 + *
1233 + * @since 1.1
1234 + * @version 5.0.5
1235 + * @param array $input already defined meta links.
1236 + * @param string $file plugin file path && name being processed.
1237 + * @param array $plugin_data relevent data about the currect plugin.
1238 + * @param string $status weather plugin is active or disabled.
1239 + * @return array $input
1240 + */
1241 + public function plugin_row_meta( $input, $file, $plugin_data, $status ) {
1242 +
1243 + $analytify_plugins = array(
1244 + 'wp-analytify/wp-analytify.php',
1245 + 'analytify-analytics-dashboard-widget/wp-analytify-dashboard.php',
1246 + 'wp-analytify-pro/wp-analytify-pro.php',
1247 + 'wp-analytify-woocommerce/wp-analytify-woocommerce.php',
1248 + 'wp-analytify-goals/wp-analytify-goals.php',
1249 + 'wp-analytify-forms/wp-analytify-forms.php',
1250 + 'wp-analytify-email/wp-analytify-email.php',
1251 + 'wp-analytify-edd/wp-analytify-edd.php',
1252 + 'wp-analytify-authors/wp-analytify-authors.php',
1253 + );
1254 +
1255 + if ( ! in_array( $file, $analytify_plugins, true ) ) {
1256 + return $input;
1257 + }
1258 +
1259 + if ( isset( $plugin_data['Author'] ) ) {
1260 +
1261 + $input[1] = sprintf(
1262 + 'By <a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
1263 + esc_url( $plugin_data['AuthorURI'] ),
1264 + esc_html( $plugin_data['Author'] )
1265 + );
1266 +
1267 + }
1268 +
1269 + if ( 'wp-analytify/wp-analytify.php' !== $file && 'analytify-analytics-dashboard-widget/wp-analytify-dashboard.php' !== $file && in_array( $file, $analytify_plugins, true ) ) {
1270 +
1271 + $input[2] = sprintf(
1272 + '<a href="%s" target="_blank" rel="noopener noreferrer">Visit Plugin Site</a>',
1273 + esc_url( $plugin_data['PluginURI'] )
1274 + );
1275 + return $input;
1276 +
1277 + }
1278 +
1279 + $links = array(
1280 + sprintf( // translators: Premium features.
1281 + esc_html__( '%1$s Explore Premium Features %2$s', 'wp-analytify' ),
1282 + '<a target="_blank" href="https://analytify.io/add-ons/?ref=27&utm_source=analytify-pro&utm_medium=plugin-action-link&utm_campaign=pro-upgrade&utm_content=Explore+Premium+Features">',
1283 + '</a>'
1284 + ),
1285 + );
1286 +
1287 + $input = array_merge( $input, $links );
1288 +
1289 + return $input;
1290 + }
1291 +
1292 + /**
1293 + * Display warning if profiles are not selected.
1294 + *
1295 + * @return void
1296 + */
1297 + public function pa_check_warnings() {
1298 + add_action( 'admin_footer', array( &$this, 'profile_warning' ) );
1299 + }
1300 +
1301 +
1302 + // Page routing function moved to Page_Management component.
1303 +
1304 +
1305 +
1306 +
1307 + // ========================================.
1308 + // ADMIN ASSETS & STYLING START.
1309 + // ========================================.
1310 +
1311 + // Admin styles function moved to Scripts_Styles component.
1312 +
1313 + // Functions moved to Scripts_Styles, Module_Manager && Promotions components.
1314 +
1315 + // ========================================.
1316 + // ANALYTICS DATA RETRIEVAL START.
1317 + // ========================================.
1318 +
1319 + // Analytics accounts function moved to Analytics_Accounts component.
1320 +
1321 + // Analytics accounts summary function moved to Analytics_Accounts component.
1322 +
1323 + /**
1324 + * Get settings URL.
1325 + *
1326 + * @return string
1327 + */
1328 + public function pa_setting_url() {
1329 + return admin_url( 'admin.php?page=analytify-settings' );
1330 + }
1331 +
1332 + /**
1333 + * Save Google token data.
1334 + *
1335 + * @param mixed $key_google_token The Google token data.
1336 + * @return bool|void
1337 + */
1338 + public function pt_save_data( $key_google_token ) {
1339 + try {
1340 + update_option( 'post_analytics_token', $key_google_token );
1341 +
1342 + if ( $this->analytify_pa_connect_v2() ) {
1343 + return true;
1344 + }
1345 + } catch ( Exception $e ) {
1346 + echo esc_html( $e->getMessage() );
1347 + }
1348 + }
1349 +
1350 + // Profile warning function moved to Promotions component.
1351 +
1352 + // AJAX handler moved to Analytics_Reports component.
1353 +
1354 + // Module state function moved to Module_Manager component.
1355 +
1356 +
1357 +
1358 +
1359 + // ========================================.
1360 + // ANALYTICS DATA RETRIEVAL END.
1361 + // ========================================.
1362 +
1363 + // Deprecated analytics function moved to Analytics_Reports component.
1364 +
1365 +
1366 +
1367 +
1368 + // ========================================.
1369 + // UTILITY & HELPER FUNCTIONS START.
1370 + // ========================================.
1371 +
1372 + // Utility functions moved to Utils component.
1373 + // Backward compatibility wrappers.
1374 + /**
1375 + * Format numbers for display.
1376 + *
1377 + * @param mixed $num The number to format.
1378 + * @return string
1379 + */
1380 + public function wpa_pretty_numbers( $num ) {
1381 + return Analytify_Utils::wpa_pretty_numbers( $num );
1382 + }
1383 +
1384 + /**
1385 + * Format number with proper formatting.
1386 + *
1387 + * @param mixed $num The number to format.
1388 + * @return string
1389 + */
1390 + public function wpa_number_format( $num ) {
1391 + return Analytify_Utils::wpa_number_format( $num );
1392 + }
1393 +
1394 + /**
1395 + * Format time for display.
1396 + *
1397 + * @param mixed $time The time to format.
1398 + * @return string
1399 + */
1400 + public function pa_pretty_time( $time ) {
1401 + return Analytify_Utils::pa_pretty_time( $time );
1402 + }
1403 +
1404 + /**
1405 + * Check user access level.
1406 + *
1407 + * @param mixed $access_level The required access level.
1408 + * @return bool
1409 + */
1410 + public function pa_check_roles( $access_level ) {
1411 + return Analytify_Utils::pa_check_roles( $access_level );
1412 + }
1413 +
1414 +
1415 + /**
1416 + * Notice to switch gtag.js tracking mode.
1417 + *
1418 + * @return void
1419 + */
1420 + // Welcome message function moved to Promotions component.
1421 +
1422 + // ========================================.
1423 + // ADMIN MENU & PAGE ROUTING START.
1424 + // ========================================.
1425 +
1426 + /**
1427 + * Create Analytics menu at the left side of dashboard
1428 + *
1429 + * @version 9.1.0
1430 + * @return void
1431 + */
1432 + public function add_admin_menu() {
1433 + $current_user = wp_get_current_user();
1434 +
1435 + if ( Analytify_Utils::is_subscriber_blocked_from_analytify() ) {
1436 + return;
1437 + }
1438 +
1439 + $allowed_roles = $this->settings->get_option( 'show_analytics_roles_dashboard', 'wp-analytify-dashboard', array() );
1440 + $allowed_roles[] = 'administrator';
1441 +
1442 + $is_author_only = $current_user && in_array( 'author', $current_user->roles, true ) && ! in_array( 'administrator', $current_user->roles, true );
1443 +
1444 + // Determine the capability to use for the dashboard.
1445 + // If the user has an allowed role, we use 'read' to ensure they can see the menu,
1446 + // since add_admin_menu already restricted registration to allowed roles.
1447 + $dashboard_cap = 'manage_options';
1448 + if ( array_intersect( $current_user->roles, $allowed_roles ) ) {
1449 + $dashboard_cap = 'read';
1450 + }
1451 +
1452 + // Allow authors to see the menu (so they can access Authors dashboard submenu).
1453 + // But restrict them from accessing main dashboard content.
1454 + if ( $is_author_only ) {
1455 + // Authors can see menu but will be restricted from main dashboard page.
1456 + // They need edit_posts capability to see Authors dashboard.
1457 + if ( ! current_user_can( 'edit_posts' ) ) {
1458 + return;
1459 + }
1460 + } elseif ( ! $this->pa_check_roles( $allowed_roles ) ) {
1461 + // For non-authors, check normal access.
1462 + return;
1463 + }
1464 +
1465 + add_submenu_page( 'admin.php', __( 'Activate', 'wp-analytify' ), __( 'Activate', 'wp-analytify' ), 'manage_options', 'analytify-optin', array( $this, 'render_optin' ) );
1466 +
1467 + add_menu_page(
1468 + ANALYTIFY_NICK,
1469 + 'Analytify',
1470 + $dashboard_cap,
1471 + 'analytify-dashboard',
1472 + array(
1473 + $this,
1474 + 'pa_page_file_path',
1475 + ),
1476 + 'data:image/svg+xml;base64,' . base64_encode( // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Used for SVG data encoding
1477 + '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
1478 + width="18px" height="18px" viewBox="0 0 18 18" style="enable-background:new 0 0 18 18;" xml:space="preserve">
1479 + <style type="text/css">
1480 + .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#23282D;}
1481 + .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#9EA3A8;}
1482 + </style>
1483 + <g>
1484 + <path class="st0" d="M17.2,16c-0.4,0-0.8-0.3-0.8-0.8v-0.8V14c-1.6,2.4-4.3,4-7.5,4c-5,0-9-4-9-9s4-9,9-9c3.1,0,5.8,1.6,7.5,4V3.8
1485 + v0l0,0c0-0.4,0.4-0.7,0.8-0.7S18,3.4,18,3.8l0,0v0V5v9.5v0.8C18,15.6,17.7,16,17.2,16z M9,1.5C4.9,1.5,1.5,4.9,1.5,9
1486 + s3.4,7.5,7.5,7.5s7.5-3.4,7.5-7.5S13.1,1.5,9,1.5z"/>
1487 + <g>
1488 + <g>
1489 + <path class="st1" d="M5.9,8.4c-0.5,0-0.9,0.4-0.9,0.9v2.9c0,0.5,0.4,0.9,0.9,0.9s0.9-0.4,0.9-0.9V9.3C6.7,8.8,6.3,8.4,5.9,8.4z
1490 + M9,7C8.5,7,8.1,7.4,8.1,7.9v4.3C8.1,12.7,8.5,13,9,13s0.9-0.4,0.9-0.9V7.9C9.9,7.4,9.5,7,9,7z M12.1,4.9c-0.5,0-0.9,0.4-0.9,0.9
1491 + v6.4c0,0.5,0.4,0.9,0.9,0.9s0.9-0.4,0.9-0.9V5.8C12.9,5.3,12.6,4.9,12.1,4.9z"/>
1492 + </g>
1493 + </g>
1494 + </g>
1495 + </svg>'
1496 + ),
1497 + 2
1498 + );
1499 +
1500 + add_submenu_page(
1501 + 'analytify-dashboard',
1502 + ANALYTIFY_NICK . esc_html__( ' Dashboards', 'wp-analytify' ),
1503 + esc_html__( 'Dashboards', 'wp-analytify' ),
1504 + $dashboard_cap,
1505 + 'analytify-dashboard',
1506 + array(
1507 + $this,
1508 + 'pa_page_file_path',
1509 + ),
1510 + 10
1511 + );
1512 +
1513 + do_action( 'analytify_add_submenu' );
1514 +
1515 + add_submenu_page(
1516 + 'analytify-dashboard',
1517 + ANALYTIFY_NICK . esc_html__( ' Settings', 'wp-analytify' ),
1518 + esc_html__( 'Settings', 'wp-analytify' ),
1519 + 'manage_options',
1520 + 'analytify-settings',
1521 + array(
1522 + $this,
1523 + 'pa_page_file_path',
1524 + ),
1525 + 50
1526 + );
1527 +
1528 + add_submenu_page(
1529 + 'analytify-dashboard',
1530 + ANALYTIFY_NICK . esc_html__( ' Help', 'wp-analytify' ),
1531 + esc_html__( 'Help', 'wp-analytify' ),
1532 + 'manage_options',
1533 + 'analytify-settings#wp-analytify-help',
1534 + array(
1535 + $this,
1536 + 'pa_page_file_path',
1537 + ),
1538 + 55
1539 + );
1540 +
1541 + // Add license submenu.
1542 + if ( class_exists( 'WP_Analytify_Pro_Base' ) ) {
1543 + add_submenu_page(
1544 + 'analytify-dashboard',
1545 + ANALYTIFY_NICK . esc_html__( ' License', 'wp-analytify' ),
1546 + esc_html__( 'License', 'wp-analytify' ),
1547 + 'manage_options',
1548 + 'analytify-settings#wp-analytify-license',
1549 + array(
1550 + $this,
1551 + 'pa_page_file_path',
1552 + ),
1553 + 60
1554 + );
1555 + }
1556 +
1557 + add_submenu_page(
1558 + 'analytify-dashboard',
1559 + ANALYTIFY_NICK . esc_html__( ' list of all Add-ons', 'wp-analytify' ),
1560 + esc_html__( 'Add-ons', 'wp-analytify' ),
1561 + 'manage_options',
1562 + 'analytify-addons',
1563 + array(
1564 + $this,
1565 + 'pa_page_file_path',
1566 + ),
1567 + 65
1568 + );
1569 +
1570 + add_submenu_page(
1571 + 'analytify-dashboard',
1572 + ANALYTIFY_NICK . esc_html__( ' FREE vs PRO', 'wp-analytify' ),
1573 + esc_html__( 'FREE vs PRO', 'wp-analytify' ),
1574 + 'manage_options',
1575 + 'analytify-go-pro',
1576 + array(
1577 + $this,
1578 + 'pa_page_file_path',
1579 + ),
1580 + 70
1581 + );
1582 +
1583 + // Promo page (will not appear in side menu).
1584 + add_submenu_page( 'analytify-dashboard', esc_html__( 'Analytify Promo', 'wp-analytify' ), null, 'manage_options', 'analytify-promo', array( $this, 'addons_promo_screen' ) );
1585 + }
1586 +
1587 + /**
1588 + * Redirect subscribers away from Analytify admin screens.
1589 + *
1590 + * @since 9.1.0
1591 + * @version 9.1.0
1592 + * @return void
1593 + */
1594 + public function block_subscriber_analytify_access() {
1595 + if ( ! Analytify_Utils::is_subscriber_blocked_from_analytify() ) {
1596 + return;
1597 + }
1598 +
1599 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Admin screen routing only.
1600 + $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
1601 +
1602 + if ( $page && 0 === strpos( $page, 'analytify' ) ) {
1603 + wp_safe_redirect( admin_url() );
1604 + exit;
1605 + }
1606 + }
1607 +
1608 + /**
1609 + * Get current screen details
1610 + *
1611 + * @version 9.1.0
1612 + * @return void
1613 + */
1614 + public function pa_page_file_path() {
1615 + $allowed_roles = $this->settings->get_option( 'show_analytics_roles_dashboard', 'wp-analytify-dashboard', array() );
1616 + $allowed_roles[] = 'administrator';
1617 +
1618 + if ( ! $this->pa_check_roles( $allowed_roles ) ) {
1619 + wp_safe_redirect( admin_url() );
1620 + exit;
1621 + }
1622 +
1623 + $screen = get_current_screen();
1624 +
1625 + if ( strpos( $screen->base, 'analytify-settings' ) !== false ) {
1626 + $version = defined( 'ANALYTIFY_PRO_VERSION' ) ? ANALYTIFY_PRO_VERSION : ANALYTIFY_VERSION;
1627 +
1628 + echo '<div class="wrap"><h2 style="display: none;"></h2></div>
1629 +
1630 + <div class="wpanalytify"><div class="wpb_plugin_wraper">
1631 +
1632 + <div class="wpb_plugin_header_wraper">
1633 + <div class="graph"></div>
1634 +
1635 + <div class="wpb_plugin_header">
1636 +
1637 + <div class="wpb_plugin_header_title"></div>
1638 +
1639 + <div class="wpb_plugin_header_info">
1640 + <a href="https://analytify.io/changelog/" target="_blank" class="btn">View Changelog</a>
1641 + </div>
1642 + <div class="wpb_plugin_header_logo">
1643 + <img src="' . esc_url( plugins_url( 'assets/img/logo.svg', __FILE__ ) ) . '" alt="Analytify">
1644 + </div>
1645 + </div></div><div class="analytify-settings-body-container"><div class="wpb_plugin_body_wraper"><div class="wpb_plugin_body">';
1646 + // Initialize settings before rendering.
1647 + $this->settings->set_sections( $this->settings->get_settings_sections() );
1648 + $this->settings->set_fields( $this->settings->get_settings_fields() );
1649 + $this->settings->rendered_settings();
1650 + $this->settings->show_tabs();
1651 + echo '<div class="wpb_plugin_tabs_content">';
1652 + $this->settings->show_forms();
1653 + echo '</div>';
1654 +
1655 + echo '</div></div></div></div>';
1656 +
1657 + } elseif ( strpos( $screen->base, 'analytify-dashboard' ) !== false ) {
1658 + // Restrict authors from accessing main dashboard - redirect to Authors dashboard.
1659 + $current_user = wp_get_current_user();
1660 + $is_author_only = $current_user && in_array( 'author', (array) $current_user->roles, true ) && ! in_array( 'administrator', (array) $current_user->roles, true );
1661 +
1662 + if ( $is_author_only ) {
1663 + // Redirect authors to their Authors dashboard.
1664 + wp_safe_redirect( admin_url( 'admin.php?page=analytify-authors' ) );
1665 + exit;
1666 + }
1667 +
1668 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading URL parameter for display purposes
1669 + if ( isset( $_GET['show'] ) ) {
1670 + do_action( 'show_detail_dashboard_content' );
1671 + } else {
1672 + require_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytics-dashboard.php';
1673 + }
1674 + } elseif ( strpos( $screen->base, 'analytify-optin' ) !== false ) {
1675 + require_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytify-optin-form.php';
1676 + } elseif ( strpos( $screen->base, 'analytify-addons' ) !== false ) {
1677 + require_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/page-addons.php';
1678 + } elseif ( strpos( $screen->base, 'analytify-woocommerce' ) !== false ) {
1679 + // WooCommerce page - this might not exist, let's check if file exists first.
1680 + $woo_file = WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytify-woocommerce.php';
1681 + if ( file_exists( $woo_file ) ) {
1682 + require_once $woo_file;
1683 + }
1684 + } elseif ( strpos( $screen->base, 'analytify-logs' ) !== false ) {
1685 + include_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/page-logs.php';
1686 + } elseif ( strpos( $screen->base, 'analytify-go-pro' ) !== false ) {
1687 + include_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytify-go-pro.php';
1688 + } elseif ( isset( $_GET['show'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading URL parameter for display purposes
1689 + do_action( 'show_detail_dashboard_content' );
1690 + } else {
1691 + // Dequeue event calendar js.
1692 + wp_dequeue_script( 'tribe-common' );
1693 + wp_dequeue_script( 'mcw-crypto-common' );
1694 + include_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytics-dashboard.php';
1695 + }
1696 + }
1697 +
1698 + // ========================================.
1699 + // ADMIN MENU & PAGE ROUTING END.
1700 + // ========================================.
1701 +
1702 + /**
1703 + * Render optin page
1704 + *
1705 + * @return void
1706 + */
1707 + public function render_optin() {
1708 + require_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytify-optin-form.php';
1709 + }
1710 +
1711 + // Functions moved to Promotions && Analytics_Reports components.
1712 +
1713 + /**
1714 + * Process logout && clear stored options.
1715 + *
1716 + * @return void
1717 + */
1718 + public function logout() {
1719 + if ( isset( $_POST['wp_analytify_log_out'] ) && isset( $_POST['analytify_analytics_logout_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['analytify_analytics_logout_nonce'] ) ), 'analytify_analytics_logout' ) ) {
1720 + delete_option( 'pt_webprofile' );
1721 + delete_option( 'pt_webprofile_dashboard' );
1722 + delete_option( 'pt_webprofile_url' );
1723 + delete_option( 'pa_google_token' );
1724 + $this->analytify_auth_settings_clear_google_oauth_email();
1725 + delete_option( 'post_analytics_token' );
1726 + delete_option( 'hide_profiles' );
1727 + delete_option( 'analytify-ga4-streams' );
1728 + delete_option( 'analytify_tracking_property_info' );
1729 + delete_option( 'analytify_reporting_property_info' );
1730 + delete_option( 'analytify_ga4_exception' );
1731 + delete_option( 'analytify_ga4_exceptions' );
1732 + delete_option( 'profiles_list_summary' );
1733 + delete_option( 'analytify_ga_properties_list' );
1734 + delete_option( 'wp-analytify-mode' );
1735 + delete_option( 'analytify-deprecated-auth' );
1736 + delete_option( 'analytify-ga-properties-summery' );
1737 + delete_option( 'analytify_profile_exception' );
1738 + delete_option( 'profiles_list_summary_backup' );
1739 + delete_transient( 'analytify_quota_exception' );
1740 + delete_transient( 'analytify_google_userinfo_probe_skip' );
1741 +
1742 + $_analytify_profile = get_option( 'wp-analytify-profile' );
1743 + if ( $_analytify_profile ) {
1744 + unset( $_analytify_profile['hide_profiles_list'], $_analytify_profile['profile_for_posts'], $_analytify_profile['profile_for_dashboard'] );
1745 + update_option( 'wp-analytify-profile', $_analytify_profile );
1746 + }
1747 +
1748 + $update_message = sprintf( // translators: Login again notice.
1749 + esc_html__( '%1$s %2$s %3$s Authentication Cleared login again. %4$s %5$s %6$s', 'wp-analytify' ),
1750 + '<div id="setting-error-settings_updated" class="updated notice is-dismissible settings-error below-h2">',
1751 + '<p>',
1752 + '<strong>',
1753 + '</strong>',
1754 + '</p>',
1755 + '</div>'
1756 + );
1757 + }
1758 + }
1759 +
1760 + /**
1761 + * Used to add query args that need to be removed from url
1762 + *
1763 + * @since 5.0.6
1764 + * @param mixed $args_array The arguments array to process.
1765 + * @return array
1766 + */
1767 + public function Analytify_remove_query( $args_array ) {
1768 + $analytify_args_to_remove = array( 'analytify-cache' );
1769 + $args_array = array_merge( $args_array, $analytify_args_to_remove );
1770 + return $args_array;
1771 + }
1772 +
1773 + /**
1774 + * Trigger logging cleanup using the logging class.
1775 + *
1776 + * Uses guarded logger (null-safe) to avoid fatal if logger unavailable.
1777 + *
1778 + * @since 2.1.23
1779 + * @version 1
1780 + * @return void
1781 + */
1782 + public static function analytify_cleanup_logs() {
1783 + $logger = function_exists( 'analytify_get_logger' ) ? analytify_get_logger() : null;
1784 + if ( class_exists( 'QM' ) ) {
1785 + QM::info( 'Analytify: Starting cleanup of expired logs.' );
1786 + }
1787 +
1788 + if ( $logger && is_callable( array( $logger, 'clear_expired_logs' ) ) ) {
1789 + $logger->clear_expired_logs();
1790 + if ( class_exists( 'QM' ) ) {
1791 + QM::info( 'Analytify: Expired logs cleared successfully.' );
1792 + }
1793 + }
1794 + }
1795 +
1796 +
1797 +
1798 +
1799 + // ========================================.
1800 + // PROFILE & SETTINGS MANAGEMENT START.
1801 + // ========================================.
1802 +
1803 + // Functions moved to Profile_Management && GA4_Property_Management components.
1804 +
1805 + // ========================================.
1806 + // PROFILE & SETTINGS MANAGEMENT END.
1807 + // ========================================.
1808 +
1809 + // Black Friday Deal Notice function moved to Promotions component.
1810 +
1811 + // Function moved to Promotions component.
1812 +
1813 + // Winter Sale promo function moved to Promotions component.
1814 +
1815 + // Winter Sale dismiss notice function moved to Promotions component.
1816 +
1817 + // Rating icon function moved to Promotions component.
1818 +
1819 + // ========================================.
1820 + // GDPR COMPLIANCE & META BOXES START.
1821 + // ========================================.
1822 +
1823 + // Functions add_exclusion_meta_box && print_exclusion_meta_box moved to GDPR_Compliance component.
1824 +
1825 + // ========================================.
1826 + // GDPR COMPLIANCE & META BOXES END.
1827 + // ========================================.
1828 +
1829 + /**
1830 + * Init the compliance class.
1831 + *
1832 + * @return void
1833 + */
1834 + public function init_gdpr_compliance() {
1835 + if ( class_exists( 'Class_Analytify_GDPR_Compliance' ) ) {
1836 + new Class_Analytify_GDPR_Compliance();
1837 + }
1838 + }
1839 +
1840 + /**
1841 + * Get a component from the loader
1842 + *
1843 + * @param string $component_name The name of the component to get.
1844 + * @return mixed|null The component instance or null if not found
1845 + */
1846 + public function get_component( $component_name ) {
1847 + if ( $this->loader && method_exists( $this->loader, 'get_component' ) ) {
1848 + return $this->loader->get_component( $component_name );
1849 + }
1850 + return null;
1851 + }
1852 +
1853 + /**
1854 + * Check if a component is loaded
1855 + *
1856 + * @param string $component_name The name of the component to check.
1857 + * @return bool True if component is loaded, false otherwise
1858 + */
1859 + public function has_component( $component_name ) {
1860 + if ( $this->loader && method_exists( $this->loader, 'has_component' ) ) {
1861 + return $this->loader->has_component( $component_name );
1862 + }
1863 + return false;
1864 + }
1865 +
1866 + // Welcome message function moved to Promotions component.
1867 +
1868 + /**
1869 + * Show promo screen for addons
1870 + *
1871 + * @return void
1872 + */
1873 + public function addons_promo_screen() {
1874 + include WP_ANALYTIFY_PLUGIN_DIR . '/views/default/admin/addons-promo.php';
1875 + }
1876 + }
1877 +} // End if class_exists check.
1878 +
1879 +// ========================================.
1880 +// MAIN PLUGIN CLASS DEFINITION END.
1881 +// ========================================.
1882 +
1883 +/**
1884 + * Create instance of wp-analytify class.
1885 + *
1886 + * @return void
1887 + */
1888 +function analytify_free_instance() {
1889 + $GLOBALS['WP_ANALYTIFY'] = WP_Analytify::get_instance();
1890 +}
1891 +add_action( 'plugins_loaded', 'analytify_free_instance', 10 );
1892 +
1893 +// ========================================.
1894 +// PLUGIN INSTANCE INITIALIZATION END.
1895 +// ========================================.
1896 +
1897 +/**
1898 + * AJAX callback function for performing a factory reset of Analytify plugin settings
1899 + *
1900 + * This function handles the secure AJAX request to reset all Analytify settings
1901 + * to their default values. It includes security checks, capability verification,
1902 + * and proper error handling.
1903 + *
1904 + * @hook wp_ajax_analytify_factory_reset
1905 + * @since 8.0.0
1906 + * @return void Sends JSON response indicating success or failure
1907 + */
1908 +function analytify_factory_reset_callback() {
1909 + // Verify the nonce for security - prevents CSRF attacks.
1910 + check_ajax_referer( 'analytify_factory_reset_nonce', 'nonce' );
1911 +
1912 + // Check if current user has administrative capabilities.
1913 + if ( ! current_user_can( 'manage_options' ) ) {
1914 + wp_send_json_error( 'Unauthorized' );
1915 + }
1916 +
1917 + // Load the factory reset class if not already available.
1918 + if ( ! class_exists( 'Analytify_Factory_Reset' ) ) {
1919 + require_once plugin_dir_path( __FILE__ ) . 'classes/analytify-factory-reset.php';
1920 + }
1921 +
1922 + // Initialize the reset class and execute the reset process.
1923 + $reset = new Analytify_Factory_Reset();
1924 + $reset->remove_settings();
1925 +
1926 + // Send success response to the AJAX request.
1927 + wp_send_json_success();
1928 +}
1929 +
1930 +/**
1931 + * Hook the factory reset function to WordPress AJAX handlers
1932 + *
1933 + * This registers the function for both privileged (admin) and non-privileged users,
1934 + * but the capability check inside the function will restrict access to admins only.
1935 + */
1936 +add_action( 'wp_ajax_analytify_factory_reset', 'analytify_factory_reset_callback' );