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