PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.5.1
Independent Analytics – WordPress Analytics Plugin v2.5.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 / Tables / Table.php
independent-analytics / IAWP / Tables Last commit date
Columns 2 years ago Groups 2 years ago Table.php 2 years ago Table_Campaigns.php 2 years ago Table_Devices.php 2 years ago Table_Geo.php 2 years ago Table_Pages.php 2 years ago Table_Referrers.php 2 years ago
Table.php
509 lines
1 <?php
2
3 namespace IAWP\Tables;
4
5 use IAWP\Campaign_Builder;
6 use IAWP\Dashboard_Options;
7 use IAWP\Date_Range\Relative_Date_Range;
8 use IAWP\Filters;
9 use IAWP\Form;
10 use IAWP\Icon_Directory_Factory;
11 use IAWP\Plugin_Group;
12 use IAWP\Rows\Filter;
13 use IAWP\Sort_Configuration;
14 use IAWP\Statistics\Statistics;
15 use IAWP\Tables\Columns\Column;
16 use IAWP\Tables\Groups\Group;
17 use IAWP\Tables\Groups\Groups;
18 use IAWP\Utils\CSV;
19 use IAWP\Utils\Currency;
20 use IAWP\Utils\Number_Formatter;
21 use IAWP\Utils\Security;
22 use IAWP\Utils\URL;
23 use IAWP\Utils\WordPress_Site_Date_Format_Pattern;
24 use IAWPSCOPED\Illuminate\Support\Str;
25 use IAWPSCOPED\Proper\Timezone;
26 /** @internal */
27 abstract class Table
28 {
29 private $filters;
30 private $visible_columns;
31 private $group;
32 private $is_new_group;
33 private $statistics;
34 /**
35 * @param string|null $group_id
36 * @param bool $is_new_group
37 */
38 public function __construct(?string $group_id = null, bool $is_new_group = \false)
39 {
40 $this->visible_columns = Dashboard_Options::getInstance()->visible_columns();
41 $this->group = $this->groups()->find_by_id($group_id);
42 $this->is_new_group = $is_new_group;
43 $this->filters = new Filters();
44 }
45 protected abstract function groups() : Groups;
46 /**
47 * @return array<Column>
48 */
49 protected abstract function local_columns() : array;
50 protected abstract function table_name() : string;
51 public function visible_column_ids()
52 {
53 $visible_columns = [];
54 foreach ($this->get_columns() as $column) {
55 if ($column->is_visible()) {
56 $visible_columns[] = $column->id();
57 }
58 }
59 return $visible_columns;
60 }
61 public function group() : Group
62 {
63 return $this->group;
64 }
65 public function column_picker_html() : string
66 {
67 return \IAWPSCOPED\iawp_blade()->run('plugin-group-options', ['option_type' => 'columns', 'option_name' => \__('Toggle Columns', 'independent-analytics'), 'option_icon' => 'columns', 'plugin_groups' => Plugin_Group::get_plugin_groups(), 'options' => $this->get_columns(\true)]);
68 }
69 public function get_table_toolbar_markup()
70 {
71 return \IAWPSCOPED\iawp_blade()->run('tables.table-toolbar', ['plugin_groups' => Plugin_Group::get_plugin_groups(), 'columns' => $this->get_columns(\true), 'groups' => $this->groups(), 'current_group' => $this->group()]);
72 }
73 public function get_table_markup(string $sort_column, string $sort_direction)
74 {
75 return \IAWPSCOPED\iawp_blade()->run('tables.table', ['table' => $this, 'table_name' => $this->table_name(), 'all_columns' => $this->get_columns(), 'visible_column_count' => $this->visible_column_count(), 'number_of_shown_rows' => 0, 'rows' => [], 'render_skeleton' => \true, 'page_size' => \IAWPSCOPED\iawp()->pagination_page_size(), 'sort_column' => $sort_column, 'sort_direction' => $sort_direction, 'has_campaigns' => Campaign_Builder::has_campaigns()]);
76 }
77 public function set_statistics(Statistics $statistics)
78 {
79 $this->statistics = $statistics;
80 }
81 public function get_row_data_attributes($row)
82 {
83 $html = '';
84 foreach ($this->get_columns() as $column) {
85 $id = $column->id();
86 $data_val = $row->{$id}();
87 $html .= ' data-' . \esc_attr($column->id()) . '="' . \esc_attr($data_val) . '"';
88 }
89 return $html;
90 }
91 public function get_cell_content($row, Column $column)
92 {
93 $column_id = $column->id();
94 if (\is_null($row->{$column_id}())) {
95 return '-';
96 }
97 if ($column_id == 'title' && $row->is_deleted()) {
98 return Security::string($row->{$column_id}()) . ' <span class="deleted-label">' . \esc_html__('(deleted)', 'independent-analytics') . '</span>';
99 } elseif ($column_id == 'views') {
100 $views = Number_Formatter::decimal($row->views());
101 // Getting a divide by zero error from the line below?
102 // It's likely an issue with $this->views which is an instance of Views. Make sure the queries there are working.
103 $views_percentage = Number_Formatter::percent($row->views() / $this->statistics->views()->value() * 100, 2);
104 return '<span class="no-wrap">' . Security::string($views) . '</span> <span class="percentage">(' . Security::string($views_percentage) . ')</span>';
105 } elseif ($column_id == 'visitors') {
106 $visitors = Number_Formatter::decimal($row->visitors());
107 $visitors_percentage = Number_Formatter::percent($row->visitors() / $this->statistics->visitors()->value() * 100, 2);
108 return '<span class="no-wrap">' . Security::string($visitors) . '</span> <span class="percentage">(' . Security::string($visitors_percentage) . ')</span>';
109 } elseif ($column_id == 'sessions') {
110 $sessions = Number_Formatter::decimal($row->sessions());
111 $sessions_percentage = Number_Formatter::percent($row->sessions() / $this->statistics->sessions()->value() * 100, 2);
112 return '<span class="no-wrap">' . Security::string($sessions) . '</span> <span class="percentage">(' . Security::string($sessions_percentage) . ')</span>';
113 } elseif ($column_id === 'entrances') {
114 $entrances = Number_Formatter::decimal($row->entrances());
115 $entrances_percentage = Number_Formatter::percent($row->entrances() / $this->statistics->sessions()->value() * 100, 2);
116 return '<span class="no-wrap">' . Security::string($entrances) . '</span> <span class="percentage">(' . Security::string($entrances_percentage) . ')</span>';
117 } elseif ($column_id === 'exits') {
118 $exits = Number_Formatter::decimal($row->exits());
119 $exits_percentage = Number_Formatter::percent($row->exits() / $this->statistics->sessions()->value() * 100, 2);
120 return '<span class="no-wrap">' . Security::string($exits) . '</span> <span class="percentage">(' . Security::string($exits_percentage) . ')</span>';
121 } elseif ($column_id === 'bounce_rate') {
122 return Security::string(Number_Formatter::percent($row->bounce_rate()));
123 } elseif ($column_id === 'average_session_duration' || $column_id === 'average_view_duration') {
124 return Number_Formatter::second_to_minute_timestamp($row->{$column_id}());
125 } elseif ($column_id === 'views_growth' || $column_id === 'visitors_growth' || $column_id === 'wc_conversion_rate' || $column_id === 'exit_percent' || Str::startsWith($column_id, 'form_conversion_rate')) {
126 return Number_Formatter::percent($row->{$column_id}(), 2);
127 } elseif ($column_id == 'url') {
128 if ($row->is_deleted()) {
129 return \urldecode(\esc_url($row->url()));
130 } else {
131 return '<a href="' . \esc_url($row->url(\true)) . '" target="_blank" class="external-link">' . \urldecode(\esc_url($row->url())) . '<span class="dashicons dashicons-external"></span></a>';
132 }
133 } elseif ($column_id == 'author') {
134 return Security::html($row->avatar()) . ' ' . Security::string($row->author());
135 } elseif ($column_id == 'date') {
136 return Security::string(\date(WordPress_Site_Date_Format_Pattern::for_php(), \strtotime($row->date())));
137 } elseif ($column_id == 'type' && \method_exists($row, 'icon') && \method_exists($row, 'type')) {
138 return $row->icon(0) . ' ' . Security::string($row->type());
139 } elseif ($column_id == 'referrer' && $row->has_link()) {
140 return '<a href="' . \esc_url($row->referrer_url()) . '" target="_blank" class="external-link">' . Security::string($row->referrer()) . '<span class="dashicons dashicons-external"></span></a>';
141 } elseif ($column_id === 'device_type') {
142 return Icon_Directory_Factory::device_types()->find($row->device_type()) . Security::string($row->device_type());
143 } elseif ($column_id === 'browser') {
144 return Icon_Directory_Factory::browsers()->find($row->browser()) . Security::string($row->browser());
145 } elseif ($column_id === 'os') {
146 return Icon_Directory_Factory::operating_systems()->find($row->os()) . Security::string($row->os());
147 } elseif ($column_id === 'country') {
148 return Icon_Directory_Factory::flags()->find($row->country_code()) . Security::string($row->country());
149 } elseif ($column_id === 'wc_gross_sales' || $column_id === 'wc_refunded_amount' || $column_id === 'wc_net_sales' || $column_id === 'wc_average_order_volume') {
150 return Security::string(Currency::format($row->{$column_id}()));
151 } elseif ($column_id === 'wc_earnings_per_visitor') {
152 return Security::string(Currency::format($row->{$column_id}(), \false));
153 } elseif ($column_id === 'views_per_session') {
154 return Number_Formatter::decimal($row->{$column_id}(), 2);
155 } else {
156 return Security::string($row->{$column_id}());
157 }
158 }
159 public function output_report_toolbar()
160 {
161 $options = Dashboard_Options::getInstance();
162 $exact_start = $options->get_date_range()->start()->setTimezone(Timezone::site_timezone())->format('Y-m-d');
163 $exact_end = $options->get_date_range()->end()->setTimezone(Timezone::site_timezone())->format('Y-m-d');
164 ?>
165 <div id="toolbar" class="toolbar" data-filter-count="<?php
166 echo \count($options->filters());
167 ?>">
168 <div class="date-picker-parent">
169 <div class="modal-parent dates"
170 data-controller="dates"
171 data-dates-relative-range-id-value="<?php
172 echo \esc_attr($options->relative_range_id());
173 ?>"
174 data-dates-exact-start-value="<?php
175 echo \esc_attr($exact_start);
176 ?>"
177 data-dates-exact-end-value="<?php
178 echo \esc_attr($exact_end);
179 ?>"
180 data-dates-first-day-of-week-value="<?php
181 echo \absint(\IAWPSCOPED\iawp()->get_option('iawp_dow', 0));
182 ?>"
183 data-dates-css-url-value="<?php
184 echo \esc_url(\IAWPSCOPED\iawp_url_to('dist/styles/easepick/datepicker.css'));
185 ?>"
186 data-dates-format-value="<?php
187 echo \esc_attr(WordPress_Site_Date_Format_Pattern::for_javascript());
188 ?>"
189 >
190 <button id="dates-button"
191 data-testid="open-calendar"
192 class="iawp-button"
193 data-action="dates#toggleModal"
194 data-dates-target="modalButton"
195 >
196 <span class="dashicons dashicons-calendar-alt"></span>
197 <span class="iawp-label"><?php
198 echo \esc_html($options->get_date_range()->label());
199 ?></span>
200 </button>
201 <div id="modal-dates"
202 class="iawp-modal large dates"
203 data-dates-target="modal"
204 >
205 <div class="modal-inner">
206 <div id="easepick-picker"
207 data-dates-target="easepick"
208 style="display: none;"
209 >
210 </div>
211 <div class="relative-dates">
212 <?php
213 foreach (Relative_Date_Range::ranges() as $date_range) {
214 ?>
215 <?php
216 $exact_start = $date_range->start()->setTimezone(Timezone::site_timezone())->format('Y-m-d');
217 ?>
218 <?php
219 $exact_end = $date_range->end()->setTimezone(Timezone::site_timezone())->format('Y-m-d');
220 ?>
221 <button class="iawp-button"
222 data-dates-target="relativeRange"
223 data-action="dates#relativeRangeSelected"
224 data-relative-range-id="<?php
225 echo \esc_attr($date_range->relative_range_id());
226 ?>"
227 data-relative-range-label="<?php
228 echo \esc_attr($date_range->label());
229 ?>"
230 data-relative-range-start="<?php
231 echo \esc_attr($exact_start);
232 ?>"
233 data-relative-range-end="<?php
234 echo \esc_attr($exact_end);
235 ?>"
236 >
237 <?php
238 echo \esc_html($date_range->label());
239 ?>
240 </button>
241 <?php
242 }
243 ?>
244 </div>
245 <div class="apply-buttons">
246 <button class="iawp-button purple"
247 data-dates-target="apply"
248 data-action="dates#apply"
249 data-testid="apply-dates"
250 >
251 <?php
252 \esc_html_e('Apply', 'independent-analytics');
253 ?>
254 </button>
255 <button class="iawp-button ghost-purple"
256 data-action="dates#closeModal"
257 data-testid="close-calendar"
258 >
259 <?php
260 \esc_html_e('Cancel', 'independent-analytics');
261 ?>
262 </button>
263 </div>
264 </div>
265 </div>
266 </div>
267 </div>
268 <div class="filter-parent">
269 <?php
270 echo $this->filters()->get_filters_html($this->get_columns());
271 ?>
272 </div>
273 <div class="download-options-parent" data-controller="modal">
274 <div class="modal-parent downloads">
275 <button id="download-options" data-modal-target="modalButton" data-action="click->modal#toggleModal" class="download-options">
276 <?php
277 \esc_html_e('Download Report', 'independent-analytics');
278 ?>
279 </button>
280 <div class="iawp-modal small downloads" data-modal-target="modal">
281 <div class="modal-inner">
282 <div class="title-small"><?php
283 \esc_html_e('Choose a format', 'independent-analytics');
284 ?></div>
285 <button id="download-csv" class="iawp-button" data-report-target="exportCSV" data-action="report#exportCSV">
286 <span class="dashicons dashicons-media-spreadsheet"></span>
287 <span class="iawp-label">
288 <?php
289 \esc_html_e('Download CSV', 'independent-analytics');
290 ?>
291 </span>
292 </button>
293 <button id="download-pdf" class="iawp-button" data-report-target="exportPDF" data-action="report#exportPDF" disabled="disabled">
294 <span class="dashicons dashicons-pdf"></span>
295 <span class="iawp-label">
296 <?php
297 \esc_html_e('Download PDF', 'independent-analytics');
298 ?>
299 </span>
300 </button>
301 </div>
302 </div>
303 </div>
304 </div>
305 </div><?php
306 }
307 public function filters_template_html() : string
308 {
309 return $this->filters()->get_condition_html($this->get_columns());
310 }
311 public function filters_condition_buttons_html(array $filters) : string
312 {
313 return $this->filters()->condition_buttons_html($filters);
314 }
315 public final function csv(array $rows, bool $is_dashboard_export = \false) : CSV
316 {
317 $columns = $this->get_columns();
318 $csv_header = [];
319 $csv_rows = [];
320 foreach ($columns as $column) {
321 if (!$this->include_column_in_csv($column, $is_dashboard_export)) {
322 continue;
323 }
324 $csv_header[] = $column->name();
325 }
326 foreach ($rows as $row) {
327 $csv_row = [];
328 foreach ($columns as $column) {
329 if (!$this->include_column_in_csv($column, $is_dashboard_export)) {
330 continue;
331 }
332 $column_id = $column->id();
333 $value = $row->{$column_id}();
334 // Todo - This logic is similar to the rendering logic for table cells. This should
335 // all be handled via the column class itself.
336 if (\is_null($value)) {
337 $csv_row[] = '-';
338 } elseif ($column_id === 'date') {
339 $csv_row[] = \date(WordPress_Site_Date_Format_Pattern::for_php(), \strtotime($value));
340 } elseif ($column_id === 'average_session_duration' || $column_id === 'average_view_duration') {
341 $csv_row[] = Number_Formatter::second_to_minute_timestamp($value);
342 } elseif ($column_id === 'views_per_session') {
343 $csv_row[] = Number_Formatter::decimal($value, 2);
344 } else {
345 $csv_row[] = $row->{$column_id}();
346 }
347 }
348 $csv_rows[] = $csv_row;
349 }
350 $csv = new CSV($csv_header, $csv_rows);
351 return $csv;
352 }
353 /**
354 * @param array[] $filters Raw filter associative arrays
355 *
356 * @return Filter[]
357 */
358 public function sanitize_filters(array $filters) : array
359 {
360 return \array_values(\array_filter(\array_map(function ($filter) {
361 return $this->sanitize_filter($filter);
362 }, $filters)));
363 }
364 public function sanitize_filter(array $filter) : ?Filter
365 {
366 $column = $this->get_column($filter['column']);
367 if (\is_null($column)) {
368 return null;
369 }
370 $valid_inclusions = ['include', 'exclude'];
371 if (!\in_array($filter['inclusion'], $valid_inclusions)) {
372 return null;
373 }
374 if (!$column->is_valid_filter_operator($filter['operator'])) {
375 return null;
376 }
377 if (!$column->is_enabled_for_group($this->group())) {
378 return null;
379 }
380 $operand = \trim(Security::string($filter['operand']));
381 if (\strlen($operand) === 0) {
382 return null;
383 }
384 if ($column->database_column() === 'cached_url' && $filter['operator'] === 'exact') {
385 $url = new URL($filter['operand']);
386 if (!$url->is_valid_url()) {
387 $filter['operand'] = \site_url($filter['operand']);
388 }
389 }
390 return new Filter(['inclusion' => Security::string($filter['inclusion']), 'column' => $column->id(), 'operator' => Security::string($filter['operator']), 'operand' => Security::string($filter['operand']), 'database_column' => $column->database_column()]);
391 }
392 public function get_column(string $id) : ?Column
393 {
394 $matches = \array_filter($this->local_columns(), function (Column $column) use($id) {
395 return $column->id() === $id;
396 });
397 return \count($matches) === 1 ? \reset($matches) : null;
398 }
399 public function sanitize_sort_parameters(?string $sort_column, ?string $sort_direction) : Sort_Configuration
400 {
401 $column = $this->get_column($sort_column);
402 if (\is_null($column) || !$column->is_enabled_for_group($this->group)) {
403 return new Sort_Configuration();
404 }
405 return new Sort_Configuration($sort_column, $sort_direction, $column->is_nullable());
406 }
407 public function get_rendered_template($rows, $just_rows = \false, string $sort_column = 'visitors', string $sort_direction = 'desc')
408 {
409 if ($just_rows) {
410 return \IAWPSCOPED\iawp_blade()->run('tables.rows', ['table' => $this, 'table_name' => $this->table_name(), 'all_columns' => $this->get_columns(), 'visible_column_count' => $this->visible_column_count(), 'number_of_shown_rows' => \count($rows), 'rows' => $rows, 'render_skeleton' => \false, 'page_size' => \IAWPSCOPED\iawp()->pagination_page_size(), 'sort_column' => $sort_column, 'sort_direction' => $sort_direction, 'has_campaigns' => Campaign_Builder::has_campaigns()]);
411 }
412 return \IAWPSCOPED\iawp_blade()->run('tables.table', ['table' => $this, 'table_name' => $this->table_name(), 'all_columns' => $this->get_columns(), 'visible_column_count' => $this->visible_column_count(), 'number_of_shown_rows' => \count($rows), 'rows' => $rows, 'render_skeleton' => \false, 'page_size' => \IAWPSCOPED\iawp()->pagination_page_size(), 'sort_column' => $sort_column, 'sort_direction' => $sort_direction, 'has_campaigns' => Campaign_Builder::has_campaigns()]);
413 }
414 protected function get_woocommerce_columns() : array
415 {
416 return [new Column(['id' => 'wc_orders', 'name' => \__('Orders', 'independent-analytics'), 'plugin_group' => 'woocommerce', 'type' => 'int']), new Column(['id' => 'wc_gross_sales', 'name' => \__('Gross Sales', 'independent-analytics'), 'plugin_group' => 'woocommerce', 'type' => 'int']), new Column(['id' => 'wc_refunds', 'name' => \__('Refunds', 'independent-analytics'), 'plugin_group' => 'woocommerce', 'type' => 'int']), new Column(['id' => 'wc_refunded_amount', 'name' => \__('Refunded Amount', 'independent-analytics'), 'plugin_group' => 'woocommerce', 'type' => 'int']), new Column(['id' => 'wc_net_sales', 'name' => \__('Net Sales', 'independent-analytics'), 'plugin_group' => 'woocommerce', 'type' => 'int']), new Column(['id' => 'wc_conversion_rate', 'name' => \__('Conversion Rate', 'independent-analytics'), 'plugin_group' => 'woocommerce', 'type' => 'int']), new Column(['id' => 'wc_earnings_per_visitor', 'name' => \__('Earnings Per Visitor', 'independent-analytics'), 'plugin_group' => 'woocommerce', 'type' => 'int']), new Column(['id' => 'wc_average_order_volume', 'name' => \__('Average Order Volume', 'independent-analytics'), 'plugin_group' => 'woocommerce', 'type' => 'int'])];
417 }
418 protected function get_form_columns() : array
419 {
420 $columns = [new Column(['id' => 'form_submissions', 'name' => \__('Submissions', 'independent-analytics'), 'plugin_group' => 'forms', 'type' => 'int']), new Column(['id' => 'form_conversion_rate', 'name' => \__('Conversion Rate', 'independent-analytics'), 'plugin_group' => 'forms', 'type' => 'int'])];
421 foreach (Form::get_forms() as $form) {
422 $columns[] = new Column(['id' => $form->submissions_column(), 'name' => $form->title() . ' ' . \__('Submissions', 'independent-analytics'), 'plugin_group' => 'forms', 'is_plugin_active' => $form->is_plugin_active(), 'plugin_group_header' => $form->plugin_name(), 'type' => 'int']);
423 $columns[] = new Column(['id' => $form->conversion_rate_column(), 'name' => $form->title() . ' ' . \__('Conversion Rate', 'independent-analytics'), 'plugin_group' => 'forms', 'is_plugin_active' => $form->is_plugin_active(), 'plugin_group_header' => $form->plugin_name(), 'type' => 'int']);
424 }
425 return $columns;
426 }
427 private function include_column_in_csv(Column $column, bool $is_dashboard_export) : bool
428 {
429 if (!$column->is_visible() && $is_dashboard_export) {
430 return \false;
431 }
432 if (!$column->exportable() && !$is_dashboard_export) {
433 return \false;
434 }
435 if (!$column->is_enabled()) {
436 return \false;
437 }
438 return \true;
439 }
440 /**
441 * @return Column[]
442 */
443 private function get_columns($show_disabled_columns = \false) : array
444 {
445 $columns_for_group = \array_filter($this->local_columns(), function (Column $column) {
446 return $column->is_enabled_for_group($this->group) && $column->is_plugin_active();
447 });
448 if ($show_disabled_columns === \true) {
449 } else {
450 $columns_for_group = \array_filter($columns_for_group, function (Column $column) {
451 return $column->is_enabled();
452 });
453 }
454 if (\is_null($this->visible_columns) || \count($this->visible_columns) === 0) {
455 return $columns_for_group;
456 }
457 if (!$this->is_new_group) {
458 return \array_map(function ($column) {
459 $column->set_visibility(\in_array($column->id(), $this->visible_columns));
460 return $column;
461 }, $columns_for_group);
462 }
463 return \array_map(function ($column) {
464 if ($column->is_group_dependent()) {
465 $column->set_visibility(\true);
466 } elseif (!\in_array($column->id(), $this->visible_columns)) {
467 $column->set_visibility(\false);
468 }
469 return $column;
470 }, $columns_for_group);
471 }
472 /**
473 * Get the number of visible columns
474 *
475 * @return int
476 */
477 private function visible_column_count() : int
478 {
479 $visible_columns = 0;
480 foreach ($this->get_columns() as $column) {
481 if ($column->is_visible()) {
482 $visible_columns++;
483 }
484 }
485 return $visible_columns;
486 }
487 private function filters()
488 {
489 return $this->filters;
490 }
491 public static function get_table_by_type(string $type) : ?string
492 {
493 switch ($type) {
494 case 'views':
495 return \IAWP\Tables\Table_Pages::class;
496 case 'referrers':
497 return \IAWP\Tables\Table_Referrers::class;
498 case 'geo':
499 return \IAWP\Tables\Table_Geo::class;
500 case 'campaigns':
501 return \IAWP\Tables\Table_Campaigns::class;
502 case 'devices':
503 return \IAWP\Tables\Table_Devices::class;
504 default:
505 return null;
506 }
507 }
508 }
509