PluginProbe ʕ •ᴥ•ʔ
ShareThis Dashboard for Google Analytics / 3.3.0
ShareThis Dashboard for Google Analytics v3.3.0
3.3.2 trunk 1.0.7 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1 2.1.2 2.1.3 2.1.4 2.1.5 2.2.5 2.3.5 2.3.6 2.3.7 2.3.8 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 3.0.0 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.3.0 3.3.1
googleanalytics / class / class-ga-stats.php
googleanalytics / class Last commit date
controller 2 months ago core 1 year ago class-ga-admin.php 2 months ago class-ga-autoloader.php 4 years ago class-ga-frontend.php 2 months ago class-ga-helper.php 2 months ago class-ga-hook.php 4 years ago class-ga-notice.php 2 months ago class-ga-oauth.php 2 months ago class-ga-sharethis.php 4 years ago class-ga-stats.php 2 months ago class-ga-template.php 4 years ago
class-ga-stats.php
1144 lines
1 <?php
2 /**
3 * Google Analytics hook class.
4 *
5 * @package GoogleAnalytics
6 */
7
8 /**
9 * Ga_Stats class
10 *
11 * Preparing request and parsing response from Google Analytics Reporting Api
12 *
13 * @author wle@adips.com
14 * @version 1.0
15 */
16 class Ga_Stats {
17
18 /**
19 * Profile object.
20 *
21 * @var array Profile.
22 */
23 private $profile = array();
24
25 /**
26 * Primary class constructor.
27 *
28 * @access public
29 * @since 7.0.0
30 */
31 public function __construct() {
32 }
33
34 /**
35 * Run a GA4 report over REST using the broker-backed access token.
36 *
37 * @param string $property_id GA4 property name or ID. Accepts "properties/123" or "123".
38 * @param array $body RunReport body.
39 * @return array
40 */
41 public function ga4_run_report_rest( $property_id, array $body ) {
42 $ga_admin = new Ga_Admin();
43 $client = $ga_admin->getGa4Client();
44 $token = $client->getAccessToken();
45
46 if ( ! is_array( $token ) || empty( $token['access_token'] ) ) {
47 return array();
48 }
49
50 $access_token = sanitize_text_field( (string) $token['access_token'] );
51
52 $property_path = (string) $property_id;
53 if ( 0 !== strpos( $property_path, 'properties/' ) ) {
54 $property_path = 'properties/' . $property_path;
55 }
56
57 $url = sprintf(
58 'https://analyticsdata.googleapis.com/v1beta/%s:runReport',
59 $property_path
60 );
61
62 $response = wp_remote_post(
63 $url,
64 array(
65 'timeout' => 20,
66 'headers' => array(
67 'Authorization' => 'Bearer ' . $access_token,
68 'Content-Type' => 'application/json',
69 ),
70 'body' => wp_json_encode( $body, JSON_UNESCAPED_SLASHES ),
71 )
72 );
73
74 if ( is_wp_error( $response ) ) {
75 return array();
76 }
77
78 $status_code = wp_remote_retrieve_response_code( $response );
79 $response_body = wp_remote_retrieve_body( $response );
80 $data = json_decode( $response_body, true );
81
82 if ( 200 !== $status_code || ! is_array( $data ) ) {
83 return array();
84 }
85
86 return $data;
87 }
88
89 /**
90 * Preparing query to get Analytics data
91 *
92 * @param string $query Query type.
93 * @param int $id_view The Analytics view ID from which to retrieve data.
94 * @param string $date_range The start date for the query in the format YYYY-MM-DD or '7daysAgo'.
95 * @param string $metric A metric expression.
96 * @param bool $old Use old query style.
97 *
98 * @return array Request query
99 */
100 public static function get_query( $query, $id_view, $date_range = null, $metric = null, $old = false ) {
101 if ( 'main_chart' === $query ) {
102 return $old ? self::main_chart_query_old( $id_view, $date_range, $metric ) : self::main_chart_query(
103 $id_view,
104 $date_range,
105 $metric
106 );
107 } elseif ( 'gender' === $query ) {
108 return self::gender_chart_query( $id_view, $date_range, $metric );
109 } elseif ( 'device' === $query ) {
110 return self::device_chart_query( $id_view, $date_range, $metric );
111 } elseif ( 'age' === $query ) {
112 return self::age_chart_query( $id_view, $date_range, $metric );
113 } elseif ( 'boxes' === $query ) {
114 return self::boxes_query( $id_view );
115 } elseif ( 'dashboard_boxes' === $query ) {
116 return $old ? self::dashboard_boxes_query_old( $id_view, $date_range ) :
117 self::dashboard_boxes_query( $id_view, $date_range );
118 } elseif ( 'sources' === $query ) {
119 return self::sources_query( $id_view, $date_range );
120 } else {
121 return array();
122 }
123 }
124
125 /**
126 * Preparing query for top traffic sources table
127 *
128 * @param int $id_view The Analytics view ID from which to retrieve data.
129 * @param array $date_ranges An array representing the date ranges that will be passed to chart query.
130 *
131 * @return array Sources query
132 */
133 public static function sources_query( $id_view, $date_ranges ) {
134 $reports_requests = array();
135
136 $ts = filter_input( INPUT_GET, 'ts', FILTER_UNSAFE_RAW );
137
138 if ( false === empty( $ts ) ) {
139 $reports_requests[] = array(
140 'viewId' => $id_view,
141 'dateRanges' => $date_ranges,
142 'metrics' => self::set_metrics( array( 'ga:pageviews' ) ),
143 'includeEmptyRows' => true,
144 'pageSize' => 10,
145 'dimensions' => self::set_dimensions( 'ga:sourceMedium' ),
146 'orderBys' => self::set_order_bys( 'ga:pageviews', 'DESCENDING' ),
147 );
148 } else {
149 $reports_requests[] = array(
150 'viewId' => $id_view,
151 'dateRanges' => $date_ranges,
152 'metrics' => self::set_metrics(
153 array(
154 'ga:pageviews',
155 'ga:uniquePageviews',
156 'ga:timeOnPage',
157 'ga:bounces',
158 'ga:entrances',
159 'ga:exits',
160 )
161 ),
162 'includeEmptyRows' => true,
163 'pageSize' => 10,
164 'dimensions' => self::set_dimensions( 'ga:pagePath' ),
165 'orderBys' => self::set_order_bys( 'ga:pageviews', 'DESCENDING' ),
166 );
167 }
168
169 $query = array(
170 'reportRequests' => $reports_requests,
171 );
172
173 return $query;
174 }
175
176 /**
177 * Preparing query for dashboard boxes
178 *
179 * @param int $id_view The Analytics view ID from which to retrieve data.
180 * @param array $date_ranges An array representing the date ranges that will be passed to chart query.
181 *
182 * @return array Dashboard boxes query
183 */
184 public static function dashboard_boxes_query( $id_view, $date_ranges ) {
185 $reports_requests = array();
186
187 $ts = filter_input( INPUT_GET, 'ts', FILTER_SANITIZE_STRING );
188
189 if ( false === empty( $ts ) ) {
190 $reports_requests[] = array(
191 'viewId' => $id_view,
192 'dateRanges' => $date_ranges,
193 'metrics' => self::set_metrics( array( 'ga:pageviews' ) ),
194 'includeEmptyRows' => true,
195 'pageSize' => 10,
196 'dimensions' => self::set_dimensions( 'ga:sourceMedium' ),
197 'orderBys' => self::set_order_bys( 'ga:pageviews', 'DESCENDING' ),
198 );
199 } else {
200 $reports_requests[] = array(
201 'viewId' => $id_view,
202 'dateRanges' => $date_ranges,
203 'metrics' => self::set_metrics(
204 array(
205 'ga:pageviews',
206 'ga:uniquePageviews',
207 'ga:timeOnPage',
208 'ga:bounces',
209 'ga:entrances',
210 'ga:exits',
211 )
212 ),
213 'includeEmptyRows' => true,
214 'pageSize' => 10,
215 'dimensions' => self::set_dimensions( 'ga:pagePath' ),
216 'orderBys' => self::set_order_bys( 'ga:pageviews', 'DESCENDING' ),
217 );
218 }
219 $query = array(
220 'reportRequests' => $reports_requests,
221 );
222
223 return $query;
224 }
225
226 /**
227 * Preparing query for dashboard boxes
228 *
229 * @param int $id_view The Analytics view ID from which to retrieve data.
230 * @param string $date_range The start date for the query in the format YYYY-MM-DD or '7daysAgo'.
231 *
232 * @return array Dashboard boxes query
233 * @deprecated
234 */
235 public static function dashboard_boxes_query_old( $id_view, $date_range ) {
236 $reports_requests = array();
237
238 $th = filter_input( INPUT_GET, 'th', FILTER_SANITIZE_STRING );
239 $ts = filter_input( INPUT_GET, 'ts', FILTER_SANITIZE_STRING );
240
241 $days_ago = false === empty( $th ) ? '30daysAgo' : '7daysAgo';
242
243 if ( false === empty( $ts ) ) {
244 $reports_requests[] = array(
245 'viewId' => $id_view,
246 'dateRanges' => self::set_date_ranges( $days_ago, 'yesterday' ),
247 'metrics' => self::set_metrics( array( 'ga:pageviews' ) ),
248 'includeEmptyRows' => true,
249 'pageSize' => 10,
250 'dimensions' => self::set_dimensions( 'ga:sourceMedium' ),
251 'orderBys' => self::set_order_bys( 'ga:pageviews', 'DESCENDING' ),
252 );
253 } else {
254 $reports_requests[] = array(
255 'viewId' => $id_view,
256 'dateRanges' => self::set_date_ranges( $days_ago, 'yesterday' ),
257 'metrics' => self::set_metrics(
258 array(
259 'ga:pageviews',
260 'ga:uniquePageviews',
261 'ga:timeOnPage',
262 'ga:bounces',
263 'ga:entrances',
264 'ga:exits',
265 )
266 ),
267 'includeEmptyRows' => true,
268 'pageSize' => 10,
269 'dimensions' => self::set_dimensions( 'ga:pagePath' ),
270 'orderBys' => self::set_order_bys( 'ga:pageviews', 'DESCENDING' ),
271 );
272 }
273 $query = array(
274 'reportRequests' => $reports_requests,
275 );
276
277 return $query;
278 }
279
280 /**
281 * Preparing query for stats boxes
282 *
283 * @param int $id_view The Analytics view ID from which to retrieve data.
284 *
285 * @return array Boxes query
286 */
287 public static function boxes_query( $id_view ) {
288 $th = filter_input( INPUT_GET, 'th', FILTER_UNSAFE_RAW );
289
290 $range = false === empty( $th ) ? '30daysAgo' : '7daysAgo';
291 $range_s_prev = false === empty( $th ) ? '60daysAgo' : '14daysAgo';
292 $range_e_prev = false === empty( $th ) ? '31daysAgo' : '8daysAgo';
293 $reports_requests = array();
294 $reports_requests[] = array(
295 'viewId' => $id_view,
296 'dateRanges' => self::set_date_ranges( $range, 'yesterday', $range_s_prev, $range_e_prev ),
297 'metrics' => self::set_metrics(
298 array(
299 'ga:users',
300 'ga:pageviews',
301 'ga:pageviewsPerSession',
302 'ga:BounceRate',
303 )
304 ),
305 'includeEmptyRows' => true,
306 'dimensions' => self::set_dimensions( 'ga:date' ),
307 );
308 $query = array(
309 'reportRequests' => $reports_requests,
310 );
311
312 return $query;
313 }
314
315 /**
316 * Preparing query for chart
317 *
318 * @param int $id_view The Analytics view ID from which to retrieve data.
319 * @param array $date_ranges An array representing the date ranges that will be passed to chart query.
320 * @param string $metric A metric expression.
321 *
322 * @return array Chart query
323 */
324 public static function main_chart_query( $id_view, $date_ranges = null, $metric = null ) {
325 if ( true === empty( $metric ) ) {
326 $metric = 'ga:pageviews';
327 } else {
328 $metric = 'ga:' . $metric;
329 }
330
331 $reports_requests = array();
332 $reports_requests[] = array(
333 'viewId' => $id_view,
334 'dateRanges' => $date_ranges,
335 'metrics' => self::set_metrics( $metric ),
336 'includeEmptyRows' => true,
337 'dimensions' => self::set_dimensions( 'ga:date' ),
338 );
339 $query = array(
340 'reportRequests' => $reports_requests,
341 );
342
343 return $query;
344 }
345
346 /**
347 * Preparing query for chart
348 *
349 * @param int $id_view The Analytics view ID from which to retrieve data.
350 * @param string $date_range The start date for the query in the format YYYY-MM-DD or '7daysAgo'.
351 * @param string $metric A metric expression.
352 *
353 * @return array Chart query
354 * @deprecated
355 */
356 public static function main_chart_query_old( $id_view, $date_range = null, $metric = null ) {
357 if ( empty( $date_range ) ) {
358 $date_ranges = self::set_date_ranges( '7daysAgo', 'yesterday', '14daysAgo', '8daysAgo' );
359 } else {
360 $date_ranges = self::set_date_ranges( $date_range, 'yesterday', '14daysAgo', '8daysAgo' );
361 }
362
363 if ( empty( $metric ) ) {
364 $metric = 'ga:pageviews';
365 } else {
366 $metric = 'ga:' . $metric;
367 }
368
369 $reports_requests = array();
370 $reports_requests[] = array(
371 'viewId' => $id_view,
372 'dateRanges' => $date_ranges,
373 'metrics' => self::set_metrics( $metric ),
374 'includeEmptyRows' => true,
375 'dimensions' => self::set_dimensions( 'ga:date' ),
376 );
377 $query = array(
378 'reportRequests' => $reports_requests,
379 );
380
381 return $query;
382 }
383
384 /**
385 * Preparing query for gender chart
386 *
387 * @param int $id_view The Analytics view ID from which to retrieve data.
388 * @param array $date_ranges An array representing the date ranges that will be passed to chart query.
389 * @param string $metric A metric expression.
390 *
391 * @return array Chart query
392 */
393 public static function gender_chart_query( $id_view, $date_ranges = null, $metric = null ) {
394 if ( true === empty( $date_ranges ) ) {
395 $date_ranges = self::set_date_ranges( '7daysAgo', 'yesterday', '14daysAgo', '8daysAgo' );
396 }
397
398 $reports_requests = array();
399 $reports_requests[] = array(
400 'viewId' => $id_view,
401 'dateRanges' => $date_ranges,
402 'metrics' => self::set_metrics( 'ga:sessions' ),
403 'includeEmptyRows' => true,
404 'dimensions' => self::set_dimensions( 'ga:userGender' ),
405 );
406 $query = array(
407 'reportRequests' => $reports_requests,
408 );
409
410 return $query;
411 }
412
413 /**
414 * Preparing query for device chart.
415 *
416 * @param int $id_view The Analytics view ID from which to retrieve data.
417 * @param array $date_ranges An array representing the date ranges that will be passed to chart query.
418 * @param string $metric A metric expression.
419 *
420 * @return array Chart query
421 * @since 2.5.2
422 */
423 public static function device_chart_query( $id_view, $date_ranges = null, $metric = null ) {
424 return array(
425 'reportRequests' => array(
426 array(
427 'viewId' => $id_view,
428 'dateRanges' => $date_ranges,
429 'metrics' => self::set_metrics( 'ga:sessions' ),
430 'includeEmptyRows' => true,
431 'dimensions' => self::set_dimensions( 'ga:deviceCategory' ),
432 ),
433 ),
434 );
435 }
436
437 /**
438 * Preparing query for age chart
439 *
440 * @param int $id_view The Analytics view ID from which to retrieve data.
441 * @param array $date_ranges An array representing the date ranges that will be passed to chart query.
442 * @param string $metric A metric expression.
443 *
444 * @return array Chart query
445 */
446 public static function age_chart_query( $id_view, $date_ranges = null, $metric = null ) {
447 if ( true === empty( $date_ranges ) ) {
448 $date_ranges = self::set_date_ranges( '7daysAgo', 'yesterday', '14daysAgo', '8daysAgo' );
449 }
450
451 $reports_requests = array();
452 $reports_requests[] = array(
453 'viewId' => $id_view,
454 'dateRanges' => $date_ranges,
455 'metrics' => self::set_metrics( 'ga:sessions' ),
456 'includeEmptyRows' => true,
457 'dimensions' => self::set_dimensions( 'ga:userAgeBracket' ),
458 );
459 $query = array(
460 'reportRequests' => $reports_requests,
461 );
462
463 return $query;
464 }
465
466 /**
467 * Setting order for requests
468 *
469 * @param string $name The field which to sort by. The default sort order is ascending. Example: ga:browser.
470 * @param string $sort The sorting order for the field. 'ASCENDING' or 'DESCENDING'.
471 *
472 * @return array OrderBys
473 */
474 public static function set_order_bys( $name, $sort ) {
475 $order = array();
476 $order[] = array(
477 'fieldName' => $name,
478 'sortOrder' => $sort,
479 );
480
481 return $order;
482 }
483
484 /**
485 * Setting metrics for requests
486 *
487 * @param mixed $expression A metric expression or array of expressions.
488 *
489 * @return array Metrics
490 */
491 public static function set_metrics( $expression ) {
492 $metrics = array();
493 if ( is_array( $expression ) ) {
494 foreach ( $expression as $exp ) {
495 $metrics[] = array(
496 'expression' => $exp,
497 );
498 }
499 } else {
500 $metrics[] = array(
501 'expression' => $expression,
502 );
503 }
504
505 return $metrics;
506 }
507
508 /**
509 * Setting dimensions for requests
510 *
511 * @param string $name Name of the dimension to fetch, for example ga:browser.
512 *
513 * @return array Dimensions
514 */
515 public static function set_dimensions( $name ) {
516 $dimensions = array();
517 $dimensions[] = array(
518 'name' => $name,
519 );
520
521 return $dimensions;
522 }
523
524 /**
525 * Setting date ranges for requests
526 *
527 * @param string $start_date The start date for the query in the format YYYY-MM-DD.
528 * @param string $end_date The end date for the query in the format YYYY-MM-DD.
529 * @param string $prev_start_date The start date (second range) for the query in the format YYYY-MM-DD.
530 * @param string $prev_end_date The start date (second range) for the query in the format YYYY-MM-DD.
531 *
532 * @return array Date ranges
533 */
534 public static function set_date_ranges( $start_date, $end_date, $prev_start_date = '', $prev_end_date = '' ) {
535 $date_danges = array();
536 $date_danges[] = array(
537 'startDate' => $start_date,
538 'endDate' => $end_date,
539 );
540 if ( false === empty( $prev_start_date ) && false === empty( $prev_end_date ) ) {
541 $date_danges[] = array(
542 'startDate' => $prev_start_date,
543 'endDate' => $prev_end_date,
544 );
545 }
546
547 return $date_danges;
548 }
549
550 /**
551 * Preparing response for data received from analytics
552 *
553 * @param array $data Analytics response.
554 *
555 * @return array Response rows
556 */
557 public static function prepare_response( $data ) {
558 $data = self::get_reports_from_response( $data );
559 self::handle_more_reports( $data );
560 $report = self::get_single_report( $data );
561 self::get_report_column_header( $report );
562 $report_data = self::get_report_data( $report );
563 self::get_totals( $report_data );
564 self::get_row_count( $report_data );
565 $rows = self::get_rows( $report_data );
566
567 return $rows;
568 }
569
570 /**
571 * Get dimensions from response row
572 *
573 * @param array $row Analytics response row.
574 *
575 * @return array|bool Dimensions
576 */
577 public static function get_dimensions( $row ) {
578 if ( false === empty( $row['dimensions'] ) ) {
579 return $row['dimensions'];
580 }
581
582 return false;
583 }
584
585 /**
586 * Get metrics from response row
587 *
588 * @param array $row Analytics response row.
589 *
590 * @return array|bool Metrics
591 */
592 public static function get_metrics( $row ) {
593 if ( false === empty( $row['metrics'] ) ) {
594 return $row['metrics'];
595 }
596
597 return false;
598 }
599
600 /**
601 * Get row from response report data
602 *
603 * @param array $report_data Analytics response report data.
604 *
605 * @return array|bool Rows
606 */
607 public static function get_rows( $report_data ) {
608 if ( false === empty( $report_data['rows'] ) ) {
609 return $report_data['rows'];
610 }
611
612 return false;
613 }
614
615 /**
616 * Get row count from response report data
617 *
618 * @param array $report_data Analytics response report data.
619 *
620 * @return array|bool Row count
621 */
622 public static function get_row_count( $report_data ) {
623 if ( false === empty( $report_data['rowCount'] ) ) {
624 return $report_data['rowCount'];
625 }
626
627 return false;
628 }
629
630 /**
631 * Get totals from response report data
632 *
633 * @param array $report_data Analytics response report data.
634 *
635 * @return array|bool Totals
636 */
637 public static function get_totals( $report_data ) {
638 if ( false === empty( $report_data['totals'] ) ) {
639 return $report_data['totals'];
640 }
641
642 return false;
643 }
644
645 /**
646 * Get reports from response data
647 *
648 * @param array $data Analytics response data.
649 *
650 * @return array|bool Reports
651 */
652 public static function get_reports_from_response( $data ) {
653 if ( false === empty( $data['reports'] ) ) {
654 return $data['reports'];
655 }
656
657 return false;
658 }
659
660 /**
661 * Show info for multiple data
662 *
663 * @param array $data Analytics response data.
664 */
665 public static function handle_more_reports( $data ) {
666 if ( count( $data ) > 1 ) {
667 echo 'more than one report';
668 }
669 }
670
671 /**
672 * Show info for multiple rows
673 *
674 * @param array $rows Analytics response rows.
675 */
676 public static function handle_more_rows( $rows ) {
677 if ( count( $rows ) > 1 ) {
678 echo 'more than one row';
679 }
680 }
681
682 /**
683 * Get single report from response data
684 *
685 * @param array $data Analytics response data.
686 *
687 * @return array|bool Report
688 */
689 public static function get_single_report( $data ) {
690 if ( false === empty( $data ) ) {
691 foreach ( $data as $report ) {
692 if ( false === empty( $report ) ) {
693 return $report;
694 }
695 }
696 }
697
698 return false;
699 }
700
701 /**
702 * Get single row from response data rows
703 *
704 * @param array $rows Analytics response data rows.
705 *
706 * @return array|bool Row
707 */
708 public static function get_single_row( $rows ) {
709 if ( false === empty( $rows ) ) {
710 foreach ( $rows as $row ) {
711 if ( false === empty( $row ) ) {
712 return $row;
713 }
714 }
715 }
716
717 return false;
718 }
719
720 /**
721 * Get column header from response data
722 *
723 * @param array $data Analytics response data.
724 *
725 * @return array Column header
726 */
727 public static function get_report_column_header( $data ) {
728 if ( false === empty( $data['columnHeader'] ) ) {
729 return $data['columnHeader'];
730 }
731
732 return false;
733 }
734
735 /**
736 * Get report data from response data
737 *
738 * @param array $data Analytics response data.
739 *
740 * @return array|bool data
741 */
742 public static function get_report_data( $data ) {
743 if ( false === empty( $data['data'] ) ) {
744 return $data['data'];
745 }
746
747 return false;
748 }
749
750 /**
751 * Get chart from response data
752 *
753 * @param array $response_data Analytics response data.
754 * @param int $period_in_days Period in days (default = 7).
755 *
756 * @return array chart data
757 */
758 public static function get_chart( $response_data, $period_in_days = 7 ) {
759 $chart_data = array();
760 if ( false === empty( $response_data ) ) {
761 $data = (
762 false === empty( $response_data['reports'] )
763 && false === empty( $response_data['reports'][0] )
764 && false === empty( $response_data['reports'][0]['data'] )
765 )
766 ? $response_data['reports'][0]['data'] : array();
767 $rows = ( false === empty( $data['rows'] ) ) ? $data['rows'] : array();
768 if ( false === empty( $rows ) ) {
769 foreach ( $rows as $key => $row ) {
770 if ( $key < $period_in_days ) {
771 $chart_data[ $key ]['previous'] = false === empty( $row['metrics'][1]['values'][0] ) ? $row['metrics'][1]['values'][0] : 0;
772 $chart_data[ $key ]['previous-day'] = gmdate( 'M j', strtotime( $row['dimensions'][0] ) );
773 } else {
774 $chart_data[ $key - $period_in_days ]['day'] = gmdate( 'M j', strtotime( $row['dimensions'][0] ) );
775 $chart_data[ $key - $period_in_days ]['current'] = false === empty( $row['metrics'][0]['values'][0] ) ? $row['metrics'][0]['values'][0] : 0;
776
777 if ( 0 === $chart_data[ $key - $period_in_days ]['current'] ) {
778 $chart_data[ $key - $period_in_days ]['current'] = false === empty( $row['metrics'][1]['values'][0] ) ? $row['metrics'][1]['values'][0] : 0;
779 }
780
781 $chart_data['date'] = strtotime( $row['dimensions'][0] );
782 }
783 }
784 }
785 }
786
787 return $chart_data;
788 }
789
790 /**
791 * Get gender chart from response data
792 *
793 * @param array $response_data Analytics response data.
794 *
795 * @return array chart data
796 */
797 public static function get_gender_chart( $response_data ) {
798 $chart_data = array();
799 if ( false === empty( $response_data ) ) {
800 $data = ( false === empty( $response_data['reports'] ) && false === empty( $response_data['reports'][0] ) && false === empty( $response_data['reports'][0]['data'] ) ) ? $response_data['reports'][0]['data'] : array();
801 $rows = ( false === empty( $data['rows'] ) ) ? $data['rows'] : array();
802 if ( false === empty( $rows ) ) {
803 foreach ( $rows as $key => $row ) {
804 $chart_data[ $row['dimensions'][0] ] = self::get_metric_value( $row['metrics'] );
805 }
806 }
807 }
808
809 return $chart_data;
810 }
811
812 /**
813 * Get device chart from response data.
814 *
815 * @param array $response_data Analytics response data array.
816 *
817 * @return array Chart data array.
818 */
819 public static function get_device_chart( $response_data ) {
820 $chart_data = array();
821 if ( false === empty( $response_data ) ) {
822 $data = ( false === empty( $response_data['reports'] ) && false === empty( $response_data['reports'][0] ) && false === empty( $response_data['reports'][0]['data'] ) ) ? $response_data['reports'][0]['data'] : array();
823 $rows = ( false === empty( $data['rows'] ) ) ? $data['rows'] : array();
824 if ( false === empty( $rows ) ) {
825 foreach ( $rows as $row ) {
826 $chart_data[ $row['dimensions'][0] ] = self::get_metric_value( $row['metrics'] );
827 }
828 }
829 }
830
831 return $chart_data;
832 }
833
834 /**
835 * Get the value of metric data response.
836 *
837 * @param array $metrics Metrics array.
838 *
839 * @return mixed
840 */
841 private static function get_metric_value( $metrics ) {
842 if ( is_array( $metrics ) ) {
843 foreach ( $metrics as $metric ) {
844 $values[] = $metric['values'][0];
845 }
846 }
847
848 return $values[0];
849 }
850
851 /**
852 * Get gender chart from response data
853 *
854 * @param array $response_data Analytics response data.
855 *
856 * @return array chart data
857 */
858 public static function get_age_chart( $response_data ) {
859 $chart_data = array();
860 if ( false === empty( $response_data ) ) {
861 $data = ( false === empty( $response_data['reports'] ) && false === empty( $response_data['reports'][0] ) && false === empty( $response_data['reports'][0]['data'] ) ) ? $response_data['reports'][0]['data'] : array();
862 $rows = ( false === empty( $data['rows'] ) ) ? $data['rows'] : array();
863 if ( false === empty( $rows ) ) {
864 foreach ( $rows as $key => $row ) {
865 $chart_data[ $row['dimensions'][0] ] = self::get_metric_value( $row['metrics'] );
866 }
867 }
868 }
869
870 return $chart_data;
871 }
872
873 /**
874 * Get dasboard chart from response data
875 *
876 * @param array $response_data Analytics response data.
877 *
878 * @return array dashboard chart data
879 */
880 public static function get_dashboard_chart( $response_data ) {
881 $chart_data = array();
882 if ( false === empty( $response_data ) ) {
883 $data = (
884 false === empty( $response_data['reports'] )
885 && false === empty( $response_data['reports'][0] )
886 && false === empty( $response_data['reports'][0]['data'] )
887 ) ? $response_data['reports'][0]['data'] : array();
888
889 $rows = ( false === empty( $data['rows'] ) ) ? $data['rows'] : array();
890 if ( false === empty( $rows ) ) {
891 foreach ( $rows as $row ) {
892 $chart_data[] = array(
893 'day' => gmdate( 'M j', strtotime( $row['dimensions'][0] ) ),
894 'current' => false === empty( $row['metrics'][0]['values'][0] ) ? $row['metrics'][0]['values'][0] : 0,
895 );
896 }
897 }
898 }
899
900 return $chart_data;
901 }
902
903 /**
904 * Get boxes from response data
905 *
906 * @param array $data Analytics response data.
907 *
908 * @return array boxes data
909 */
910 public static function get_boxes( $data ) {
911 if ( false === empty( $data ) ) {
912 $data = self::get_reports_from_response( $data );
913 self::handle_more_reports( $data );
914 $report = self::get_single_report( $data );
915 self::get_report_column_header( $report );
916 $report_data = self::get_report_data( $report );
917 $totals = self::get_totals( $report_data );
918
919 return self::get_boxes_from_totals( $totals );
920 }
921 }
922
923 /**
924 * Get boxes from totals
925 *
926 * @param array $totals Analytics response totals.
927 *
928 * @return array|bool boxes data
929 */
930 public static function get_boxes_from_totals( $totals ) {
931 if ( false === empty( $totals ) ) {
932 $boxes_data = array();
933 foreach ( $totals as $key => $total ) {
934 if ( 0 === $key ) {
935 $boxes_data['Users']['current'] = $total['values'][0];
936 $boxes_data['Pageviews']['current'] = $total['values'][1];
937 $boxes_data['PageviewsPerSession']['current'] = $total['values'][2];
938 $boxes_data['BounceRate']['current'] = round( $total['values'][3], 2 );
939 } else {
940 $boxes_data['Users']['previous'] = $total['values'][0];
941 $boxes_data['Pageviews']['previous'] = $total['values'][1];
942 $boxes_data['PageviewsPerSession']['previous'] = $total['values'][2];
943 $boxes_data['BounceRate']['previous'] = round( $total['values'][3], 2 );
944 }
945 }
946
947 return self::prepare_boxes( $boxes_data );
948 }
949
950 return false;
951 }
952
953 /**
954 * Prepare boxes data
955 *
956 * @param array $boxes_data Boxes data.
957 *
958 * @return array boxes data
959 */
960 public static function prepare_boxes( $boxes_data ) {
961 $boxes_data['Users']['diff'] = ( $boxes_data['Users']['previous'] > 0 ) ? round( ( $boxes_data['Users']['current'] - $boxes_data['Users']['previous'] ) / $boxes_data['Users']['previous'] * 100, 2 ) : 100;
962 $boxes_data['Pageviews']['diff'] = ( $boxes_data['Pageviews']['previous'] > 0 ) ? round( ( $boxes_data['Pageviews']['current'] - $boxes_data['Pageviews']['previous'] ) / $boxes_data['Pageviews']['previous'] * 100, 2 ) : 100;
963 $boxes_data['PageviewsPerSession']['diff'] = ( $boxes_data['PageviewsPerSession']['previous'] > 0 ) ? round( ( $boxes_data['PageviewsPerSession']['current'] - $boxes_data['PageviewsPerSession']['previous'] ) / $boxes_data['PageviewsPerSession']['previous'] * 100, 2 ) : 100;
964 $boxes_data['BounceRate']['diff'] = ( $boxes_data['BounceRate']['previous'] > 0 ) ? round( ( $boxes_data['BounceRate']['current'] - $boxes_data['BounceRate']['previous'] ) / $boxes_data['BounceRate']['previous'] * 100, 2 ) : 100;
965 $boxes_data['Users']['diff'] = ( 0 === $boxes_data['Users']['previous'] && 0 === $boxes_data['Users']['current'] ) ? 0 : $boxes_data['Users']['diff'];
966 $boxes_data['Pageviews']['diff'] = ( 0 === $boxes_data['Pageviews']['previous'] && 0 === $boxes_data['Pageviews']['current'] ) ? 0 : $boxes_data['Pageviews']['diff'];
967 $boxes_data['PageviewsPerSession']['diff'] = ( 0 === $boxes_data['PageviewsPerSession']['previous'] && 0 === $boxes_data['PageviewsPerSession']['current'] ) ? 0 : $boxes_data['PageviewsPerSession']['diff'];
968 $boxes_data['BounceRate']['diff'] = ( 0 === $boxes_data['BounceRate']['previous'] && 0 === $boxes_data['BounceRate']['current'] ) ? 0 : $boxes_data['BounceRate']['diff'];
969 $boxes_data['Users']['label'] = 'Users';
970 $boxes_data['Pageviews']['label'] = 'Pageviews';
971 $boxes_data['PageviewsPerSession']['label'] = 'Pages / Session';
972 $boxes_data['BounceRate']['label'] = 'Bounce Rate';
973 $boxes_data['Users']['comparison'] = $boxes_data['Users']['current'] . ' vs ' . $boxes_data['Users']['previous'];
974 $boxes_data['Pageviews']['comparison'] = $boxes_data['Pageviews']['current'] . ' vs ' . $boxes_data['Pageviews']['previous'];
975 $boxes_data['PageviewsPerSession']['comparison'] = self::number_format_clean( $boxes_data['PageviewsPerSession']['current'], 2, '.', ',' ) . ' vs ' . self::number_format_clean( $boxes_data['PageviewsPerSession']['previous'], 2, '.', ',' );
976 $boxes_data['BounceRate']['comparison'] = self::number_format_clean( $boxes_data['BounceRate']['current'], 2, '.', ',' ) . '% vs ' . self::number_format_clean( $boxes_data['BounceRate']['previous'], 2, '.', ',' ) . '%';
977 $boxes_data['Users']['color'] = ( $boxes_data['Users']['diff'] > 0 ) ? 'green' : 'red';
978 $boxes_data['Pageviews']['color'] = ( $boxes_data['Pageviews']['diff'] > 0 ) ? 'green' : 'red';
979 $boxes_data['PageviewsPerSession']['color'] = ( $boxes_data['PageviewsPerSession']['diff'] > 0 ) ? 'green' : 'red';
980 $boxes_data['BounceRate']['color'] = ( $boxes_data['BounceRate']['diff'] > 0 ) ? 'red' : 'green';
981 $boxes_data['Users']['color'] = ( 0 !== $boxes_data['Users']['diff'] ) ? $boxes_data['Users']['color'] : 'black';
982 $boxes_data['Pageviews']['color'] = ( 0 !== $boxes_data['Pageviews']['diff'] ) ? $boxes_data['Pageviews']['color'] : 'black';
983 $boxes_data['PageviewsPerSession']['color'] = ( 0 !== $boxes_data['PageviewsPerSession']['diff'] ) ? $boxes_data['PageviewsPerSession']['color'] : 'black';
984 $boxes_data['BounceRate']['color'] = ( 0 !== $boxes_data['BounceRate']['diff'] ) ? $boxes_data['BounceRate']['color'] : 'black';
985
986 return $boxes_data;
987 }
988
989 /**
990 * Number format for boxes
991 *
992 * @param float $number Number to format.
993 * @param int $precision Precision.
994 * @param string $dec_point Decimal point.
995 * @param string $thousands_sep Thousands Separator.
996 *
997 * @return string clean number format
998 */
999 public static function number_format_clean( $number, $precision = 0, $dec_point = '.', $thousands_sep = ',' ) {
1000 if ( 0 === $number ) {
1001 return 0;
1002 } else {
1003 $format = number_format( $number, $precision, $dec_point, $thousands_sep );
1004 if ( '.00' === substr( $format, 2 ) ) {
1005 return substr( $format, 0, - 3 );
1006 }
1007
1008 return $format;
1009 }
1010 }
1011
1012 /**
1013 * Get sources from analytics response data
1014 *
1015 * @param array $data Analytics response data.
1016 *
1017 * @return array|bool sources data
1018 */
1019 public static function get_sources( $data ) {
1020 if ( false === empty( $data ) ) {
1021 $data = self::get_reports_from_response( $data );
1022 self::handle_more_reports( $data );
1023 $report = self::get_single_report( $data );
1024 self::get_report_column_header( $report );
1025 $report_data = self::get_report_data( $report );
1026 $rows = self::get_rows( $report_data );
1027 $totals = self::get_totals( $report_data );
1028 $total_count = array();
1029 if ( false === empty( $totals ) ) {
1030 foreach ( $totals as $key => $total ) {
1031 $total_count = $total['values'][0];
1032 }
1033 }
1034 $sources = array(
1035 'total' => $total_count,
1036 'sum' => 0,
1037 'rows' => array(),
1038 );
1039 if ( false === empty( $rows ) ) {
1040 $i = 1;
1041 foreach ( $rows as $row ) {
1042 if ( false === empty( $row ) ) {
1043 foreach ( $row as $key => $value ) {
1044 if ( 'dimensions' === $key ) {
1045 $sources['rows'][ $i ]['name'] = $value[0];
1046 $sources['rows'][ $i ]['url'] = $value[0];
1047 } elseif ( 'metrics' === $key ) {
1048 $sources['rows'][ $i ]['number'] = $value[0]['values'][0];
1049 $sources['rows'][ $i ]['percent'] = ( false === empty( $total_count ) ) ? round( $value[0]['values'][0] / $total_count * 100, 2 ) : 0;
1050 $sources['sum'] += $value[0]['values'][0];
1051 }
1052 }
1053 $i ++;
1054 }
1055 }
1056 }
1057
1058 return $sources;
1059 }
1060
1061 return false;
1062 }
1063
1064 /**
1065 * Get dashboard boxes data from analytics response data
1066 *
1067 * @param array $data Analytics response data.
1068 *
1069 * @return array dashboard boxes data
1070 */
1071 public static function get_dashboard_boxes_data( $data ) {
1072 if ( false === empty( $data ) ) {
1073 $data = self::get_reports_from_response( $data );
1074 self::handle_more_reports( $data );
1075 $report = self::get_single_report( $data );
1076 self::get_report_column_header( $report );
1077 $report_data = self::get_report_data( $report );
1078 $totals = self::get_totals( $report_data );
1079 $boxes_data = array();
1080 $boxes_data['Sessions'] = array(
1081 'label' => 'Visits',
1082 'value' => $totals[0]['values'][0],
1083 );
1084 $boxes_data['Pageviews'] = array(
1085 'label' => 'Pageviews',
1086 'value' => $totals[0]['values'][1],
1087 );
1088 $boxes_data['pageviewsPerSession'] = array(
1089 'label' => 'Pages / Visit',
1090 'value' => self::number_format_clean( $totals[0]['values'][2], 2, '.', ',' ),
1091 );
1092 $boxes_data['BounceRate'] = array(
1093 'label' => 'Bounce Rate',
1094 'value' => self::number_format_clean( $totals[0]['values'][3], 2, '.', ',' ) . '%',
1095 );
1096 $boxes_data['avgTimeOnPage'] = array(
1097 'label' => 'Avg. Time on Site',
1098 'value' => gmdate( 'H:i:s', $totals[0]['values'][4] ),
1099 );
1100 $boxes_data['percentNewSessions'] = array(
1101 'label' => '% of New Visits',
1102 'value' => self::number_format_clean( $totals[0]['values'][5], 2, '.', ',' ),
1103 );
1104
1105 return $boxes_data;
1106 }
1107 }
1108
1109 /**
1110 * Get Empty Boxes Structure.
1111 *
1112 * @return array Array of empty boxes structure values.
1113 */
1114 public static function get_empty_boxes_structure() {
1115 $boxes_data = array();
1116 $boxes_data['Sessions'] = array(
1117 'label' => 'Visits',
1118 'value' => 0,
1119 );
1120 $boxes_data['Pageviews'] = array(
1121 'label' => 'Pageviews',
1122 'value' => 0,
1123 );
1124 $boxes_data['pageviewsPerSession'] = array(
1125 'label' => 'Pages / Visit',
1126 'value' => self::number_format_clean( 0, 2, '.', ',' ),
1127 );
1128 $boxes_data['BounceRate'] = array(
1129 'label' => 'Bounce Rate',
1130 'value' => self::number_format_clean( 0, 2, '.', ',' ) . '%',
1131 );
1132 $boxes_data['avgTimeOnPage'] = array(
1133 'label' => 'Avg. Time on Site',
1134 'value' => gmdate( 'H:i:s', 0 ),
1135 );
1136 $boxes_data['percentNewSessions'] = array(
1137 'label' => '% of New Visits',
1138 'value' => self::number_format_clean( 0, 2, '.', ',' ),
1139 );
1140
1141 return $boxes_data;
1142 }
1143 }
1144