PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / trunk
MainWP Dashboard: Self-hosted WordPress Management for Agencies vtrunk
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / class / class-mainwp-client-list-table.php

class-mainwp-client-list-table.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies trunk, at class/class-mainwp-client-list-table.php

843 lines 37.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Clients List Table.
4 *
5 * @package MainWP/Dashboard
6 */
7
8 namespace MainWP\Dashboard;
9
10 // Exit if accessed directly.
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 /**
16 * Class MainWP_Client_List_Table
17 *
18 * @package MainWP\Dashboard
19 *
20 * MainWP sites client list.
21 *
22 * @devtodo The only variables that seam to be used are $column_headers.
23 *
24 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_List_Table
25 */
26 class MainWP_Client_List_Table extends MainWP_Manage_Sites_List_Table { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
27
28 /**
29 * Protected variable to hold columns headers
30 *
31 * @var array
32 */
33 protected $column_headers;
34
35 /**
36 * MainWP_Client_List_Table constructor.
37 *
38 * Run each time the class is called.
39 * Add action to generate tabletop.
40 */
41 public function __construct() {
42 add_action( 'mainwp_manageclients_tabletop', array( &$this, 'generate_tabletop' ) );
43 }
44
45 /**
46 * Get the default primary column name.
47 *
48 * @return string Child site name.
49 */
50 protected function get_default_primary_column_name() {
51 return 'site';
52 }
53
54
55 /**
56 * Set the column names.
57 *
58 * @param mixed $item MainWP site table item.
59 * @param string $column_name Column name to use.
60 *
61 * @return string Column name.
62 */
63 public function column_default( $item, $column_name ) { // phpcs:ignore -- NOSONAR - complex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
64
65 /**
66 * Filter: mainwp_clients_sitestable_item
67 *
68 * Filters the Clients table column items. Allows user to create new column item.
69 *
70 * @param array $item Array containing child site data.
71 *
72 * @since 4.1
73 */
74 $item = apply_filters( 'mainwp_clients_sitestable_item', $item, $item );
75
76 if ( isset( $item[ $column_name ] ) && ! empty( $item[ $column_name ] ) ) {
77 switch ( $column_name ) {
78 case 'client_phone':
79 return '<a href="tel:' . esc_attr( $item[ $column_name ] ) . '" class="ui mini icon button" data-tooltip="' . esc_attr( $item[ $column_name ] ) . '" data-inverted="" data-position="left center"><i class="phone grey icon"></i></a>';
80 case 'client_facebook':
81 return '<a href="' . esc_attr( $item[ $column_name ] ) . '" target="_blank" class="ui mini icon button"><i class="facebook grey icon"></i></a>';
82 case 'client_twitter':
83 return '<a href="' . esc_attr( $item[ $column_name ] ) . '" target="_blank" class="ui mini icon button"><i class="twitter grey icon"></i></a>';
84 case 'client_instagram':
85 return '<a href="' . esc_attr( $item[ $column_name ] ) . '" target="_blank" class="ui mini icon button"><i class="instagram grey icon"></i></a>';
86 case 'client_linkedin':
87 return '<a href="' . esc_attr( $item[ $column_name ] ) . '" target="_blank" class="ui mini icon button"><i class="linkedin grey icon"></i></a>';
88 default:
89 return $item[ $column_name ];
90 }
91 }
92 }
93
94 /**
95 * Get sortable columns.
96 *
97 * @return array $sortable_columns Array of sortable column names.
98 */
99 public function get_sortable_columns() {
100 return array(
101 'client' => array( 'client', false ),
102 'name' => array( 'name', false ),
103 'client_email' => array( 'client_email', false ),
104 'suspended' => array( 'suspended', false ),
105 'tags' => array( 'tags', false ),
106 'websites' => array( 'websites', false ),
107 'contact_name' => array( 'contact_name', false ),
108 'address_1' => array( 'address_1', false ),
109 'address_2' => array( 'address_2', false ),
110 'city' => array( 'city', false ),
111 'zip' => array( 'zip', false ),
112 'state' => array( 'state', false ),
113 'created' => array( 'created', false ),
114 'country' => array( 'country', false ),
115 );
116 }
117
118 /**
119 * Gets default columns.
120 *
121 * @return array Array of default column names.
122 */
123 public function get_default_columns() {
124 return array(
125 'cb' => '<input type="checkbox" />',
126 'image' => esc_html__( 'Image', 'mainwp' ),
127 'client' => esc_html__( 'Client', 'mainwp' ),
128 'suspended' => esc_html__( 'Status', 'mainwp' ),
129 'name' => esc_html__( 'Name', 'mainwp' ),
130 'tags' => esc_html__( 'Tags', 'mainwp' ),
131 'contact_name' => esc_html__( 'Primary Contact', 'mainwp' ),
132 'client_email' => esc_html__( 'Client Email', 'mainwp' ),
133 'client_phone' => '<i class="phone grey icon"></i>',
134 'client_facebook' => '<i class="facebook grey icon"></i>',
135 'client_twitter' => '<i class="twitter grey icon"></i>',
136 'client_instagram' => '<i class="instagram grey icon"></i>',
137 'client_linkedin' => '<i class="linkedin grey icon"></i>',
138 'websites' => esc_html__( 'Websites', 'mainwp' ),
139 'address_1' => esc_html__( 'Address 1', 'mainwp' ),
140 'address_2' => esc_html__( 'Address 2', 'mainwp' ),
141 'city' => esc_html__( 'City', 'mainwp' ),
142 'zip' => esc_html__( 'Zip', 'mainwp' ),
143 'state' => esc_html__( 'State', 'mainwp' ),
144 'country' => esc_html__( 'Country', 'mainwp' ),
145 'created' => esc_html__( 'Added on', 'mainwp' ),
146 'notes' => esc_html__( 'Notes', 'mainwp' ),
147 );
148 }
149
150 /**
151 * Method get_columns()
152 *
153 * Combine all columns.
154 *
155 * @return array $columns Array of column names.
156 */
157 public function get_columns() {
158
159 $columns = $this->get_default_columns();
160
161 /**
162 * Filter: mainwp_clients_sitestable_getcolumns
163 *
164 * Filters the Clients table columns. Allows user to create a new column.
165 *
166 * @param array $columns Array containing table columns.
167 *
168 * @since 4.1
169 */
170 $columns = apply_filters( 'mainwp_clients_sitestable_getcolumns', $columns, $columns );
171
172 $columns['client_actions'] = '';
173
174 return $columns;
175 }
176
177 /**
178 * Instantiate Columns.
179 *
180 * @return array $init_cols
181 */
182 public function get_columns_init() {
183 $cols = $this->get_columns();
184 $init_cols = array();
185 foreach ( $cols as $key => $val ) {
186 $init_cols[] = array( 'data' => esc_html( $key ) );
187 }
188 return $init_cols;
189 }
190
191 /**
192 * Method generate_tabletop()
193 *
194 * Run the render_manage_sites_table_top menthod.
195 */
196 public function generate_tabletop() {
197 $this->render_manage_sites_table_top();
198 }
199
200 /**
201 * Create bulk actions drop down.
202 *
203 * @return array $actions Return actions through the mainwp_manageclients_bulk_actions filter.
204 */
205 public function get_bulk_actions() {
206
207 $actions = array(
208 'delete' => esc_html__( 'Delete', 'mainwp' ),
209 );
210
211 /**
212 * Filter: mainwp_manageclients_bulk_actions
213 *
214 * Filters bulk actions on the Clients page. Allows user to hook in new actions or remove default ones.
215 *
216 * @since 4.1
217 */
218 return apply_filters( 'mainwp_manageclients_bulk_actions', $actions );
219 }
220
221 /**
222 * Render manage sites table top.
223 *
224 * @uses \MainWP\Dashboard\MainWP_DB_Common::get_groups_for_manage_sites()
225 */
226 public function render_manage_sites_table_top() {
227 $items_bulk = $this->get_bulk_actions();
228
229 $selected_group = isset( $_REQUEST['tags'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['tags'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
230 $default_filter = empty( $selected_group ) ? true : false;
231 ?>
232 <div class="ui grid">
233 <div class="equal width row ui mini form">
234 <div class="middle aligned column">
235 <div id="mainwp-clients-bulk-actions-menu" class="ui selection dropdown disabled">
236 <div class="default text"><?php esc_html_e( 'Bulk actions', 'mainwp' ); ?></div>
237 <i class="dropdown icon"></i>
238 <div class="menu">
239 <?php
240 foreach ( $items_bulk as $value => $title ) {
241 if ( 'seperator_' === substr( $value, 0, 10 ) ) {
242 ?>
243 <div class="ui divider"></div>
244 <?php
245 } else {
246 ?>
247 <div class="item" data-value="<?php echo esc_attr( $value ); ?>"><?php echo esc_html( $title ); ?></div>
248 <?php
249 }
250 }
251 ?>
252 </div>
253 </div>
254 <button class="ui mini basic button" id="mainwp-do-clients-bulk-actions" disabled="disabled"><?php esc_html_e( 'Apply', 'mainwp' ); ?></button>
255 </div>
256 <div class="right aligned middle aligned column">
257 <?php
258 $groups = MainWP_DB_Common::instance()->get_groups_for_manage_sites();
259
260 if ( empty( $groups ) ) {
261 ?>
262 <a href="admin.php?page=ManageGroups" class="ui mini green basic button">
263 <i class="tag icon"></i> <?php esc_html_e( 'Create Tags', 'mainwp' ); ?>
264 </a>
265 <?php
266 } else {
267 ?>
268 <div id="mainwp-filter-clients-group" class="ui selection multiple dropdown" style="vertical-align:bottom">
269 <input type="hidden" value="<?php echo esc_html( $selected_group ); ?>">
270 <i class="dropdown icon"></i>
271 <div class="default text"><?php esc_html_e( 'All tags', 'mainwp' ); ?></div>
272 <div class="menu">
273 <?php foreach ( $groups as $group ) : ?>
274 <div class="item" data-value="<?php echo intval( $group->id ); ?>"><?php echo esc_html( stripslashes( $group->name ) ); ?></div>
275 <?php endforeach; ?>
276 <div class="item" data-value="nogroups"><?php esc_html_e( 'No Tags', 'mainwp' ); ?></div>
277 </div>
278 </div>
279 <button onclick="mainwp_manage_clients_filter()" class="ui mini basic green button"><i class="filter icon"></i> <?php esc_html_e( 'Filter', 'mainwp' ); ?></button>
280 <a href="admin.php?page=ManageClients" class="ui mini button" <?php echo $default_filter ? 'disabled="disabled"' : ''; ?>><i class="times icon"></i> <?php esc_html_e( 'Reset', 'mainwp' ); ?></a>
281 <?php
282 }
283 ?>
284 </div>
285 </div>
286 </div>
287 <script type="text/javascript">
288 jQuery( document ).ready( function () {
289 mainwp_manage_clients_filter = function() {
290 let group = jQuery( "#mainwp-filter-clients-group" ).dropdown( "get value" );
291 let isNot = jQuery( "#mainwp-is-not-client" ).dropdown( "get value" );
292 let params = '';
293 params += '&tags=' + group;
294
295 window.location = 'admin.php?page=ManageClients' + params;
296 return false;
297 }
298 } );
299 </script>
300 <?php
301 }
302
303 /**
304 * Prepair the items to be listed.
305 *
306 * @param bool $optimize true|false Whether or not to optimize.
307 */
308 public function prepare_items( $optimize = false ) { // phpcs:ignore -- NOSONAR - complex.
309
310 $params = array(
311 'with_selected_sites' => true,
312 'with_tags' => true,
313 );
314
315 if ( isset( $_GET['tags'] ) && ! empty( $_GET['tags'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
316 $tags = sanitize_text_field( rawurldecode( wp_unslash( $_GET['tags'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
317 if ( ! empty( $tags ) ) {
318 if ( false !== strpos( $tags, ',' ) ) {
319 $tags = explode( ',', $tags );
320 } else {
321 $tags = explode( ';', $tags );
322 }
323 $params['by_tags'] = array_filter( $tags );
324 }
325 }
326
327 $clients = MainWP_DB_Client::instance()->get_wp_client_by( 'all', null, ARRAY_A, $params );
328
329 $totalRecords = ( $clients ? count( $clients ) : 0 );
330
331 $clients_ids = array();
332 if ( is_array( $clients ) ) {
333 foreach ( $clients as $item ) {
334 if ( ! empty( $item['client_id'] ) ) {
335 $clients_ids[] = $item['client_id'];
336 }
337 }
338 }
339
340 // for compatible.
341 $optimize = $optimize ? true : false;
342
343 do_action( 'mainwp_clientstable_prepared_items', $clients, $clients_ids );
344
345 $this->items = $clients;
346 $this->total_items = $totalRecords;
347 }
348
349 /**
350 * Display the table.
351 *
352 * @param bool $optimize true|false Whether or not to optimize.
353 */
354 public function display( $optimize = false ) {
355
356 // for compatible.
357 $optimize = $optimize ? true : false;
358
359 $sites_per_page = get_option( 'mainwp_default_manage_clients_per_page', 25 );
360
361 $sites_per_page = intval( $sites_per_page );
362
363 $pages_length = array(
364 25 => '25',
365 10 => '10',
366 50 => '50',
367 100 => '100',
368 300 => '300',
369 );
370
371 $pages_length = $pages_length + array( $sites_per_page => $sites_per_page );
372 ksort( $pages_length );
373
374 if ( isset( $pages_length[-1] ) ) {
375 unset( $pages_length[-1] );
376 }
377
378 $pagelength_val = implode( ',', array_keys( $pages_length ) );
379 $pagelength_title = implode( ',', array_values( $pages_length ) );
380
381 MainWP_Client_Handler::show_notice_existed_contact_emails();
382 ?>
383 <table id="mainwp-manage-clients-table" style="width:100%" class="ui single line selectable unstackable table mainwp-with-preview-table mainwp-manage-wpsites-table">
384 <thead>
385 <tr>
386 <?php $this->print_column_headers( $optimize, true ); ?>
387 </tr>
388 </thead>
389 <tbody id="mainwp-manage-sites-body-table">
390 <?php $this->display_rows_or_placeholder(); ?>
391 </tbody>
392 </table>
393 <div id="mainwp-loading-sites" style="display: none;">
394 <div class="ui active page dimmer">
395 <div class="ui double text loader"><?php esc_html_e( 'Loading...', 'mainwp' ); ?></div>
396 </div>
397 </div>
398 <?php MainWP_UI::render_modal_edit_notes( 'client' ); ?>
399 <?php
400
401 $table_features = array(
402 'searching' => 'true',
403 'paging' => 'true',
404 'pagingType' => 'full_numbers',
405 'info' => 'true',
406 'colReorder' => '{columns:":not(.check-column):not(.manage-client_actions-column)"}',
407 'stateSave' => 'true',
408 'stateDuration' => '60 * 60 * 24 * 30',
409 'order' => '[]',
410 'scrollX' => 'true',
411 'responsive' => 'true',
412 'searchDelay' => 350,
413 );
414
415 /**z
416 * Filter: mainwp_clients_table_features
417 *
418 * Filter the Clients table features.
419 *
420 * @since 4.1
421 */
422 $table_features = apply_filters( 'mainwp_clients_table_features', $table_features );
423 ?>
424 <script type="text/javascript">
425 jQuery( document ).ready( function( $ ) {
426 window.mainwp_manage_clients_screen_options = function () {
427 jQuery( '#mainwp-manage-sites-screen-options-modal' ).modal( {
428 allowMultiple: true,
429 onHide: function () {
430 let val = jQuery( '#mainwp_default_manage_clients_per_page' ).val();
431 let saved = jQuery( '#mainwp_default_manage_clients_per_page' ).attr( 'saved-value' );
432 if ( saved != val ) {
433 jQuery( '#mainwp-manage-clients-table' ).DataTable().page.len( val );
434 jQuery( '#mainwp-manage-clients-table' ).DataTable().state.save();
435 }
436 }
437 } ).modal( 'show' );
438
439 jQuery( '#manage-sites-screen-options-form' ).submit( function() {
440 if ( jQuery('input[name=reset_manageclients_columns_order]').attr('value') == 1 ) {
441 $manage_sites_table.colReorder.reset();
442 }
443 jQuery( '#mainwp-manage-sites-screen-options-modal' ).modal( 'hide' );
444 } );
445 return false;
446 };
447
448 let responsive = <?php echo esc_js( $table_features['responsive'] ); ?>;
449 if( jQuery( window ).width() > 1140 ) {
450 responsive = false;
451 }
452
453 try {
454 $manage_sites_table = jQuery( '#mainwp-manage-clients-table' ).DataTable( {
455 "responsive" : responsive,
456 "searching" : <?php echo esc_js( $table_features['searching'] ); ?>,
457 "paging" : <?php echo esc_js( $table_features['paging'] ); ?>,
458 "pagingType" : "<?php echo esc_js( $table_features['pagingType'] ); ?>",
459 "info" : <?php echo esc_js( $table_features['info'] ); ?>,
460 "colReorder" : <?php echo $table_features['colReorder']; // phpcs:ignore -- specical chars. ?>,
461 "stateSave" : <?php echo esc_js( $table_features['stateSave'] ); ?>,
462 "stateDuration" : <?php echo esc_js( $table_features['stateDuration'] ); ?>,
463 "order" : <?php echo $table_features['order']; // phpcs:ignore -- specical chars. ?>,
464 "scrollX" : <?php echo esc_js( $table_features['scrollX'] ); ?>,
465 "columnDefs": [
466 {
467 "targets": 'no-sort',
468 "orderable": false
469 },
470 {
471 "targets": 'manage-site-column',
472 "type": 'natural-nohtml'
473 },
474 <?php do_action( 'mainwp_manage_sites_table_columns_defs' ); ?>
475 ],
476 "lengthMenu" : [ [<?php echo esc_js( $pagelength_val ); ?>, -1 ], [<?php echo esc_js( $pagelength_title ); ?>, "All" ] ],
477 "pageLength": <?php echo intval( $sites_per_page ); ?>,
478 "drawCallback": function( settings ) {
479 jQuery( '#mainwp-manage-sites-body-table .ui.checkbox' ).checkbox();
480 },
481 select: {
482 items: 'row',
483 style: 'multi+shift',
484 selector: 'tr>td.check-column'
485 },
486 stateSaveParams: function (settings, data) {
487 data._mwpv = mainwpParams.mainwpVersion || 'dev';
488 },
489 stateLoadParams: function (settings, data) {
490 if ((mainwpParams.mainwpVersion || 'dev') !== data._mwpv) return false;
491 },
492 search: { regex: false, smart: false },
493 orderMulti: false,
494 searchDelay: <?php echo intval( $table_features['searchDelay'] ); ?>
495 } ).on( 'columns-reordered', function () {
496 setTimeout(() => {
497 $( '#mainwp-manage-clients-table .ui.dropdown' ).dropdown();
498 $( '#mainwp-manage-clients-table .ui.checkbox' ).checkbox();
499 mainwp_datatable_fix_menu_overflow('#mainwp-manage-clients-tabl');
500 }, 1000 );
501 } ).on('select', function (e, dt, type, indexes) {
502 if( 'row' == type ){
503 dt.rows(indexes)
504 .nodes()
505 .to$().find('td.check-column .ui.checkbox' ).checkbox('set checked');
506 }
507 }).on('deselect', function (e, dt, type, indexes) {
508 if( 'row' == type ){
509 dt.rows(indexes)
510 .nodes()
511 .to$().find('td.check-column .ui.checkbox' ).checkbox('set unchecked');
512 }
513 });
514 } catch(err) {
515 // to fix js error.
516 }
517 mainwp_datatable_fix_menu_overflow('#mainwp-manage-clients-table');
518
519 // Initialize header checkboxes
520 jQuery( '#mainwp-manage-clients-table thead .ui.checkbox' ).checkbox();
521
522 _init_manage_sites_screen = function() {
523 jQuery( '#mainwp-manage-sites-screen-options-modal input[type=checkbox][id^="mainwp_show_column_"]' ).each( function() {
524 let col_id = jQuery( this ).attr( 'id' );
525 col_id = col_id.replace( "mainwp_show_column_", "" );
526 try {
527 $manage_sites_table.column( '#' + col_id ).visible( jQuery(this).is( ':checked' ) );
528 } catch(err) {
529 // to fix js error.
530 }
531 } );
532 };
533 _init_manage_sites_screen();
534 } );
535 </script>
536 <?php
537 }
538
539 /**
540 * Echo the column headers.
541 *
542 * @param bool $optimize true|false Whether or not to optimize.
543 * @param bool $top true|false.
544 */
545 public function print_column_headers( $optimize, $top = true ) { // phpcs:ignore -- NOSONAR - complex.
546 // for compatible.
547 $optimize = $optimize ? true : false;
548
549 list( $columns, $sortable ) = $this->get_column_info();
550
551 if ( ! empty( $columns['cb'] ) ) {
552 $columns['cb'] = '<div class="ui checkbox"><input id="' . ( $top ? 'cb-select-all-top' : 'cb-select-all-bottom' ) . '" type="checkbox" aria-label="' . esc_attr__( 'Select all clients.', 'mainwp' ) . '" /><label></label></div>';
553 }
554
555 $def_columns = $this->get_default_columns();
556 $def_columns['client_actions'] = '';
557
558 foreach ( $columns as $column_client_key => $column_display_name ) {
559
560 $class = array( 'manage-' . $column_client_key . '-column' );
561 $attr = '';
562 if ( ! isset( $def_columns[ $column_client_key ] ) ) {
563 $class[] = 'extra-column';
564
565 }
566
567 if ( 'cb' === $column_client_key ) {
568 $class[] = 'check-column';
569 $class[] = 'collapsing';
570 }
571
572 if ( 'suspended' === $column_client_key ) {
573 $class[] = 'collapsing center aligned';
574 }
575
576 if ( 'image' === $column_client_key ) {
577 $class[] = 'collapsing center aligned';
578 }
579
580 if ( 'name' === $column_client_key ) {
581 $class[] = 'collapsing';
582 }
583
584 if ( 'websites' === $column_client_key ) {
585 $class[] = 'collapsing';
586 }
587
588 if ( 'created' === $column_client_key ) {
589 $class[] = 'collapsing center aligned';
590 }
591
592 if ( 'notes' === $column_client_key ) {
593 $class[] = 'collapsing center aligned';
594 }
595
596 if ( 'tags' === $column_client_key ) {
597 $class[] = 'collapsing';
598 }
599
600 if ( 'client_facebook' === $column_client_key ) {
601 $class[] = 'collapsing center aligned';
602 }
603
604 if ( 'client_instagram' === $column_client_key ) {
605 $class[] = 'collapsing center aligned';
606 }
607
608 if ( 'client_twitter' === $column_client_key ) {
609 $class[] = 'collapsing center aligned';
610 }
611
612 if ( 'client_linkedin' === $column_client_key ) {
613 $class[] = 'collapsing center aligned';
614 }
615
616 if ( 'client_phone' === $column_client_key ) {
617 $class[] = 'collapsing center aligned';
618 }
619
620 if ( 'client_actions' === $column_client_key ) {
621 $class[] = 'collapsing';
622 }
623
624 if ( 'contact_name' === $column_client_key ) {
625 $class[] = 'collapsing';
626 }
627
628 if ( ! isset( $sortable[ $column_client_key ] ) ) {
629 $class[] = 'no-sort';
630 }
631
632 $tag = 'th';
633 $id = "id='$column_client_key'";
634
635 if ( ! empty( $class ) ) {
636 $class = "class='" . join( ' ', $class ) . "'";
637 }
638
639 echo "<$tag $id $class $attr>$column_display_name</$tag>"; // phpcs:ignore WordPress.Security.EscapeOutput
640 }
641 }
642
643 /**
644 * Get column info.
645 */
646 protected function get_column_info() {
647
648 if ( isset( $this->column_headers ) && is_array( $this->column_headers ) ) {
649 $column_headers = array( array(), array(), array(), $this->get_default_primary_column_name() );
650 foreach ( $this->column_headers as $key => $value ) {
651 $column_headers[ $key ] = $value;
652 }
653
654 return $column_headers;
655 }
656
657 $columns = $this->get_columns();
658
659 $sortable_columns = $this->get_sortable_columns();
660
661 $_sortable = $sortable_columns;
662
663 $sortable = array();
664 foreach ( $_sortable as $id => $data ) {
665 if ( empty( $data ) ) {
666 continue;
667 }
668
669 $data = (array) $data;
670 if ( ! isset( $data[1] ) ) {
671 $data[1] = false;
672 }
673
674 $sortable[ $id ] = $data;
675 }
676
677 $primary = $this->get_default_primary_column_name();
678 $this->column_headers = array( $columns, $sortable, $primary );
679
680 return $this->column_headers;
681 }
682
683 /**
684 * Fetch single row item.
685 *
686 * @return mixed Single Row Item.
687 */
688 public function display_rows() {
689 if ( $this->items ) {
690 foreach ( $this->items as $item ) {
691 $this->single_row( $item );
692 }
693 }
694 }
695
696
697 /**
698 * Single row.
699 *
700 * @param mixed $item Object containing the client info.
701 */
702 public function single_row( $item ) {
703 echo '<tr id="client-site-' . intval( $item['client_id'] ) . '" clientid=' . intval( $item['client_id'] ) . ' >';
704 $this->single_row_columns( $item );
705 echo '</tr>';
706 }
707
708
709 /**
710 * Columns for a single row.
711 *
712 * @param mixed $item Object containing the client info.
713 * @param bool $compatible to compatible param - DO NOT remove.
714 */
715 protected function single_row_columns( $item, $compatible = true ) { // phpcs:ignore -- NOSONAR - complex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
716
717 list( $columns ) = $this->get_column_info();
718
719 foreach ( $columns as $column_name => $column_display_name ) {
720
721 $classes = "$column_name column-$column_name";
722
723 $attributes = "class='$classes'";
724 ?>
725 <?php if ( 'cb' === $column_name ) { ?>
726 <td class="check-column">
727 <div class="ui checkbox">
728 <input type="checkbox" value="<?php echo intval( $item['client_id'] ); ?>" name="" aria-label="<?php esc_attr_e( 'Select the site.', 'mainwp' ); ?>"/>
729 <label></label>
730 </div>
731 </td>
732 <?php
733 } elseif ( 'suspended' === $column_name ) {
734 $client_status = '';
735 if ( 0 === intval( $item['suspended'] ) ) {
736 $client_status = '<span class="ui green mini fluid center aligned label">' . esc_html__( 'Active', 'mainwp' ) . '</span>';
737 } elseif ( 1 === intval( $item['suspended'] ) ) {
738 $client_status = '<span class="ui yellow mini fluid center aligned label">' . esc_html__( 'Suspended', 'mainwp' ) . '</span>';
739 } elseif ( 2 === intval( $item['suspended'] ) ) {
740 $client_status = '<span class="ui blue mini fluid center aligned label">' . esc_html__( 'Lead', 'mainwp' ) . '</span>';
741 } elseif ( 3 === intval( $item['suspended'] ) ) {
742 $client_status = '<span class="ui red mini fluid center aligned label">' . esc_html__( 'Lost', 'mainwp' ) . '</span>';
743 }
744 ?>
745 <td><?php echo $client_status; //phpcs:ignore -- ok. ?></td>
746 <?php } elseif ( 'image' === $column_name ) { ?>
747 <?php echo "<td $attributes>"; // phpcs:ignore WordPress.Security.EscapeOutput ?>
748 <?php $client_display_image = MainWP_Client_Handler::get_client_contact_image( $item ); ?>
749 <a class="item" href="admin.php?page=ManageClients&client_id=<?php echo intval( $item['client_id'] ); ?>"><?php echo $client_display_image; //phpcs:ignore -- NOSONAR - ok.?></a>
750 <?php echo '</td>'; ?>
751 <?php } elseif ( 'client' === $column_name ) { ?>
752 <?php echo "<td $attributes>"; // phpcs:ignore WordPress.Security.EscapeOutput ?>
753 <a href="admin.php?page=ManageClients&client_id=<?php echo intval( $item['client_id'] ); ?>"><?php echo esc_html( $item['name'] ); ?></a>
754 <div>
755 <span class="ui small text">
756 <a class="ui grey text" href="admin.php?page=ManageClients&client_id=<?php echo intval( $item['client_id'] ); ?>">
757 <?php echo esc_html( $item['client_email'] ); ?>
758 </a>
759 </span>
760 </div>
761 <?php echo '</td>'; ?>
762 <?php } elseif ( 'created' === $column_name ) { ?>
763 <td data-order="<?php echo intval( $item['created'] ); ?>"><?php echo 0 !== (int)( $item['created'] ) ? '<span data-tooltip="' . MainWP_Utility::format_date( $item['created'] ) . '" data-inverted="" data-position="left center">' . MainWP_Utility::time_elapsed_string( $item['created'] ) . '</span>' : 'N/A'; //phpcs:ignore -- output ok. ?></td>
764 <?php } elseif ( 'name' === $column_name ) { ?>
765 <?php echo "<td $attributes>"; // phpcs:ignore WordPress.Security.EscapeOutput ?>
766 <a href="admin.php?page=ManageClients&client_id=<?php echo intval( $item['client_id'] ); ?>"><?php echo esc_html( $item['name'] ); ?></a>
767 <?php echo '</td>'; ?>
768 <?php } elseif ( 'client_email' === $column_name ) { ?>
769 <?php echo "<td $attributes>"; // phpcs:ignore WordPress.Security.EscapeOutput ?>
770 <a href="admin.php?page=ClientAddNew&client_id=<?php echo intval( $item['client_id'] ); ?>"><?php echo esc_html( $item['client_email'] ); ?></a>
771 <?php echo '</td>'; ?>
772 <?php } elseif ( 'tags' === $column_name ) { ?>
773 <td class="collapsing"><?php echo MainWP_System_Utility::get_site_tags( $item, true ); // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
774 <?php
775 } elseif ( 'websites' === $column_name ) {
776 $selected_sites = isset( $item['selected_sites'] ) ? trim( $item['selected_sites'] ) : '';
777 $selected_ids = ( '' !== $selected_sites ) ? explode( ',', $selected_sites ) : array();
778
779 $count = count( $selected_ids );
780 ?>
781 <?php echo "<td $attributes>"; // phpcs:ignore WordPress.Security.EscapeOutput ?>
782 <a class="ui mini grey button" href="admin.php?page=managesites&client=<?php echo intval( $item['client_id'] ); ?>"><i class="wordpress icon"></i><?php echo intval( $count ); ?></a>
783 <?php echo '</td>'; ?>
784 <?php
785 } elseif ( 'notes' === $column_name ) {
786 $note = html_entity_decode( $item['note'] );
787 $esc_note = MainWP_Utility::esc_content( $note );
788 $strip_note = wp_strip_all_tags( $esc_note );
789 echo "<td $attributes>"; // phpcs:ignore WordPress.Security.EscapeOutput
790 if ( empty( $item['note'] ) ) :
791 $cl_id1 = $item['client_id'];
792 ?>
793 <a href="javascript:void(0)" class="mainwp-edit-client-note ui mini icon button" id="mainwp-notes-<?php echo intval( $cl_id1 ); ?>" data-tooltip="<?php esc_attr_e( 'Edit client notes.', 'mainwp' ); ?>" data-position="left center" data-inverted=""><i class="sticky note outline icon"></i></a>
794 <?php else :
795 $cl_id2 = $item['client_id']; ?>
796 <a href="javascript:void(0)" class="mainwp-edit-client-note ui mini icon button" id="mainwp-notes-<?php echo intval( $cl_id2 ); ?>" data-tooltip="<?php echo substr( wp_unslash( $strip_note ), 0, 100 ); // phpcs:ignore WordPress.Security.EscapeOutput ?>" data-position="left center" data-inverted=""><i class="sticky green note icon"></i></a>
797 <?php endif; ?>
798 <span style="display: none" id="mainwp-notes-<?php echo intval( $item['client_id'] ); ?>-note"><?php echo wp_unslash( $esc_note ); // phpcs:ignore WordPress.Security.EscapeOutput ?></span>
799 <?php echo '</td>'; ?>
800 <?php } elseif ( 'client_actions' === $column_name ) { ?>
801 <?php $selected_sites = isset( $item['selected_sites'] ) ? trim( $item['selected_sites'] ) : ''; ?>
802 <td class="collapsing manage-clients-actions not-selectable">
803 <div class="ui right pointing dropdown" style="z-index:999;">
804 <i class="ellipsis vertical icon"></i>
805 <div class="menu" clientid=<?php echo intval( $item['client_id'] ); ?>>
806 <a class="item client_getedit" href="admin.php?page=ClientAddNew&client_id=<?php echo intval( $item['client_id'] ); ?>"><?php esc_html_e( 'Edit', 'mainwp' ); ?></a>
807 <a class="item" href="admin.php?page=managesites&client=<?php echo intval( $item['client_id'] ); ?>"><?php esc_html_e( 'View Sites', 'mainwp' ); ?></a>
808 <?php
809 if ( is_plugin_active( 'mainwp-pro-reports-extension/mainwp-pro-reports-extension.php' ) ) {
810 $report_url = add_query_arg(
811 array(
812 'page' => 'Extensions-Mainwp-Pro-Reports-Extension',
813 'tab' => 'report',
814 'action' => 'newreport',
815 'selected_sites' => $selected_sites,
816 ),
817 'admin.php'
818 );
819 ?>
820 <a class="ui basic mini right floated button" href="<?php echo esc_url( $report_url ); ?>"><?php echo esc_html__( 'Create Report', 'mainwp' ); ?></a>
821 <?php } ?>
822 <a class="item client_deleteitem" href="#"><?php esc_html_e( 'Delete', 'mainwp' ); ?></a>
823 </div>
824 </div>
825 </td>
826 <?php
827 } elseif ( method_exists( $this, 'column_' . $column_name ) ) {
828 echo "<td $attributes>"; // phpcs:ignore WordPress.Security.EscapeOutput
829 echo call_user_func( array( $this, 'column_' . $column_name ), $item ); // phpcs:ignore WordPress.Security.EscapeOutput
830 echo '</td>';
831 } else {
832 echo "<td $attributes>"; // phpcs:ignore WordPress.Security.EscapeOutput
833 echo $this->column_default( $item, $column_name ); // phpcs:ignore WordPress.Security.EscapeOutput
834 echo '</td>';
835 }
836 }
837
838 if ( ! $compatible ) {
839 $compatible = true;
840 }
841 }
842 }
843