PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 1.5
Independent Analytics – WordPress Analytics Plugin v1.5
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 / table.php
independent-analytics / inc Last commit date
models 4 years ago queries 4 years ago utils 4 years ago chart.php 4 years ago db.php 4 years ago delete_data_ajax.php 4 years ago filters.php 4 years ago filters_ajax.php 4 years ago rest_api.php 4 years ago settings.php 4 years ago settings_ajax.php 4 years ago super_secret_content_generator.php 4 years ago table.php 4 years ago table_referrers.php 4 years ago table_views.php 4 years ago track_resource_changes.php 4 years ago
table.php
245 lines
1 <?php
2
3 namespace IAWP;
4
5 abstract class Table
6 {
7 abstract protected function table_name();
8
9 private $filters;
10
11 public function __construct()
12 {
13 add_action('admin_init', [$this, 'register_settings']);
14 $this->filters = new Filters();
15 }
16
17 public function filters()
18 {
19 return $this->filters;
20 }
21
22 public function output_data_table(array $dates = null)
23 {
24 if ($dates == null) {
25 $dates = IAWP()->default_date_range();
26 }
27
28 $rows = $this->rows($dates);
29 $columns = $this->default_columns();
30
31 // Todo - Add a way for the UI to figure out what type of data it's working with...
32 $html = "<div id='data-table' class='data-table' data-table-name='" . esc_attr($this->table_name()) . "'
33 data-columns='" . Security::json_encode($columns) . "' data-column-count='" . count($columns) . "'>";
34 $html .= '<div id="columns" class="columns">';
35 $html .= '<div class="row">';
36 $html .= $this->cells('heading', $columns, null, count($rows));
37 $html .= '</div>';
38 $html .= '</div>';
39 $html .= $this->data_table_rows($rows, $columns);
40 $html .= '</div>';
41
42 return $html;
43 }
44
45 public function data_table_rows(array $rows, array $columns)
46 {
47 $html = '<div id="rows" class="rows">';
48 if (count($rows) == 0) {
49 $html .= '<p id="data-error" class="data-error">' . esc_html__('No ' . $this->display_name() . ' found.', 'iawp') . '</p>';
50 } else {
51 $count = 1;
52 foreach ($rows as $row) {
53 $classes = 'row';
54 if ($this->table_name() == 'views') {
55 $classes = $row->is_deleted() ? 'row deleted' : 'row';
56 }
57 $html .= '<div class="' . esc_attr($classes) . '" ' . $this->row_data_attrs($row) . '>';
58 $html .= $this->cells('rows', $columns, $row, $count);
59 $html .= '</div>';
60 $count++;
61 }
62 }
63
64 $html .= '</div>';
65
66 return $html;
67 }
68
69 public function cells($context, $columns, $data = null, $count = null)
70 {
71 $html = '';
72 foreach ($this->columns() as $key => $value) {
73 $classes = 'cell';
74 $classes .= !in_array($key, $columns) ? ' hide' : '';
75 $html .= '<div class="' . esc_attr($classes) . '" data-column="' . esc_attr($key) . '">';
76 if ($context == 'heading') {
77 $html .= $this->heading_cell_content($key, $value, $count);
78 } else {
79 $html .= $this->row_cell_content($key, $data, $count);
80 }
81 $html .= '</div>';
82 }
83
84 return $html;
85 }
86
87 public function heading_cell_content($key, $value, $count)
88 {
89 $classes = $key == 'views' ? 'sort-button desc' : 'sort-button';
90 $html = '<button class="' . esc_attr($classes) . '" data-sort="' . esc_attr($key) . '">';
91 $html .= '<div class="row-number">' . absint($count) . '</div>';
92 $html .= '<span class="name">' . esc_html($value) . '</span>';
93 $html .= '<span class="dashicons dashicons-arrow-right"></span><span class="dashicons dashicons-arrow-up"></span><span class="dashicons dashicons-arrow-down"></span>';
94 $html .= '<div class="animator"></div>';
95 $html .= '</button>';
96
97 return $html;
98 }
99
100 public function row_cell_content($key, $data, $count)
101 {
102 return '<div class="row-number">' . absint($count) . '</div><span class="cell-content">' . $this->get_cell_content($data, $key) . '</span><div class="animator"></div>';
103 }
104
105 public function row_data_attrs($data)
106 {
107 $html = '';
108
109 foreach ($this->columns() as $key => $value) {
110 $data_val = $data->$key();
111 // Need to make an exception for labels so that sorting matches what people see e.g. attachment -> Media
112 if ($key == 'type') {
113 $data_val = $data->type_label();
114 }
115
116 $html .= ' data-' . esc_attr($key) . '="' . esc_attr($data_val) . '"';
117 }
118
119 return $html;
120 }
121
122 public function get_cell_content($data, string $column)
123 {
124 if ($data->$column() == null) {
125 return null;
126 }
127 if ($column == 'title' && $data->is_deleted()) {
128 return Security::string($data->$column()) . ' <span class="deleted-label">' . esc_html__('(deleted)', 'iawp') . '</span>';
129 } elseif ($column == 'views') {
130 return number_format($data->views(), 0);
131 } elseif ($column == 'url') {
132 if ($data->is_deleted()) {
133 return esc_url($data->url());
134 } else {
135 return '<a href="' . esc_url($data->url()) . '" target="_blank" class="external-link">' . esc_url($data->url()) . '<span class="dashicons dashicons-external"></span></a>';
136 }
137 } elseif ($column == 'author') {
138 return Security::html($data->avatar()) . ' ' . Security::string($data->author());
139 } elseif ($column == 'date') {
140 return Security::string(date(Date_Format::php(), $data->date()));
141 } elseif ($column == 'type' && method_exists($data, 'icon')) {
142 return Security::html($data->icon(0)) . ' ' . Security::string($data->type_label());
143 } elseif ($column == 'referrer' && !$data->is_direct()) {
144 return '<a href="' . esc_url($data->referrer()) . '" target="_blank" class="external-link">' . Security::string($data->referrer_name()) . '<span class="dashicons dashicons-external"></span></a>';
145 } else {
146 return $data->$column();
147 }
148 }
149
150 public function output_toolbar(array $columns, $quick_stats = '')
151 {
152 list($start, $end) = IAWP()->default_date_range(); ?>
153 <div class="toolbar">
154 <div class="buttons">
155 <div class="modal-parent">
156 <button id="dates-button" class="iawp-button ghost-white" data-relative-range-id="LAST_THIRTY"
157 data-start="<?php echo esc_attr($start->format('Y-m-d')); ?>"
158 data-end="<?php echo esc_attr($end->format('Y-m-d')); ?>"
159 data-relative-range-text="Last 30 days">
160 <span class="dashicons dashicons-calendar-alt"></span>
161 <span><?php esc_html_e('Last 30 Days', 'iawp'); ?></span>
162 </button>
163 <div id="modal-dates" class="modal large flex">
164 <div class="modal-inner">
165 <!-- <div class="title-small">-->
166 <?php //esc_html_e('Custom dates', 'iawp');
167 ?><!--</div>-->
168 <div id="easepick-picker"
169 style="display: none;"
170 data-format="<?php echo esc_attr(Date_Format::js()); ?>"
171 data-start="<?php echo esc_attr($start->format('Y-m-d')); ?>"
172 data-end="<?php echo esc_attr($end->format('Y-m-d')); ?>"
173 data-dow="<?php echo absint(IAWP()->get_option('iawp_dow', 1)); ?>"
174 data-css="<?php echo esc_url(IAWP_URL) . 'dist/styles/easepick/datepicker.css' ?>"></div>
175 <!-- <div class="title-small">-->
176 <?php //esc_html_e('Relative dates', 'iawp');
177 ?><!--</div>-->
178 <div class="relative-dates">
179 <?php
180 foreach (Relative_Dates::supported_relative_dates() as $relative_date) {
181 ?>
182 <button class="iawp-button ghost-purple"
183 data-relative-range-id="<?php echo $relative_date[0] ?>"
184 data-relative-range-text="<?php echo $relative_date[1] ?>"><?php echo $relative_date[1] ?></button>
185 <?php
186 } ?>
187 </div>
188 <div>
189 <hr/>
190 </div>
191 <div>
192 <button data-target-apply class="iawp-button purple">Apply</button>
193 <button data-target-cancel class="iawp-button ghost-purple">Cancel</button>
194 </div>
195 </div>
196 </div>
197 </div>
198 <div class="customize-filters modal-parent">
199 <button id="customize-filters" class="iawp-button ghost-white">
200 <span class="dashicons dashicons-filter"></span> <?php esc_html_e('Filter Rows', 'iawp'); ?> <span
201 class="count"></span>
202 </button>
203 <?php Security::html($this->filters()->output_filters($columns)); ?>
204 </div>
205 <div class="customize-columns modal-parent small">
206 <button id="customize-columns" class="iawp-button ghost-white"><span
207 class="dashicons dashicons-columns"></span> <?php esc_html_e('Edit Columns', 'iawp'); ?>
208 </button>
209 <?php Security::html($this->column_picker()); ?>
210 </div>
211 </div>
212 <?php echo $quick_stats; ?>
213 </div><?php
214 }
215
216 public function column_picker()
217 { ?>
218 <div id="modal-columns" class="modal small">
219 <div class="modal-inner">
220 <div class="title-small"><?php esc_html_e('Choose your columns', 'iawp'); ?>
221 </div>
222 <?php Security::html($this->columns_callback()); ?>
223 </div>
224 </div>
225 <?php
226 }
227
228 public function columns_callback()
229 {
230 $defaults = $this->default_columns();
231
232 foreach ($this->columns() as $key => $label) {
233 $selected = in_array($key, $defaults) ? true : false; ?>
234 <label class="column-label"
235 for="iawp-column-<?php echo esc_attr($key); ?>">
236 <input type="checkbox" name="iawp_columns[]"
237 id="iawp-column-<?php echo esc_attr($key); ?>" <?php checked(true, $selected, true); ?>
238 value="<?php echo esc_attr($key); ?>"
239 data-column="<?php echo esc_attr($key); ?>">
240 <span><?php echo esc_html($label); ?></span>
241 </label><?php
242 }
243 }
244 }
245