PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.1
6.2.2 6.2.1 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 All 155 releases
mainwp / modules / logs / classes / class-log-events-list-table.php

class-log-events-list-table.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.2.1, at modules/logs/classes/class-log-events-list-table.php

1,550 lines 64.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Manage Logs List Table.
4 *
5 * @package MainWP/Dashboard
6 * @version 4.6
7 */
8
9 namespace MainWP\Dashboard\Module\Log;
10
11 use MainWP\Dashboard\MainWP_Utility;
12 use MainWP\Dashboard\MainWP_UI;
13 use MainWP\Dashboard\MainWP_Connect;
14 use MainWP\Dashboard\MainWP_Manage_Sites;
15 use MainWP\Dashboard\MainWP_Updates_Helper;
16 use MainWP\Dashboard\MainWP_Site_Open;
17
18 // Exit if accessed directly.
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit;
21 }
22
23 /**
24 * Class Log_Events_List_Table
25 *
26 * @package MainWP\Dashboard
27 */
28 class Log_Events_List_Table { //phpcs:ignore -- NOSONAR - complex.
29
30 /**
31 * Holds instance of manager object
32 *
33 * @var Log_Manager
34 */
35 public $manager;
36
37
38 /**
39 * Public variable to hold Items information.
40 *
41 * @var array
42 */
43 public $items;
44
45
46 /**
47 * Public variable to hold Items information.
48 *
49 * @var array
50 */
51 public $sites_opts = array();
52
53 /**
54 * Public variable to hold Previous Items information.
55 *
56 * @var array
57 */
58 public $items_prev;
59
60
61 /**
62 * Public variable to hold type value.
63 *
64 * @var array
65 */
66 public $table_id_prefix = null;
67
68
69 /**
70 * Public variable to hold total items number.
71 *
72 * @var integer
73 */
74 public $total_items;
75
76 /**
77 * Public variable to hold extra data.
78 *
79 * @var integer
80 */
81 public $items_extra_data;
82
83 /**
84 * Protected variable to hold columns headers
85 *
86 * @var array
87 */
88 protected $column_headers;
89
90
91 /**
92 * Private static variable to hold the optimize value.
93 *
94 * @var mixed Default null
95 */
96 private $optimize_table = false;
97
98
99 /**
100 * Private static variable to hold the forced modified events title value.
101 *
102 * @var mixed Default null
103 */
104 private $forced_modified_events = null;
105
106 /**
107 * Class constructor.
108 *
109 * Run each time the class is called.
110 *
111 * @param Log_Manager $manager Instance of manager object.
112 * @param Strings $type Events table type: manage_events|widget_overview|widget_insight.
113 * @param bool $optimize Whether optimize table.
114 */
115 public function __construct( $manager, $type = '', $optimize = false ) {
116 $this->manager = $manager;
117 $this->table_id_prefix = $type;
118 $this->optimize_table = $optimize;
119 }
120
121 /**
122 * Get the default primary column name.
123 *
124 * @return string Child Site name.
125 */
126 protected function get_default_primary_column_name() {
127 return 'name';
128 }
129
130 // @NO_SONAR_START@ - duplicated issue.
131 /**
132 * Get sortable columns.
133 *
134 * @return array $sortable_columns Array of sortable column names.
135 */
136 public function get_sortable_columns() {
137 return array(
138 'event' => array( 'event', false ),
139 'action' => array( 'action', false ),
140 'log_object' => array( 'log_object', false ),
141 'created' => array( 'created', false ),
142 'name' => array( 'name', false ),
143 'user_id' => array( 'user_id', false ),
144 'source' => array( 'source', false ),
145 );
146 }
147
148 /**
149 * Get default columns.
150 *
151 * @return array Array of default column names.
152 */
153 public function get_default_columns() {
154 if ( 'widget-overview' === $this->table_id_prefix ) {
155 $columns = array(
156 'created' => esc_html__( 'Time', 'mainwp' ),
157 'log_object' => esc_html__( 'Object', 'mainwp' ),
158 'event' => esc_html__( 'Event', 'mainwp' ),
159 'name' => esc_html__( 'Site', 'mainwp' ),
160 );
161 } else {
162 $columns = array(
163 'cb' => '<input type="checkbox" />',
164 'created' => esc_html__( 'Date', 'mainwp' ),
165 'user_id' => esc_html__( 'User', 'mainwp' ),
166 'action' => esc_html__( 'Action', 'mainwp' ),
167 'log_object' => esc_html__( 'Object', 'mainwp' ),
168 'icon' => '',
169 'name' => esc_html__( 'Website', 'mainwp' ),
170 'event' => esc_html__( 'Event', 'mainwp' ),
171 'source' => esc_html__( 'Source', 'mainwp' ),
172 'col_action' => '',
173 );
174 }
175
176 if ( 'manage-events' !== $this->table_id_prefix ) {
177 unset( $columns['source'] );
178 }
179
180 if ( 'widget-overview' === $this->table_id_prefix ) {
181 unset( $columns['log_site_name'] );
182 unset( $columns['icon'] );
183 unset( $columns['user_id'] );
184 unset( $columns['action'] );
185 unset( $columns['source'] );
186 unset( $columns['col_action'] );
187 unset( $columns['cb'] );
188 }
189
190 return $columns;
191 }
192
193 /**
194 * Method get_columns()
195 *
196 * Combine all columns.
197 *
198 * @return array $columns Array of column names.
199 */
200 public function get_columns() {
201 return $this->get_default_columns();
202 }
203
204 /**
205 * Instantiate Columns.
206 *
207 * @return array $init_cols
208 */
209 public function get_columns_init() {
210 $cols = $this->get_columns();
211 $init_cols = array();
212 foreach ( $cols as $key => $val ) {
213 $init_cols[] = array( 'data' => esc_html( $key ) );
214 }
215 return $init_cols;
216 }
217
218 /**
219 * Get column defines.
220 *
221 * @return array $defines
222 */
223 public function get_columns_defines() {
224 $defines = array();
225 $defines[] = array(
226 'targets' => 'no-sort',
227 'orderable' => false,
228 );
229 $defines[] = array(
230 'targets' => 'manage-cb-column',
231 'className' => 'check-column',
232 );
233 $defines[] = array(
234 'targets' => 'manage-created-column',
235 'className' => 'mainwp-created-cell',
236 );
237 $defines[] = array(
238 'targets' => 'manage-icon-column',
239 'className' => 'manage-icon-cell center aligned collapsing',
240 );
241 $defines[] = array(
242 'targets' => 'manage-site-column',
243 'className' => 'column-site-bulk mainwp-site-cell',
244 );
245 $defines[] = array(
246 'targets' => 'manage-user-column',
247 'className' => 'mainwp-user-cell',
248 );
249 $defines[] = array(
250 'targets' => array( 'manage-col_action-column' ),
251 'className' => 'collapsing',
252 );
253 $defines[] = array(
254 'targets' => array( 'manage-log_object-column' ),
255 'className' => 'mainwp-sites-changes-object-cell',
256 );
257
258 return $defines;
259 }
260 // @NO_SONAR_END@ .
261
262 /**
263 * Returns the column content for the provided item and column.
264 *
265 * @param object $item Record data.
266 * @param string $column_name Column name.
267 * @param array $site_opts Site options.
268 *
269 * @return string $out Output.
270 */
271 public function column_default( $item, $column_name ) { //phpcs:ignore -- NOSONAR -complex.
272 $out = '';
273
274 $record = new Log_Record( $item );
275
276 $escaped = false;
277 switch ( $column_name ) {
278 case 'cb':
279 $out = '<div class="ui checkbox">
280 <input type="checkbox" value="' . (int) $record->log_id . '" name="" aria-label="' . esc_attr__( 'Select the change.', 'mainwp' ) . '"/>
281 </div>';
282 $escaped = true;
283 break;
284 case 'event':
285 $out = $this->get_event_title( $record, 'action', true );
286 $escaped = true;
287 break;
288 case 'action':
289 $out = $this->get_action_title( $record );
290 $escaped = true;
291 break;
292 case 'log_object':
293 $out = $this->get_object_title( $record );
294 $escaped = true;
295 break;
296 case 'created':
297 $site_info = is_array( $this->sites_opts ) && isset( $this->sites_opts[ $record->site_id ] ) && isset( $this->sites_opts[ $record->site_id ]['site_info'] ) ? $this->sites_opts[ $item->site_id ]['site_info'] : array();
298 $site_dtf = is_array( $site_info ) && isset( $site_info['format_datetime'] ) ? $site_info['format_datetime'] : false;
299
300 $child_time = MainWP_Utility::format_timezone( (int) $record->created, false, $site_dtf );
301 if ( ! empty( $child_time ) ) {
302 /* translators: %s: Child site time */
303 $tooltip_text = esc_attr__( 'Child Site time: %s', 'mainwp' );
304 $date_string = sprintf(
305 '<span data-tooltip="' . $tooltip_text . ' " created-time="' . esc_attr( $record->created ) . '" data-inverted="" data-position="right center"><time datetime="%s" class="relative-time record-created">%s</time></span>',
306 $child_time,
307 mainwp_module_log_get_iso_8601_extended_date( $record->created ),
308 MainWP_Utility::format_timezone( $record->created )
309 );
310 } else {
311 $date_string = sprintf(
312 '<time datetime="%s" created-time="' . esc_attr( $record->created ) . '" class="relative-time record-created">%s</time>',
313 mainwp_module_log_get_iso_8601_extended_date( $record->created ),
314 MainWP_Utility::format_timezone( $record->created )
315 );
316 }
317 $out = $date_string;
318 $escaped = true;
319 break;
320 case 'icon':
321 $out = 'N/A';
322 if ( ! empty( $record->log_site_name ) ) {
323 $site_opts = is_array( $this->sites_opts ) && isset( $this->sites_opts[ $record->site_id ] ) ? $this->sites_opts[ $record->site_id ] : array();
324 $siteObj = (object) array(
325 'id' => $record->site_id,
326 'url' => $record->url,
327 'name' => $record->log_site_name,
328 'favi_icon' => is_array( $site_opts ) && isset( $site_opts['favi_icon'] ) ? $site_opts['favi_icon'] : '',
329 );
330 $favi_url = MainWP_Connect::get_favico_url( $siteObj );
331 $site_icon = MainWP_Manage_Sites::get_instance()->get_site_icon_display( is_array( $site_opts ) && isset( $site_opts['cust_site_icon_info'] ) ? $site_opts['cust_site_icon_info'] : '', $favi_url );
332
333 ob_start();
334 echo $site_icon; // phpcs:ignore WordPress.Security.EscapeOutput
335 $out = ob_get_clean();
336 }
337 $escaped = true;
338 break;
339 case 'name':
340 $out = 'N/A';
341
342 if ( ! empty( $record->log_site_name ) ) {
343 ob_start();
344 if ( \mainwp_current_user_can( 'dashboard', 'access_wpadmin_on_child_sites' ) ) : ?>
345 <a href="<?php MainWP_Site_Open::get_open_site_url( $record->site_id ); ?>" class="open_newwindow_wpadmin" target="_blank"><i class="sign in icon"></i></a>
346 <?php endif; ?>
347 <a href="<?php echo 'admin.php?page=managesites&dashboard=' . intval( $record->site_id ); ?>">
348 <?php echo esc_attr( stripslashes( $record->log_site_name ) ); ?>
349 </a>
350 <div>
351 <span class="ui small text">
352 <a href="<?php echo esc_url( $record->url ); ?>" class="mainwp-may-hide-referrer open_site_url ui grey text" target="_blank">
353 <?php echo esc_html( MainWP_Utility::get_nice_url( $record->url ) ); ?>
354 </a>
355 </span>
356 </div>
357 <?php
358 $out = ob_get_clean();
359 }
360 $escaped = true;
361 break;
362 case 'user_id':
363 $user_meta = ! empty( $record->user_meta ) ? $record->user_meta : array();
364
365 if ( empty( $user_meta['full_name'] ) && isset( $record->meta['first_name'] ) && isset( $record->meta['last_name'] ) ) {
366 $user_meta['wp_user_id'] = $record->user_id;
367 $user_meta['full_name'] = $record->meta['first_name'] . ' ' . $record->meta['last_name'];
368 $user_meta['ip'] = ! empty( $record->meta['client_ip'] ) ? $record->meta['client_ip'] : '';
369 }
370
371 $user = new Log_Author( $record->user_id, $user_meta );
372
373 if ( empty( $out ) ) {
374 if ( ! empty( $record->log_type_id ) || 'non-mainwp-changes' === $record->connector ) {
375 $out = $user->get_full_name();
376 } else {
377 $out = $user->get_display_name();
378 }
379 }
380
381 if ( empty( $out ) ) {
382 $out = $user->get_agent_label( $user->get_agent() );
383 }
384 $escaped = true;
385 break;
386 case 'source':
387 if ( ! empty( $record->source ) ) {
388 $out = $record->source; // sub query field.
389 } else {
390 $out = ( 'non-mainwp-changes' === $record->connector ) ? 'WP Admin' : 'Dashboard';
391 }
392 break;
393 case 'col_action':
394 ob_start();
395 ?>
396 <div action-id="<?php echo intval( $record->log_id ); ?>">
397 <a class="ui mini green button insights-actions-row-dismiss" href="javascript:void(0)" data-tooltip="<?php esc_attr_e( 'Dismiss the change.', 'mainwp' ); ?>" data-position="left center" data-inverted=""><?php esc_html_e( 'Dismiss', 'mainwp' ); ?></a>
398 </div>
399 <?php
400 $out = ob_get_clean();
401 break;
402 default:
403 }
404
405 if ( empty( $out ) ) {
406 return '';
407 }
408
409 if ( ! $escaped ) {
410 $allowed_tags = wp_kses_allowed_html( 'post' );
411 $allowed_tags['time'] = array(
412 'datetime' => true,
413 'class' => true,
414 );
415
416 $allowed_tags['img']['srcset'] = true;
417
418 return wp_kses( $out, $allowed_tags );
419 } else {
420 return $out; //phpcs:ignore -- escaped.
421 }
422 }
423
424
425 /**
426 * Returns the label for a status.
427 *
428 * @param object $record record item.
429 *
430 * @return string
431 */
432 public function get_state_title( $record ) {
433
434 $state = esc_html__( 'Undefined', 'mainwp' );
435 if ( is_null( $record->state ) ) {
436 $state = 'N/A';
437 } elseif ( '0' === $record->state ) {
438 $state = esc_html__( 'Failed', 'mainwp' );
439 } elseif ( '1' === $record->state ) {
440 $state = esc_html__( 'Success', 'mainwp' );
441 }
442 return $state;
443 }
444
445 /**
446 * Returns the label for a connector term.
447 *
448 * @param object $record Event data.
449 * @return string
450 */
451 public function get_action_title( $record ) {
452 if ( ! empty( $record->log_type_id ) ) {
453 $action = $this->parse_changes_action_title( $record );
454 } else {
455 $act = $record->action;
456 $type = 'action';
457
458 if ( ! isset( $this->manager->connectors->term_labels[ 'logs_' . $type ][ $act ] ) ) {
459 $title = $act;
460 } else {
461 $title = $this->manager->connectors->term_labels[ 'logs_' . $type ][ $act ];
462 }
463 $title = is_string( $title ) ? ucfirst( $title ) : $title;
464 $action = $title;
465 }
466 return $action;
467 }
468
469 /**
470 * Returns the forced modified event title.
471 *
472 * @return array Logs type ids.
473 */
474 public function get_forced_modified_event_title() {
475 if ( null === $this->forced_modified_events ) {
476 $defaults = array( 1460, 1330, 1335, 1495, 1720, 1721, 1725, 1726 );
477 $this->forced_modified_events = apply_filters( 'mainwp_module_logs_forced_modified_event_title', $defaults );
478 }
479 if ( ! is_array( $this->forced_modified_events ) ) {
480 $this->forced_modified_events = array();
481 }
482 return $this->forced_modified_events;
483 }
484
485
486 /**
487 * Returns the label for a connector term.
488 *
489 * @param string $record Log data.
490 * @param string $type Connector term.
491 * @param bool $coloring Coloring term.
492 * @return string
493 */
494 public function get_event_title( $record, $type, $coloring = false ) { //phpcs:ignore -- NOSONAR - complex.
495
496 $act = $record->action;
497
498 if ( ! empty( $record->log_type_id ) ) {
499 $title = $act;
500 if ( in_array( (int) $record->log_type_id, $this->get_forced_modified_event_title() ) ) {
501 $title = esc_html__( 'Modified', 'mainwp' );
502 } else {
503 $title = ucfirst( $title );
504 }
505 } else {
506 if ( ! isset( $this->manager->connectors->term_labels[ 'logs_' . $type ][ $act ] ) ) {
507 $title = $act;
508 } else {
509 $title = $this->manager->connectors->term_labels[ 'logs_' . $type ][ $act ];
510 }
511 $title = is_string( $title ) ? ucfirst( $title ) : $title;
512 }
513
514 if ( $coloring ) {
515
516 $color = '';
517
518 if ( in_array( $act, array( 'deleted', 'removed', 'revoked', 'deactivated', 'disabled', 'suspended', 'trashed' ), true ) ) {
519 $color = 'red';
520 } elseif ( in_array( $act, array( 'updated', 'modified', 'unapproved', 'spammed' ), true ) ) {
521 $color = 'orange';
522 } elseif ( in_array( $act, array( 'added', 'activated', 'created', 'published', 'enabled', 'approved' ), true ) ) {
523 $color = 'green';
524 } elseif ( in_array( $act, array( 'synced', 'installed', 'uploaded' ), true ) ) {
525 $color = 'teal';
526 } elseif ( in_array( $act, array( 'opened', 'logged-in', 'logged-out', 'unspammed' ), true ) ) {
527 $color = 'blue';
528 } else {
529 $color = 'grey'; // fallback / unknown event
530 }
531
532 /* Compatibility aliases */
533 if ( 'delete' === $act ) {
534 $color = 'red';
535 } elseif ( 'deactivate' === $act ) {
536 $color = 'red';
537 } elseif ( 'update' === $act ) {
538 $color = 'orange';
539 } elseif ( in_array( $act, array( 'install', 'activate' ), true ) ) {
540 $color = 'teal';
541 }
542
543 $title = sprintf( '<span class="ui mini basic %s label">%s</span>', $color, esc_html( $title ) );
544 }
545
546 return $title;
547 }
548
549 /**
550 * Returns the icons for object.
551 *
552 * @param string $record Log data.
553 * @return string
554 */
555 public function get_object_icon( $record ) {
556 $context = $record->context;
557 $icon = '';
558 switch ( $context ) {
559 case 'post':
560 $icon = 'file text';
561 break;
562 case 'file':
563 $icon = 'file';
564 break;
565 case 'system-setting':
566 $icon = 'cogs';
567 break;
568 case 'category':
569 $icon = 'layer group';
570 break;
571 case 'tag':
572 $icon = 'tag';
573 break;
574 case 'widget':
575 $icon = 'puzzle piece';
576 break;
577 case 'plugin':
578 $icon = 'plug';
579 break;
580 case 'theme':
581 $icon = 'tint icon';
582 break;
583 case 'menu':
584 $icon = 'bars';
585 break;
586 case 'comment':
587 $icon = 'comment';
588 break;
589 case 'user':
590 $icon = 'user';
591 break;
592 case 'database':
593 $icon = 'database';
594 break;
595 case 'cron':
596 $icon = 'clock';
597 break;
598 case 'sites':
599 $icon = 'globe';
600 break;
601 // To compatible.
602 case 'translation':
603 $icon = 'language';
604 break;
605 case 'core':
606 $icon = 'wordpress icon';
607 break;
608 case 'posts':
609 $icon = 'file text';
610 break;
611 case 'clients':
612 $icon = 'address card';
613 break;
614 case 'users':
615 $icon = 'users';
616 break;
617 default:
618 break;
619 }
620 return ! empty( $icon ) ? sprintf( '<i class="%s icon"></i>', $icon ) : '';
621 }
622
623 /**
624 * Parse event title.
625 *
626 * @param object $record Log record object.
627 * @param bool $with_icon Return with icon.
628 * @param bool $with_context_suffix Return name object with context suffix.
629 *
630 * @return string
631 */
632 public function get_object_title( $record, $with_icon = true, $with_context_suffix = true ) { //phpcs:ignore -- NOSONAR - complex.
633 $extra_meta = ! empty( $record->extra_meta ) ? json_decode( $record->extra_meta, true ) : array();
634 if ( ! is_array( $extra_meta ) ) {
635 $extra_meta = array();
636 }
637 $title = '';
638 $roll_msg = '';
639 if ( 'posts' === $record->connector || 'users' === $record->connector || 'client' === $record->connector || 'installer' === $record->connector ) {
640 $title = $record->item;
641 if ( 'installer' === $record->connector && ! empty( $extra_meta['rollback_info'] ) ) {
642 $roll_msg = MainWP_Updates_Helper::get_roll_msg( $extra_meta['rollback_info'], true ) . ' ';
643 }
644 } elseif ( 'site' === $record->connector ) {
645 $title = esc_html__( 'Website', 'mainwp' );
646 } elseif ( 'non-mainwp-changes' === $record->connector ) {
647 $title = esc_html( $record->item );
648 if ( ! empty( $record->log_type_id ) ) {
649 $title = $this->get_changes_object_title( $record );
650 }
651 } elseif ( isset( $extra_meta['name'] ) ) {
652 $title = $extra_meta['name'];
653 if ( 'installer' === $record->connector && ! empty( $extra_meta['rollback_info'] ) ) {
654 $roll_msg = MainWP_Updates_Helper::get_roll_msg( $extra_meta['rollback_info'], true ) . ' ';
655 }
656 }
657
658 if ( empty( $record->log_type_id && $with_context_suffix ) ) {
659 $title = $roll_msg . $this->get_context_title( $title, $record->context, $record->connector );
660 }
661
662 if ( ! $with_context_suffix ) {
663 $title = trim( $title );
664 $title = preg_replace( '/( ?(plugin|theme))$/i', '', $title );
665 }
666
667 if ( ! empty( $record->log_type_id ) ) {
668 $title = Log_Changes_Logs_Helper::get_changes_logs_object_title( $record, $title );
669 }
670
671 if ( $with_icon ) {
672 $obj_icon = $this->get_object_icon( $record );
673 return $obj_icon . $title;
674 }
675
676 return $title;
677 }
678
679 /**
680 * Method get_log_author_name().
681 *
682 * @param object $record Logs record.
683 *
684 * @return string Author name.
685 */
686 public function get_log_author_name( $record ) { //phpcs:ignore -- NOSONAR - long function.
687 $name = '';
688 $user_meta = ! empty( $record->user_meta ) ? $record->user_meta : array();
689
690 if ( empty( $user_meta['full_name'] ) && isset( $record->meta['first_name'] ) && isset( $record->meta['last_name'] ) ) {
691 $user_meta['wp_user_id'] = $record->user_id;
692 $user_meta['full_name'] = $record->meta['first_name'] . ' ' . $record->meta['last_name'];
693 $user_meta['ip'] = ! empty( $record->meta['client_ip'] ) ? $record->meta['client_ip'] : '';
694 }
695
696 $user = new Log_Author( $record->user_id, $user_meta );
697
698 if ( ! empty( $record->log_type_id ) || 'non-mainwp-changes' === $record->connector ) {
699 $name = $user->get_full_name();
700 } else {
701 $name = $user->get_display_name();
702 }
703
704 return ! empty( $name ) ? $name : 'N/A';
705 }
706
707 /**
708 * Parse event changes logs title.
709 *
710 * @param object $record Log record object.
711 * @return string
712 */
713 public function parse_changes_action_title( $record ) {
714 $data = array( 'action' => ucfirst( $record->action ) );
715 $meta = ! empty( $record->meta ) && is_array( $record->meta ) ? $record->meta : array();
716 $na = 'N/A';
717 switch ( (int) $record->log_type_id ) {
718 case 1455:
719 $name = ! empty( $meta['name'] ) ? $meta['name'] : '';
720 if ( empty( $name ) ) {
721 $name = ! empty( $meta['plugin'] ) ? $meta['plugin'] : $na;
722 }
723 $data['plugin'] = $name;
724 break;
725 case 1465:
726 $data['theme'] = ! empty( $meta['theme'] ) ? basename( $meta['theme'] ) : $na;
727 break;
728 case 1460:
729 case 1470:
730 $data['name'] = ! empty( $meta['name'] ) ? $meta['name'] : $na;
731 break;
732 default:
733 break;
734 }
735 $parse_title = Log_Changes_Logs_Helper::get_changes_log_title( $record->log_type_id, $data, 'action' );
736 return ! empty( $parse_title ) ? $parse_title : ucfirst( $record->action );
737 }
738
739 /**
740 * Parse object changes logs title.
741 *
742 * @param string $title Object title.
743 * @param object $record Log record object.
744 * @return string
745 */
746 public function get_changes_formatted_object_title( $title, $record ) {
747 $meta = ! empty( $record->meta ) && is_array( $record->meta ) ? $record->meta : array();
748 $na = 'N/A';
749 $data = array();
750 switch ( (int) $record->log_type_id ) { // NOSONAR - switch is ok.
751 case 1461:
752 case 1965:
753 $name = ! empty( $meta['name'] ) ? $meta['name'] : '';
754 if ( empty( $name ) ) {
755 $name = ! empty( $meta['plugin'] ) ? $meta['plugin'] : $na;
756 }
757 $data['plugin'] = $name;
758 break;
759 default:
760 break;
761 }
762 if ( ! empty( $data ) ) {
763 $formatted_title = Log_Changes_Logs_Helper::get_changes_log_title( $record->log_type_id, $data, 'object' );
764 if ( ! empty( $formatted_title ) ) {
765 return $formatted_title;
766 }
767 }
768 return $title;
769 }
770
771 /**
772 * Returns the label for a context.
773 *
774 * @param string $title Current title.
775 * @param string $context Log context.
776 * @param string $connector Log connector.
777 * @return string
778 */
779 public function get_context_title( $title, $context, $connector ) {
780 $context_title = '';
781
782 if ( in_array( $context, array( 'plugin', 'theme' ) ) ) {
783 $title = preg_replace( '/( ?(plugin|theme|translation))$/i', '', $title );
784 $title = trim( $title );
785 }
786
787 if ( 'plugin' === $context ) {
788 $context_title = esc_html__( 'Plugin', 'mainwp' );
789 } elseif ( 'theme' === $context ) {
790 $context_title = esc_html__( 'Theme', 'mainwp' );
791 } elseif ( 'translation' === $context ) {
792 $context_title = esc_html__( 'Translation', 'mainwp' );
793 } elseif ( 'core' === $context ) {
794 $context_title = esc_html__( 'WordPress', 'mainwp' );
795 } elseif ( 'posts' === $connector ) {
796 if ( 'post' === $context ) {
797 $context_title = esc_html__( 'Post', 'mainwp' );
798 } elseif ( 'page' === $context ) {
799 $context_title = esc_html__( 'Page', 'mainwp' );
800 } else {
801 $context_title = esc_html__( 'Custom Post', 'mainwp' );
802 }
803 } elseif ( 'clients' === $context ) {
804 $context_title = esc_html__( 'Client', 'mainwp' );
805 } elseif ( 'users' === $context ) {
806 $context_title = esc_html__( 'User', 'mainwp' );
807 }
808
809 if ( ! empty( $context_title ) ) {
810 $title .= ' ' . $context_title;
811 }
812
813 return $title;
814 }
815
816 /**
817 * Parse changes logs object title.
818 *
819 * @param object $record Log record object.
820 * @return string
821 */
822 public function get_changes_object_title( $record ) {
823 $title = esc_html( ucwords( str_replace( '-', ' ', $record->context ) ) );
824 $title = $this->get_changes_formatted_object_title( $title, $record );
825 return $title;
826 }
827
828 /**
829 * Html output if no Child Sites are connected.
830 */
831 public function no_items() {
832 MainWP_UI::render_empty_element_placeholder( __( 'No Activity Logged Yet', 'mainwp' ), __( 'Site actions and updates will appear here once activity is detected.', 'mainwp' ), '<em data-emoji=":calendar_spiral:" class="medium"></em>' );
833 }
834
835 /**
836 * Method has_items().
837 *
838 * Verify if items exist.
839 */
840 public function has_items() {
841 return ! empty( $this->items );
842 }
843
844 /**
845 * Get last query found rows
846 *
847 * @return integer
848 */
849 public function get_total_found_rows() {
850 return $this->total_items;
851 }
852
853 /**
854 * Prepare the items to be listed.
855 *
856 * @param bool $with_prev_data To get previous data.
857 * @param array $insights_filters Required: Insights filters.
858 */
859 public function prepare_items( $with_prev_data, $insights_filters ) { //phpcs:ignore -- NOSONAR - complex method.
860
861 $req_orderby = '';
862 $req_order = null;
863
864 // phpcs:disable WordPress.Security.NonceVerification
865 if ( isset( $_REQUEST['order'] ) ) {
866 $order_values = MainWP_Utility::instance()->get_table_orders( $_REQUEST );
867 $req_orderby = $order_values['orderby'];
868 $req_order = $order_values['order'];
869 }
870
871 $filter_dtsstart = '';
872 $filter_dtsstop = '';
873 $array_clients_ids = array();
874 $array_groups_ids = array();
875 $array_usersfilter_sites_ids = array();
876
877 $sources_conds = '';
878 $array_sites_ids = array();
879 $array_events_list = array();
880
881 extract( $insights_filters ); //phpcs:ignore -- ok.
882
883 if ( ! empty( $filter_dtsstart ) && ! empty( $filter_dtsstop ) && ! is_numeric( $filter_dtsstart ) && ! is_numeric( $filter_dtsstop ) ) { // after extract.
884 // to fix string of date.
885 $filter_dtsstart = gmdate( 'Y-m-d', strtotime( $filter_dtsstart ) );
886 $filter_dtsstop = gmdate( 'Y-m-d', strtotime( $filter_dtsstop ) );
887 }
888 // phpcs:enable WordPress.Security.NonceVerification
889
890 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
891 $perPage = isset( $_REQUEST['length'] ) ? intval( $_REQUEST['length'] ) : false;
892
893 if ( 'widget-overview' === $this->table_id_prefix && ( false === $perPage || -1 === (int) $perPage ) ) {
894 $perPage = 25;
895 }
896
897 if ( -1 === (int) $perPage || empty( $perPage ) ) {
898 $perPage = 9999999;
899 }
900 $start = isset( $_REQUEST['start'] ) ? intval( $_REQUEST['start'] ) : 0;
901
902 $search = isset( $_REQUEST['search']['value'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['search']['value'] ) ) : '';
903
904 $recent_number = isset( $_REQUEST['recent_number'] ) ? intval( $_REQUEST['recent_number'] ) : 0;
905
906 $now = time();
907
908 // Get last 24 hours items.
909 if ( 'widget-overview' === $this->table_id_prefix ) {
910 if ( empty( $filter_dtsstart ) && empty( $filter_dtsstop ) ) {
911 $filter_dtsstart = $now - DAY_IN_SECONDS;
912 $filter_dtsstop = $now;
913 }
914 } else {
915 $filter_dtsstart = ! empty( $filter_dtsstart ) ? strtotime( $filter_dtsstart . ' 00:00:00' ) : '';
916 $filter_dtsstop = ! empty( $filter_dtsstop ) ? strtotime( $filter_dtsstop . ' 23:59:59' ) : '';
917 }
918
919 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
920
921 $args = array(
922 'order' => ( 'asc' === $req_order ) ? 'asc' : 'desc',
923 'orderby' => $req_orderby,
924 'start' => $start,
925 'recent_number' => $recent_number,
926 'search' => $search,
927 'groups_ids' => $array_groups_ids,
928 'client_ids' => $array_clients_ids,
929 'usersfilter_sites_ids' => $array_usersfilter_sites_ids, // format: userid-siteid, siteid = 0 => dashboard user.
930 'timestart' => $filter_dtsstart,
931 'timestop' => $filter_dtsstop,
932 'dismiss' => 0,
933 'view' => 'events_list',
934 'wpid' => ! empty( $insights_filters['wpid'] ) ? $insights_filters['wpid'] : 0, // int or array of site ids.
935 'sources_conds' => $sources_conds,
936 'sites_ids' => $array_sites_ids,
937 'events' => $array_events_list,
938 );
939
940 if ( isset( $_REQUEST['optimize_table'] ) && 1 === intval( $_REQUEST['optimize_table'] ) ) { //phpcs:ignore --ok.
941 $args['optimize'] = 1;
942 $args['optimize_with_meta'] = 1;
943 }
944
945 $args['records_per_page'] = $perPage;
946 $args['dev_log_query'] = 0; // 1 for dev logs.
947
948 if ( 'widget-overview' === $this->table_id_prefix ) {
949 $args['optimize'] = 1;
950 $args['optimize_with_meta'] = 1;
951 $args['not_count'] = true;
952 $args['optimize_has_more'] = true;
953 } else {
954 $args['with_all_logs_meta'] = 1; // so it will enable optimize_with_meta too.
955 }
956
957 $this->items = $this->manager->db->get_records( $args );
958 $this->total_items = $this->manager->db->get_found_records_count(); // get this value for recent events request only.
959 $this->sites_opts = $this->manager->db->get_logs_sites_opts();
960 $this->items_extra_data = $this->manager->db->get_logs_extra_data();
961
962 $this->items_prev = array();
963 if ( $with_prev_data && ! empty( $args['timestart'] ) && ! empty( $args['timestop'] ) && $args['timestart'] < $args['timestop'] ) {
964 $timestart_prev = $args['timestart'] - ( $args['timestop'] - $args['timestart'] );
965 $timestop_prev = $args['timestart'];
966 $args['timestart'] = $timestart_prev;
967 $args['timestop'] = $timestop_prev;
968 $this->items_prev = $this->manager->db->get_records( $args );
969 }
970 }
971
972
973 /**
974 * Display the table.
975 */
976 public function display() {
977
978 $sites_per_page = get_option( 'mainwp_default_manage_insights_events_per_page', 25 );
979
980 $sites_per_page = intval( $sites_per_page );
981
982 $pages_length = array(
983 25 => '25',
984 10 => '10',
985 50 => '50',
986 100 => '100',
987 300 => '300',
988 );
989
990 if ( ! isset( $pages_length[ $sites_per_page ] ) ) {
991 $pages_length = $pages_length + array( $sites_per_page => $sites_per_page );
992 }
993
994 ksort( $pages_length );
995
996 if ( isset( $pages_length[-1] ) ) {
997 unset( $pages_length[-1] );
998 }
999
1000 // @since version 5.5.
1001 $pages_length = apply_filters( 'mainwp_site_changes_table_pages_length', $pages_length, $this->table_id_prefix );
1002
1003 if ( 'widget-overview' === $this->table_id_prefix ) {
1004 $pages_length = array(
1005 25 => '25',
1006 );
1007 $sites_per_page = 25;
1008 }
1009
1010 $pagelength_val = implode( ',', array_keys( $pages_length ) );
1011 $pagelength_title = implode( ',', array_values( $pages_length ) );
1012
1013 $ajaxaction = 'mainwp_module_log_manage_events_display_rows';
1014 if ( 'widget-insight' === $this->table_id_prefix ) {
1015 $ajaxaction = 'mainwp_module_log_widget_insights_display_rows';
1016 } elseif ( 'widget-overview' === $this->table_id_prefix ) {
1017 $ajaxaction = 'mainwp_module_log_widget_events_overview_display_rows';
1018 }
1019
1020 $events_tbl_id = 'mainwp-module-log-records-table';
1021 if ( ! empty( $this->table_id_prefix ) ) {
1022 $events_tbl_id .= '-' . esc_attr( $this->table_id_prefix );
1023 }
1024
1025 if ( 'manage-events' === $this->table_id_prefix ) {
1026 ?>
1027 <div class="ui padded segment">
1028 <?php
1029 }
1030 ?>
1031 <div id="mainwp-module-log-records-table-container" style="opacity:0;">
1032 <table id="<?php echo esc_attr( $events_tbl_id ); ?>" style="width:100%" class="ui single line <?php echo 'manage-events' === $this->table_id_prefix ? 'selectable' : ''; ?> unstackable table mainwp-with-preview-table">
1033 <thead>
1034 <tr><?php $this->print_column_headers( true ); ?></tr>
1035 </thead>
1036 </table>
1037 </div>
1038 <?php
1039 if ( 'manage-events' === $this->table_id_prefix ) {
1040 ?>
1041 </div>
1042 <?php
1043 }
1044 if ( 'widget-overview' !== $this->table_id_prefix ) {
1045 ?>
1046 <div id="mainwp-loading-sites">
1047 <div class="ui active page dimmer">
1048 <div class="ui double text loader"><?php esc_html_e( 'Loading...', 'mainwp' ); ?></div>
1049 </div>
1050 </div>
1051 <?php
1052 }
1053 $table_features = array(
1054 'searching' => 'true',
1055 'paging' => 'true',
1056 'pagingType' => 'full_numbers',
1057 'info' => 'true',
1058 'colReorder' => '{columns:":not(.check-column):not(:last-child)"}',
1059 'stateSave' => 'true',
1060 'stateDuration' => '60 * 60 * 24 * 30',
1061 'order' => '[]',
1062 'scrollX' => 'true',
1063 'responsive' => 'true',
1064 'fixedColumns' => '',
1065 'searchDelay' => 350,
1066 'numbers' => 7,
1067 );
1068
1069 // Fix for widget state save overview table.
1070 if ( 'widget-overview' === $this->table_id_prefix ) {
1071 $table_features['stateSave'] = 'false';
1072 $table_features['searching'] = 'false';
1073 $table_features['paging'] = 'true';
1074 $table_features['info'] = 'false';
1075 $table_features['numbers'] = 3;
1076 }
1077
1078 ?>
1079
1080 <script type="text/javascript">
1081 var responsive = <?php echo esc_js( $table_features['responsive'] ); ?>;
1082 if( jQuery( window ).width() > 1140 ) {
1083 responsive = false;
1084 }
1085 var $module_log_table = null;
1086 jQuery( document ).ready( function( $ ) {
1087 const manage_tbl_id = '#<?php echo esc_js( $events_tbl_id ); ?>';
1088 const ajax_action = '<?php echo esc_js( $ajaxaction ); ?>';
1089
1090 let widgetViewSource = '';
1091
1092 if( jQuery('#widget-sites-changes-dropdown-selector').length ){
1093 widgetViewSource = mainwp_ui_state_load('sites-changes-widget');
1094 widgetViewSource = ['wp-admin', 'dashboard', '' ].includes(widgetViewSource) ? widgetViewSource : 'wp-admin';
1095 }
1096
1097 try {
1098
1099 const nextButton = document.createElement('a');
1100 nextButton.href = '#';
1101 nextButton.className = 'ui tiny basic button';
1102 nextButton.innerHTML = '<?php echo esc_js( __( 'More', 'mainwp' ) ); ?>';
1103
1104 //jQuery( '#mainwp-sites-table-loader' ).hide();
1105 $module_log_table = jQuery( manage_tbl_id ).on( 'processing.dt', function ( e, settings, processing ) {
1106 if(jQuery( '#mainwp-loading-sites' ).length){
1107 jQuery( '#mainwp-loading-sites' ).css( 'display', processing ? 'block' : 'none' );
1108 }
1109 if (!processing) {
1110 let tb = jQuery( manage_tbl_id );
1111 tb.find( 'th[cell-cls]' ).each( function(){
1112 let ceIdx = this.cellIndex;
1113 let cls = jQuery( this ).attr( 'cell-cls' );
1114 jQuery( manage_tbl_id + ' tr' ).each(function(){
1115 jQuery(this).find( 'td:eq(' + ceIdx + ')' ).addClass(cls);
1116 } );
1117 } );
1118 $( manage_tbl_id + ' .ui.dropdown' ).dropdown();
1119 $( manage_tbl_id + ' .ui.checkbox' ).checkbox();
1120 }
1121 } ).DataTable( {
1122 "ajax": {
1123 "url": ajaxurl,
1124 "type": "POST",
1125 "data": function ( d ) {
1126 let data = mainwp_secure_data( {
1127 action: ajax_action,
1128 range: $( '#mainwp-module-log-filter-ranges').length ? $( '#mainwp-module-log-filter-ranges').dropdown('get value') : '',
1129 group: $( '#mainwp-module-log-filter-groups').length ? $( '#mainwp-module-log-filter-groups').dropdown('get value') : '',
1130 client: $( '#mainwp-module-log-filter-clients').length ? $( '#mainwp-module-log-filter-clients').dropdown('get value') : 0,
1131 user: $( '#mainwp-module-log-filter-users').length ? $( '#mainwp-module-log-filter-users').dropdown('get value') : 0,
1132 dtsstart: $('#mainwp-module-log-filter-dtsstart input[type=text]').length ? $('#mainwp-module-log-filter-dtsstart input[type=text]').val() : '',
1133 dtsstop: $('#mainwp-module-log-filter-dtsstop input[type=text]').length ? $('#mainwp-module-log-filter-dtsstop input[type=text]').val() : '',
1134 current_client_id: $( '#mainwp-widget-filter-current-client-id').length ? $( '#mainwp-widget-filter-current-client-id').val() : 0,
1135 current_site_id: $( '#mainwp-widget-filter-current-site-id').length ? $( '#mainwp-widget-filter-current-site-id').val() : 0,
1136 } );
1137
1138 <?php if ( $this->optimize_table ) { ?>
1139 data.optimize_table = 1;
1140 <?php } ?>
1141
1142 if('mainwp_module_log_manage_events_display_rows' === ajax_action ){
1143 data.source = $( '#mainwp-module-log-filter-source').length ? $( '#mainwp-module-log-filter-source').dropdown('get value') : '';
1144 data.sites = $( '#mainwp-module-log-filter-sites').length ? $( '#mainwp-module-log-filter-sites').dropdown('get value') : '';
1145 data.events = $( '#mainwp-module-log-filter-events').length ? $( '#mainwp-module-log-filter-events').dropdown('get value') : '';
1146 } else {
1147 if( 'mainwp_module_log_widget_events_overview_display_rows' === ajax_action ){
1148 data.source = widgetViewSource;
1149 } else if( 'mainwp_module_log_widget_insights_display_rows' === ajax_action ) {
1150 // set recent number for none-manage-events table.
1151 data.recent_number = $( '#mainwp-widget-filter-events-limit').length ? $( '#mainwp-widget-filter-events-limit').val() : 100;
1152 }
1153 }
1154
1155 if('mainwp_module_log_manage_events_display_rows' === ajax_action ){
1156 if( ( data.source == '' || data.source == 'allsource' ) &&
1157 ( data.events == '' || data.events == 'allevents' ) &&
1158 ( data.sites == '' || data.sites == 'allsites' ) &&
1159 ( data.group == '' || data.group == 'alltags' ) &&
1160 ( data.client == '' || data.client == 'allclients' ) &&
1161 ( data.user == '' || data.user == 'allusers' ) &&
1162 data.range == 'thismonth' &&
1163 data.current_client_id == '' &&
1164 data.current_site_id == ''
1165 ){
1166 jQuery('#mainwp-module-log-filters-row').fadeOut(300);
1167 } else{
1168 jQuery('#mainwp-module-log-filters-row').fadeIn(300);
1169 }
1170 }
1171
1172 return $.extend( {}, d, data );
1173 },
1174 "dataSrc": function ( json ) {
1175 for ( let i=0, ien=json.data.length ; i < ien ; i++ ) {
1176 json.data[i].rowClass = json.rowsInfo[i].rowClass;
1177 json.data[i].log_id = json.rowsInfo[i].log_id;
1178 json.data[i].created_sort = json.rowsInfo[i].created;
1179 json.data[i].state_sort = json.rowsInfo[i].state;
1180 }
1181
1182 <?php if ( 'widget-overview' === $this->table_id_prefix ) { ?>
1183 if (json?.has_more) {
1184 nextButton.classList.remove('disabled');
1185 nextButton.removeAttribute('aria-disabled');
1186 nextButton.removeAttribute('tabindex');
1187 nextButton.setAttribute('href', '#');
1188 } else {
1189 nextButton.classList.add('disabled');
1190 nextButton.setAttribute('aria-disabled', 'true');
1191 nextButton.setAttribute('tabindex', '-1');
1192 nextButton.removeAttribute('href');
1193 }
1194 <?php } ?>
1195 return json.data;
1196 }
1197 },
1198 "layout": {
1199 <?php
1200 if ( 'widget-overview' === $this->table_id_prefix ) {
1201 ?>
1202 "topStart": null,
1203 "bottomEnd": nextButton
1204 <?php
1205 } else {
1206 ?>
1207 "bottomEnd": {
1208 "paging": {
1209 "numbers": <?php echo intval( $table_features['numbers'] ); ?>
1210 }
1211 }
1212 <?php
1213 }
1214 ?>
1215 },
1216 'responsive': responsive,
1217 'searching' : <?php echo esc_js( $table_features['searching'] ); ?>,
1218 "paging" : <?php echo esc_js( $table_features['paging'] ); ?>,
1219 "pagingType" : "<?php echo esc_js( $table_features['pagingType'] ); ?>",
1220 "info" : <?php echo esc_js( $table_features['info'] ); ?>,
1221 "colReorder" : <?php echo $table_features['colReorder']; // phpcs:ignore -- specical chars. ?>,
1222 "scrollX" : <?php echo esc_js( $table_features['scrollX'] ); ?>,
1223 "stateSave" : <?php echo esc_js( $table_features['stateSave'] ); ?>,
1224 "stateDuration" : <?php echo esc_js( $table_features['stateDuration'] ); ?>,
1225 "order" : <?php echo $table_features['order']; // phpcs:ignore -- specical chars. ?>,
1226 "fixedColumns" : <?php echo ! empty( $table_features['fixedColumns'] ) ? esc_js( $table_features['fixedColumns'] ) : '""'; ?>,
1227 "lengthMenu" : [ [<?php echo esc_js( $pagelength_val ); ?>], [<?php echo esc_js( $pagelength_title ); ?>] ],
1228 "serverSide": true,
1229 "pageLength": <?php echo intval( $sites_per_page ); ?>,
1230 "columnDefs": <?php echo wp_json_encode( $this->get_columns_defines() ); ?>,
1231 "columns": <?php echo wp_json_encode( $this->get_columns_init() ); ?>,
1232 "language": {
1233 "emptyTable": "<?php echo 'widget-overview' === $this->table_id_prefix ? esc_html__( 'No matching activity was found in the last 24 hours.', 'mainwp' ) : esc_html__( 'No events found.', 'mainwp' ); ?>"
1234 },
1235 "drawCallback": function( settings ) {
1236 this.api().tables().body().to$().attr( 'id', 'mainwp-module-log-records-body-table' );
1237 jQuery( '#mainwp-module-log-records-table-container' ).css( 'opacity', '1' );
1238 mainwp_datatable_fix_menu_overflow(manage_tbl_id);
1239 if ( typeof mainwp_preview_init_event !== "undefined" ) {
1240 mainwp_preview_init_event();
1241 }
1242 //jQuery( '#mainwp-sites-table-loader' ).hide();
1243 if ( jQuery('#mainwp-module-log-records-body-table td.dt-empty').length > 0 && jQuery('#sites-table-count-empty').length ){
1244 jQuery('#mainwp-module-log-records-body-table td.dt-empty').html(jQuery('#sites-table-count-empty').html());
1245 }
1246 if( 'manage-events' === '<?php echo esc_js( $this->table_id_prefix ); ?>' ){
1247 setTimeout(() => {
1248 jQuery(manage_tbl_id + ' .ui.checkbox').checkbox();
1249 mainwp_datatable_fix_menu_overflow(manage_tbl_id);
1250 mainwp_table_check_columns_init(manage_tbl_id);
1251 if (typeof mainwp_sites_changes_update_dismiss_button_state !== 'undefined') {
1252 mainwp_sites_changes_update_dismiss_button_state();
1253 }
1254 }, 1000);
1255 }
1256 },
1257 "initComplete": function( settings, json ) {
1258 if( 'widget-overview' === '<?php echo esc_js( $this->table_id_prefix ); ?>' ){
1259 setTimeout(() => {
1260 jQuery('#mainwp-module-log-records-table-container div.dt-search #dt-search-1').val('');// to fix issue autofill for chrome.
1261 }, 100);
1262 }
1263 },
1264 rowCallback: function (row, data) {
1265 jQuery( row ).addClass(data.rowClass);
1266 jQuery( row ).attr( 'id', "log-row-" + data.log_id );
1267 jQuery( row ).attr( 'log-id', data.log_id );
1268 jQuery( row ).find('.mainwp-date-cell').attr('data-sort', data.created_sort );
1269 jQuery( row ).find('.mainwp-state-cell').attr('data-sort', data.state_sort );
1270 },
1271 stateSaveParams: function (settings, data) {
1272 data._mwpv = mainwpParams.mainwpVersion || 'dev';
1273 },
1274 stateLoadParams: function (settings, data) {
1275 if ((mainwpParams.mainwpVersion || 'dev') !== data._mwpv) return false;
1276 },
1277 search: { regex: false, smart: false },
1278 orderMulti: false,
1279 searchDelay: <?php echo intval( $table_features['searchDelay'] ); ?>
1280 <?php
1281 if ( 'manage-events' === $this->table_id_prefix ) {
1282 echo ",select: {
1283 items: 'row',
1284 style: 'multi+shift',
1285 selector: 'tr>td.check-column'
1286 }"; // phpcs:ignore -- NOSONAR -- ok.
1287 }
1288 ?>
1289 })
1290
1291 if( 'manage-events' === '<?php echo esc_js( $this->table_id_prefix ); ?>' ){
1292 $module_log_table.on('select', function (e, dt, type, indexes) {
1293 if( 'row' == type ){
1294 dt.rows(indexes)
1295 .nodes()
1296 .to$().find('td.check-column .ui.checkbox' ).checkbox('set checked');
1297 }
1298 }).on('deselect', function (e, dt, type, indexes) {
1299 if( 'row' == type ){
1300 dt.rows(indexes)
1301 .nodes()
1302 .to$().find('td.check-column .ui.checkbox' ).checkbox('set unchecked');
1303 }
1304 });
1305 }
1306
1307
1308 nextButton.addEventListener('click', function (e) {
1309 e.preventDefault();
1310
1311 if (nextButton.classList.contains('disabled')) {
1312 return;
1313 }
1314 $module_log_table.page('next').draw('page');
1315 });
1316
1317 } catch(err) {
1318 // to fix js error.
1319 console.log(err);
1320 }
1321
1322 // Delay dropdown initialization to prevent it from being overwritten.
1323 setTimeout(() => {
1324 jQuery( '#widget-sites-changes-dropdown-selector' ).dropdown( {
1325 onChange: function( value ) {
1326 mainwp_ui_state_save('sites-changes-widget', value);
1327 if(widgetViewSource !== value ){
1328 widgetViewSource = value;
1329 $module_log_table.ajax.reload();
1330 }
1331 }
1332 } ).dropdown("set selected", widgetViewSource);
1333 }, 1000);
1334
1335
1336 mainwp_module_log_overview_content_filter = function() {
1337 if(jQuery( '#mainwp-common-filter-segments-model-name').length && 'manage-events' === jQuery( '#mainwp-common-filter-segments-model-name').val() ){
1338 mainwp_module_log_manage_events_filter();
1339 return;
1340 }
1341 let range = jQuery( '#mainwp-module-log-filter-ranges').dropdown('get value');
1342 let group = jQuery( '#mainwp-module-log-filter-groups').dropdown('get value');
1343 let client = jQuery( '#mainwp-module-log-filter-clients').dropdown('get value');
1344 let user = jQuery( '#mainwp-module-log-filter-users').dropdown('get value');
1345 let dtsstart = jQuery('#mainwp-module-log-filter-dtsstart input[type=text]').val();
1346 let dtsstop = jQuery('#mainwp-module-log-filter-dtsstop input[type=text]').val();
1347 let params = '';
1348 params += '&range=' + encodeURIComponent( range );
1349 params += '&group=' + encodeURIComponent( group );
1350 params += '&client=' + encodeURIComponent( client );
1351 params += '&user=' + encodeURIComponent( user );
1352 params += '&dtsstart=' + encodeURIComponent( dtsstart );
1353 params += '&dtsstop=' + encodeURIComponent( dtsstop );
1354 params += '&_insights_opennonce=' + mainwpParams._wpnonce;
1355 window.location = 'admin.php?page=InsightsOverview' + params;
1356 return false;
1357 };
1358 mainwp_module_log_overview_content_reset_filters = function(resetObj) {
1359 try {
1360 jQuery( '#mainwp-module-log-filter-ranges').dropdown('set selected', 'thismonth');
1361 jQuery( '#mainwp-module-log-filter-groups').dropdown('clear');
1362 jQuery( '#mainwp-module-log-filter-clients').dropdown('clear');
1363 jQuery( '#mainwp-module-log-filter-users').dropdown('clear');
1364 jQuery('#mainwp-module-log-filter-dtsstart input[type=text]').val('');
1365 jQuery('#mainwp-module-log-filter-dtsstop input[type=text]').val('');
1366 jQuery(resetObj).attr('disabled', 'disabled');
1367 mainwp_module_log_overview_content_filter();
1368 } catch(err) {
1369 // to fix js error.
1370 console.log(err);
1371 }
1372 };
1373 _init_manage_events_screen();
1374 } );
1375
1376 _init_manage_events_screen = function() {
1377 jQuery( '#mainwp-manage-events-screen-options-modal input[type=checkbox][id^="mainwp_show_column_"]' ).each( function() {
1378 let check_id = jQuery( this ).attr( 'id' );
1379 col_id = check_id.replace( "mainwp_show_column_", "" );
1380 try {
1381 $module_log_table.column( '#' + col_id ).visible( jQuery(this).is( ':checked' ) );
1382 } catch(err) {
1383 // to fix js error.
1384 }
1385 } );
1386 };
1387
1388 mainwp_manage_events_screen_options = function () {
1389 jQuery( '#mainwp-manage-events-screen-options-modal' ).modal( {
1390 allowMultiple: true,
1391 onHide: function () {
1392 //ok.
1393 }
1394 } ).modal( 'show' );
1395
1396 jQuery( '#manage-events-screen-options-form' ).submit( function() {
1397 if ( jQuery('input[name=reset_manage_events_columns_order]').attr('value') == 1 ) {
1398 $module_log_table.colReorder.reset();
1399 }
1400 jQuery( '#mainwp-manage-events-screen-options-modal' ).modal( 'hide' );
1401 } );
1402 return false;
1403 };
1404
1405 </script>
1406 <?php
1407 }
1408
1409 /**
1410 * Get the column count.
1411 *
1412 * @return int Column Count.
1413 */
1414 public function get_column_count() {
1415 list( $columns ) = $this->get_column_info();
1416 return count( $columns );
1417 }
1418
1419 /**
1420 * Echo the column headers.
1421 *
1422 * @param bool $top Top header.
1423 * @return void
1424 */
1425 public function print_column_headers( $top ) {
1426 list( $columns, $sortable ) = $this->get_column_info();
1427
1428 $def_columns = $this->get_default_columns();
1429 $def_columns['site_actions'] = '';
1430
1431 if ( ! empty( $columns['cb'] ) ) {
1432 $columns['cb'] = '<div class="ui checkbox"><input id="' . ( $top ? 'cb-select-all-top' : 'cb-select-all-bottom' ) . '" type="checkbox" aria-label="Select all clients." /></div>';
1433 }
1434
1435 foreach ( $columns as $column_event_key => $column_display_name ) {
1436
1437 $class = array( 'manage-' . $column_event_key . '-column' );
1438 $attr = '';
1439 if ( ! isset( $def_columns[ $column_event_key ] ) ) {
1440 $class[] = 'extra-column';
1441 $attr = 'cell-cls="' . esc_html( "collapsing $column_event_key column-$column_event_key" ) . '"';
1442 }
1443
1444 if ( ! isset( $sortable[ $column_event_key ] ) ) {
1445 $class[] = 'no-sort';
1446 }
1447
1448 if ( 'cb' === $column_event_key ) {
1449 $class[] = 'check-column';
1450 $class[] = 'collapsing';
1451 }
1452
1453 $tag = 'th';
1454 $id = "id='$column_event_key'";
1455
1456 if ( ! empty( $class ) ) {
1457 $class = "class='" . join( ' ', $class ) . "'";
1458 }
1459
1460 echo "<$tag $id $class $attr>$column_display_name</$tag>"; // phpcs:ignore WordPress.Security.EscapeOutput
1461 }
1462 }
1463
1464 /**
1465 * Get column info.
1466 */
1467 protected function get_column_info() {
1468
1469 if ( isset( $this->column_headers ) && is_array( $this->column_headers ) ) {
1470 $column_headers = array( array(), array(), array(), $this->get_default_primary_column_name() );
1471 foreach ( $this->column_headers as $key => $value ) {
1472 $column_headers[ $key ] = $value;
1473 }
1474
1475 return $column_headers;
1476 }
1477
1478 $columns = $this->get_columns();
1479
1480 $sortable_columns = $this->get_sortable_columns();
1481
1482 $_sortable = $sortable_columns;
1483
1484 $sortable = array();
1485 foreach ( $_sortable as $id => $data ) {
1486 if ( empty( $data ) ) {
1487 continue;
1488 }
1489
1490 $data = (array) $data;
1491 if ( ! isset( $data[1] ) ) {
1492 $data[1] = false;
1493 }
1494
1495 $sortable[ $id ] = $data;
1496 }
1497
1498 $primary = $this->get_default_primary_column_name();
1499 $this->column_headers = array( $columns, $sortable, $primary );
1500
1501 return $this->column_headers;
1502 }
1503
1504
1505 /**
1506 * Get table rows.
1507 *
1508 * Optimize for shared hosting or big networks.
1509 *
1510 * @return array Rows html.
1511 */
1512 public function ajax_get_datatable_rows() {
1513
1514 $all_rows = array();
1515 $info_rows = array();
1516
1517 $columns = $this->get_columns();
1518
1519 if ( $this->items ) {
1520 foreach ( $this->items as $log ) {
1521 $created_time = intval( $log->created / 1000000 ); // Seconds.
1522 $rw_classes = 'log-item mainwp-log-item-' . intval( $log->log_id );
1523
1524 $info_item = array(
1525 'rowClass' => esc_html( $rw_classes ),
1526 'log_id' => $log->log_id,
1527 'site_id' => ! empty( $log->site_id ) ? $log->site_id : 0,
1528 'created' => $created_time,
1529 'state' => is_null( $log->state ) ? - 1 : $log->state,
1530 );
1531 $cols_data = array();
1532 foreach ( $columns as $column_name => $column_display_name ) {
1533 ob_start();
1534 echo $this->column_default( $log, $column_name ); // phpcs:ignore WordPress.Security.EscapeOutput
1535 $cols_data[ $column_name ] = ob_get_clean();
1536 }
1537 $all_rows[] = $cols_data;
1538 $info_rows[] = $info_item;
1539 }
1540 }
1541 return array(
1542 'data' => $all_rows,
1543 'recordsTotal' => $this->total_items,
1544 'recordsFiltered' => $this->total_items,
1545 'rowsInfo' => $info_rows,
1546 'has_more' => is_array( $this->items_extra_data ) && ! empty( $this->items_extra_data['has_more'] ) ? true : false,
1547 );
1548 }
1549 }
1550