PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.15.2
Independent Analytics – WordPress Analytics Plugin v2.15.2
2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / IAWP / RealTime / RecentTraffic.php
independent-analytics / IAWP / RealTime Last commit date
RealTime.php 3 days ago RecentTraffic.php 3 days ago RecentVisitors.php 3 days ago
RecentTraffic.php
162 lines
1 <?php
2
3 namespace IAWP\RealTime;
4
5 use IAWP\Date_Range\Exact_Date_Range;
6 use IAWP\Examiner_Config;
7 use IAWP\Illuminate_Builder;
8 use IAWP\Query_Taps;
9 use IAWP\Tables;
10 /** @internal */
11 class RecentTraffic
12 {
13 private int $interval_seconds;
14 private array $short_labels;
15 private array $long_labels;
16 private array $timestamps;
17 private array $views;
18 private array $orders;
19 private array $clicks;
20 private array $form_submissions;
21 public function __construct(Exact_Date_Range $range, ?Examiner_Config $examiner_config, int $interval_seconds = 10)
22 {
23 $this->interval_seconds = $interval_seconds;
24 $this->populate_data($range, $examiner_config);
25 }
26 public function short_labels() : array
27 {
28 return $this->short_labels;
29 }
30 public function long_labels() : array
31 {
32 return $this->long_labels;
33 }
34 public function timestamps() : array
35 {
36 return $this->timestamps;
37 }
38 public function views() : array
39 {
40 return $this->views;
41 }
42 public function view_count() : int
43 {
44 return \array_sum($this->views);
45 }
46 public function orders() : array
47 {
48 return $this->orders;
49 }
50 public function order_count() : int
51 {
52 return \array_sum($this->orders);
53 }
54 public function clicks() : array
55 {
56 return $this->clicks;
57 }
58 public function click_count() : int
59 {
60 return \array_sum($this->clicks);
61 }
62 public function form_submissions() : array
63 {
64 return $this->form_submissions;
65 }
66 public function form_submission_count() : int
67 {
68 return \array_sum($this->form_submissions);
69 }
70 private function populate_data(Exact_Date_Range $range, ?Examiner_Config $examiner_config) : void
71 {
72 $bucket_end = $this->get_bucket_end($range);
73 $iso_bucket_end = $bucket_end->format('Y-m-d\\TH:i:s');
74 $clicks_query = Illuminate_Builder::new()->selectRaw('0 AS views')->selectRaw('COUNT(*) AS clicks')->selectRaw('0 AS form_submissions')->selectRaw('0 AS orders')->selectRaw("ABS(CEILING(TIMESTAMPDIFF(SECOND, '{$iso_bucket_end}', clicks.created_at) / {$this->interval_seconds})) AS interval_ago")->from(Tables::clicks(), 'clicks')->leftJoin(Tables::views() . ' AS views', 'views.id', '=', 'clicks.view_id')->leftJoin(Tables::sessions() . ' AS sessions', 'sessions.session_id', '=', 'views.session_id')->tap(Query_Taps::tap_related_to_examined_record($examiner_config))->whereBetween('clicks.created_at', [$range->iso_start(), $range->iso_end()])->groupBy('interval_ago');
75 $orders_query = Illuminate_Builder::new()->selectRaw('0 AS views')->selectRaw('0 AS clicks')->selectRaw('0 AS form_submissions')->selectRaw('COUNT(*) AS orders')->selectRaw("ABS(CEILING(TIMESTAMPDIFF(SECOND, '{$iso_bucket_end}', orders.created_at) / {$this->interval_seconds})) AS interval_ago")->from(Tables::orders(), 'orders')->leftJoin(Tables::views() . ' AS views', 'views.id', '=', 'orders.view_id')->leftJoin(Tables::sessions() . ' AS sessions', 'sessions.session_id', '=', 'views.session_id')->tap(Query_Taps::tap_related_to_examined_record($examiner_config))->whereBetween('orders.created_at', [$range->iso_start(), $range->iso_end()])->groupBy('interval_ago');
76 $form_submissions_query = Illuminate_Builder::new()->selectRaw('0 AS views')->selectRaw('0 AS clicks')->selectRaw('COUNT(*) AS form_submissions')->selectRaw('0 AS orders')->selectRaw("ABS(CEILING(TIMESTAMPDIFF(SECOND, '{$iso_bucket_end}', form_submissions.created_at) / {$this->interval_seconds})) AS interval_ago")->from(Tables::form_submissions(), 'form_submissions')->leftJoin(Tables::views() . ' AS views', 'views.id', '=', 'form_submissions.view_id')->leftJoin(Tables::sessions() . ' AS sessions', 'sessions.session_id', '=', 'views.session_id')->tap(Query_Taps::tap_related_to_examined_record($examiner_config))->whereBetween('form_submissions.created_at', [$range->iso_start(), $range->iso_end()])->groupBy('interval_ago');
77 $views_query = Illuminate_Builder::new()->selectRaw('COUNT(*) AS views')->selectRaw('0 AS clicks')->selectRaw('0 AS form_submissions')->selectRaw('0 AS orders')->selectRaw("ABS(CEILING(TIMESTAMPDIFF(SECOND, '{$iso_bucket_end}', views.viewed_at) / {$this->interval_seconds})) AS interval_ago")->from(Tables::views(), 'views')->leftJoin(Tables::sessions() . ' AS sessions', 'sessions.session_id', '=', 'views.session_id')->tap(Query_Taps::tap_related_to_examined_record($examiner_config))->whereBetween('viewed_at', [$range->iso_start(), $range->iso_end()])->unionAll($clicks_query)->unionAll($form_submissions_query)->unionAll($orders_query)->groupBy('interval_ago');
78 $union_query = Illuminate_Builder::new()->select(['interval_ago'])->selectRaw('SUM(views) AS views')->selectRaw('SUM(clicks) AS clicks')->selectRaw('SUM(form_submissions) AS form_submissions')->selectRaw('SUM(orders) AS orders')->from($views_query)->groupBy('interval_ago')->orderBy('interval_ago');
79 // Illuminate_Builder::ray($union_query);
80 $rows = $union_query->get()->all();
81 $interval = new \DateInterval("PT{$this->interval_seconds}S");
82 $period = new \DatePeriod($range->start(), $interval, $bucket_end);
83 foreach ($period as $interval => $date) {
84 $views = 0;
85 $orders = 0;
86 $clicks = 0;
87 $form_submissions = 0;
88 // Search the rows for a matching interval to pull data from
89 foreach ($rows as $row) {
90 if (\intval($row->interval_ago) !== $interval) {
91 continue;
92 }
93 $views = \intval($row->views);
94 $orders = \intval($row->orders);
95 $clicks = \intval($row->clicks);
96 $form_submissions = \intval($row->form_submissions);
97 break;
98 }
99 $this->short_labels[] = $this->get_short_label($interval);
100 $this->long_labels[] = $this->get_long_label($interval);
101 $this->timestamps[] = $date->getTimestamp();
102 $this->views[] = $views;
103 $this->orders[] = $orders;
104 $this->clicks[] = $clicks;
105 $this->form_submissions[] = $form_submissions;
106 }
107 $this->short_labels = \array_reverse($this->short_labels);
108 $this->long_labels = \array_reverse($this->long_labels);
109 $this->timestamps = \array_reverse($this->timestamps);
110 $this->views = \array_reverse($this->views);
111 $this->orders = \array_reverse($this->orders);
112 $this->clicks = \array_reverse($this->clicks);
113 $this->form_submissions = \array_reverse($this->form_submissions);
114 }
115 private function get_bucket_end(Exact_Date_Range $range) : \DateTime
116 {
117 $bucket_end = clone $range->end();
118 if ($this->interval_seconds === 60) {
119 $bucket_end->setTime(\intval($bucket_end->format('H')), \intval($bucket_end->format('i')), 0)->modify('+1 minute');
120 }
121 return $bucket_end;
122 }
123 private function get_short_label(int $interval) : string
124 {
125 if ($interval === 0) {
126 if ($this->interval_seconds === 60) {
127 return \__('0 mins', 'independent-analytics');
128 } else {
129 return \__('Now', 'independent-analytics');
130 }
131 }
132 $seconds_passed = $interval * $this->interval_seconds;
133 $is_whole_minute = $seconds_passed % 60 === 0;
134 if (!$is_whole_minute) {
135 // Don't show short labels for partial minutes
136 return '';
137 }
138 $minutes_passed = $seconds_passed / 60;
139 if ($this->interval_seconds === 60 && $minutes_passed % 5 !== 0) {
140 return '';
141 }
142 if ($minutes_passed === 1) {
143 return '-' . $minutes_passed . ' ' . \__('min', 'independent-analytics');
144 }
145 return '-' . $minutes_passed . ' ' . \__('mins', 'independent-analytics');
146 }
147 private function get_long_label(int $interval) : string
148 {
149 if ($interval === 0 && $this->interval_seconds === 10) {
150 return \__('Now', 'independent-analytics');
151 }
152 if ($this->interval_seconds === 60) {
153 if ($interval === 1) {
154 return \sprintf(\__('%d minute ago', 'independent-analytics'), $interval);
155 }
156 return \sprintf(\__('%d minutes ago', 'independent-analytics'), $interval);
157 }
158 $seconds_passed = $interval * $this->interval_seconds;
159 return \sprintf(\__('%d seconds ago', 'independent-analytics'), $seconds_passed);
160 }
161 }
162