PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 1.18
Independent Analytics – WordPress Analytics Plugin v1.18
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
column.php 3 years ago table.php 3 years ago table_campaigns.php 3 years ago table_geo.php 3 years ago table_referrers.php 3 years ago table_views.php 3 years ago
table.php
423 lines
1 <?php
2
3 namespace IAWP;
4
5 abstract class Table
6 {
7 /**
8 * @return array<Column>
9 */
10 protected abstract function local_columns() : array;
11
12 protected abstract function table_name() : string;
13
14 private $filters ;
15 private $visible_columns ;
16 private $views ;
17 public function __construct( $visible_columns = null )
18 {
19 $this->filters = new Filters();
20 $this->visible_columns = $visible_columns;
21 }
22
23 public function get_columns() : array
24 {
25 if ( $this->visible_columns === null ) {
26 return $this->local_columns();
27 }
28 return array_map( function ( $column ) {
29 if ( in_array( $column->id(), $this->visible_columns ) ) {
30 $column->set_visible( true );
31 }
32 return $column;
33 }, $this->local_columns() );
34 }
35
36 public function visible_column_ids()
37 {
38 $visible_columns = [];
39 foreach ( $this->get_columns() as $column ) {
40 if ( $column->visible() ) {
41 $visible_columns[] = $column->id();
42 }
43 }
44 return $visible_columns;
45 }
46
47 public function get_table_markup()
48 {
49 $opts = new Dashboard_Options();
50 $templates = IAWP()->templates();
51 return $templates->render( 'table/index', [
52 'just_rows' => false,
53 'table_name' => $this->table_name(),
54 'all_columns' => $this->get_columns(),
55 'visible_columns' => $this->get_visible_columns(),
56 'row_count' => 0,
57 'rows' => [],
58 'render_skeleton' => true,
59 'page_size' => IAWP()->pagination_page_size(),
60 'opts' => $opts,
61 ] );
62 }
63
64 public function set_views( $views )
65 {
66 $this->views = $views;
67 }
68
69 public function get_row_markup( $rows )
70 {
71 return $this->get_rendered_template( $rows, true );
72 }
73
74 private function get_visible_columns() : int
75 {
76 $visible_columns = 0;
77 foreach ( $this->get_columns() as $column ) {
78 if ( $column->visible() ) {
79 $visible_columns++;
80 }
81 }
82 return $visible_columns;
83 }
84
85 private function get_rendered_template( $rows, $just_rows = false )
86 {
87 $opts = new Dashboard_Options();
88 $templates = IAWP()->templates();
89 $templates->registerFunction( 'row_data_attributes', [ $this, 'get_row_data_attributes' ] );
90 $templates->registerFunction( 'cell_content', [ $this, 'get_cell_content' ] );
91 return $templates->render( 'table/index', [
92 'just_rows' => $just_rows,
93 'table_name' => $this->table_name(),
94 'all_columns' => $this->get_columns(),
95 'visible_columns' => $this->get_visible_columns(),
96 'row_count' => count( $rows ),
97 'rows' => $rows,
98 'render_skeleton' => false,
99 'page_size' => IAWP()->pagination_page_size(),
100 'opts' => $opts,
101 ] );
102 }
103
104 public function get_row_data_attributes( $row )
105 {
106 $html = '';
107 foreach ( $this->get_columns() as $column ) {
108 $id = $column->id();
109 $data_val = $row->{$id}();
110 $html .= ' data-' . esc_attr( $column->id() ) . '="' . esc_attr( $data_val ) . '"';
111 }
112 return $html;
113 }
114
115 public function get_cell_content( $row, $column_id )
116 {
117 if ( is_null( $row->{$column_id}() ) ) {
118 return null;
119 }
120
121 if ( $column_id == 'title' && $row->is_deleted() ) {
122 return Security::string( $row->{$column_id}() ) . ' <span class="deleted-label">' . esc_html__( '(deleted)', 'iawp' ) . '</span>';
123 } elseif ( $column_id == 'views' ) {
124 $views = number_format( $row->views(), 0 );
125 // Getting a divide by zero error from the line below?
126 // It's likely an issue with $this->views which is an instance of Views. Make sure the queries there are working.
127 $views_percentage = Number_Formatter::format( $row->views() / $this->views->views() * 100, 'percent', 2 );
128 return Security::string( $views ) . ' <span class="percentage">(' . Security::string( $views_percentage ) . ')</span>';
129 } elseif ( $column_id == 'visitors' ) {
130 $visitors = number_format( $row->visitors(), 0 );
131 $visitors_percentage = Number_Formatter::format( $row->visitors() / $this->views->visitors() * 100, 'percent', 2 );
132 return Security::string( $visitors ) . ' <span class="percentage">(' . Security::string( $visitors_percentage ) . ')</span>';
133 } elseif ( $column_id === 'views_growth' || $column_id === 'visitors_growth' || $column_id === 'woocommerce_conversion_rate' ) {
134 return Number_Formatter::format( $row->{$column_id}(), 'percent', 2 );
135 } elseif ( $column_id == 'url' ) {
136
137 if ( $row->is_deleted() ) {
138 return Security::string( esc_url( $row->url() ) );
139 } else {
140 return '<a href="' . Security::string( esc_url( $row->url( true ) ) ) . '" target="_blank" class="external-link">' . Security::string( esc_url( $row->url() ) ) . '<span class="dashicons dashicons-external"></span></a>';
141 }
142
143 } elseif ( $column_id == 'author' ) {
144 return Security::html( $row->avatar() ) . ' ' . Security::string( $row->author() );
145 } elseif ( $column_id == 'date' ) {
146 return Security::string( date( Date_Format::php(), $row->date() ) );
147 } elseif ( $column_id == 'type' && method_exists( $row, 'icon' ) ) {
148 return $row->icon( 0 ) . ' ' . Security::string( $row->type() );
149 } elseif ( $column_id == 'referrer' && !$row->is_direct() ) {
150 return '<a href="' . esc_url( $row->referrer_url() ) . '" target="_blank" class="external-link">' . Security::string( $row->referrer() ) . '<span class="dashicons dashicons-external"></span></a>';
151 } elseif ( $column_id === 'country' ) {
152 return '<img class="flag" alt="Country flag" src="' . Security::string( $row->flag() ) . '"/>' . Security::string( $row->country() );
153 } elseif ( function_exists( 'wc_price' ) && ($column_id === 'wc_gross_sales' || $column_id === 'wc_refunded_amount' || $column_id === 'wc_net_sales' || $column_id === 'woocommerce_earnings_per_visitor' || $column_id === 'woocommerce_average_order_volume') ) {
154 return Security::string( wc_price( $row->{$column_id}() ) );
155 } else {
156 return Security::string( $row->{$column_id}() );
157 }
158
159 }
160
161 private function filters()
162 {
163 return $this->filters;
164 }
165
166 public function output_toolbar()
167 {
168 $opts = new Dashboard_Options();
169 ?>
170 <div class="toolbar">
171 <div class="buttons">
172 <div class="modal-parent"
173 data-controller="dates"
174 data-dates-relative-range-id-value="<?php
175 echo $opts->relative_range() ;
176 ?>"
177 data-dates-exact-start-value="<?php
178 echo $opts->start() ;
179 ?>"
180 data-dates-exact-end-value="<?php
181 echo $opts->end() ;
182 ?>"
183 data-dates-first-day-of-week-value="<?php
184 echo absint( IAWP()->get_option( 'iawp_dow', 0 ) ) ;
185 ?>"
186 data-dates-css-url-value="<?php
187 echo esc_url( url_to( 'dist/styles/easepick/datepicker.css' ) ) ;
188 ?>"
189 data-dates-format-value="<?php
190 echo esc_attr( Date_Format::js() ) ;
191 ?>"
192 >
193 <button id="dates-button"
194 class="iawp-button ghost-white"
195 data-action="dates#toggleModal"
196 data-dates-target="modalButton"
197 >
198 <span class="dashicons dashicons-calendar-alt"></span>
199 <span><?php
200 echo $opts->date_label() ;
201 ?></span>
202 </button>
203 <div id="modal-dates"
204 class="modal large flex"
205 data-dates-target="modal"
206 >
207 <div class="modal-inner">
208 <div id="easepick-picker"
209 data-dates-target="easepick"
210 style="display: none;"
211 >
212 </div>
213 <div class="relative-dates">
214 <?php
215 foreach ( Relative_Range::ranges() as $range ) {
216 ?>
217 <button class="iawp-button ghost-purple"
218 data-dates-target="relativeRange"
219 data-action="dates#relativeRangeSelected"
220 data-relative-range-id="<?php
221 echo $range->id ;
222 ?>"
223 data-relative-range-label="<?php
224 echo $range->label ;
225 ?>"
226 data-relative-range-start="<?php
227 echo $range->start->format( 'Y-m-d' ) ;
228 ?>"
229 data-relative-range-end="<?php
230 echo $range->end->format( 'Y-m-d' ) ;
231 ?>"
232 >
233 <?php
234 echo $range->label ;
235 ?>
236 </button>
237 <?php
238 }
239 ?>
240 </div>
241 <div>
242 <hr/>
243 </div>
244 <div>
245 <button class="iawp-button purple"
246 data-dates-target="apply"
247 data-action="dates#apply"
248 >
249 <?php
250 esc_html_e( 'Apply', 'iawp' );
251 ?>
252 </button>
253 <button class="iawp-button ghost-purple"
254 data-action="dates#closeModal"
255 >
256 <?php
257 esc_html_e( 'Cancel', 'iawp' );
258 ?>
259 </button>
260 </div>
261 </div>
262 </div>
263 </div>
264 <?php
265 $this->filters()->output_filters( $this->get_columns() );
266 ?>
267 <?php
268 $this->column_picker();
269 ?>
270 </div>
271 <div class="buttons">
272 <button class="iawp-button ghost-white"
273 data-controller="clipboard"
274 data-action="clipboard#copy"
275 >
276 <span class="dashicons dashicons-admin-page"></span>
277 <span data-clipboard-target="statusTextElement">
278 <?php
279 esc_html_e( 'Copy Dashboard URL', 'iawp' );
280 ?>
281 </span>
282 </button>
283 <a class="learn-more"
284 href="https://independentwp.com/knowledgebase/dashboard/save-reports-revisit-later/"
285 target="_blank"><span class="dashicons dashicons-info-outline"></span></a>
286 </div>
287 </div><?php
288 }
289
290 private function column_picker()
291 {
292 ?>
293
294 <div class="customize-columns modal-parent small"
295 data-controller="columns"
296 >
297 <button id="customize-columns"
298 class="iawp-button ghost-white"
299 data-action="columns#toggleModal"
300 data-columns-target="modalButton"
301 >
302 <span class="dashicons dashicons-columns"></span>
303 <span><?php
304 esc_html_e( 'Edit Columns', 'iawp' );
305 ?></span>
306 </button>
307 <div id="modal-columns"
308 class="modal small"
309 data-columns-target="modal"
310 >
311 <div class="modal-inner">
312 <div class="title-small">
313 <?php
314 esc_html_e( 'Columns', 'iawp' );
315 ?>
316 </div>
317 <?php
318 foreach ( $this->get_columns() as $column ) {
319 ?>
320 <?php
321
322 if ( $column->id() === 'wc_orders' ) {
323 ?>
324 <p class="title-small wc-title">
325 <?php
326 esc_html_e( 'WooCommerce', 'iawp' );
327 ?>
328 <?php
329 ?>
330 <span class="pro-label"><?php
331 esc_html_e( 'PRO', 'iawp' );
332 ?></span>
333 <?php
334 ?>
335 </p>
336 <?php
337 }
338
339 ?>
340
341 <label class="column-label"
342 for="iawp-column-<?php
343 echo esc_attr( $column->id() ) ;
344 ?>"
345 >
346 <input id="iawp-column-<?php
347 echo esc_attr( $column->id() ) ;
348 ?>"
349 <?php
350
351 if ( $column->requires_pro() && !IAWP_FS()->can_use_premium_code__premium_only() ) {
352 ?>
353 <?php
354 checked( true, false, true );
355 ?>
356 disabled="disabled"
357 data-locked-behind-pro="true"
358 <?php
359 } else {
360 ?>
361 <?php
362 checked( true, $column->visible(), true );
363 ?>
364 data-columns-target="checkbox"
365 data-action="columns#check"
366 <?php
367 }
368
369 ?>
370 type="checkbox"
371 name="<?php
372 esc_attr_e( $column->id() );
373 ?>"
374 data-test-visibility="<?php
375 echo ( $column->visible() ? 'visible' : 'hidden' ) ;
376 ?>"
377 >
378 <span><?php
379 echo esc_html( $column->label() ) ;
380 ?></span>
381 </label>
382 <?php
383 }
384 ?>
385 </div>
386 </div>
387 </div>
388 <?php
389 }
390
391 public final function csv( $rows )
392 {
393 $columns = $this->get_columns();
394 $csv_header = [];
395 $csv_rows = [];
396 foreach ( $columns as $column ) {
397 if ( !$column->exportable() || $column->requires_pro() && !IAWP_FS()->can_use_premium_code__premium_only() ) {
398 continue;
399 }
400 $csv_header[] = $column->label();
401 }
402 foreach ( $rows as $row ) {
403 $csv_row = [];
404 foreach ( $columns as $column ) {
405 if ( !$column->exportable() || $column->requires_pro() && !IAWP_FS()->can_use_premium_code__premium_only() ) {
406 continue;
407 }
408 $column_id = $column->id();
409
410 if ( $column_id === 'date' ) {
411 $csv_row[] = date( Date_Format::php(), $row->{$column_id}() );
412 } else {
413 $csv_row[] = $row->{$column_id}();
414 }
415
416 }
417 $csv_rows[] = $csv_row;
418 }
419 $csv = array_merge( [ $csv_header ], $csv_rows );
420 return Array_To_CSV::array2csv( $csv );
421 }
422
423 }