PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 1.19.1
Independent Analytics – WordPress Analytics Plugin v1.19.1
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 / IAWP / Filters.php
independent-analytics / IAWP Last commit date
AJAX 3 years ago Migrations 3 years ago Models 3 years ago Queries 3 years ago Tables 3 years ago Utils 3 years ago Campaign_Builder.php 3 years ago Capability_Manager.php 3 years ago Chart.php 3 years ago Chart_Geo.php 3 years ago Chart_SVG.php 3 years ago Current_Resource.php 3 years ago Dashboard_Options.php 3 years ago Dashboard_Widget.php 3 years ago Email_Reports.php 3 years ago Filters.php 3 years ago Geo_Database.php 3 years ago Geo_Database_Download_Job.php 3 years ago Health_Check.php 3 years ago Independent_Analytics.php 3 years ago Known_Referrers.php 3 years ago PDF.php 3 years ago Query.php 3 years ago Quick_Stats.php 3 years ago REST_API.php 3 years ago Real_Time.php 3 years ago Settings.php 3 years ago Track_Resource_Changes.php 3 years ago View_Counter.php 3 years ago WP_Option_Cache_Bust.php 3 years ago
Filters.php
408 lines
1 <?php
2
3 namespace IAWP;
4
5 use IAWP\Utils\Date_Format;
6 use IAWP\Utils\Security;
7
8 class Filters
9 {
10 public function output_filters(array $columns)
11 {
12 $opts = new Dashboard_Options(); ?>
13 <div class="modal-parent"
14 data-controller="filters"
15 data-filters-filters-value="<?php esc_html_e(json_encode($opts->filters())) ?>"
16 >
17 <button id="filters-button" class="iawp-button ghost-white"
18 data-action="filters#toggleModal"
19 data-filters-target="modalButton"
20 >
21 <span class="dashicons dashicons-filter"></span>
22 <?php echo ' ' . esc_html__('Filter Rows', 'iawp') . ' ' ?>
23 <span class="count" data-filters-target="filterCount"></span>
24 </button>
25 <div class="modal large"
26 data-filters-target="modal"
27 >
28 <div class="modal-inner">
29 <div class="title-small"><?php esc_html_e('Filters', 'iawp'); ?></div>
30 <div id="filters" data-filters-target="filters" class="filters" data-filters="[]">
31 </div>
32 <template data-filters-target="blueprint">
33 <?php echo Security::form(self::get_condition_html($columns)); ?>
34 </template>
35 <div>
36 <button id="add-condition" class="iawp-button text"
37 data-action="filters#addCondition"
38 >
39 <?php esc_html_e('+ Add another condition', 'iawp'); ?>
40 </button>
41 </div>
42 <div class="actions">
43 <button id="filters-apply" class="iawp-button purple"
44 data-action="filters#apply"
45 >
46 <?php esc_html_e('Apply', 'iawp') ?>
47 </button>
48 <button id="filters-reset" class="iawp-button ghost-purple"
49 data-action="filters#reset"
50 data-filters-target="reset"
51 disabled
52 >
53 <?php esc_html_e('Reset', 'iawp'); ?>
54 </button>
55 </div>
56 </div>
57 </div>
58 </div><?php
59 }
60
61 private function get_condition_html(array $columns)
62 {
63 ?>
64 <div class="condition" data-filters-target="condition">
65 <div class="input-group">
66 <div>
67 <?php echo self::get_inclusion_selects(); ?>
68 </div>
69 <div>
70 <?php echo self::get_column_select($columns); ?>
71 </div>
72 <div class="operator-select-container">
73 <?php echo self::get_all_operator_selects(); ?>
74 </div>
75 <div class="operand-field-container">
76 <?php echo self::get_all_operand_fields($columns); ?>
77 </div>
78 </div>
79 <button class="delete-button" data-action="filters#removeCondition">
80 <span class="dashicons dashicons-no"></span></button>
81 </div>
82 <?php
83 }
84
85 private function get_inclusion_selects()
86 {
87 $html = '<select class="filters-include" data-filters-target="inclusion">';
88 $html .= '<option value="include">' . esc_html__('Include', 'iawp') . '</option>';
89 $html .= '<option value="exclude">' . esc_html__('Exclude', 'iawp') . '</option>';
90 $html .= '</select>';
91
92 return $html;
93 }
94
95 private function get_column_select(array $columns)
96 {
97 ?>
98 <select class="filters-column" data-filters-target="column"
99 data-action="filters#columnSelect"
100 >
101 <option value="">
102 <?php esc_html_e('Choose a column', 'iawp') ?>
103 </option>
104 <?php foreach ($columns as $column): ?>
105 <?php if ($column->requires_woocommerce() && !iawp_using_woocommerce()) {
106 continue;
107 } ?>
108 <option value="<?php esc_attr_e($column->id()) ?>"
109 data-type="<?php esc_attr_e(self::get_column_data_type($column->id())) ?>"
110 >
111 <?php esc_html_e($column->label()) ?>
112 </option>
113 <?php endforeach ?>
114 </select>
115 <?php
116 }
117
118 private function get_all_operator_selects()
119 {
120 $html = '';
121 foreach (self::get_data_types() as $data_type) {
122 $html .= '<select data-filters-target="operator" data-type="' . esc_attr($data_type) . '">';
123 foreach (self::get_operators($data_type) as $key => $value) {
124 $html .= '<option value="' . esc_attr($key) . '">' . esc_html($value) . '</option>';
125 }
126 $html .= '</select>';
127 }
128
129 return $html;
130 }
131
132 private function get_all_operand_fields($columns)
133 {
134 $html = '';
135 foreach ($columns as $column) {
136 $id = $column->id();
137 if ($id == 'title') {
138 $html .= '<input data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="title" type="text" />';
139 } elseif ($id == 'referrer') {
140 $html .= '<input data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="referrer" type="text" />';
141 } elseif ($id == 'continent') {
142 $html .= '<input data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="continent" type="text" />';
143 } elseif ($id == 'country') {
144 $html .= '<input data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="country" type="text" />';
145 } elseif ($id == 'subdivision') {
146 $html .= '<input data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="subdivision" type="text" />';
147 } elseif ($id == 'city') {
148 $html .= '<input data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="city" type="text" />';
149 } elseif ($id == 'utm_source') {
150 $html .= '<input data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="utm_source" type="text" />';
151 } elseif ($id == 'utm_medium') {
152 $html .= '<input data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="utm_medium" type="text" />';
153 } elseif ($id == 'utm_campaign') {
154 $html .= '<input data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="utm_campaign" type="text" />';
155 } elseif ($id == 'utm_term') {
156 $html .= '<input data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="utm_term" type="text" />';
157 } elseif ($id == 'utm_content') {
158 $html .= '<input data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="utm_content" type="text" />';
159 } elseif ($id == 'referrer_type') {
160 $html .= '<select data-filters-target="operand" data-column="referrer_type">';
161 $html .= '<option value="Search">' . esc_html__('Search', 'iawp') . '</option>';
162 $html .= '<option value="Social">' . esc_html__('Social', 'iawp') . '</option>';
163 $html .= '<option value="Referrer">' . esc_html__('Referrer', 'iawp') . '</option>';
164 $html .= '<option value="Direct">' . esc_html__('Direct', 'iawp') . '</option>';
165 $html .= '</select>';
166 } elseif ($id == 'url') {
167 $html .= '<input type="text" data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="url"/>';
168 } elseif ($id == 'views') {
169 $html .= '<input type="number" data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="views"/>';
170 } elseif ($id == 'views_growth') {
171 $html .= '<input type="number" data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="views_growth"/>';
172 } elseif ($id == 'visitors') {
173 $html .= '<input type="number" data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="visitors"/>';
174 } elseif ($id == 'visitors_growth') {
175 $html .= '<input type="number" data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="visitors_growth"/>';
176 } elseif ($id == 'sessions') {
177 $html .= '<input type="number" data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="sessions"/>';
178 } elseif (in_array($id, ['wc_orders', 'wc_gross_sales', 'wc_refunds', 'wc_refunded_amount', 'wc_net_sales'])) {
179 $html .= '<input type="number" data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="' . esc_attr($id) . '"/>';
180 } elseif ($id == 'author') {
181 $html .= '<select data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="author">';
182 foreach (iawp()->get_users_can_write() as $author) {
183 $html .= '<option value="' . esc_attr($author->ID) . '">' . esc_html($author->display_name) . '</option>';
184 }
185 $html .= '</select>';
186 } elseif ($id == 'type') {
187 $html .= '<select data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="type">';
188 $html .= '<option value="post">' . esc_html__('Post', 'iawp') . '</option>';
189 $html .= '<option value="page">' . esc_html__('Page', 'iawp') . '</option>';
190 $html .= '<option value="attachment">' . esc_html__('Attachment', 'iawp') . '</option>';
191 foreach (iawp()->get_custom_types() as $cpt) {
192 $html .= '<option value="' . esc_attr($cpt) . '">' . esc_html(get_post_type_object($cpt)->labels->singular_name) . '</option>';
193 }
194 $html .= '<option value="category">' . esc_html__('Category', 'iawp') . '</option>';
195 $html .= '<option value="post_tag">' . esc_html__('Tag', 'iawp') . '</option>';
196 foreach (iawp()->get_custom_types(true) as $tax) {
197 $html .= '<option value="' . esc_attr($tax) . '">' . esc_html(get_taxonomy_labels(get_taxonomy($tax))->singular_name) . '</option>';
198 }
199 $html .= '<option value="blog-archive">' . esc_html__('Blog Home', 'iawp') . '</option>';
200 $html .= '<option value="author-archive">' . esc_html__('Author Archive', 'iawp') . '</option>';
201 $html .= '<option value="date-archive">' . esc_html__('Date Archive', 'iawp') . '</option>';
202 $html .= '<option value="search-archive">' . esc_html__('Search Results', 'iawp') . '</option>';
203 $html .= '<option value="not-found">' . esc_html__('404', 'iawp') . '</option>';
204 $html .= '</select>';
205 } elseif ($id == 'date') {
206 $html .= '<input type="text"
207 data-filters-target="operand"
208 data-action="keydown->filters#operandKeyDown filters#operandChange"
209 data-column="date"
210 data-controller="easepick"
211 data-css="' . esc_url(iawp_url_to('dist/styles/easepick/datepicker.css')) . '" data-dow="' . absint(iawp()->get_option('iawp_dow', 1)) . '"
212 data-format="' . esc_attr(Date_Format::js()) . '" />';
213 } elseif ($id == 'category') {
214 $html .= '<select data-filters-target="operand" data-action="keydown->filters#operandKeyDown filters#operandChange" data-column="category">';
215 foreach (get_categories() as $category) {
216 $html .= '<option value="' . esc_attr($category->term_id) . '">' . esc_html($category->name) . '</option>';
217 }
218 $html .= '</select>';
219 }
220 }
221
222 return $html;
223 }
224
225 private function get_data_types()
226 {
227 return ['string', 'int', 'date', 'bool'];
228 }
229
230 private function get_operators(string $data_type)
231 {
232 if ($data_type == 'string') {
233 return [
234 'contains' => esc_html__('Contains', 'iawp'),
235 'exact' => esc_html__('Exactly matches', 'iawp'),
236 ];
237 } elseif ($data_type == 'int') {
238 return [
239 'greater' => esc_html__('Greater than', 'iawp'),
240 'lesser' => esc_html__('Less than', 'iawp'),
241 'equal' => esc_html__('Equal to', 'iawp'),
242 ];
243 } elseif ($data_type == 'bool') {
244 return [
245 'is' => esc_html__('Is', 'iawp'),
246 'isnt' => esc_html__('Isn\'t', 'iawp'),
247 ];
248 } elseif ($data_type == 'date') {
249 return [
250 'before' => esc_html__('Before', 'iawp'),
251 'after' => esc_html__('After', 'iawp'),
252 'on' => esc_html__('On', 'iawp'),
253 ];
254 } else {
255 return null;
256 }
257 }
258
259 private function get_column_data_type(string $column)
260 {
261 $columns = [
262 'title' => 'string',
263 'url' => 'string',
264 'referrer' => 'string',
265 'continent' => 'string',
266 'country' => 'string',
267 'subdivision' => 'string',
268 'city' => 'string',
269 'utm_source' => 'string',
270 'utm_medium' => 'string',
271 'utm_campaign' => 'string',
272 'utm_term' => 'string',
273 'utm_content' => 'string',
274 'author' => 'bool',
275 'type' => 'bool',
276 'referrer_type' => 'bool',
277 'category' => 'bool',
278 'views' => 'int',
279 'views_growth' => 'int',
280 'visitors' => 'int',
281 'visitors_growth' => 'int',
282 'sessions' => 'int',
283 'date' => 'date',
284 'wc_orders' => 'int',
285 'wc_gross_sales' => 'int',
286 'wc_refunds' => 'int',
287 'wc_refunded_amount' => 'int',
288 'wc_net_sales' => 'int',
289 ];
290
291 if (array_key_exists($column, $columns)) {
292 return $columns[$column];
293 } else {
294 return null;
295 }
296 }
297
298 public function filter_views(array $rows, array $filters)
299 {
300 if ($filters == '') {
301 return $rows;
302 }
303 $filtered_rows = [];
304
305 foreach ($rows as $row) {
306 $match_count = 0;
307 foreach ($filters as $filter) {
308 if (self::include_row($row, $filter)) {
309 $match_count++;
310 }
311 }
312 if ($match_count == count($filters)) {
313 $filtered_rows[] = $row;
314 }
315 }
316
317 return $filtered_rows;
318 }
319
320 public function include_row($row, $filter)
321 {
322 $inclusion = $filter['inclusion'];
323 $column = $filter['column'];
324 $operator = $filter['operator'];
325 $operand = strtolower($filter['operand']);
326 $column_data_type = $this->get_column_data_type($column);
327 $match = false;
328
329 if ($column_data_type === 'int') {
330 if ($operator === 'greater') {
331 if ($row->$column() > $operand) {
332 $match = true;
333 }
334 } elseif ($operator === 'lesser') {
335 if ($row->$column() < $operand) {
336 $match = true;
337 }
338 } elseif ($operator === 'equal') {
339 if ($row->$column() == $operand) {
340 $match = true;
341 }
342 }
343 } elseif ($column_data_type === 'string') {
344 $value = strtolower($row->$column());
345
346 if ($operator == 'contains') {
347 if (strpos($value, $operand) !== false) {
348 $match = true;
349 }
350 } elseif ($operator == 'exact') {
351 if ($value == $operand) {
352 $match = true;
353 }
354 }
355 } elseif ($filter['column'] == 'referrer_type') {
356 $referrer_type = strtolower($row->referrer_type());
357 if ($filter['operator'] == 'is' && $referrer_type == $operand) {
358 $match = true;
359 } elseif ($filter['operator'] == 'isnt' && $referrer_type != $operand) {
360 $match = true;
361 }
362 } elseif ($filter['column'] == 'author') {
363 if ($filter['operator'] == 'is' && $row->author_id() == $operand) {
364 $match = true;
365 } elseif ($filter['operator'] == 'isnt' && $row->author_id() != $operand) {
366 $match = true;
367 }
368 } elseif ($filter['column'] == 'type') {
369 if ($filter['operator'] == 'is' && $row->type(true) == $operand) {
370 $match = true;
371 } elseif ($filter['operator'] == 'isnt' && $row->type(true) != $operand) {
372 $match = true;
373 }
374 } elseif ($filter['column'] == 'date') {
375 // Don't "continue" or row won't be included when excluding
376 if ($row->date() != null) {
377 $date = new \DateTime($operand);
378 if ($filter['operator'] == 'before' && $row->date() < $date->format('U')) {
379 $match = true;
380 } elseif ($filter['operator'] == 'after' && $row->date() > $date->format('U')) {
381 $match = true;
382 } elseif ($filter['operator'] == 'on') {
383 $formatted_date = \DateTime::createFromFormat('U', $row->date());
384 $formatted_date = $formatted_date->format('Y-m-d');
385 if ($date->format('Y-m-d') == $formatted_date) {
386 $match = true;
387 }
388 }
389 }
390 } elseif ($filter['column'] == 'category') {
391 if ($filter['operator'] == 'is' && in_array($operand, $row->category(false) ?? [])) {
392 $match = true;
393 } elseif ($filter['operator'] == 'isnt' && !in_array($operand, $row->category(false) ?? [])) {
394 $match = true;
395 }
396 }
397
398 if (
399 ($filter['inclusion'] == 'include' && $match) ||
400 ($filter['inclusion'] == 'exclude' && !$match)
401 ) {
402 return true;
403 } else {
404 return false;
405 }
406 }
407 }
408