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 / classes / analytify-utils / analytify-utils-ga.php

analytify-utils-ga.php in Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) trunk, at classes/analytify-utils/analytify-utils-ga.php

517 lines 13.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php // phpcs:ignore Squiz.Commenting.FileComment.Missing -- File doc comment exists
2 /**
3 * Analytify Utils GA Trait
4 *
5 * Contains Google Analytics (GA) utility functions for the Analytify plugin.
6 * This trait separates GA utility logic from the main utils class,
7 * providing helper functions for GA4 streams, properties, and analytics data.
8 *
9 * @package WP_Analytify
10 * @subpackage Utils
11 * @since 8.0.0
12 */
13
14 trait Analytify_Utils_GA {
15
16 /**
17 * Fetch GA4 streams data.
18 *
19 * Retrieves and formats GA4 measurement streams data for the
20 * configured profile, handling both new and legacy data structures.
21 *
22 * @since 7.0.5
23 * @version 7.0.5
24 * @return array<string, mixed> Array of measurement IDs mapped to stream names.
25 */
26 public static function fetch_ga4_streams() {
27 $_analytify_profile = get_option( 'wp-analytify-profile' );
28 $post_profile = isset( $_analytify_profile['profile_for_posts'] ) ? $_analytify_profile['profile_for_posts'] : '';
29 $post_profile = explode( ':', $post_profile )[1] ?? false;
30 $streams = array();
31
32 if ( $post_profile ) {
33 $properties = get_option( 'analytify-ga4-streams' );
34 $streams_data = $properties[ $post_profile ] ?? array();
35 $using_old_structure = false;
36
37 foreach ( $streams_data as $stream ) {
38 if ( ! is_array( $stream ) ) {
39 $using_old_structure = true;
40 break;
41 }
42 $streams[ $stream['measurement_id'] ] = $stream['stream_name'];
43 }
44
45 if ( $using_old_structure && isset( $streams_data['measurement_id'] ) ) {
46 $streams[ $streams_data['measurement_id'] ] = $streams_data['stream_name'];
47 }
48 }
49 return $streams;
50 }
51
52 /**
53 * Get current GA mode.
54 *
55 * Returns the current Google Analytics mode being used.
56 * Always returns 'ga4' as Universal Analytics (UA) is deprecated and no longer supported.
57 *
58 * @since 7.0.5
59 * @version 7.0.5
60 * @param string $property_for Property context for mode determination (reserved for future use).
61 * @return string GA mode ('ga4').
62 */
63 public static function get_ga_mode( $property_for = 'profile_for_dashboard' ) {
64 unset( $property_for ); // Reserved for future use.
65 // Universal Analytics (UA) is deprecated and no longer supported by Google.
66 // Only GA4 is supported going forward.
67 return 'ga4';
68 }
69
70 /**
71 * Get reporting property ID.
72 *
73 * Retrieves the property ID used for reporting, extracting it
74 * from the profile configuration and handling GA4 format.
75 *
76 * @since 7.0.5
77 * @version 7.0.5
78 * @return string Property ID for reporting.
79 */
80 public static function get_reporting_property() {
81 $property_id = $GLOBALS['WP_ANALYTIFY']->settings->get_option( 'profile_for_dashboard', 'wp-analytify-profile' );
82 if ( false !== strpos( $property_id, 'ga4:' ) ) {
83 $property_id = explode( ':', $property_id )[1];
84 }
85 return $property_id;
86 }
87
88 /**
89 * Generate dashboard subtitle section.
90 *
91 * Creates HTML for displaying property information in the dashboard
92 * subtitle, including stream name and URL with proper formatting.
93 *
94 * @since 7.0.5
95 * @version 7.0.5
96 * @return void
97 */
98 public static function dashboard_subtitle_section() {
99 $name = WP_ANALYTIFY_FUNCTIONS::ga_reporting_property_info( 'stream_name' );
100 $url = WP_ANALYTIFY_FUNCTIONS::ga_reporting_property_info( 'url' );
101
102 if ( $name && $url ) {
103 ?>
104 <span class="analytify_stats_of">
105 <a href="<?php echo esc_url( $url ); ?>" target="_blank">
106 <?php echo esc_html( $url ); ?>
107 </a>
108 (<?php echo esc_html( $name ); ?>)
109 </span>
110 <?php
111 }
112 }
113
114 /**
115 * Get property URL for analytics.
116 *
117 * Retrieves the website URL associated with the current property,
118 * handling both GA4 and Universal Analytics formats.
119 *
120 * @version 7.0.5
121 * @return string Property website URL.
122 */
123 public static function get_property_url() {
124 return ( 'ga4' === self::get_ga_mode() )
125 ? WP_ANALYTIFY_FUNCTIONS::ga_reporting_property_info( 'url' )
126 : WP_ANALYTIFY_FUNCTIONS::search_profile_info( self::get_reporting_property(), 'websiteUrl' );
127 }
128
129 /**
130 * Process GA4 social statistics.
131 *
132 * Formats raw social statistics data from GA4 into a structured
133 * format for display, mapping session sources to session counts.
134 *
135 * @version 7.0.5
136 * @param array<string, mixed> $social_stats_raw Raw social statistics from GA4.
137 * @return array<string, mixed> Formatted social statistics.
138 */
139 public static function ga4_social_stats( $social_stats_raw ) {
140 $social_network = array(
141 array(
142 'sessionSource' => 'facebook',
143 'sessions' => 0,
144 ),
145 array(
146 'sessionSource' => 'instagram',
147 'sessions' => 0,
148 ),
149 array(
150 'sessionSource' => 'wordpress',
151 'sessions' => 0,
152 ),
153 array(
154 'sessionSource' => 'linkedin',
155 'sessions' => 0,
156 ),
157 array(
158 'sessionSource' => 'youtube',
159 'sessions' => 0,
160 ),
161 array(
162 'sessionSource' => 'twitter',
163 'sessions' => 0,
164 ),
165 array(
166 'sessionSource' => 'pinterest',
167 'sessions' => 0,
168 ),
169 array(
170 'sessionSource' => 'yelp',
171 'sessions' => 0,
172 ),
173 array(
174 'sessionSource' => 'tumblr',
175 'sessions' => 0,
176 ),
177 array(
178 'sessionSource' => 'quora',
179 'sessions' => 0,
180 ),
181 array(
182 'sessionSource' => 'reddit',
183 'sessions' => 0,
184 ),
185 );
186
187 foreach ( $social_stats_raw as $stat ) {
188 foreach ( $social_network as &$item ) {
189 if ( false !== strpos( $stat['sessionSource'], $item['sessionSource'] ) ) {
190 $item['sessions'] += $stat['sessions'];
191 break;
192 }
193 }
194 }
195
196 $social_network = array_filter(
197 $social_network,
198 function ( $item ) {
199 return isset( $item['sessions'] ) && is_numeric( $item['sessions'] ) && (int) $item['sessions'] > 0;
200 }
201 );
202
203 usort(
204 $social_network,
205 function ( $a, $b ) {
206 return $b['sessions'] - $a['sessions'];
207 }
208 );
209
210 return $social_network;
211 }
212
213 /**
214 * Dashboard GA4 custom dimensions created on property connect.
215 *
216 * @since 9.1.0
217 * @version 9.1.0
218 *
219 * @return array<int, array{parameter_name: string, display_name: string, scope: string}>
220 */
221 public static function required_dashboard_dimensions(): array {
222 return array(
223 array(
224 'parameter_name' => 'page_title',
225 'display_name' => 'Page Title',
226 'scope' => 'EVENT',
227 ),
228 array(
229 'parameter_name' => 'page_path',
230 'display_name' => 'Page Path',
231 'scope' => 'EVENT',
232 ),
233 array(
234 'parameter_name' => 'user_type',
235 'display_name' => 'User Type',
236 'scope' => 'USER',
237 ),
238 array(
239 'parameter_name' => 'device_category',
240 'display_name' => 'Device Category',
241 'scope' => 'EVENT',
242 ),
243 array(
244 'parameter_name' => 'country',
245 'display_name' => 'Country',
246 'scope' => 'EVENT',
247 ),
248 array(
249 'parameter_name' => 'source',
250 'display_name' => 'Source',
251 'scope' => 'EVENT',
252 ),
253 array(
254 'parameter_name' => 'medium',
255 'display_name' => 'Medium',
256 'scope' => 'EVENT',
257 ),
258 array(
259 'parameter_name' => 'campaign',
260 'display_name' => 'Campaign',
261 'scope' => 'EVENT',
262 ),
263 array(
264 'parameter_name' => 'landing_page',
265 'display_name' => 'Landing Page',
266 'scope' => 'EVENT',
267 ),
268 array(
269 'parameter_name' => 'exit_page',
270 'display_name' => 'Exit Page',
271 'scope' => 'EVENT',
272 ),
273 );
274 }
275
276 /**
277 * Get required dimensions for GA4.
278 *
279 * Register these in GA4 Admin custom definitions (Event scope) so reports work.
280 * Enhanced Tel Link Analytics uses wpa_category, wpa_link_action, wpa_link_label,
281 * wpa_device_category, wpa_click_hour, wpa_click_day, wpa_traffic_source, plus the
282 * standard dimension country (not listed here).
283 *
284 * @since 1.0.0
285 * @version 9.1.0
286 *
287 * @return array
288 */
289 public static function required_dimensions(): array {
290 $dimensions = array(
291 array(
292 'parameter_name' => 'wpa_author',
293 'display_name' => 'WPA Author',
294 'scope' => 1,
295 ),
296 array(
297 'parameter_name' => 'wpa_post_type',
298 'display_name' => 'WPA Post Type',
299 'scope' => 1,
300 ),
301 array(
302 'parameter_name' => 'wpa_published_at',
303 'display_name' => 'WPA Published At',
304 'scope' => 1,
305 ),
306 array(
307 'parameter_name' => 'wpa_category',
308 'display_name' => 'WPA Category',
309 'scope' => 1,
310 ),
311 array(
312 'parameter_name' => 'wpa_tags',
313 'display_name' => 'WPA Tags',
314 'scope' => 1,
315 ),
316 array(
317 'parameter_name' => 'wpa_user_id',
318 'display_name' => 'WPA WP User ID',
319 'scope' => 1,
320 ),
321 array(
322 'parameter_name' => 'wpa_logged_in',
323 'display_name' => 'WPA Logged In',
324 'scope' => 1,
325 ),
326 array(
327 'parameter_name' => 'wpa_seo_score',
328 'display_name' => 'WPA SEO Score',
329 'scope' => 1,
330 ),
331 array(
332 'parameter_name' => 'wpa_focus_keyword',
333 'display_name' => 'WPA Focus Keyword',
334 'scope' => 1,
335 ),
336 array(
337 'parameter_name' => 'wpa_link_action',
338 'display_name' => 'WPA Link Action',
339 'scope' => 1,
340 ),
341 array(
342 'parameter_name' => 'wpa_label',
343 'display_name' => 'WPA Label',
344 'scope' => 1,
345 ),
346 array(
347 'parameter_name' => 'wpa_affiliate_label',
348 'display_name' => 'WPA Affiliate Label',
349 'scope' => 1,
350 ),
351 array(
352 'parameter_name' => 'wpa_email_address',
353 'display_name' => 'WPA Email Address',
354 'scope' => 1,
355 ),
356 array(
357 'parameter_name' => 'wpa_form_id',
358 'display_name' => 'WPA Form Id',
359 'scope' => 1,
360 ),
361 array(
362 'parameter_name' => 'wpa_is_affiliate_link',
363 'display_name' => 'WPA Is Affiliate Link',
364 'scope' => 1,
365 ),
366 array(
367 'parameter_name' => 'wpa_link_label',
368 'display_name' => 'WPA Link Label',
369 'scope' => 1,
370 ),
371 array(
372 'parameter_name' => 'wpa_link_text',
373 'display_name' => 'WPA Link Text',
374 'scope' => 1,
375 ),
376 array(
377 'parameter_name' => 'wpa_outbound',
378 'display_name' => 'WPA Outbound',
379 'scope' => 1,
380 ),
381 array(
382 'parameter_name' => 'wpa_tel_number',
383 'display_name' => 'WPA Tel Number',
384 'scope' => 1,
385 ),
386 array(
387 'parameter_name' => 'wpa_scroll_depth',
388 'display_name' => 'WPA Scroll Depth',
389 'scope' => 1,
390 ),
391 array(
392 'parameter_name' => 'wpa_percentage',
393 'display_name' => 'WPA Percentage',
394 'scope' => 1,
395 ),
396 array(
397 'parameter_name' => 'wpa_post_category',
398 'display_name' => 'WPA Post Category',
399 'scope' => 1,
400 ),
401 array(
402 'parameter_name' => 'wpa_video_provider',
403 'display_name' => 'WPA Video Provider',
404 'scope' => 1,
405 ),
406 array(
407 'parameter_name' => 'wpa_video_action',
408 'display_name' => 'WPA Video Action',
409 'scope' => 1,
410 ),
411 array(
412 'parameter_name' => 'wpa_video_duration',
413 'display_name' => 'WPA Video Duration',
414 'scope' => 1,
415 ),
416 array(
417 'parameter_name' => 'wpa_video_title',
418 'display_name' => 'WPA Video Title',
419 'scope' => 1,
420 ),
421 array(
422 'parameter_name' => 'wpa_archive_type',
423 'display_name' => 'WPA Archive Type',
424 'scope' => 1,
425 ),
426 array(
427 'parameter_name' => 'wpa_llms_post_type',
428 'display_name' => 'WPA LLMS Post Type',
429 'scope' => 1,
430 ),
431 array(
432 'parameter_name' => 'wpa_llms_instructor',
433 'display_name' => 'WPA LLMS Instructor',
434 'scope' => 1,
435 ),
436 array(
437 'parameter_name' => 'wpa_device_category',
438 'display_name' => 'WPA Device Category',
439 'scope' => 1,
440 ),
441 array(
442 'parameter_name' => 'wpa_click_hour',
443 'display_name' => 'WPA Click Hour',
444 'scope' => 1,
445 ),
446 array(
447 'parameter_name' => 'wpa_click_day',
448 'display_name' => 'WPA Click Day',
449 'scope' => 1,
450 ),
451 array(
452 'parameter_name' => 'wpa_traffic_source',
453 'display_name' => 'WPA Traffic Source',
454 'scope' => 1,
455 ),
456 array(
457 'parameter_name' => 'wpa_country_code',
458 'display_name' => 'WPA Country Code',
459 'scope' => 1,
460 ),
461
462 );
463
464 $result = array();
465 foreach ( $dimensions as $dimension ) {
466 $result[ $dimension['parameter_name'] ] = $dimension;
467 }
468 return $result;
469 }
470
471 /**
472 * Get all stats link.
473 *
474 * Builds and returns a complete GA4 report link.
475 *
476 * @version 7.0.5
477 * @param string $report_url GA report URL identifier.
478 * @param string $report Report type key.
479 * @param string|bool $date_range Optional. Date range parameter (currently unused).
480 * @return string GA4 report link.
481 */
482 public static function get_all_stats_link( $report_url, $report, $date_range = false ) {
483 unset( $date_range ); // Not used currently, kept for future use.
484
485 $report_link = 'https://analytics.google.com/analytics/web/#/' . $report_url . '/reports/explorer/?';
486 $link = '';
487
488 switch ( $report ) {
489 case 'top_pages':
490 $link = 'top_pages';
491 break;
492 case 'top_countries':
493 $link = 'top_countries';
494 break;
495 case 'top_cities':
496 $link = 'top_cities';
497 break;
498 case 'referer':
499 $link = 'referer';
500 break;
501 case 'top_products':
502 $link = 'top_products';
503 break;
504 case 'source_medium':
505 $link = $report_link . 'params=_u..nav%3Dmaui${date_parameter}&r=lifecycle-traffic-acquisition-v2&ruid=lifecycle-traffic-acquisition-v2,3078873331,acquisition';
506 break;
507 case 'top_countries_sales':
508 $link = $report_link . 'params=_u..nav%3Dmaui${date_parameter}%26_r.explorerCard..selmet%3D%5B%22activeUsers%22%5D%26_r.explorerCard..seldim%3D%5B%22country%22%5D&r=user-demographics-detail&ruid=user-demographics-detail,user,demographics&collectionId=user';
509 break;
510 default:
511 $link = '';
512 break;
513 }
514 return $link;
515 }
516 }
517