PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 1.15
Independent Analytics – WordPress Analytics Plugin v1.15
2.15.5 2.15.4 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 / inc / queries / views.php
independent-analytics / inc / queries Last commit date
campaigns.php 3 years ago current_traffic_finder.php 3 years ago geos.php 3 years ago range_query.php 3 years ago referrers.php 3 years ago reset_database.php 3 years ago resources.php 3 years ago view.php 3 years ago views.php 3 years ago visitors_over_time_finder.php 3 years ago
views.php
230 lines
1 <?php
2
3 namespace IAWP;
4
5 class Views extends Range_Query
6 {
7 const REFERRERS = 'REFERRERS';
8 const RESOURCES = 'RESOURCES';
9 const GEO = 'GEO';
10 const CAMPAIGNS = 'CAMPAIGNS';
11 private $views;
12 private $prev_period_views;
13 private $daily_views;
14 private $visitors;
15 private $prev_period_visitors;
16 private $daily_visitors;
17
18 public function __construct($type, $ids = null, $start = null, $end = null)
19 {
20 parent::__construct([
21 'start' => $start,
22 'end' => $end,
23 ]);
24 if ($type === self::RESOURCES || $type === self::REFERRERS || $type === self::GEO || $type === self::CAMPAIGNS) {
25 $this->query($type, $ids);
26 } else {
27 throw new \Exception('IAWP_Views: Unsupported type');
28 }
29 }
30
31 public function views()
32 {
33 return $this->views;
34 }
35
36 public function prev_period_views()
37 {
38 return $this->prev_period_views;
39 }
40
41 public function daily_views()
42 {
43 return $this->daily_views;
44 }
45
46 public function views_percentage_growth()
47 {
48 if ($this->views() === 0 || $this->prev_period_views() === 0) {
49 return 0;
50 } else {
51 return round((($this->views() / $this->prev_period_views()) - 1) * 100);
52 }
53 }
54
55 public function visitors()
56 {
57 return $this->visitors;
58 }
59
60 public function visitors_percentage_growth()
61 {
62 if ($this->visitors() === 0 || $this->prev_period_visitors() === 0) {
63 return 0;
64 } else {
65 return round((($this->visitors() / $this->prev_period_visitors()) - 1) * 100);
66 }
67 }
68
69 public function prev_period_visitors()
70 {
71 return $this->prev_period_visitors;
72 }
73
74 public function daily_visitors()
75 {
76 return $this->daily_visitors;
77 }
78
79 private function query($type, $ids)
80 {
81 global $wpdb;
82 $views_table = DB::get_table_name(DB::VIEWS);
83 $visitors_table = DB::get_table_name(DB::VISITORS);
84
85 if (is_null($ids)) {
86 $skip_in = 1;
87 $ids = [0];
88 $in = '%s';
89 } elseif (count($ids) === 0) {
90 $skip_in = 0;
91 $ids = [0];
92 $in = '%s';
93 } else {
94 $skip_in = 0;
95 $in = implode(',', array_fill(0, count($ids), '%s'));
96 }
97
98 if ($type === self::RESOURCES) {
99 $column = 'resource_id';
100 } elseif ($type === self::REFERRERS) {
101 $column = 'referrer_id';
102 } elseif ($type === self::GEO) {
103 $column = 'visitor_id';
104 } elseif ($type === self::CAMPAIGNS) {
105 $column = 'campaign_id';
106 }
107
108 $has_null_id = false;
109 foreach ($ids as $id) {
110 if (is_null($id)) {
111 $has_null_id = true;
112 break;
113 }
114 }
115 $null_check = '';
116
117 if ($type === self::REFERRERS && $has_null_id) {
118 $null_check = "OR $column IS NULL";
119 }
120
121 $utc = Timezone::utc_offset();
122 $local_offset = Timezone::local_offset();
123 $query = $wpdb->prepare(
124 "
125 SELECT
126 DATE(CONVERT_TZ(viewed_at, '$utc', '$local_offset')) as date,
127 COUNT(*) as views,
128 COUNT(DISTINCT visitor_id) as visitors
129 FROM $views_table
130 INNER JOIN $visitors_table ON $views_table.visitor_id = $visitors_table.id
131 WHERE viewed_at BETWEEN %s AND %s
132 AND (%d = 1 OR $column IN ($in) $null_check)
133 AND ('$type' != 'GEO' OR $visitors_table.country_code IS NOT NULL)
134 AND ('$type' != 'CAMPAIGNS' OR $views_table.campaign_id IS NOT NULL)
135 GROUP BY DATE(CONVERT_TZ(viewed_at, '$utc', '$local_offset'))",
136 $this->formatted_start(),
137 $this->formatted_end(),
138 $skip_in,
139 ...$ids
140 );
141 $rows = $wpdb->get_results($query);
142
143 // This separate query for visitor counts is required
144 // Without it, visitors visiting on separate days are counted twice in the quick stats
145 $visitors_query = $wpdb->prepare(
146 "
147 SELECT
148 COUNT(DISTINCT visitor_id) as visitors
149 FROM $views_table
150 INNER JOIN $visitors_table ON $views_table.visitor_id = $visitors_table.id
151 WHERE viewed_at BETWEEN %s AND %s
152 AND (%d = 1 OR $column IN ($in) $null_check)
153 AND ('$type' != 'GEO' OR $visitors_table.country_code IS NOT NULL)
154 AND ('$type' != 'CAMPAIGNS' OR $views_table.campaign_id IS NOT NULL)
155 ",
156 $this->formatted_start(),
157 $this->formatted_end(),
158 $skip_in,
159 ...$ids
160 );
161 $visitors = intval($wpdb->get_var($visitors_query));
162
163 $prev_period_query = $wpdb->prepare(
164 "
165 SELECT
166 COUNT(*) as views,
167 COUNT(DISTINCT visitor_id) as visitors
168 FROM $views_table
169 INNER JOIN $visitors_table ON $views_table.visitor_id = $visitors_table.id
170 WHERE viewed_at BETWEEN %s AND %s
171 AND (%d = 1 OR $column IN ($in) $null_check)
172 AND ('$type' != 'GEO' OR $visitors_table.country_code IS NOT NULL)
173 AND ('$type' != 'CAMPAIGNS' OR $views_table.campaign_id IS NOT NULL)
174 ",
175 $this->prev_period_formatted_start(),
176 $this->prev_period_formatted_end(),
177 $skip_in,
178 ...$ids
179 );
180 $prev_period_results = $wpdb->get_row($prev_period_query);
181 $prev_period_views = intval($prev_period_results->views);
182 $prev_period_visitors = intval($prev_period_results->visitors);
183
184 $views = 0;
185 $daily_views = [];
186 $daily_visitors = [];
187
188 foreach ($rows as $row) {
189 $views += $row->views;
190 $daily_views[] = [$row->date, intval($row->views)];
191 $daily_visitors[] = [$row->date, intval($row->visitors)];
192 }
193
194 $this->views = $views;
195 $this->prev_period_views = $prev_period_views;
196 $this->visitors = $visitors;
197 $this->prev_period_visitors = $prev_period_visitors;
198 $this->daily_views = $this->fill_in_data_range($daily_views);
199 $this->daily_visitors = $this->fill_in_data_range($daily_visitors);
200 }
201
202 private function fill_in_data_range($partial_data)
203 {
204 $interval = new \DateInterval('P1D');
205 $start = clone $this->start();
206 $end = clone $this->end();
207 $user_timezone = new \DateTimeZone(Timezone::local_offset());
208 $start->setTimezone($user_timezone);
209 $end->setTimezone($user_timezone);
210
211 $date_range = new \DatePeriod($start, $interval, $end);
212 $new_data = [];
213
214 foreach ($date_range as $date) {
215 $views = 0;
216
217 foreach ($partial_data as $data_point) {
218 if ($date == (new \DateTime($data_point[0], $user_timezone))) {
219 $views = intval($data_point[1]);
220 break;
221 }
222 }
223
224 $new_data[] = [$date, $views];
225 }
226
227 return $new_data;
228 }
229 }
230