PluginProbe
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) / 8.1.2
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) v8.1.2
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
wp-analytify / wp-analytify.php

wp-analytify.php in Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) 8.1.2, at wp-analytify.php

1,468 lines 46.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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: 8.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: 6.9
13 * Domain Path: /languages
14 * GitHub Plugin URI: https://github.com/WPBrigade/wp-analytify
15 *
16 * @package WP_ANALYTIFY
17 */
18
19
20 // ========================================.
21 // TELEMETRY SDK INITIALIZATION START.
22 // ========================================.
23
24 if ( ! function_exists( 'wa_wpb78834179' ) ) {
25
26 /**
27 * Telemetry function.
28 *
29 * @return mixed
30 */
31 function wa_wpb78834179() {
32 global $wa_wpb78834179;
33
34 if ( ! isset( $wa_wpb78834179 ) ) {
35
36 require_once __DIR__ . '/lib/wpb-sdk/start.php';
37
38 $wa_wpb78834179 = wpb_dynamic_init(
39 array(
40 'id' => '7',
41 'slug' => 'wp-analytify',
42 'type' => 'plugin',
43 'public_key' => '1|4aOA8EuyIN4pi2miMvC23LLpnHbBZFNki9R9pVmwd673d3c8',
44 'secret_key' => 'sk_b36c525848fee035',
45 'is_premium' => false,
46 'has_addons' => false,
47 'has_paid_plans' => false,
48 'menu' => array(
49 'slug' => 'wp-analytify',
50 'account' => false,
51 'support' => false,
52 ),
53 'settings' => array(
54 'wp_analytify_modules' => '',
55 'wp-analytify-tracking' => '',
56 'wp-analytify-email' => '',
57 'wp-analytify-events-tracking' => '',
58 'wp-analytify-front' => '',
59 'wp-analytify-custom-dimensions' => '',
60 'wp-analytify-forms' => '',
61 'analytify_widget_date_differ' => '',
62 'wp-analytify-profile' => '',
63 'wp-analytify-admin' => '',
64 'wp-analytify-dashboard' => '',
65 'wp-analytify-advanced' => '',
66 'analytify_ua_code' => '',
67 'analytify_date_differ' => '',
68 'wp_analytify_review_dismiss_4_1_8' => '',
69 'wpanalytify_settings' => '',
70 'analytify_license_key' => '',
71 'analytify_license_status' => '',
72 'analytify_campaigns_license_status' => '',
73 'analytify_campaigns_license_key' => '',
74 'analytify_goals_license_status' => '',
75 'analytify_goals_license_key' => '',
76 'Analytify_Addon_Forms_license_status' => '',
77 'analytify_forms_license_key' => '',
78 'analytify_authors_license_status' => '',
79 'analytify_authors_license_key' => '',
80 'analytify_woo_license_status' => '',
81 'analytify_woo_license_key' => '',
82 'analytify_email_license_status' => '',
83 'analytify_email_license_key' => '',
84 'analytify-google-ads-tracking' => '',
85 '_analytify_optin' => '',
86 'analytify_cache_timeout' => '',
87 'analytify_csv_data' => '',
88 'analytify_active_date' => '',
89 'analytify_edd_license_status' => '',
90 'analytify_edd_license_key' => '',
91 '_transient_timeout_analytify_api_addons' => '',
92 '_transient_analytify_api_addons' => '',
93 'analytify_ga4_exceptions' => '',
94 'analytify-ga-properties-summery' => '',
95 'analytify_ga4-streams' => '',
96 'analytify_tracking_property_info' => '',
97 'analytify_reporting_property_info' => '',
98 'analytify_gtag_move_to_notice' => '',
99 'analytify_current_version' => '',
100 'analytify_logs_setup' => '',
101 'analytify_pro_default_settings' => '',
102 'analytify_pro_active_date' => '',
103 'analytify_pro_upgrade_routine' => '',
104 'analytify_pro_current_version' => '',
105 'WP_ANALYTIFY_PRO_PLUGIN_VERSION' => '',
106 'wp-analytify-license' => '',
107 'analytify_authentication_date' => '',
108 'WP_ANALYTIFY_PLUGIN_VERSION_OLD' => '',
109 'WP_ANALYTIFY_PRO_PLUGIN_VERSION_OLD' => '',
110 'analytify_default_settings' => '',
111 'analytify_free_upgrade_routine' => '',
112 'WP_ANALYTIFY_PLUGIN_VERSION' => '',
113 'wp_analytify_active_time' => '',
114 'wp-analytify-authentication' => '',
115 'wp-analytify-help' => '',
116 'WP_ANALYTIFY_NEW_LOGIN' => '',
117 'profiles_list_summary' => '',
118 'pa_google_token' => '',
119 'post_analytics_token' => '',
120 ),
121 )
122 );
123 }
124
125 return $wa_wpb78834179;
126 }
127
128
129 wa_wpb78834179();
130
131 do_action( 'wa_wpb78834179_loaded' );
132 }
133
134 // ========================================.
135 // TELEMETRY SDK INITIALIZATION END.
136 // ========================================.
137
138 if ( ! defined( 'ABSPATH' ) ) {
139 exit;
140 }
141
142
143
144
145 require_once __DIR__ . '/inc/analytify-constants.php';
146
147 if ( ! class_exists( 'Analytify_General' ) ) {
148 require_once 'analytify-general.php';
149 }
150
151
152
153 // ========================================.
154 // MAIN PLUGIN CLASS DEFINITION START.
155 // ========================================.
156
157 if ( ! class_exists( 'WP_Analytify' ) ) {
158 /**
159 * Main WP_Analytify class.
160 *
161 * @since 1.0.0
162 */
163 // phpcs:ignore Universal.Files.SeparateFunctionsFromOO.Mixed,Squiz.Commenting.ClassComment.Missing
164 class WP_Analytify extends Analytify_General {
165
166 /**
167 * Plugin instance.
168 *
169 * @var WP_Analytify $instance The one true WP_Analytify
170 * @since 1.2.2
171 */
172 private static $instance = null;
173
174 /**
175 * Token data.
176 *
177 * @var mixed
178 */
179 public $token = false;
180 /**
181 * Client instance.
182 *
183 * @var mixed
184 */
185 public $client = null;
186
187 /**
188 * Post stats disable flag.
189 *
190 * @var mixed
191 */
192 protected $disable_post_stats;
193
194 /**
195 * Settings data.
196 *
197 * @var mixed
198 */
199 public $settings;
200
201 /**
202 * Component loader instance
203 *
204 * @var Analytify_Loader
205 */
206 private $loader;
207
208 // ========================================.
209 // CONSTRUCTOR & CORE METHODS START.
210 // ========================================.
211
212 /**
213 * Constructor.
214 *
215 * @since 1.2.2
216 */
217 public function __construct() {
218 parent::__construct();
219 $this->setup_constants();
220 $this->includes();
221 $this->disable_post_stats = $this->settings->get_option( 'enable_back_end', 'wp-analytify-admin' );
222 $this->hooks();
223 }
224
225 /**
226 * Get active instance.
227 *
228 * @access public
229 * @since 1.2.2
230 * @return object self::$instance The one true WP_Analytify
231 */
232 public static function get_instance() {
233 if ( ! self::$instance ) {
234 self::$instance = new WP_Analytify();
235 }
236
237 return self::$instance;
238 }
239
240 /**
241 * Setup plugin constants
242 *
243 * @access private
244 * @since 1.2.2
245 * @return void
246 */
247 private function setup_constants() {
248
249 $upload_dir = wp_upload_dir( null, false );
250 }
251
252 /**
253 * Define constant if not already set
254 *
255 * @since 1.2.4
256 * @param string $name contanst name.
257 * @param string|bool $value constant value.
258 * @return void
259 */
260 private function define( $name, $value ) {
261 if ( ! defined( $name ) ) {
262 define( $name, $value );
263 }
264 }
265
266 /**
267 * What type of request is this?
268 *
269 * @since 1.2.4
270 * @param string $type ajax, frontend or admin.
271 * @return bool
272 */
273 private function is_request( $type ) {
274 switch ( $type ) {
275 case 'admin':
276 return is_admin();
277 case 'ajax':
278 return defined( 'DOING_AJAX' );
279 case 'cron':
280 return defined( 'DOING_CRON' );
281 case 'frontend':
282 return ( ! is_admin() || defined( 'DOING_AJAX' ) ) && ! defined( 'DOING_CRON' );
283 default:
284 return false;
285 }
286 }
287
288
289 /**
290 * Include necessary files
291 *
292 * @access private
293 * @since 1.2.2
294 * @return void
295 */
296 private function includes() {
297 $files = array(
298 WP_ANALYTIFY_LIB_PATH . 'logs/class-analytify-log-handler-interface.php',
299 WP_ANALYTIFY_LIB_PATH . 'logs/class-analytify-logger-interface.php',
300 WP_ANALYTIFY_LIB_PATH . 'logs/class-analytify-log-levels.php',
301 WP_ANALYTIFY_LIB_PATH . 'logs/class-analytify-logger.php',
302 WP_ANALYTIFY_LIB_PATH . 'logs/abstract-analytify-log-handler.php',
303 WP_ANALYTIFY_LIB_PATH . 'logs/class-analytify-log-handler-file.php',
304 WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-logs.php',
305 WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-sanitize.php',
306 WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytify-core-functions.php',
307 WP_ANALYTIFY_PLUGIN_DIR . '/inc/class-analytify-adminbar.php',
308 WP_ANALYTIFY_PLUGIN_DIR . '/classes/abstracts/analytify-report-abstract.php',
309 WP_ANALYTIFY_PLUGIN_DIR . '/classes/abstracts/analytify-host-analytics-abstract.php',
310 WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-host-analytics.php',
311 WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-report-core.php',
312 WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-rest-api.php',
313 WP_ANALYTIFY_PLUGIN_DIR . '/inc/class-analytify-ajax.php',
314 WP_ANALYTIFY_PLUGIN_DIR . '/inc/class-analytify-post-columns.php',
315 WP_ANALYTIFY_PLUGIN_DIR . '/classes/class-wp-analytify-compatibility-upgrade.php',
316 WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-dashboard-widget.php',
317 WP_ANALYTIFY_PLUGIN_DIR . '/classes/class-analytify-user-optout.php',
318 WP_ANALYTIFY_PLUGIN_DIR . '/classes/class-analytify-gdpr-compliance.php',
319 WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-email.php',
320 WP_ANALYTIFY_PLUGIN_DIR . '/classes/analytify-settings.php',
321 );
322
323 foreach ( $files as $file ) {
324 if ( file_exists( $file ) ) {
325 include_once $file;
326 } else {
327
328 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>';
329 return;
330 }
331 }
332
333 if ( file_exists( WP_ANALYTIFY_PLUGIN_DIR . '/inc/class-analytify-loader.php' ) ) {
334 require_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/class-analytify-loader.php';
335 if ( class_exists( 'Analytify_Loader' ) ) {
336 $this->loader = new Analytify_Loader( $this );
337 }
338 }
339 }
340
341 // ========================================.
342 // CONSTRUCTOR & CORE METHODS END.
343 // ========================================.
344
345 // ========================================.
346 // WordPress HOOKS & ACTIONS START.
347 // ========================================.
348
349 /**
350 * Run action && filter hooks
351 *
352 * @access private
353 * @since 1.2.2
354 * @return void
355 */
356 private function hooks() {
357
358 add_action( 'init', array( $this, 'load_textdomain' ) ); // Hook load_textdomain.
359 add_action( 'admin_init', array( $this, '_save_core_version' ) );
360 add_action( 'admin_init', array( $this, 'wpa_check_authentication' ) );
361 add_action( 'admin_init', array( $this, 'logout' ), 1 );
362 add_filter( 'removable_query_args', array( $this, 'Analytify_remove_query' ) );
363 add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
364
365 add_action( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 4 );
366
367 add_action( 'wp_head', array( $this, 'analytify_add_analytics_code' ) );
368 add_action( 'wp_head', array( $this, 'analytify_add_manual_analytics_code' ) );
369
370 add_filter( 'admin_footer_text', 'wpa_admin_rate_footer_text', 1 );
371 add_action( 'admin_footer', 'wpa_print_js', 25 );
372
373 add_action( 'admin_init', array( $this, 'redirect_optin' ) );
374
375 add_action( 'analytify_cleanup_logs', array( $this, 'analytify_cleanup_logs' ) );
376
377 add_action(
378 'init',
379 function () {
380 if ( WPANALYTIFY_Utils::get_option( 'locally_host_analytics', 'wp-analytify-advanced', false ) && ! wp_next_scheduled( 'analytify_analytics_lib_cron' ) ) {
381 wp_schedule_event( time(), 'daily', 'analytify_analytics_lib_cron' );
382 }
383 }
384 );
385
386 add_action(
387 'analytify_analytics_lib_cron',
388 function () {
389 if ( class_exists( 'Analytify_Host_Analytics' ) ) {
390 new Analytify_Host_Analytics( 'gtag', true );
391 }
392 }
393 );
394 }
395
396 // ========================================.
397 // WordPress HOOKS & ACTIONS END.
398 // ========================================.
399
400
401 // ========================================.
402 // ADMIN NOTICES & PROMOTIONS START.
403 // ========================================.
404
405
406
407 /**
408 * Redirect to Welcome page.
409 *
410 * @since 2.0.14
411 * @return void
412 */
413 public function redirect_optin() {
414 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading URL parameter for display purposes
415 $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
416 if ( $page && ( 'analytify-settings' === $page || 'analytify-dashboard' === $page || 'analytify-woocommerce' === $page || 'analytify-addons' === $page ) ) {
417 if ( ! get_site_option( '_analytify_optin' ) ) {
418 wp_safe_redirect( admin_url( 'admin.php?page=analytify-optin' ) );
419 exit;
420 }
421 }
422 }
423
424
425 /**
426 * Internationalization.
427 *
428 * @access public
429 * @since 1.2.2
430 * @return void
431 */
432 public function load_textdomain() {
433 $plugin_dir = basename( __DIR__ );
434 load_plugin_textdomain( 'wp-analytify', false, $plugin_dir . '/languages/' );
435 }
436
437
438 /**
439 *
440 * Save Authentication code on return
441 * && nonce verification
442 *
443 * @return void
444 */
445 public function wpa_check_authentication() {
446
447 $state = isset( $_GET['state'] ) ? json_decode( urldecode( sanitize_text_field( wp_unslash( $_GET['state'] ) ) ), true ) : null;
448
449 if ( isset( $_GET['code'] ) && isset( $_GET['page'] ) && 'analytify-settings' === sanitize_text_field( wp_unslash( $_GET['page'] ) ) ) {
450 $get_nonce = isset( $_GET['nonce'] ) ? sanitize_text_field( wp_unslash( $_GET['nonce'] ) ) : null;
451 $nonce = isset( $state['nonce'] ) ? $state['nonce'] : $get_nonce;
452
453 if ( wp_verify_nonce( $nonce, 'analytify_analytics_login' ) ) {
454
455 $key_google_token = sanitize_text_field( wp_unslash( $_GET['code'] ) );
456 update_option( 'WP_ANALYTIFY_NEW_LOGIN', 'yes' );
457 self::pt_save_data( $key_google_token );
458 wp_safe_redirect( admin_url( 'admin.php?page=analytify-settings' ) . '#wp-analytify-profile' );
459 exit;
460
461 } else {
462 $plugin_page_url = admin_url( 'plugins.php' );
463 wp_die(
464 sprintf( // translators: Nonce verification failed.
465 esc_html__( 'Sorry, you are not allowed as nonce verification failed. %1$sClick here to return to the Dashboard%2$s.', 'wp-analytify' ),
466 '<a href="' . esc_url( $plugin_page_url ) . '">',
467 '</a>'
468 )
469 );
470 }
471 }
472 }
473
474 /**
475 * Save version number of the plugin && show a custom message for users
476 *
477 * @since 1.3
478 * @return void
479 */
480 public function _save_core_version() { // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore -- Underscore prefix is intentional for internal method
481 if ( ANALYTIFY_VERSION !== get_option( 'WP_ANALYTIFY_PLUGIN_VERSION' ) ) {
482 update_option( 'WP_ANALYTIFY_PLUGIN_VERSION_OLD', get_option( 'WP_ANALYTIFY_PLUGIN_VERSION' ), true ); // saving old plugin version.
483 update_option( 'WP_ANALYTIFY_PLUGIN_VERSION', ANALYTIFY_VERSION );
484 }
485 }
486
487
488
489
490
491 // ========================================.
492 // GOOGLE ANALYTICS TRACKING CODE START.
493 // ========================================.
494
495 /**
496 * Add Google Analytics JS code
497 *
498 * @since 1.0.0
499 * @version 7.0.4
500 * @return bool|void Returns false if tracking is blocked/skipped, true if code is output, void otherwise.
501 */
502 public function analytify_add_analytics_code() {
503 if ( WPANALYTIFY_Utils::skip_page_tracking() ) {
504 return false;
505 }
506
507 // Check for GDPR compliance.
508 if ( Analytify_GDPR_Compliance::is_gdpr_compliance_blocking() ) {
509 return false;
510 }
511
512 if ( 'on' === $this->settings->get_option( 'install_ga_code', 'wp-analytify-profile', 'off' ) ) {
513 global $current_user;
514
515 $roles = $current_user->roles;
516
517 if ( isset( $roles[0] ) && in_array( $roles[0], $this->settings->get_option( 'exclude_users_tracking', 'wp-analytify-profile', array() ), true ) ) {
518 echo '<!-- This user is disabled from tracking by Analytify !-->';
519 return false;
520 } else {
521 if ( ! $this->settings->get_option( 'profile_for_posts', 'wp-analytify-profile' ) ) {
522 return false;
523 }
524
525 $ua_code = WP_ANALYTIFY_FUNCTIONS::get_UA_code();
526
527 // Validate UA code before outputting tracking code.
528 if ( empty( $ua_code ) ) {
529 // Add a comment in HTML for debugging.
530 echo '<!-- Analytify: No tracking code - check profile selection or OAuth connection -->';
531 return false;
532 }
533
534 if ( 'gtag' === WP_ANALYTIFY_TRACKING_MODE ) {
535 $ga_code = $this->output_gtag_code( $ua_code );
536 } else {
537 $ga_code = $this->output_ga_code( $ua_code );
538 }
539
540 echo apply_filters( 'analytify_ga_script', $ga_code ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JavaScript code needs to be output directly
541 return true;
542 }
543 }
544 }
545
546 /**
547 * Add Google Manual Analytics JS code
548 *
549 * @return void
550 */
551 public function analytify_add_manual_analytics_code() {
552 if ( get_option( 'pa_google_token' ) ) {
553 return;
554 }
555
556 $manual_ua_code = $this->settings->get_option( 'manual_ua_code', 'wp-analytify-authentication', false );
557
558 if ( ! $manual_ua_code ) {
559 return;
560 }
561
562 global $current_user;
563 $roles = $current_user->roles;
564
565 if ( in_array( 'administrator', $roles, true ) ) {
566 echo '<!-- This user is disabled from tracking by Analytify !-->';
567 } elseif ( apply_filters( 'analytify_manaul_ga_script', false ) ) {
568 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
569 } else {
570 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
571 }
572 }
573
574 /**
575 * Generate gtag code.
576 *
577 * @param string $ua_code Google Analytics UA code.
578 * @since 3.0
579 * @version 7.0.4
580 * @return $gtag_code
581 */
582 private function output_gtag_code( $ua_code ) {
583 ob_start();
584
585 $local_analytics_file = class_exists( 'Analytify_Host_Analytics' ) ? ( new Analytify_Host_Analytics( 'gtag', false ) )->local_analytics_file_url() : false;
586
587 if ( false !== apply_filters( 'analytify_tracking_code_comments', true ) ) {
588 printf( // translators: Tracking code comments.
589 esc_html__( '%2$s This code is added by Analytify (%1$s) %4$s %3$s', 'wp-analytify' ),
590 esc_html( ANALYTIFY_VERSION ),
591 '<!--',
592 '!-->',
593 'https://analytify.io/'
594 );
595 }
596
597 $allow_display_features = ( 'on' === $this->settings->get_option( 'demographic_interest_tracking', 'wp-analytify-advanced' ) ) ? 'true' : 'false';
598 $linker_cross_domain_tracking = ( 'on' === $this->settings->get_option( 'linker_cross_domain_tracking', 'wp-analytify-advanced' ) ) ? true : false;
599 $linked_domains = array();
600
601 if ( $linker_cross_domain_tracking ) {
602 $all_linked_domains = $this->settings->get_option( 'linked_domain', 'wp-analytify-advanced' );
603 $all_linked_domains = trim( $all_linked_domains ? $all_linked_domains : '' );
604
605 if ( ! empty( $all_linked_domains ) ) {
606 $all_linked_domains = str_replace( "'", '', $all_linked_domains );
607 $all_linked_domains = str_replace( '"', '', $all_linked_domains );
608
609 $all_linked_domains = preg_replace( '/\s+/', '', $all_linked_domains );
610
611 $list_linked_domains = explode( ',', $all_linked_domains );
612 $number_of_linked_domains = count( $list_linked_domains );
613
614 if ( $number_of_linked_domains > 0 ) {
615 $linked_domains = array_filter(
616 (array) $list_linked_domains,
617 function ( $value ) {
618 return strlen( $value ) > 0;
619 }
620 );
621 } else {
622 $linked_domains = (array) $all_linked_domains;
623 }
624 } else {
625 $linker_cross_domain_tracking = false;
626 }
627 }
628
629 $configuration = array(
630
631 'allow_display_features' => $allow_display_features,
632 );
633
634 if ( $linker_cross_domain_tracking ) {
635 $configuration['linker'] = array(
636 'domains' => $linked_domains,
637 );
638 }
639
640 $debug_mode = apply_filters( 'analytify_debug_mode', true );
641
642 if ( $debug_mode ) {
643 $configuration['debug_mode'] = true;
644 }
645
646 if ( 'on' === $this->settings->get_option( 'track_user_id', 'wp-analytify-advanced' ) && is_user_logged_in() ) {
647 $configuration['user_id'] = esc_html( (string) get_current_user_id() );
648 }
649
650 $configuration = apply_filters( 'analytify_gtag_configuration', $configuration );
651 $configuration_json = wp_json_encode( $configuration, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT );
652
653 // Build the script src URL correctly.
654 $script_src = $local_analytics_file ?? 'https://www.googletagmanager.com/gtag/js';
655 $script_src .= ( strpos( $script_src, '?' ) !== false ? '&' : '?' ) . 'id=' . esc_attr( $ua_code );
656
657 ?>
658
659 <?php // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript -- Inline gtag script must be output directly in the page head. ?>
660 <script async src="<?php echo esc_url( $script_src ); ?>"></script>
661 <script>
662 window.dataLayer = window.dataLayer || [];
663 function gtag(){dataLayer.push(arguments);}
664 gtag('js', new Date());
665
666 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. ?>;
667 const gaID = '<?php echo esc_js( $ua_code ); ?>';
668
669 <?php do_action( 'analytify_tracking_code_before_pageview' ); ?>
670
671 gtag('config', gaID, configuration);
672
673 <?php
674 if ( $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' ) ) {
675 $custom_js = $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' );
676
677 if ( ! empty( $custom_js ) ) {
678 echo wp_kses_post( $custom_js );
679 }
680 }
681
682 do_action( 'ga_ecommerce_js' );
683 do_action( 'analytify_tracking_code_after_pageview' );
684 ?>
685
686 </script>
687
688 <?php
689 if ( false !== apply_filters( 'analytify_tracking_code_comments', true ) ) {
690 printf( // translators: Tracking code comments.
691 esc_html__( '%2$s This code is added by Analytify (%1$s) %3$s', 'wp-analytify' ),
692 esc_html( ANALYTIFY_VERSION ),
693 '<!--',
694 '!-->'
695 );
696 }
697
698 $gtag_code = ob_get_contents();
699 ob_end_clean();
700 return $gtag_code ? $gtag_code : '';
701 }
702
703 /**
704 * Generate gtag code.
705 *
706 * @param string $ua_code Google Analytics UA code.
707 * @since 3.0
708 * @return string
709 */
710 public function output_ga_code( $ua_code ) {
711 ob_start();
712
713 $src = apply_filters( 'analytify_output_ga_js_src', '//www.google-analytics.com/analytics.js' );
714
715 if ( false !== apply_filters( 'analytify_tracking_code_comments', true ) ) {
716 printf( // translators: Tracking code comments.
717 esc_html__( '%2$s This code is added by Analytify (%1$s) %4$s %3$s', 'wp-analytify' ),
718 esc_html( ANALYTIFY_VERSION ),
719 '<!--',
720 '!-->',
721 'https://analytify.io/'
722 );
723 }
724 ?>
725
726 <script>
727 (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
728 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
729 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
730 })
731
732 (window,document,'script','<?php echo esc_url( $src ); ?>','ga');
733
734 <?php
735 if ( 'on' === $this->settings->get_option( 'linker_cross_domain_tracking', 'wp-analytify-advanced' ) ) {
736 echo " ga('create', '" . esc_js( $ua_code ) . "', 'auto', {'allowLinker': true});";
737 echo "ga('require', 'linker');";
738 } else {
739 echo " ga('create', '" . esc_js( $ua_code ) . "', 'auto');";
740 }
741
742 if ( 'on' === $this->settings->get_option( 'track_user_id', 'wp-analytify-advanced' ) && is_user_logged_in() ) {
743 echo "ga('set', 'userId', " . esc_html( (string) get_current_user_id() ) . ');';
744 }
745
746 if ( 'on' === $this->settings->get_option( 'demographic_interest_tracking', 'wp-analytify-advanced' ) ) {
747 echo "ga('require', 'displayfeatures');";
748 }
749
750 if ( $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' ) ) {
751
752 $custom_js = $this->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' );
753
754 if ( $custom_js && false !== $custom_js ) {
755 $custom_js = wp_kses(
756 $custom_js,
757 array(
758 'script' => array(),
759 'noscript' => array(),
760 'div' => array(
761 'id' => array(),
762 'class' => array(),
763 ),
764 'span' => array(
765 'id' => array(),
766 'class' => array(),
767 ),
768 )
769 );
770 echo '<script type="text/javascript">' . esc_js( wp_strip_all_tags( $custom_js ) ) . '</script>';
771 }
772 }
773
774 do_action( 'ga_ecommerce_js' );
775 do_action( 'analytify_tracking_code_before_pageview' );
776 echo "ga('send', 'pageview');";
777 ?>
778
779 </script>
780
781 <?php
782 if ( false !== apply_filters( 'analytify_tracking_code_comments', true ) ) {
783 printf( // translators: Tracking code comments.
784 esc_html__( '%2$s This code is added by Analytify (%1$s) %3$s', 'wp-analytify' ),
785 esc_html( ANALYTIFY_VERSION ),
786 '<!--',
787 '!-->'
788 );
789 }
790
791 $ga_code = ob_get_contents();
792 ob_end_clean();
793 return $ga_code ? $ga_code : '';
794 }
795
796 // ========================================.
797 // GOOGLE ANALYTICS TRACKING CODE END.
798 // ========================================.
799
800
801 /**
802 * Plugin row meta links
803 *
804 * @since 1.1
805 * @version 5.0.5
806 * @param array $input already defined meta links.
807 * @param string $file plugin file path && name being processed.
808 * @param array $plugin_data relevent data about the currect plugin.
809 * @param string $status weather plugin is active or disabled.
810 * @return array $input
811 */
812 public function plugin_row_meta( $input, $file, $plugin_data, $status ) {
813
814 $analytify_plugins = array(
815 'wp-analytify/wp-analytify.php',
816 'analytify-analytics-dashboard-widget/wp-analytify-dashboard.php',
817 'wp-analytify-pro/wp-analytify-pro.php',
818 'wp-analytify-woocommerce/wp-analytify-woocommerce.php',
819 'wp-analytify-goals/wp-analytify-goals.php',
820 'wp-analytify-forms/wp-analytify-forms.php',
821 'wp-analytify-email/wp-analytify-email.php',
822 'wp-analytify-edd/wp-analytify-edd.php',
823 'wp-analytify-authors/wp-analytify-authors.php',
824 );
825
826 if ( ! in_array( $file, $analytify_plugins, true ) ) {
827 return $input;
828 }
829
830 if ( isset( $plugin_data['Author'] ) ) {
831
832 $input[1] = sprintf(
833 'By <a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
834 esc_url( $plugin_data['AuthorURI'] ),
835 esc_html( $plugin_data['Author'] )
836 );
837
838 }
839
840 if ( 'wp-analytify/wp-analytify.php' !== $file && 'analytify-analytics-dashboard-widget/wp-analytify-dashboard.php' !== $file && in_array( $file, $analytify_plugins, true ) ) {
841
842 $input[2] = sprintf(
843 '<a href="%s" target="_blank" rel="noopener noreferrer">Visit Plugin Site</a>',
844 esc_url( $plugin_data['PluginURI'] )
845 );
846 return $input;
847
848 }
849
850 $links = array(
851 sprintf( // translators: Premium features.
852 esc_html__( '%1$s Explore Premium Features %2$s', 'wp-analytify' ),
853 '<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">',
854 '</a>'
855 ),
856 );
857
858 $input = array_merge( $input, $links );
859
860 return $input;
861 }
862
863
864 /**
865 * Display warning if profiles are not selected.
866 *
867 * @return void
868 */
869 public function pa_check_warnings() {
870 add_action( 'admin_footer', array( &$this, 'profile_warning' ) );
871 }
872
873
874 // Page routing function moved to Page_Management component.
875
876
877
878
879 // ========================================.
880 // ADMIN ASSETS & STYLING START.
881 // ========================================.
882
883 // Admin styles function moved to Scripts_Styles component.
884
885 // Functions moved to Scripts_Styles, Module_Manager && Promotions components.
886
887 // ========================================.
888 // ANALYTICS DATA RETRIEVAL START.
889 // ========================================.
890
891 // Analytics accounts function moved to Analytics_Accounts component.
892
893 // Analytics accounts summary function moved to Analytics_Accounts component.
894
895 /**
896 * Get settings URL.
897 *
898 * @return string
899 */
900 public function pa_setting_url() {
901 return admin_url( 'admin.php?page=analytify-settings' );
902 }
903
904 /**
905 * Save Google token data.
906 *
907 * @param mixed $key_google_token The Google token data.
908 * @return bool|void
909 */
910 public function pt_save_data( $key_google_token ) {
911 try {
912 update_option( 'post_analytics_token', $key_google_token );
913
914 if ( $this->analytify_pa_connect_v2() ) {
915 return true;
916 }
917 } catch ( Exception $e ) {
918 echo esc_html( $e->getMessage() );
919 }
920 }
921
922 // Profile warning function moved to Promotions component.
923
924 // AJAX handler moved to Analytics_Reports component.
925
926 // Module state function moved to Module_Manager component.
927
928
929
930
931 // ========================================.
932 // ANALYTICS DATA RETRIEVAL END.
933 // ========================================.
934
935 // Deprecated analytics function moved to Analytics_Reports component.
936
937
938
939
940 // ========================================.
941 // UTILITY & HELPER FUNCTIONS START.
942 // ========================================.
943
944 // Utility functions moved to Utils component.
945 // Backward compatibility wrappers.
946 /**
947 * Format numbers for display.
948 *
949 * @param mixed $num The number to format.
950 * @return string
951 */
952 public function wpa_pretty_numbers( $num ) {
953 return Analytify_Utils::wpa_pretty_numbers( $num );
954 }
955
956 /**
957 * Format number with proper formatting.
958 *
959 * @param mixed $num The number to format.
960 * @return string
961 */
962 public function wpa_number_format( $num ) {
963 return Analytify_Utils::wpa_number_format( $num );
964 }
965
966 /**
967 * Format time for display.
968 *
969 * @param mixed $time The time to format.
970 * @return string
971 */
972 public function pa_pretty_time( $time ) {
973 return Analytify_Utils::pa_pretty_time( $time );
974 }
975
976 /**
977 * Check user access level.
978 *
979 * @param mixed $access_level The required access level.
980 * @return bool
981 */
982 public function pa_check_roles( $access_level ) {
983 return Analytify_Utils::pa_check_roles( $access_level );
984 }
985
986
987 /**
988 * Notice to switch gtag.js tracking mode.
989 *
990 * @return void
991 */
992 // Welcome message function moved to Promotions component.
993
994 // ========================================.
995 // ADMIN MENU & PAGE ROUTING START.
996 // ========================================.
997
998 /**
999 * Create Analytics menu at the left side of dashboard
1000 *
1001 * @version 8.1.0
1002 * @return void
1003 */
1004 public function add_admin_menu() {
1005 $allowed_roles = $this->settings->get_option( 'show_analytics_roles_dashboard', 'wp-analytify-dashboard', array() );
1006 $allowed_roles[] = 'administrator';
1007
1008 $current_user = wp_get_current_user();
1009 $is_author_only = $current_user && in_array( 'author', $current_user->roles, true ) && ! in_array( 'administrator', $current_user->roles, true );
1010
1011 // Determine the capability to use for the dashboard.
1012 // If the user has an allowed role, we use 'read' to ensure they can see the menu,
1013 // since add_admin_menu already restricted registration to allowed roles.
1014 $dashboard_cap = 'manage_options';
1015 if ( array_intersect( $current_user->roles, $allowed_roles ) ) {
1016 $dashboard_cap = 'read';
1017 }
1018
1019 // Allow authors to see the menu (so they can access Authors dashboard submenu).
1020 // But restrict them from accessing main dashboard content.
1021 if ( $is_author_only ) {
1022 // Authors can see menu but will be restricted from main dashboard page.
1023 // They need edit_posts capability to see Authors dashboard.
1024 if ( ! current_user_can( 'edit_posts' ) ) {
1025 return;
1026 }
1027 } elseif ( ! $this->pa_check_roles( $allowed_roles ) ) {
1028 // For non-authors, check normal access.
1029 return;
1030 }
1031
1032 add_submenu_page( 'admin.php', __( 'Activate', 'wp-analytify' ), __( 'Activate', 'wp-analytify' ), 'manage_options', 'analytify-optin', array( $this, 'render_optin' ) );
1033
1034 add_menu_page(
1035 ANALYTIFY_NICK,
1036 'Analytify',
1037 $dashboard_cap,
1038 'analytify-dashboard',
1039 array(
1040 $this,
1041 'pa_page_file_path',
1042 ),
1043 'data:image/svg+xml;base64,' . base64_encode( // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Used for SVG data encoding
1044 '<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"
1045 width="18px" height="18px" viewBox="0 0 18 18" style="enable-background:new 0 0 18 18;" xml:space="preserve">
1046 <style type="text/css">
1047 .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#23282D;}
1048 .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#9EA3A8;}
1049 </style>
1050 <g>
1051 <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
1052 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
1053 s3.4,7.5,7.5,7.5s7.5-3.4,7.5-7.5S13.1,1.5,9,1.5z"/>
1054 <g>
1055 <g>
1056 <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
1057 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
1058 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"/>
1059 </g>
1060 </g>
1061 </g>
1062 </svg>'
1063 ),
1064 2
1065 );
1066
1067 add_submenu_page(
1068 'analytify-dashboard',
1069 ANALYTIFY_NICK . esc_html__( ' Dashboards', 'wp-analytify' ),
1070 esc_html__( 'Dashboards', 'wp-analytify' ),
1071 $dashboard_cap,
1072 'analytify-dashboard',
1073 array(
1074 $this,
1075 'pa_page_file_path',
1076 ),
1077 10
1078 );
1079
1080 do_action( 'analytify_add_submenu' );
1081
1082 add_submenu_page(
1083 'analytify-dashboard',
1084 ANALYTIFY_NICK . esc_html__( ' Settings', 'wp-analytify' ),
1085 esc_html__( 'Settings', 'wp-analytify' ),
1086 'manage_options',
1087 'analytify-settings',
1088 array(
1089 $this,
1090 'pa_page_file_path',
1091 ),
1092 50
1093 );
1094
1095 add_submenu_page(
1096 'analytify-dashboard',
1097 ANALYTIFY_NICK . esc_html__( ' Help', 'wp-analytify' ),
1098 esc_html__( 'Help', 'wp-analytify' ),
1099 'manage_options',
1100 'analytify-settings#wp-analytify-help',
1101 array(
1102 $this,
1103 'pa_page_file_path',
1104 ),
1105 55
1106 );
1107
1108 // Add license submenu.
1109 if ( class_exists( 'WP_Analytify_Pro_Base' ) ) {
1110 add_submenu_page(
1111 'analytify-dashboard',
1112 ANALYTIFY_NICK . esc_html__( ' License', 'wp-analytify' ),
1113 esc_html__( 'License', 'wp-analytify' ),
1114 'manage_options',
1115 'analytify-settings#wp-analytify-license',
1116 array(
1117 $this,
1118 'pa_page_file_path',
1119 ),
1120 60
1121 );
1122 }
1123
1124 add_submenu_page(
1125 'analytify-dashboard',
1126 ANALYTIFY_NICK . esc_html__( ' list of all Add-ons', 'wp-analytify' ),
1127 esc_html__( 'Add-ons', 'wp-analytify' ),
1128 'manage_options',
1129 'analytify-addons',
1130 array(
1131 $this,
1132 'pa_page_file_path',
1133 ),
1134 65
1135 );
1136
1137 add_submenu_page(
1138 'analytify-dashboard',
1139 ANALYTIFY_NICK . esc_html__( ' PRO vs FREE', 'wp-analytify' ),
1140 esc_html__( 'PRO vs FREE', 'wp-analytify' ),
1141 'manage_options',
1142 'analytify-go-pro',
1143 array(
1144 $this,
1145 'pa_page_file_path',
1146 ),
1147 70
1148 );
1149
1150 // Promo page (will not appear in side menu).
1151 add_submenu_page( 'analytify-dashboard', esc_html__( 'Analytify Promo', 'wp-analytify' ), null, 'manage_options', 'analytify-promo', array( $this, 'addons_promo_screen' ) );
1152 }
1153
1154 /**
1155 * Get current screen details
1156 *
1157 * @return void
1158 */
1159 public function pa_page_file_path() {
1160 $screen = get_current_screen();
1161
1162 if ( strpos( $screen->base, 'analytify-settings' ) !== false ) {
1163 $version = defined( 'ANALYTIFY_PRO_VERSION' ) ? ANALYTIFY_PRO_VERSION : ANALYTIFY_VERSION;
1164
1165 echo '<div class="wrap"><h2 style="display: none;"></h2></div>
1166
1167 <div class="wpanalytify"><div class="wpb_plugin_wraper">
1168
1169 <div class="wpb_plugin_header_wraper">
1170 <div class="graph"></div>
1171
1172 <div class="wpb_plugin_header">
1173
1174 <div class="wpb_plugin_header_title"></div>
1175
1176 <div class="wpb_plugin_header_info">
1177 <a href="https://analytify.io/changelog/" target="_blank" class="btn">View Changelog</a>
1178 </div>
1179 <div class="wpb_plugin_header_logo">
1180 <img src="' . esc_url( plugins_url( 'assets/img/logo.svg', __FILE__ ) ) . '" alt="Analytify">
1181 </div>
1182 </div></div><div class="analytify-settings-body-container"><div class="wpb_plugin_body_wraper"><div class="wpb_plugin_body">';
1183 // Initialize settings before rendering.
1184 $this->settings->set_sections( $this->settings->get_settings_sections() );
1185 $this->settings->set_fields( $this->settings->get_settings_fields() );
1186 $this->settings->rendered_settings();
1187 $this->settings->show_tabs();
1188 echo '<div class="wpb_plugin_tabs_content">';
1189 $this->settings->show_forms();
1190 echo '</div>';
1191
1192 echo '</div></div></div></div>';
1193
1194 } elseif ( strpos( $screen->base, 'analytify-dashboard' ) !== false ) {
1195 // Restrict authors from accessing main dashboard - redirect to Authors dashboard.
1196 $current_user = wp_get_current_user();
1197 $is_author_only = $current_user && in_array( 'author', (array) $current_user->roles, true ) && ! in_array( 'administrator', (array) $current_user->roles, true );
1198
1199 if ( $is_author_only ) {
1200 // Redirect authors to their Authors dashboard.
1201 wp_safe_redirect( admin_url( 'admin.php?page=analytify-authors' ) );
1202 exit;
1203 }
1204
1205 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading URL parameter for display purposes
1206 if ( isset( $_GET['show'] ) ) {
1207 do_action( 'show_detail_dashboard_content' );
1208 } else {
1209 require_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytics-dashboard.php';
1210 }
1211 } elseif ( strpos( $screen->base, 'analytify-optin' ) !== false ) {
1212 require_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytify-optin-form.php';
1213 } elseif ( strpos( $screen->base, 'analytify-addons' ) !== false ) {
1214 require_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/page-addons.php';
1215 } elseif ( strpos( $screen->base, 'analytify-woocommerce' ) !== false ) {
1216 // WooCommerce page - this might not exist, let's check if file exists first.
1217 $woo_file = WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytify-woocommerce.php';
1218 if ( file_exists( $woo_file ) ) {
1219 require_once $woo_file;
1220 }
1221 } elseif ( strpos( $screen->base, 'analytify-logs' ) !== false ) {
1222 include_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/page-logs.php';
1223 } elseif ( strpos( $screen->base, 'analytify-go-pro' ) !== false ) {
1224 include_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytify-go-pro.php';
1225 } elseif ( isset( $_GET['show'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading URL parameter for display purposes
1226 do_action( 'show_detail_dashboard_content' );
1227 } else {
1228 // Dequeue event calendar js.
1229 wp_dequeue_script( 'tribe-common' );
1230 wp_dequeue_script( 'mcw-crypto-common' );
1231 include_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytics-dashboard.php';
1232 }
1233 }
1234
1235 // ========================================.
1236 // ADMIN MENU & PAGE ROUTING END.
1237 // ========================================.
1238
1239 /**
1240 * Render optin page
1241 *
1242 * @return void
1243 */
1244 public function render_optin() {
1245 require_once WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytify-optin-form.php';
1246 }
1247
1248 // Functions moved to Promotions && Analytics_Reports components.
1249
1250 /**
1251 * Process logout && clear stored options.
1252 *
1253 * @return void
1254 */
1255 public function logout() {
1256 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' ) ) {
1257 delete_option( 'pt_webprofile' );
1258 delete_option( 'pt_webprofile_dashboard' );
1259 delete_option( 'pt_webprofile_url' );
1260 delete_option( 'pa_google_token' );
1261 delete_option( 'post_analytics_token' );
1262 delete_option( 'hide_profiles' );
1263 delete_option( 'analytify-ga4-streams' );
1264 delete_option( 'analytify_tracking_property_info' );
1265 delete_option( 'analytify_reporting_property_info' );
1266 delete_option( 'analytify_ga4_exception' );
1267 delete_option( 'analytify_ga4_exceptions' );
1268 delete_option( 'profiles_list_summary' );
1269 delete_option( 'analytify_ga_properties_list' );
1270 delete_option( 'wp-analytify-mode' );
1271 delete_option( 'analytify-deprecated-auth' );
1272 delete_option( 'analytify-ga-properties-summery' );
1273 delete_option( 'analytify_profile_exception' );
1274 delete_option( 'profiles_list_summary_backup' );
1275 delete_transient( 'analytify_quota_exception' );
1276
1277 $_analytify_profile = get_option( 'wp-analytify-profile' );
1278 if ( $_analytify_profile ) {
1279 unset( $_analytify_profile['hide_profiles_list'], $_analytify_profile['profile_for_posts'], $_analytify_profile['profile_for_dashboard'] );
1280 update_option( 'wp-analytify-profile', $_analytify_profile );
1281 }
1282
1283 $update_message = sprintf( // translators: Login again notice.
1284 esc_html__( '%1$s %2$s %3$s Authentication Cleared login again. %4$s %5$s %6$s', 'wp-analytify' ),
1285 '<div id="setting-error-settings_updated" class="updated notice is-dismissible settings-error below-h2">',
1286 '<p>',
1287 '<strong>',
1288 '</strong>',
1289 '</p>',
1290 '</div>'
1291 );
1292 }
1293 }
1294
1295 /**
1296 * Used to add query args that need to be removed from url
1297 *
1298 * @since 5.0.6
1299 * @param mixed $args_array The arguments array to process.
1300 * @return array
1301 */
1302 public function Analytify_remove_query( $args_array ) {
1303 $analytify_args_to_remove = array( 'analytify-cache' );
1304 $args_array = array_merge( $args_array, $analytify_args_to_remove );
1305 return $args_array;
1306 }
1307
1308 /**
1309 * Trigger logging cleanup using the logging class.
1310 *
1311 * @since 2.1.23
1312 * @return void
1313 */
1314 public static function analytify_cleanup_logs() {
1315 $logger = analytify_get_logger();
1316 if ( class_exists( 'QM' ) ) {
1317 QM::info( 'Analytify: Starting cleanup of expired logs.' );
1318 }
1319
1320 if ( is_callable( array( $logger, 'clear_expired_logs' ) ) ) {
1321 $logger->clear_expired_logs();
1322 if ( class_exists( 'QM' ) ) {
1323 QM::info( 'Analytify: Expired logs cleared successfully.' );
1324 }
1325 }
1326 }
1327
1328
1329
1330
1331 // ========================================.
1332 // PROFILE & SETTINGS MANAGEMENT START.
1333 // ========================================.
1334
1335 // Functions moved to Profile_Management && GA4_Property_Management components.
1336
1337 // ========================================.
1338 // PROFILE & SETTINGS MANAGEMENT END.
1339 // ========================================.
1340
1341 // Black Friday Deal Notice function moved to Promotions component.
1342
1343 // Function moved to Promotions component.
1344
1345 // Winter Sale promo function moved to Promotions component.
1346
1347 // Winter Sale dismiss notice function moved to Promotions component.
1348
1349 // Rating icon function moved to Promotions component.
1350
1351 // ========================================.
1352 // GDPR COMPLIANCE & META BOXES START.
1353 // ========================================.
1354
1355 // Functions add_exclusion_meta_box && print_exclusion_meta_box moved to GDPR_Compliance component.
1356
1357 // ========================================.
1358 // GDPR COMPLIANCE & META BOXES END.
1359 // ========================================.
1360
1361 /**
1362 * Init the compliance class.
1363 *
1364 * @return void
1365 */
1366 public function init_gdpr_compliance() {
1367 if ( class_exists( 'Class_Analytify_GDPR_Compliance' ) ) {
1368 new Class_Analytify_GDPR_Compliance();
1369 }
1370 }
1371
1372 /**
1373 * Get a component from the loader
1374 *
1375 * @param string $component_name The name of the component to get.
1376 * @return mixed|null The component instance or null if not found
1377 */
1378 public function get_component( $component_name ) {
1379 if ( $this->loader && method_exists( $this->loader, 'get_component' ) ) {
1380 return $this->loader->get_component( $component_name );
1381 }
1382 return null;
1383 }
1384
1385 /**
1386 * Check if a component is loaded
1387 *
1388 * @param string $component_name The name of the component to check.
1389 * @return bool True if component is loaded, false otherwise
1390 */
1391 public function has_component( $component_name ) {
1392 if ( $this->loader && method_exists( $this->loader, 'has_component' ) ) {
1393 return $this->loader->has_component( $component_name );
1394 }
1395 return false;
1396 }
1397
1398 // Welcome message function moved to Promotions component.
1399
1400 /**
1401 * Show promo screen for addons
1402 *
1403 * @return void
1404 */
1405 public function addons_promo_screen() {
1406 include WP_ANALYTIFY_PLUGIN_DIR . '/views/default/admin/addons-promo.php';
1407 }
1408 }
1409 } // End if class_exists check.
1410
1411 // ========================================.
1412 // MAIN PLUGIN CLASS DEFINITION END.
1413 // ========================================.
1414
1415 /**
1416 * Create instance of wp-analytify class.
1417 *
1418 * @return void
1419 */
1420 function analytify_free_instance() {
1421 $GLOBALS['WP_ANALYTIFY'] = WP_Analytify::get_instance();
1422 }
1423 add_action( 'plugins_loaded', 'analytify_free_instance', 10 );
1424
1425 // ========================================.
1426 // PLUGIN INSTANCE INITIALIZATION END.
1427 // ========================================.
1428
1429 /**
1430 * AJAX callback function for performing a factory reset of Analytify plugin settings
1431 *
1432 * This function handles the secure AJAX request to reset all Analytify settings
1433 * to their default values. It includes security checks, capability verification,
1434 * and proper error handling.
1435 *
1436 * @hook wp_ajax_analytify_factory_reset
1437 * @since 8.0.0
1438 * @return void Sends JSON response indicating success or failure
1439 */
1440 function analytify_factory_reset_callback() {
1441 // Verify the nonce for security - prevents CSRF attacks.
1442 check_ajax_referer( 'analytify_factory_reset_nonce', 'nonce' );
1443
1444 // Check if current user has administrative capabilities.
1445 if ( ! current_user_can( 'manage_options' ) ) {
1446 wp_send_json_error( 'Unauthorized' );
1447 }
1448
1449 // Load the factory reset class if not already available.
1450 if ( ! class_exists( 'Analytify_Factory_Reset' ) ) {
1451 require_once plugin_dir_path( __FILE__ ) . 'classes/analytify-factory-reset.php';
1452 }
1453
1454 // Initialize the reset class and execute the reset process.
1455 $reset = new Analytify_Factory_Reset();
1456 $reset->remove_settings();
1457
1458 // Send success response to the AJAX request.
1459 wp_send_json_success();
1460 }
1461
1462 /**
1463 * Hook the factory reset function to WordPress AJAX handlers
1464 *
1465 * This registers the function for both privileged (admin) and non-privileged users,
1466 * but the capability check inside the function will restrict access to admins only.
1467 */
1468 add_action( 'wp_ajax_analytify_factory_reset', 'analytify_factory_reset_callback' );