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
wp-analytify / inc / scripts-styles.php

scripts-styles.php in Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) trunk, at inc/scripts-styles.php

696 lines 29.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 -- File naming is acceptable
2 /**
3 * Scripts & Styles Component for WP Analytify
4 *
5 * This file contains all script and style enqueuing functions
6 * that were previously in the main plugin file.
7 *
8 * @package WP_Analytify
9 * @since 8.0.0
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 /**
17 * Scripts & Styles Component Class
18 */
19 class Analytify_Scripts_Styles {
20
21 /**
22 * Main plugin instance
23 *
24 * @var WP_Analytify
25 */
26 private $analytify;
27
28 /**
29 * Main plugin file path
30 *
31 * @var string
32 */
33 private $plugin_file;
34
35 /**
36 * Constructor
37 *
38 * @param WP_Analytify $analytify Main plugin instance.
39 */
40 public function __construct( $analytify ) {
41 $this->analytify = $analytify;
42 $this->plugin_file = WP_ANALYTIFY_PLUGIN_DIR . '/wp-analytify.php';
43 }
44
45 /**
46 * Loading admin styles CSS for the plugin.
47 *
48 * @param string $page loaded page name.
49 * @return void
50 */
51 public function admin_styles( $page ) {
52 $suffix = analytify_get_asset_suffix();
53
54 wp_enqueue_style( 'dashicons' );
55 wp_enqueue_style( 'admin-bar-style', plugins_url( "assets/css/admin_bar_styles{$suffix}.css", $this->plugin_file ), array(), ANALYTIFY_VERSION );
56
57 // For Settings only.
58 if ( 'analytify_page_analytify-settings' === $page || 'analytify_page_analytify-campaigns' === $page ) {
59 wp_enqueue_style( 'jquery_tooltip', '//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css', array(), ANALYTIFY_VERSION );
60 }
61
62 // For Single Page/Post Stats.
63 if ( 'analytify_page_analytify-settings' === $page || 'post.php' === $page || 'post-new.php' === $page ) {
64 wp_enqueue_style( 'chosen', plugins_url( 'assets/css/chosen.min.css', $this->plugin_file ), array(), ANALYTIFY_VERSION ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- Version is set
65 }
66
67 if ( false !== strpos( $page, 'analytify' ) || 'post.php' === $page || 'post-new.php' === $page || 'index.php' === $page ) {
68 wp_enqueue_style( 'wp-analytify-style', plugins_url( "assets/css/wp-analytify-style{$suffix}.css", $this->plugin_file ), array(), ANALYTIFY_VERSION );
69 wp_enqueue_style( 'wp-analytify-default-style', plugins_url( "assets/css/styles{$suffix}.css", $this->plugin_file ), array(), ANALYTIFY_VERSION );
70
71 $conditional_style = '';
72
73 // Filter dashboard header animation.
74 if ( apply_filters( 'analytify_dashboard_head_animate', true ) ) {
75 $conditional_style .= '
76 .wpanalytify .graph {
77 -webkit-animation: graph_animation 130s linear infinite;
78 -moz-animation: graph_animation 130s linear infinite;
79 -o-animation: graph_animation 130s linear infinite;
80 animation: graph_animation 130s linear infinite;
81 }
82 .wpanalytify .graph:after {
83 -webkit-animation: graph_animation 250s linear infinite;
84 -moz-animation: graph_animation 250s linear infinite;
85 -o-animation: graph_animation 250s linear infinite;
86 animation: graph_animation 250s linear infinite;
87 }';
88 }
89
90 // Add conditional style.
91 wp_add_inline_style( 'wp-analytify-default-style', $conditional_style );
92 }
93
94 wp_enqueue_style( 'wp-analytify-utils-style', plugins_url( "assets/css/utils{$suffix}.css", $this->plugin_file ), array(), ANALYTIFY_VERSION );
95 // For WP Pointer.
96 if ( 1 !== (int) get_option( 'show_tracking_pointer_1' ) ) {
97 wp_enqueue_style( 'wp-pointer' );
98 }
99
100 // Hide unnamed menu item (promo page) from Analytify submenu.
101 $hide_submenu_style = '
102 #toplevel_page_analytify-dashboard .wp-submenu li a[href*="analytify-promo"] {
103 display: none !important;
104 }';
105 wp_add_inline_style( 'wp-analytify-utils-style', $hide_submenu_style );
106 }
107
108 /**
109 * Loading admin scripts JS for the plugin.
110 *
111 * @param string $page Current page.
112 * @version 9.1.1
113 * @return void
114 */
115 public function admin_scripts( $page ) {
116 $suffix = analytify_get_asset_suffix();
117
118 wp_enqueue_script( 'wp-analytify-script-js', plugins_url( "assets/js/wp-analytify{$suffix}.js", $this->plugin_file ), array( 'jquery' ), ANALYTIFY_VERSION, false ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter -- Script loaded in header intentionally
119
120 wp_localize_script(
121 'wp-analytify-script-js',
122 'wp_analytify_script',
123 array(
124 'url' => esc_url_raw( rest_url( 'wp-analytify/v1/get_report/' ) ),
125 'nonce' => wp_create_nonce( 'wp_rest' ),
126 'delimiter' => WPANALYTIFY_Utils::get_delimiter(),
127 'no_stats_message' => __( 'No activity during this period.', 'wp-analytify' ),
128 'error_message' => __( 'Something went wrong. Please try again later single.', 'wp-analytify' ),
129 )
130 );
131
132 global $post_type;
133
134 // For main page.
135 $allowed_pages = array(
136 'index.php',
137 'toplevel_page_analytify-dashboard',
138 'analytify_page_analytify-woocommerce',
139 'analytify_page_analytify-lifterlms',
140 'analytify_page_analytify-learndash',
141 'analytify_page_analytify-pmpro',
142 'analytify_page_edd-dashboard',
143 'analytify_page_analytify-campaigns',
144 'analytify_page_analytify-goals',
145 'analytify_page_analytify-forms',
146 'analytify_page_analytify-dimensions',
147 'analytify_page_analytify-authors',
148 'analytify_page_analytify-events',
149 'analytify_page_analytify-promo',
150 );
151 if ( in_array( $page, $allowed_pages, true ) || in_array( $post_type, $this->analytify->settings->get_option( 'show_analytics_post_types_back_end', 'wp-analytify-admin', array() ), true ) ) {
152 // Using WP's internal moment-js, after 4.2.1.
153
154 /**
155 * Filter to force moment js to use the same timezone as the one set within WordPress.
156 * Default is false.
157 *
158 * Filter was remove after 4.2.1
159 *
160 * Example use: add_filter( 'analytify_set_moment_timezone_to_match_wp', '__return_true' );
161 */
162
163 /* phpcs:ignore Squiz.PHP.CommentedOutCode.Found -- Kept for reference
164 // phpcs:disable
165 $apply_timezone_match = apply_filters( 'analytify_set_moment_timezone_to_match_wp', false );
166 $timezone = $apply_timezone_match ? WPANALYTIFY_Utils::timezone() : false;
167
168 if ( $timezone ) {
169 wp_enqueue_script( 'moment-timezone-with-data', plugins_url( 'assets/js/moment-timezone-with-data.min.js', __FILE__ ), array( 'jquery', 'moment' ), '0.5.34' );
170 }
171
172 wp_localize_script( 'moment', 'moment_analytify', array( 'timezone' => $timezone ) );
173 // phpcs:enable
174 */
175
176 wp_enqueue_script( 'pikaday-js', plugins_url( "assets/js/pikaday{$suffix}.js", $this->plugin_file ), array( 'moment' ), ANALYTIFY_VERSION, false ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter -- Script loaded in header intentionally
177
178 $analytify_dashboard_js_deps = array( 'pikaday-js' );
179 // jsPDF 4.2.1+ (patched HTML-in-new-window / output options); bundled under assets (see package.json).
180 if ( 'toplevel_page_analytify-dashboard' === $page ) {
181 wp_enqueue_script(
182 'analytify-jspdf',
183 plugins_url( 'assets/js/jspdf.umd.min.js', $this->plugin_file ),
184 array(),
185 '4.2.1',
186 false
187 ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter -- PDF export; must load before dashboard JS
188 wp_enqueue_script(
189 'analytify-html2canvas',
190 plugins_url( 'assets/js/html2canvas.min.js', $this->plugin_file ),
191 array(),
192 '1.4.1',
193 false
194 ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter -- PDF export; vendored (same as jsPDF)
195 wp_enqueue_script(
196 'analytify-xlsx',
197 plugins_url( 'assets/js/xlsx.mini.min.js', $this->plugin_file ),
198 array(),
199 '0.20.3',
200 false
201 ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter -- Excel export; vendored SheetJS
202 $analytify_dashboard_js_deps[] = 'analytify-jspdf';
203 $analytify_dashboard_js_deps[] = 'analytify-html2canvas';
204 $analytify_dashboard_js_deps[] = 'analytify-xlsx';
205 }
206
207 wp_enqueue_script( 'analytify-dashboard-js', plugins_url( "assets/js/wp-analytify-dashboard{$suffix}.js", $this->plugin_file ), $analytify_dashboard_js_deps, ANALYTIFY_VERSION, false ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter -- Script loaded in header intentionally
208
209 wp_localize_script(
210 'analytify-dashboard-js',
211 'analytify_dashboard',
212 array(
213 'i18n' => array(
214 'previousMonth' => __( 'Previous Month', 'wp-analytify' ),
215 'nextMonth' => __( 'Next Month', 'wp-analytify' ),
216 'months' => array(
217 __( 'January', 'wp-analytify' ),
218 __( 'February', 'wp-analytify' ),
219 __( 'March', 'wp-analytify' ),
220 __( 'April', 'wp-analytify' ),
221 __( 'May', 'wp-analytify' ),
222 __( 'June', 'wp-analytify' ),
223 __( 'July', 'wp-analytify' ),
224 __( 'August', 'wp-analytify' ),
225 __( 'September', 'wp-analytify' ),
226 __( 'October', 'wp-analytify' ),
227 __( 'November', 'wp-analytify' ),
228 __( 'December', 'wp-analytify' ),
229 ),
230 'weekdays' => array(
231 __( 'Sunday', 'wp-analytify' ),
232 __( 'Monday', 'wp-analytify' ),
233 __( 'Tuesday', 'wp-analytify' ),
234 __( 'Wednesday', 'wp-analytify' ),
235 __( 'Thursday', 'wp-analytify' ),
236 __( 'Friday', 'wp-analytify' ),
237 __( 'Saturday', 'wp-analytify' ),
238 ),
239 'weekdaysShort' => array(
240 __( 'Sun', 'wp-analytify' ),
241 __( 'Mon', 'wp-analytify' ),
242 __( 'Tue', 'wp-analytify' ),
243 __( 'Wed', 'wp-analytify' ),
244 __( 'Thu', 'wp-analytify' ),
245 __( 'Fri', 'wp-analytify' ),
246 __( 'Sat', 'wp-analytify' ),
247 ),
248 ),
249 )
250 );
251 }
252
253 // For dashboard only.
254 $analytify_chart_pages = array( 'toplevel_page_analytify-dashboard', 'analytify_page_analytify-woocommerce', 'analytify_page_edd-dashboard', 'analytify_page_analytify-pmpro', 'analytify_page_analytify-learndash', 'analytify_page_analytify-lifterlms', 'analytify_page_analytify-campaigns' );
255
256 if ( in_array( $page, $analytify_chart_pages, true ) ) {
257 // Enqueue the main JavaScript file.
258 wp_enqueue_script( 'echarts-js', plugins_url( 'assets/js/echarts.min.js', $this->plugin_file ), array(), ANALYTIFY_VERSION, true );
259 wp_enqueue_script( 'echarts-world-js', 'https://cdn.jsdelivr.net/npm/echarts-maps@1.1.0/world.min.js', array(), ANALYTIFY_VERSION, true );
260 }
261
262 // Main dashboard file that handles AJAX calls for core, also generates the template.
263 if ( 'toplevel_page_analytify-dashboard' === $page ) {
264 /**
265 * Tells the script to load the data via an ajax request on date change.
266 * Only load data via ajax if the Pro version is 5.0.0 or higher.
267 */
268 $load_via_ajax = true;
269 if ( defined( 'ANALYTIFY_PRO_VERSION' ) && 0 > version_compare( ANALYTIFY_PRO_VERSION, '5.0.0' ) ) {
270 $load_via_ajax = false;
271 }
272
273 wp_enqueue_style( 'analytify-dashboard-core', plugins_url( "assets/css/common-dashboard{$suffix}.css", $this->plugin_file ), array(), ANALYTIFY_VERSION );
274 // Code added by jawad for fixing.
275 $rest_url = esc_url_raw( get_rest_url() );
276 $api_url = $rest_url . 'wp-analytify/v1/get_report/';
277
278 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading URL parameters for display purposes
279 $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
280 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading URL parameters for display purposes
281 $show = isset( $_GET['show'] ) ? sanitize_text_field( wp_unslash( $_GET['show'] ) ) : '';
282 if ( class_exists( 'WP_Analytify_Pro_Base' ) && version_compare( ANALYTIFY_PRO_VERSION, '5.0.0' ) >= 0 && ! empty( $page ) && empty( $show ) && 'analytify-dashboard' === $page ) {
283 wp_enqueue_script( 'analytify-stats-core', plugins_url( "assets/js/stats-core{$suffix}.js", $this->plugin_file ), array( 'jquery', 'echarts-js', 'analytify-comp-chart' ), ANALYTIFY_VERSION, true );
284
285 } else {
286 wp_enqueue_script( 'analytify-stats-core', plugins_url( "assets/js/stats-core{$suffix}.js", $this->plugin_file ), array( 'jquery', 'echarts-js' ), ANALYTIFY_VERSION, true );
287 }
288 // Localize the GeoJSON file URL to use in JavaScript.
289 wp_localize_script(
290 'analytify-stats-core',
291 'geoJsonData',
292 array(
293 'geoJsonUrl' => plugins_url( 'assets/js/geo.json', $this->plugin_file ),
294 )
295 );
296
297 wp_localize_script(
298 'analytify-stats-core',
299 'analytify_stats_core',
300 array(
301 'url' => $api_url,
302 'delimiter' => WPANALYTIFY_Utils::get_delimiter(),
303 'ga_mode' => WPANALYTIFY_Utils::get_ga_mode(),
304 'ga4_report_url' => WP_ANALYTIFY_FUNCTIONS::get_ga_report_url( WPANALYTIFY_Utils::get_reporting_property() ),
305 'nonce' => wp_create_nonce( 'wp_rest' ),
306 'load_via_ajax' => $load_via_ajax,
307 'dist_js_url' => plugins_url( 'assets/js/', $this->plugin_file ),
308 'no_stats_message' => __( 'No activity during this period.', 'wp-analytify' ),
309 'error_message' => __( 'Something went wrong. Please try again.', 'wp-analytify' ),
310 )
311 );
312 }
313
314 // For Settings only.
315 if ( 'analytify_page_analytify-settings' === $page ) {
316 wp_enqueue_script( 'chosen-js', plugins_url( 'assets/js/chosen.jquery.min.js', $this->plugin_file ), array( 'jquery' ), ANALYTIFY_VERSION, false ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter -- Script loaded in header intentionally
317 wp_enqueue_script( 'analytify-settings-js', plugins_url( "assets/js/wp-analytify-settings{$suffix}.js", $this->plugin_file ), array( 'jquery-ui-tooltip', 'jquery', 'chosen-js' ), ANALYTIFY_VERSION, false ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter -- Script loaded in header intentionally
318 wp_localize_script(
319 'analytify-settings-js',
320 'analytify_settings',
321 array(
322 'is_hide_profile' => $this->analytify->settings->get_option( 'hide_profiles_list', 'wp-analytify-profile', 'off' ),
323 'is_authenticate' => (bool) get_option( 'pa_google_token' ),
324 'ga_mode' => WPANALYTIFY_Utils::get_ga_mode(),
325 'copy_failed_message' => __( 'Failed to copy to clipboard. Please copy manually.', 'wp-analytify' ),
326 'copy_success_message' => __( 'Copied!', 'wp-analytify' ),
327 'no_diagnostic_message' => __( 'No diagnostic information available to copy. Please load the diagnostic log first.', 'wp-analytify' ),
328 'import_no_file_message' => __( 'Please select a file to import.', 'wp-analytify' ),
329 'import_invalid_file_message' => __( 'Invalid file. Please select a valid Analytify export file (.json) exported from this plugin.', 'wp-analytify' ),
330 'import_failed_message' => __( 'Import failed. The file does not contain valid Analytify settings data. Please select the correct export file and try again.', 'wp-analytify' ),
331 'import_error_message' => __( 'Import failed. Please try again.', 'wp-analytify' ),
332 )
333 );
334
335 // Localize wpanalytify_data for settings script.
336 // This must be done here to ensure the data is available when the script loads.
337 $nonces_pre = array(
338 'check_license' => wp_create_nonce( 'check-license' ),
339 'activate_license' => wp_create_nonce( 'activate-license' ),
340 'clear_log' => wp_create_nonce( 'clear-log' ),
341 'fetch_log' => wp_create_nonce( 'fetch-log' ),
342 'import_export' => wp_create_nonce( 'import-export' ),
343 'analytify_rated' => wp_create_nonce( 'analytify-rated' ),
344 'reactivate_license' => wp_create_nonce( 'reactivate-license' ),
345 'single_post_stats' => wp_create_nonce( 'analytify-get-single-stats' ),
346 'send_single_post_email' => wp_create_nonce( 'analytify-single-post-email' ),
347 );
348
349 $nonces = apply_filters( 'wpanalytify_nonces', $nonces_pre );
350
351 $data_pre = array(
352 'this_url' => esc_html( addslashes( home_url() ) ),
353 'is_multisite' => esc_html( is_multisite() ? 'true' : 'false' ),
354 'nonces' => $nonces,
355 );
356
357 $data = apply_filters( 'wpanalytify_data', $data_pre );
358
359 // Backup the complete data before localization.
360 // This is needed because the Pro plugin's filter uses array_merge which replaces
361 // the entire nonces array instead of merging it, and other scripts may overwrite
362 // wpanalytify_data after this script loads.
363 //
364 // Security Note: Nonces are meant to be in JavaScript (this is how WordPress AJAX works).
365 // The security comes from server-side verification via check_ajax_referer() which:
366 // - Verifies the nonce is valid for the action
367 // - Checks the nonce is tied to the current user session
368 // - Validates the HTTP referer
369 // - Requires manage_options capability
370 // The backup variable is just a copy of the same nonce already exposed in JavaScript.
371 $settings_data_backup = $data;
372 $backup_json = wp_json_encode( $settings_data_backup );
373
374 wp_localize_script( 'analytify-settings-js', 'wpanalytify_data', $data );
375
376 // Add backup variable BEFORE the settings script loads.
377 // This backup is used as a fallback if wpanalytify_data gets overwritten.
378 wp_add_inline_script(
379 'analytify-settings-js',
380 'var wpanalytify_data_settings_backup = ' . $backup_json . ';',
381 'before'
382 );
383
384 // Add restore script that runs immediately and on jQuery ready.
385 // This ensures wpanalytify_data is restored if it gets overwritten by other scripts.
386 add_action(
387 'admin_footer',
388 function () use ( $backup_json ) {
389 $restore_script = '
390 (function() {
391 var backup = ' . $backup_json . ';
392 function restoreIfNeeded() {
393 if (typeof wpanalytify_data === "undefined" || !wpanalytify_data.nonces || !wpanalytify_data.nonces.fetch_log) {
394 wpanalytify_data = backup;
395 return true;
396 }
397 return false;
398 }
399 // Restore immediately when this script runs.
400 restoreIfNeeded();
401 // Also restore when DOM is ready (in case something overwrites it).
402 if (document.readyState === "loading") {
403 document.addEventListener("DOMContentLoaded", restoreIfNeeded);
404 }
405 // Also restore when jQuery is ready (in case something overwrites it).
406 if (typeof jQuery !== "undefined") {
407 jQuery(document).ready(restoreIfNeeded);
408 }
409 })();
410 ';
411
412 // Output as standalone script to ensure it runs after all other scripts.
413 echo '<script type="text/javascript">' . $restore_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JSON is already escaped, script is intentional
414 },
415 999
416 );
417 }
418
419 // Addons page script - Basic localization here, full localization with slugs happens in page-addons.php.
420 if ( 'analytify_page_analytify-addons' === $page ) {
421 // Core updates script is required for the install-plugin AJAX action.
422 wp_enqueue_script( 'updates' );
423 wp_enqueue_script( 'analytify-addons-js', plugins_url( "assets/js/wp-analytify-addons{$suffix}.js", $this->plugin_file ), array( 'jquery', 'updates' ), ANALYTIFY_VERSION, false ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter -- Script loaded in header intentionally.
424 // Basic localization - page-addons.php will override with full data including allowed_slugs.
425 // Nonces must live here: page-addons.php loads after admin_enqueue_scripts.
426 wp_localize_script(
427 'analytify-addons-js',
428 'analytify_addons',
429 array(
430 'ajaxurl' => admin_url( 'admin-ajax.php' ),
431 'nonce' => wp_create_nonce( 'addons' ),
432 'install_nonce' => wp_create_nonce( 'updates' ),
433 'activate_dashboard_nonce' => wp_create_nonce( 'activate-analytify-dashboard' ),
434 'allowed_slugs' => array(), // Will be populated by page-addons.php.
435 'i18n' => array(
436 'installing' => __( 'Installing...', 'wp-analytify' ),
437 'activating' => __( 'Activating...', 'wp-analytify' ),
438 'installed' => __( 'Installed & Activated', 'wp-analytify' ),
439 'get_addon' => __( 'Get this add-on', 'wp-analytify' ),
440 ),
441 )
442 );
443 }
444
445 // For Single Page/Post Stats.
446 if ( 'post.php' === $page || 'post-new.php' === $page ) {
447 wp_enqueue_script( 'chosen-js', plugins_url( 'assets/js/chosen.jquery.min.js', $this->plugin_file ), array( 'jquery' ), ANALYTIFY_VERSION, false ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter -- Script loaded in header intentionally
448 }
449
450 if ( 1 !== (int) get_option( 'show_tracking_pointer_1' ) ) {
451 wp_enqueue_script( 'wp-pointer' );
452 }
453
454 wp_localize_script(
455 'wp-analytify-script-js',
456 'wpanalytify_strings',
457 array(
458 'enter_license_key' => __( 'Please enter your license key.', 'wp-analytify' ),
459 'register_license_problem' => __( 'A problem occurred when trying to register the license, please try again.', 'wp-analytify' ),
460 'license_check_problem' => __( 'A problem occurred when trying to check the license, please try again.', 'wp-analytify' ),
461 'license_registered' => __( 'Your license has been activated. You will now receive automatic updates and access to email support.', 'wp-analytify' ),
462 )
463 );
464
465 $nonces = apply_filters(
466 'wpanalytify_nonces',
467 array(
468 'check_license' => wp_create_nonce( 'check-license' ),
469 'activate_license' => wp_create_nonce( 'activate-license' ),
470 'clear_log' => wp_create_nonce( 'clear-log' ),
471 'fetch_log' => wp_create_nonce( 'fetch-log' ),
472 'import_export' => wp_create_nonce( 'import-export' ),
473 'analytify_rated' => wp_create_nonce( 'analytify-rated' ),
474 'reactivate_license' => wp_create_nonce( 'reactivate-license' ),
475 'single_post_stats' => wp_create_nonce( 'analytify-get-single-stats' ),
476 'send_single_post_email' => wp_create_nonce( 'analytify-single-post-email' ),
477 )
478 );
479
480 $data = apply_filters(
481 'wpanalytify_data',
482 array(
483 'this_url' => esc_html( addslashes( home_url() ) ),
484 'is_multisite' => esc_html( is_multisite() ? 'true' : 'false' ),
485 'nonces' => $nonces,
486 )
487 );
488
489 // Fix: Only localize wpanalytify_data to wp-analytify-script-js if NOT on settings page.
490 // Reason: wp-analytify-script-js doesn't use wpanalytify_data, but analytify-settings-js does.
491 // If we localize to both scripts with the same variable name, the second one overwrites the first.
492 // By skipping localization to wp-analytify-script-js on the settings page, we prevent the overwrite.
493 if ( 'analytify_page_analytify-settings' !== $page ) {
494 wp_localize_script( 'wp-analytify-script-js', 'wpanalytify_data', $data );
495 }
496
497 // Also ensure ajaxurl is available for settings script if it's loaded.
498 if ( 'analytify_page_analytify-settings' === $page ) {
499 add_action(
500 'admin_footer',
501 function () {
502 // Ensure ajaxurl is available if not already set.
503 if ( ! wp_script_is( 'analytify-settings-js', 'done' ) ) {
504 wp_add_inline_script(
505 'analytify-settings-js',
506 'if (typeof ajaxurl === "undefined") { var ajaxurl = "' . esc_js( admin_url( 'admin-ajax.php' ) ) . '"; }',
507 'before'
508 );
509 }
510 },
511 20
512 );
513 }
514
515 // Print JS at footer.
516 }
517
518 /**
519 * Loading frontend scripts JS for the plugin.
520 *
521 * @since 8.0.0
522 * @version 9.1.0
523 * @return void
524 */
525 public function front_scripts() {
526 if ( 'on' === $this->analytify->settings->get_option( 'disable_front_end', 'wp-analytify-front', 'off' ) ) {
527 return;
528 }
529
530 $suffix = analytify_get_asset_suffix();
531
532 // Only enqueue if file exists to prevent 404 errors.
533 $front_js_path = plugin_dir_path( $this->plugin_file ) . 'assets/js/front-analytics.js';
534 if ( file_exists( $front_js_path ) ) {
535 wp_enqueue_script( 'wp-analytify-front-js', plugins_url( 'assets/js/front-analytics.js', $this->plugin_file ), array( 'jquery' ), ANALYTIFY_VERSION, false ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter -- Script loaded in header intentionally
536
537 wp_localize_script(
538 'wp-analytify-front-js',
539 'wp_analytify_front',
540 array(
541 'ajax_url' => admin_url( 'admin-ajax.php' ),
542 'nonce' => wp_create_nonce( 'wp_analytify_front_nonce' ),
543 )
544 );
545 }
546
547 // Enqueue scroll depth script if enabled.
548 if ( 'on' === $this->analytify->settings->get_option( 'depth_percentage', 'wp-analytify-advanced', 'off' ) ) {
549 wp_enqueue_script( 'wp-analytify-scrolldepth', plugins_url( "assets/js/scrolldepth{$suffix}.js", $this->plugin_file ), array( 'jquery' ), ANALYTIFY_VERSION, true );
550
551 $ga_mode = class_exists( 'WPANALYTIFY_Utils' ) && method_exists( 'WPANALYTIFY_Utils', 'get_ga_mode' ) ? WPANALYTIFY_Utils::get_ga_mode() : 'ga3';
552 $tracking_mode = defined( 'WP_ANALYTIFY_TRACKING_MODE' ) ? WP_ANALYTIFY_TRACKING_MODE : 'gtag';
553
554 // Only enqueue scroll depth for GA4 + gtag to avoid UA incompatibility.
555 if ( 'ga4' === $ga_mode && 'gtag' === $tracking_mode ) {
556 wp_enqueue_script( 'wp-analytify-scrolldepth', plugins_url( "assets/js/scrolldepth{$suffix}.js", $this->plugin_file ), array( 'jquery' ), ANALYTIFY_VERSION, true );
557 wp_localize_script(
558 'wp-analytify-scrolldepth',
559 'analytifyScroll',
560 array(
561 'tracking_mode' => $tracking_mode,
562 'ga4_tracking' => true,
563 'permalink' => get_permalink(),
564 )
565 );
566 }
567 }
568
569 // Enqueue video tracking script if enabled.
570 if ( 'on' === $this->analytify->settings->get_option( 'video_tracking', 'wp-analytify-advanced', 'off' ) ) {
571 $ga_mode = class_exists( 'WPANALYTIFY_Utils' ) && method_exists( 'WPANALYTIFY_Utils', 'get_ga_mode' ) ? WPANALYTIFY_Utils::get_ga_mode() : 'ga3';
572 $tracking_mode = defined( 'WP_ANALYTIFY_TRACKING_MODE' ) ? WP_ANALYTIFY_TRACKING_MODE : 'gtag';
573
574 // Only enqueue video tracking for GA4 + gtag to avoid UA incompatibility.
575 if ( 'ga4' === $ga_mode && 'gtag' === $tracking_mode ) {
576 $video_tracking_path = plugin_dir_path( $this->plugin_file ) . 'assets/js/video_tracking.js';
577 if ( file_exists( $video_tracking_path ) ) {
578 wp_enqueue_script( 'wp-analytify-video-tracking', plugins_url( "assets/js/video_tracking{$suffix}.js", $this->plugin_file ), array( 'jquery' ), ANALYTIFY_VERSION, true );
579 wp_localize_script(
580 'wp-analytify-video-tracking',
581 'analytifyVideo',
582 array(
583 'tracking_mode' => $tracking_mode,
584 'ga4_tracking' => true,
585 'permalink' => get_permalink(),
586 )
587 );
588 }
589 }
590 }
591
592 // Enqueue 404 / JS / AJAX error tracking when any Advanced option is on.
593 $track_404 = $this->analytify->settings->get_option( '404_page_track', 'wp-analytify-advanced', 'off' );
594 $track_js = $this->analytify->settings->get_option( 'javascript_error_track', 'wp-analytify-advanced', 'off' );
595 $track_ajax = $this->analytify->settings->get_option( 'ajax_error_track', 'wp-analytify-advanced', 'off' );
596
597 if ( 'on' === $track_404 || 'on' === $track_js || 'on' === $track_ajax ) {
598 $ga_mode = class_exists( 'WPANALYTIFY_Utils' ) && method_exists( 'WPANALYTIFY_Utils', 'get_ga_mode' ) ? WPANALYTIFY_Utils::get_ga_mode() : 'ga4';
599 $tracking_mode = defined( 'WP_ANALYTIFY_TRACKING_MODE' ) ? WP_ANALYTIFY_TRACKING_MODE : 'gtag';
600
601 // GA4 + gtag only (Pro reports use customEvent dims).
602 if ( 'ga4' === $ga_mode && 'gtag' === $tracking_mode ) {
603 $misc_path = plugin_dir_path( $this->plugin_file ) . 'assets/js/miscellaneous-tracking.js';
604 if ( file_exists( $misc_path ) ) {
605 $request_uri = isset( $_SERVER['REQUEST_URI'] )
606 ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) )
607 : '/';
608 $current_url = home_url( $request_uri );
609
610 wp_enqueue_script(
611 'wp-analytify-miscellaneous-tracking',
612 plugins_url( "assets/js/miscellaneous-tracking{$suffix}.js", $this->plugin_file ),
613 array( 'jquery' ),
614 ANALYTIFY_VERSION,
615 true
616 );
617 wp_localize_script(
618 'wp-analytify-miscellaneous-tracking',
619 'miscellaneous_tracking_options',
620 array(
621 'track_404_page' => array(
622 'should_track' => $track_404,
623 'is_404' => is_404(),
624 'current_url' => $current_url,
625 ),
626 'track_js_error' => $track_js,
627 'track_ajax_error' => $track_ajax,
628 )
629 );
630 }
631 }
632 }
633 }
634
635 /**
636 * Loading frontend styles CSS for the plugin.
637 *
638 * @return void
639 */
640 public function front_styles() {
641 if ( 'on' === $this->analytify->settings->get_option( 'disable_front_end', 'wp-analytify-front', 'off' ) ) {
642 return;
643 }
644
645 // Only enqueue if file exists to prevent 404 errors.
646 $front_css_path = plugin_dir_path( $this->plugin_file ) . 'assets/css/front-analytics.css';
647 if ( file_exists( $front_css_path ) ) {
648 wp_enqueue_style( 'wp-analytify-front-style', plugins_url( 'assets/css/front-analytics.css', $this->plugin_file ), array(), ANALYTIFY_VERSION );
649 }
650 }
651
652 /**
653 * Add dashboard inline styles
654 *
655 * @return void
656 */
657 public function add_dashboard_inline_styles() {
658 $custom_css = $this->analytify->settings->get_option( 'custom_css_code', 'wp-analytify-advanced' );
659 if ( ! empty( $custom_css ) ) {
660 echo '<style type="text/css">' . wp_kses( $custom_css, array( 'style' => array() ) ) . '</style>';
661 }
662 }
663
664 /**
665 * Add dashboard inline scripts
666 *
667 * @return void
668 */
669 public function add_dashboard_inline_scripts() {
670 $custom_js = $this->analytify->settings->get_option( 'custom_js_code', 'wp-analytify-advanced' );
671 if ( ! empty( $custom_js ) ) {
672 echo '<script type="text/javascript">' . wp_kses( $custom_js, array( 'script' => array() ) ) . '</script>';
673 }
674
675 // Move Analytify "refresh stats" notice below the Dashboard H1 (match native placement).
676 $screen = get_current_screen();
677 if ( $screen && 'dashboard' === $screen->id ) {
678 ?>
679 <script type="text/javascript">
680 (function($){
681 $(function(){
682 var $wrap = $('.wrap').first();
683 var $title = $wrap.find('h1').first();
684 var $notice = $('.wp-analytify-notification.wp-analytify-refresh-stats').first();
685
686 if ($wrap.length && $title.length && $notice.length) {
687 $notice.insertAfter($title);
688 }
689 });
690 })(jQuery);
691 </script>
692 <?php
693 }
694 }
695 }
696