PluginProbe
Welcart e-Commerce / 2.12.3
Welcart e-Commerce v2.12.3
2.12.3 2.11.35 2.12.2 2.12.1 2.11.34 2.11.33 2.11.32 2.11.31 2.11.30 1.3.16 1.3.17 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 All 291 releases
usc-e-shop / classes / loglist.class.php

loglist.class.php in Welcart e-Commerce 2.12.3, at classes/loglist.class.php

1,426 lines 42.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Log List table class.
4 *
5 * @since 2.7.4
6 * @package Welcart
7 * @author Collne Inc.
8 * @since 2.7.4
9 */
10
11 if ( ! class_exists( 'WP_List_Table' ) ) {
12 require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
13 }
14
15 /**
16 * Class Log_List_Table
17 */
18 class Log_List_Table extends WP_List_Table {
19 /**
20 * The "usces_admin_log" database table
21 *
22 * @since 2.7.4
23 * @access private
24 * @var string $admin_log_table
25 */
26 private $admin_log_table = 'usces_admin_log';
27
28 /**
29 * The mode: all, order, member. Default: all
30 *
31 * @since 2.7.4
32 * @access private
33 * @var string $mode
34 */
35 private $mode = 'all';
36
37 /**
38 * Amount items are display per each page. Default: 50
39 *
40 * @since 2.7.4
41 * @access private
42 * @var integer $items_per_page
43 */
44 private $items_per_page = 50;
45
46 /**
47 * The view mode: compact view or expanded view. Default: compact view
48 *
49 * @since 2.7.4
50 * @access private
51 * @var string $view_mode
52 */
53 private $view_mode = 'compact_view';
54
55 /**
56 * The loglist screen id.
57 *
58 * @since 2.7.4
59 * @access private
60 * @var string $screen_id
61 */
62 public $screen_id = '';
63
64 /**
65 * The base info
66 *
67 * @since 2.7.4
68 * @access private
69 * @var array
70 */
71 private $base_info = array();
72
73 /**
74 * Override: WP_List_Table::__construct()
75 *
76 * @since 2.7.4
77 * @param string $mode The mode.
78 */
79 public function __construct( $mode = 'all' ) {
80 global $wpdb;
81
82 $this->mode = $mode;
83 $this->base_info = $this->get_base_info();
84 $this->admin_log_table = $wpdb->prefix . $this->admin_log_table;
85 $this->populate_screen_options();
86
87 parent::__construct();
88 }
89
90 /**
91 * Create the instance of the "Log_List_Table" class.
92 *
93 * @since 2.7.4
94 * @access public
95 */
96 public static function get_instance() {
97 return new self();
98 }
99
100 /**
101 * Create the admin submenu under the "usces_orderlist" menu
102 *
103 * @since 2.7.4
104 * @access public
105 */
106 public static function add_submenu_page() {
107 if ( self::is_enabled() ) {
108 $log_list = self::get_instance();
109 $admin_log_screen_id = add_submenu_page(
110 'usces_orderlist',
111 __( 'Operation log', 'usces' ),
112 __( 'Operation log', 'usces' ),
113 'wel_manage_order',
114 'usces_loglist',
115 array( $log_list, 'display' )
116 );
117
118 $log_list->screen_id = $admin_log_screen_id;
119 add_action( "load-{$admin_log_screen_id}", array( $log_list, 'add_screen_options' ) );
120 add_filter( 'screen_settings', array( $log_list, 'display_screen_options' ), 10, 2 );
121 }
122 }
123
124 /**
125 * Implementation of the hook "set_screen_option_{option}"
126 * Handle saving the log screen options.
127 *
128 * @see includes/default_filter.php: add_filter('set_screen_option_usces_admin_log_screen_options')
129 * @since 2.7.4
130 * @access public
131 * @param string $status The status.
132 * @param string $option The option name.
133 * @param string $value The option value.
134 * @return array The screen option.
135 */
136 public static function set_screen_options( $status, $option, $value ) {
137 $usces_admin_log_options = filter_input_array(
138 INPUT_POST,
139 array(
140 'usces_admin_log_screen_options' => array(
141 'view_mode' => array(
142 'filter' => FILTER_DEFAULT,
143 ),
144 'items_per_page' => array(
145 'filter' => FILTER_VALIDATE_INT,
146 ),
147 'flags' => FILTER_REQUIRE_ARRAY,
148 ),
149 )
150 );
151
152 return $usces_admin_log_options['usces_admin_log_screen_options'];
153 }
154
155 /**
156 * Add the meta box on the editing member screen.
157 *
158 * @since 2.7.4
159 * @access public
160 * @param string $member_action The member action.
161 */
162 public static function add_member_meta_box( $member_action ) {
163 if ( self::is_member_metabox_enabled() ) {
164 $allowed_member_actions = array( 'editpost', 'newpost', 'edit' );
165 if ( in_array( $member_action, $allowed_member_actions, true ) ) {
166 $log_list = new self( 'member' );
167 add_meta_box( 'member-logs', __( 'Operation log', 'usces' ), array( $log_list, 'display' ), 'member', 'edit' );
168 }
169 }
170 }
171
172 /**
173 * Add the meta box on the editing order screen.
174 *
175 * @since 2.7.4
176 * @access public
177 * @param string $order_action The order action.
178 * @return void
179 */
180 public static function add_order_meta_box( $order_action ) {
181 if ( self::is_order_metabox_enabled() ) {
182 $allowed_order_actions = array( 'editpost', 'newpost', 'edit' );
183 if ( in_array( $order_action, $allowed_order_actions, true ) ) {
184 $log_list = new self( 'order' );
185 add_meta_box( 'order-logs', __( 'Operation log', 'usces' ), array( $log_list, 'display' ), 'order', 'edit' );
186 }
187 }
188 }
189
190 /**
191 * Clear up the admin log by the period set.
192 *
193 * @since 2.7.4
194 * @see functions\utility.php: usces_cron_do()
195 * @access public
196 * @return void
197 */
198 public static function clearup() {
199 if ( self::is_enabled() ) {
200 global $usces, $wpdb;
201 $period = '-' . self::get_retention_period();
202 $period_ago_datetime = get_date_from_gmt( gmdate( 'Y-m-d 00:00:00', strtotime( $period ) ) );
203 $table = $wpdb->prefix . 'usces_admin_log';
204 $res = $wpdb->query(
205 $wpdb->prepare(
206 "DELETE FROM {$table} WHERE `datetime` < %s",
207 $period_ago_datetime
208 )
209 );
210 }
211 }
212
213 /**
214 * Override: WP_List_Table::display()
215 *
216 * @since 2.7.4
217 */
218 public function display() {
219 $this->enqueue_script();
220 $this->enqueue_style();
221
222 $this->prepare_items();
223
224 if ( $this->is_all_mode() ) {
225 $total_items = $this->count_logs();
226 $per_page = $this->items_per_page;
227 $this->set_pagination_args(
228 array(
229 'total_items' => $total_items,
230 'per_page' => $per_page,
231 )
232 );
233 }
234
235 $this->set_anchor();
236 $wrapper_ele_id = "{$this->mode}-log-table";
237 ?>
238 <div class="wrap" id="<?php echo esc_attr( $wrapper_ele_id ); ?>">
239 <div class="usces_admin">
240 <?php if ( $this->is_all_mode() ) : ?>
241 <h1>Welcart Management <?php echo esc_html__( 'Operation log', 'usces' ); ?></h1>
242 <p class="version_info">Version <?php echo esc_html( USCES_VERSION ); ?></p>
243 <?php endif; ?>
244 <?php $this->start_form(); ?>
245 <?php parent::display(); ?>
246 <?php $this->end_form(); ?>
247 </div>
248 </div>
249 <?php
250 }
251
252 /**
253 * Implementation of the hook "load-{screen_id}"
254 * Add the screen options for the log list page.
255 *
256 * @since 2.7.4
257 * @access public
258 */
259 public function add_screen_options() {
260 add_screen_option(
261 'items_per_page',
262 array(
263 'label' => __( 'Number of items per page:' ),
264 'default' => $this->items_per_page,
265 'option' => 'items_per_page',
266 )
267 );
268
269 add_screen_option(
270 'view_mode',
271 array(
272 'label' => __( 'View mode' ),
273 'default' => $this->view_mode,
274 'option' => 'view_mode',
275 )
276 );
277 }
278
279 /**
280 * Implementation of the hook "screen_settings"
281 * Render the html markup of the screen options in the log list page.
282 *
283 * @since 2.7.4
284 * @access public
285 * @param string $screen_settings The screen settings.
286 * @param Object $current_screen The Wp_Screen.
287 * @return string The html markup.
288 */
289 public function display_screen_options( $screen_settings, $current_screen ) {
290 if ( $this->screen_id === $current_screen->id ) {
291 $options = $current_screen->get_options();
292 ob_start();
293 ?>
294 <div class="metabox-prefs usces-admin-log-screen-options">
295 <input type="hidden" name="wp_screen_options[option]" value="usces_admin_log_screen_options" />
296 <input type="hidden" name="wp_screen_options[value]" value="yes" />
297 <fieldset class="screen-options">
298 <legend><?php esc_html_e( 'Pagination' ); ?></legend>
299 <label for="items_per_page"><?php echo esc_html( $options['items_per_page']['label'] ); ?></label>
300 <input type="number" step="1" min="1" max="999" class="items-per-page" name="usces_admin_log_screen_options[items_per_page]" id="items_per_page" maxlength="3" value="<?php echo esc_attr( $options['items_per_page']['default'] ); ?>">
301 </fieldset>
302 <fieldset class="screen-options">
303 <legend><?php echo esc_html( $options['view_mode']['label'] ); ?></legend>
304 <input type="radio" class="view-mode" value="compact_view" id="compact_view" name="usces_admin_log_screen_options[view_mode]" <?php checked( $options['view_mode']['default'], 'compact_view' ); ?>/><label for="compact_view"><?php esc_html_e( 'Compact view' ); ?></label>
305 <input type="radio" class="view-mode" value="expanded_view" id="expanded_view" name="usces_admin_log_screen_options[view_mode]" <?php checked( $options['view_mode']['default'], 'expanded_view' ); ?>/><label for="expanded_view"> <?php esc_html_e( 'Extended view' ); ?></label>
306 </fieldset>
307 </div><!-- metabox-prefs -->
308 <br class="clear">
309 <?php
310 // get_submit_button() returns an escaped HTML string, so direct echoing is safe here.
311 $button = get_submit_button( __( 'Apply' ), 'button button-primary', 'screen-options-apply', false );
312 echo $button; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
313 return ob_get_clean();
314 } else {
315 return $screen_settings;
316 }
317 }
318
319 /**
320 * Override: WP_List_Table::get_columns()
321 *
322 * @since 2.7.4
323 * @return array List of columns.
324 */
325 public function get_columns() {
326 $columns = array(
327 'ID' => __( 'ID', 'usces' ),
328 'author' => __( 'Author', 'usces' ),
329 'datetime' => __( 'Datetime', 'usces' ),
330 'action' => __( 'Action', 'usces' ),
331 'screen' => __( 'Screen', 'usces' ),
332 'entity_id' => __( 'Entity', 'usces' ),
333 'message' => __( 'Message', 'usces' ),
334 );
335
336 return $columns;
337 }
338
339 /**
340 * Override: WP_List_Table::prepare_items()
341 *
342 * @since 2.7.4
343 */
344 public function prepare_items() {
345 $columns = $this->get_columns();
346 $hidden = array();
347 $sortable = $this->get_sortable_columns();
348 $this->_column_headers = array( $columns, $hidden, $sortable );
349 $logs = $this->get_logs();
350 $this->items = array();
351 foreach ( $logs as $log ) {
352 $this->items[] = array(
353 'ID' => $log->ID,
354 'author' => $log->author,
355 'message' => $log->message,
356 'screen' => $log->screen,
357 'entity_id' => $log->entity_id,
358 'action' => $log->action,
359 'data' => $log->data,
360 'datetime' => $log->datetime,
361 );
362 }
363 }
364
365 /**
366 * Override: WP_List_Table::extra_tablenav()
367 *
368 * @since 2.7.4
369 * @param string $which The top or bottom.
370 */
371 protected function extra_tablenav( $which ) {
372 if ( $this->is_all_mode() ) {
373 $this->display_search_form();
374 }
375 }
376
377 /**
378 * Override: WP_List_Table::column_default()
379 *
380 * @since 2.7.4
381 * @param array $item The item.
382 * @param string $column_name The column name.
383 * @return string $output The output.
384 */
385 public function column_default( $item, $column_name ) {
386 switch ( $column_name ) {
387 case 'message':
388 $output = $item[ $column_name ];
389 $output .= $this->display_data_popup( $item );
390 break;
391 case 'author':
392 $author_login = $item[ $column_name ];
393 $author = get_user_by( 'login', $author_login );
394 $author_url = get_edit_user_link( $author->ID );
395 $output = "<a href='{$author_url}' title='{$author_login}' target='_blank'>{$author_login}</a>";
396 break;
397 case 'entity_id':
398 $entity_id = $item['entity_id'];
399 $deleted = 'delete' === $item['action'];
400 if ( $this->is_order_mode() || $this->is_member_mode() || $deleted ) {
401 $output = $entity_id;
402 } else {
403 $edit_entity_url = '#';
404 if ( $this->is_order_screen( $item['screen'] ) ) {
405 $edit_entity_url = $this->get_edit_order_url( $entity_id );
406 }
407 if ( $this->is_member_screen( $item['screen'] ) ) {
408 $edit_entity_url = $this->get_edit_member_url( $entity_id );
409 }
410 $output = "<a href='{$edit_entity_url}' title='{$entity_id}' target='_blank'>{$entity_id}</a>";
411 }
412 break;
413 case 'screen':
414 $output = $this->get_display_label( $item[ $column_name ] );
415 break;
416 case 'action':
417 $output = $this->get_display_label( $item[ $column_name ] );
418 break;
419 default:
420 $output = $item[ $column_name ];
421 }
422
423 return $output;
424 }
425
426 /**
427 * Override: WP_List_Table::get_sortable_columns().
428 *
429 * @since 2.7.4
430 * @return array $sortable_columns The sortable columns.
431 */
432 public function get_sortable_columns() {
433 $sortable_columns = array(
434 'ID' => array( 'ID', false ),
435 'author' => array( 'author', false ),
436 'screen' => array( 'screen', false ),
437 'entity_id' => array( 'entity_id', false ),
438 'action' => array( 'action', false ),
439 'datetime' => array( 'datetime', false ),
440 );
441
442 return $sortable_columns;
443 }
444
445 /**
446 * Populate screen options to this instance.
447 */
448 private function populate_screen_options() {
449 $screen_options = get_user_meta(
450 get_current_user_id(),
451 'usces_admin_log_screen_options',
452 array(
453 'view_mode' => 'compact',
454 'items_per_page' => 50,
455 )
456 );
457
458 $this->view_mode = isset( $screen_options['view_mode'] ) ? $screen_options['view_mode'] : 'compact_view';
459 $this->items_per_page = isset( $screen_options['items_per_page'] ) ? $screen_options['items_per_page'] : 50;
460 }
461
462 /**
463 * Get the display label.
464 *
465 * @access private
466 * @param string $label_key The label key.
467 * @return string The label.
468 */
469 private function get_display_label( $label_key ) {
470 if ( isset( $this->base_info['screens']['order'][ $label_key ] ['label'] ) ) {
471 return $this->base_info['screens']['order'][ $label_key ]['label'];
472 } elseif ( isset( $this->base_info['screens']['member'][ $label_key ]['label'] ) ) {
473 return $this->base_info['screens']['member'][ $label_key ]['label'];
474 } elseif ( isset( $this->base_info['actions'][ $label_key ]['label'] ) ) {
475 return $this->base_info['actions'][ $label_key ]['label'];
476 } else {
477 return '';
478 }
479 }
480
481 /**
482 * Check if the screent is order screen or not.
483 *
484 * @access private
485 * @param string $screen_id The screen id.
486 * @return boolean true/false
487 */
488 private function is_order_screen( $screen_id ) {
489 return isset( $this->base_info['screens']['order'][ $screen_id ] );
490 }
491
492 /**
493 * Check if the screent is member screen or not.
494 *
495 * @access private
496 * @param string $screen_id The screen id.
497 * @return boolean true/false
498 */
499 private function is_member_screen( $screen_id ) {
500 return isset( $this->base_info['screens']['member'][ $screen_id ] );
501 }
502
503 /**
504 * Get list of logs.
505 *
506 * @since 2.7.4
507 * @access private
508 * @return array $logs The logs.
509 */
510 private function get_logs() {
511 global $wpdb;
512 $sql = "SELECT * FROM {$this->admin_log_table}";
513 $sql .= $this->get_sql_where_clause();
514 $sql .= $this->get_sql_order_clause();
515
516 if ( $this->is_all_mode() ) {
517 $current_page = max( filter_input( INPUT_GET, 'paged' ), 1 );
518 $from = ( $current_page - 1 ) * $this->items_per_page;
519 } else {
520 $from = 0;
521 $this->items_per_page = 1000;
522 }
523
524 $sql .= " LIMIT {$from}, {$this->items_per_page}";
525 $logs = $wpdb->get_results( $sql );
526 if ( ! empty( $logs ) ) {
527 return $logs;
528 } else {
529 return array();
530 }
531 }
532
533 /**
534 * Count the total of logs.
535 *
536 * @since 2.7.4
537 * @access private
538 * @return integer $total The total.
539 */
540 private function count_logs() {
541 global $wpdb;
542
543 $sql = "SELECT COUNT(id) FROM {$this->admin_log_table}";
544 $sql .= $this->get_sql_where_clause();
545
546 $total = $wpdb->get_var( $sql );
547 return $total;
548 }
549
550 /**
551 * Render open tag <form>
552 *
553 * @since 2.7.4
554 * @access private
555 * @return void
556 */
557 private function start_form() {
558 if ( $this->is_all_mode() ) {
559 echo '<form>';
560 }
561 }
562
563 /**
564 * Render end tag <form>
565 *
566 * @since 2.7.4
567 * @access private
568 * @return void
569 */
570 private function end_form() {
571 if ( $this->is_all_mode() ) {
572 echo '</form>';
573 }
574 }
575
576 /**
577 * Generate the SQL order clause.
578 *
579 * @since 2.7.4
580 * @access private
581 * @return string $sql The SQL order clause.
582 */
583 private function get_sql_order_clause() {
584 global $wpdb;
585
586 $sql = '';
587 $orderby = filter_input( INPUT_GET, 'orderby' );
588 $order = filter_input( INPUT_GET, 'order' );
589
590 if ( empty( $orderby ) ) {
591 $orderby = 'ID';
592 } else {
593 if ( ! array_key_exists( $orderby, $this->get_columns() ) ) {
594 $orderby = 'ID';
595 }
596 }
597
598 if ( empty( $order ) ) {
599 $order = 'DESC';
600 } else {
601 if ( 'DESC' !== strtoupper( $order ) && 'ASC' !== strtoupper( $order ) ) {
602 $order = 'DESC';
603 }
604 }
605
606 $sql = $wpdb->prepare( ' ORDER BY %s %s', esc_sql( $orderby ), esc_sql( $order ) );
607 $sql = str_replace( "'", '', stripslashes( $sql ) );
608
609 return $sql;
610 }
611
612 /**
613 * Generate the SQL where clause.
614 *
615 * @since 2.7.4
616 * @access private
617 * @return string $sql The SQL where clause.
618 */
619 private function get_sql_where_clause() {
620 global $wpdb;
621
622 $sql = '';
623 if ( $this->is_all_mode() ) {
624 $screen = filter_input( INPUT_GET, 'usces_screen' );
625 $authors = filter_input( INPUT_GET, 'usces_author' );
626 $action = filter_input( INPUT_GET, 'usces_action' );
627 $datetime = filter_input( INPUT_GET, 'usces_datetime' );
628 $entity_id = filter_input( INPUT_GET, 'usces_entity_id' );
629 $where = array();
630 if ( ! empty( $authors ) ) {
631 $where[] = $wpdb->prepare( 'author = %s', esc_sql( $authors ) );
632 }
633
634 if ( ! empty( $action ) ) {
635 $where[] = $wpdb->prepare( 'action = %s', esc_sql( $action ) );
636 }
637
638 if ( ! empty( $screen ) ) {
639 $where[] = $wpdb->prepare( 'screen = %s', esc_sql( $screen ) );
640 }
641
642 if ( ! empty( $datetime ) ) {
643 $datetime = trim( $datetime );
644 $where[] = $wpdb->prepare( 'datetime LIKE %s', esc_sql( $datetime ) . '%' );
645 }
646
647 if ( ! empty( $entity_id ) ) {
648 $entity_id = trim( $entity_id );
649 $where[] = $wpdb->prepare( 'entity_id = %s', esc_sql( $entity_id ) );
650 }
651 } elseif ( $this->is_order_mode() ) {
652 $order_id = $this->get_context_entity_id( 'order_id' );
653 $where[] = $wpdb->prepare( 'screen IN ( %s )', implode( "','", $this->get_order_screen_ids() ) );
654 $where[] = $wpdb->prepare( 'entity_id = %s', esc_sql( $order_id ) );
655 } elseif ( $this->is_member_mode() ) {
656 $member_id = $this->get_context_entity_id( 'member_id' );
657 $where[] = $wpdb->prepare( 'screen IN ( %s )', implode( "','", $this->get_member_screen_ids() ) );
658 $where[] = $wpdb->prepare( 'entity_id = %s', esc_sql( $member_id ) );
659 }
660
661 if ( ! empty( $where ) ) {
662 $sql .= ' WHERE ' . implode( ' AND ', $where );
663 $sql = stripslashes( $sql );
664 }
665
666 return $sql;
667 }
668
669 /**
670 * Get entity id on the editing entity screen.
671 *
672 * @since 2.7.4
673 * @access private
674 * @param string $name The name of variable.
675 * @return integer $order_id The SQL where clause.
676 */
677 private function get_context_entity_id( $name ) {
678 $entity_id = filter_input( INPUT_GET, $name );
679
680 if ( empty( $entity_id ) ) {
681 $entity_id = filter_input( INPUT_POST, $name );
682 }
683
684 return (int) $entity_id;
685 }
686
687 /**
688 * Set anchor.
689 *
690 * @since 2.7.4
691 * @access private
692 * @return void
693 */
694 private function set_anchor() {
695 $anchor = "#{$this->mode}-log-table";
696 $_SERVER['REQUEST_URI'] = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) . $anchor;
697 }
698
699 /**
700 * Check if the mode is member mode or not
701 *
702 * @since 2.7.4
703 * @access private
704 * @return boolean true/false
705 */
706 private function is_member_mode() {
707 return 'member' === $this->mode;
708 }
709
710 /**
711 * Check if the mode is order mode or not
712 *
713 * @since 2.7.4
714 * @access private
715 * @return boolean true/false
716 */
717 private function is_order_mode() {
718 return 'order' === $this->mode;
719 }
720
721 /**
722 * Check if the mode is all mode or not
723 *
724 * @since 2.7.4
725 * @access private
726 * @return boolean true/false
727 */
728 private function is_all_mode() {
729 return 'all' === $this->mode;
730 }
731
732 /**
733 * Generate the edit order link.
734 *
735 * @since 2.7.4
736 * @access private
737 * @param integer $order_id The order id.
738 * @return string $url The edit order link.
739 */
740 private function get_edit_order_url( $order_id ) {
741 $url = esc_url( USCES_ADMIN_URL . "?page=usces_orderlist&order_action=edit&order_id={$order_id}&wc_nonce=" . wp_create_nonce( 'order_edit' ) );
742 return $url;
743 }
744
745 /**
746 * Generate the edit order link.
747 *
748 * @since 2.7.4
749 * @access private
750 * @param integer $member_id The order id.
751 * @return string $url The edit order link.
752 */
753 private function get_edit_member_url( $member_id ) {
754 $url = esc_url( USCES_ADMIN_URL . "?page=usces_memberlist&member_action=edit&member_id={$member_id}&wc_nonce=" . wp_create_nonce( 'member_list' ) );
755 return $url;
756 }
757
758 /**
759 * Display data.
760 *
761 * @since 2.7.4
762 * @access private
763 * @param array $item The log.
764 * @return string $output The output.
765 */
766 private function display_data_popup( $item ) {
767 $output = '';
768 $data = wel_safe_maybe_unserialize( $item['data'] );
769 $compared_mode = ! empty( $data['differed'] );
770 $item['mode'] = ( $compared_mode ) ? 'diff' : 'all';
771 $diff_ele_id = 'log-dialog-' . $item['ID'];
772 $output .= '<p><a href="javascript:void(0);" class="log-dialog-button" for="' . $diff_ele_id . '">' . __( 'More Details' ) . '</a></p>';
773 $output .= '<div style="display:none;" class="log-dialog" id="' . $diff_ele_id . '" title="' . __( 'Detailed information', 'usces' ) . '">';
774 $output .= $this->display_control_buttons( $item );
775
776 $display_table = '<table width="90%" align="center" class="compared-table">';
777 if ( $compared_mode ) {
778 $display_table .= '<tr><th>' . __( 'Field', 'usces' ) . '</th><th>' . __( 'Before', 'usces' ) . '</th><th>' . __( 'After', 'usces' ) . '</th></tr>';
779 } else {
780 $deleled = 'delete' === $item['action'];
781 $label = ( $deleled ) ? __( 'Before', 'usces' ) : __( 'After', 'usces' );
782 $display_table .= '<tr><th>' . __( 'Field', 'usces' ) . '</th><th colspan="2">' . $label . '</th></tr>';
783 }
784
785 $display_data = $data['display_data'];
786 foreach ( $display_data as $key => $data_field ) {
787 $data_field['compared_mode'] = $compared_mode;
788 $display_table .= $this->display_field_data( $data_field );
789 }
790
791 $display_table .= '</table></div>';
792 $output .= $display_table;
793 $inline_showed = $this->is_expanded_view_mode() && $compared_mode;
794 if ( $inline_showed ) {
795 $output = '<div class="inline-diff"><h4>' . __( 'Detailed information', 'usces' ) . '</h4>' . $display_table . '</div>' . $output;
796 }
797
798 return $output;
799 }
800
801 /**
802 * Check if the view mode is expanded or not.
803 *
804 * @return boolean true/false.
805 */
806 private function is_expanded_view_mode() {
807 return 'expanded_view' === $this->view_mode;
808 }
809
810 /**
811 * Display the control button.
812 *
813 * @since 2.7.4
814 * @access private
815 * @param array $item The log.
816 * @return string $output The output.
817 */
818 private function display_control_buttons( $item ) {
819 $display_log_mode_id = 'display_log_mode_' . $item['ID'];
820 $screen = $item['screen'];
821 $output = '<fieldset class="display-control"><legend>' . __( 'Display control', 'usces' ) . '</legend>';
822 $output .= '<table width="90%" align="center" class="control-table">';
823 $output .= '<tr><th>' . __( 'Mode', 'usces' ) . '</th>';
824 $output .= '<td><label><input type="radio" name="' . $display_log_mode_id . '" value="all" ' . checked( 'all', $item['mode'], false ) . '/>' . __( 'All', 'usces' ) . '</label></td>';
825 $output .= '<td><label><input type="radio" name="' . $display_log_mode_id . '" value="diff" ' . checked( 'diff', $item['mode'], false ) . ' />' . __( 'Only changes', 'usces' ) . '</label></td></tr>';
826 $output .= '<tr><th>' . __( 'Fields', 'usces' ) . '</th>';
827 if ( $this->is_order_screen( $screen ) ) {
828 $output .= '<td>';
829 $output .= '<label><input type="checkbox" name="group" value="other" checked />' . __( 'Other', 'usces' ) . '</label><br>';
830 $output .= '<label><input type="checkbox" value="order_cart" name="group" checked />' . __( 'Cart', 'usces' ) . '</label>';
831 $output .= '</td><td>';
832 $output .= '<label><input type="checkbox" value="custom_order" name="group" checked />' . __( 'Custom order field', 'usces' ) . '</label><br>';
833 $output .= '<label><input type="checkbox" value="custom_customer" name="group" checked />' . __( 'Custom customer field', 'usces' ) . '</label><br>';
834 $output .= '<label><input type="checkbox" value="custom_delivery" name="group" checked />' . __( 'Custom delivery field', 'usces' ) . '</label><br>';
835 $output .= '<label><input type="checkbox" value="payment_transaction_logs" name="group" checked />' . __( 'Payment information', 'usces' ) . '</label><br>';
836 $output .= '</td>';
837 } elseif ( $this->is_member_screen( $screen ) ) {
838 $output .= '<td>';
839 $output .= '<label><input type="checkbox" name="group" value="other" checked />' . __( 'Other', 'usces' ) . '</label><br>';
840 $output .= '<label><input type="checkbox" value="custom_member" name="group" checked />' . __( 'Custom member field', 'usces' ) . '</label>';
841 $output .= '</td><td>';
842 $output .= '<label><input type="checkbox" value="custom_admin_member" name="group" checked />' . __( 'Admin custom field', 'usces' ) . '</label><br>';
843 $output .= '</td>';
844 }
845 $output .= '</tr>';
846 $output .= '</table>';
847 $output .= '</fieldset><p></p>';
848 return $output;
849 }
850
851 /**
852 * Render the field data.
853 *
854 * @since 2.7.4
855 * @access private
856 * @param array $field_data The field data.
857 * @return string $output The output.
858 */
859 private function display_field_data( $field_data ) {
860 $output = '';
861 $is_repeater_field = ! empty( $field_data['is_repeater'] );
862 $is_group_field = ! empty( $field_data['is_group'] );
863
864 if ( $is_repeater_field ) {
865 $output .= $this->display_repeater_field( $field_data );
866 } elseif ( $is_group_field ) {
867 $output .= $this->display_group_field( $field_data );
868 } else {
869 $output .= $this->display_plain_field( $field_data );
870 }
871
872 return $output;
873 }
874
875 /**
876 * Get classes for the field row.
877 *
878 * @param boolean $is_diff The field is different or not.
879 * @param string $group The field group.
880 * @return array $classes The list of classes.
881 */
882 private function get_row_classes( $is_diff = false, $group = '' ) {
883 $classes = array();
884
885 if ( ! empty( $group ) ) {
886 $classes[] = $group;
887 }
888
889 if ( $is_diff ) {
890 $classes[] = 'different';
891 } else {
892 $classes[] = 'same-row';
893 $classes[] = 'log-hidden';
894 }
895
896 return $classes;
897 }
898
899 /**
900 * Render the repeater field data.
901 *
902 * @since 2.7.4
903 * @access private
904 * @param array $field_data The field data.
905 * @return string $output The output.
906 */
907 private function display_repeater_field( $field_data ) {
908 $is_diff = ! empty( $field_data['is_diff'] );
909 $group = ! empty( $field_data['field']['group'] ) ? $field_data['field']['group'] : '';
910 $label = $field_data['field']['label'];
911 $compared_mode = ! empty( $field_data['compared_mode'] );
912 $is_key_and_value = ! empty( $field_data['is_key_and_value'] );
913
914 $output = $this->display_header_row( $label, $is_diff, $group );
915
916 $rows = ! empty( $field_data['rows'] ) ? $field_data['rows'] : array();
917 $index = 1;
918 foreach ( $rows as $row ) {
919 $has_row_label = isset( $field_data['field']['row_label'] );
920 if ( $has_row_label ) {
921 $is_row_diff = false;
922 if ( $is_key_and_value ) {
923 $is_row_diff = ! empty( $row['is_diff'] );
924 } else {
925 foreach ( $row as $col ) {
926 $is_row_diff = $is_row_diff || ! empty( $col['is_diff'] );
927 }
928 }
929 $row_label = $field_data['field']['row_label'] . ' ' . $index;
930
931 $output .= $this->display_header_row( $row_label, $is_row_diff, $group );
932 }
933
934 if ( $is_key_and_value ) {
935 $row['compared_mode'] = $compared_mode;
936 $output .= $this->display_field_data( $row );
937 } else {
938 foreach ( $row as $key => $col ) {
939 if ( ! empty( $col ) ) {
940 $col['compared_mode'] = $compared_mode;
941 }
942
943 $output .= $this->display_field_data( $col );
944 }
945 }
946
947 $index++;
948 }
949
950 return $output;
951 }
952
953 /**
954 * Display header row for the field.
955 *
956 * @param string $label The label.
957 * @param boolean $is_diff The field is different or not.
958 * @param string $group The field group.
959 * @return string The html of the header.
960 */
961 private function display_header_row( $label, $is_diff, $group = '' ) {
962 $output = '';
963 if ( ! empty( $label ) ) {
964 $classes = $this->get_row_classes( $is_diff, $group );
965 $row_class = implode( ' ', $classes );
966 $style = ( $is_diff ) ? '' : ' style="display:none;"';
967 $output = '<tr class="' . esc_attr( $row_class ) . '"><td colspan="3"><h3>' . esc_html( $label ) . '</h3></tr>';
968 }
969
970 return $output;
971 }
972
973 /**
974 * Render the plain field data.
975 *
976 * @since 2.7.4
977 * @access private
978 * @param array $field_data The field data.
979 * @return string $output The output.
980 */
981 private function display_plain_field( $field_data ) {
982 if ( empty( $field_data ) ) {
983 return '';
984 } else {
985 $compared_mode = ! empty( $field_data['compared_mode'] );
986 $group = ! empty( $field_data['field']['group'] ) ? $field_data['field']['group'] : '';
987 $is_diff = ! empty( $field_data['is_diff'] );
988 $row_classes = $this->get_row_classes( $is_diff, $group );
989 $classes = implode( ' ', $row_classes );
990 $label = ( ! empty( $field_data['field']['label'] ) ) ? $field_data['field']['label'] : '';
991
992 $output = '<tr class="' . esc_attr( $classes ) . '">';
993 $output .= '<th width="20%">' . esc_html( $label ) . '</th>';
994 if ( $compared_mode ) {
995 $output .= '<td>' . esc_html( $field_data['before'] ) . '</td>';
996 $output .= '<td>' . esc_html( $field_data['after'] ) . '</td>';
997 } else {
998 $field_value = ( ! empty( $field_data['after'] ) ) ? $field_data['after'] : $field_data['before'];
999 $output .= '<td colspan="2">' . esc_html( $field_value ) . '</td>';
1000 }
1001
1002 $output .= '</tr>';
1003
1004 return $output;
1005 }
1006 }
1007
1008 /**
1009 * Render the group field data.
1010 *
1011 * @since 2.7.4
1012 * @access private
1013 * @param array $field_data The field data.
1014 * @return string $output The output.
1015 */
1016 private function display_group_field( $field_data ) {
1017 $output = '';
1018
1019 if ( ! empty( $field_data['field']['label'] ) ) {
1020 $is_diff = ! empty( $field_data['is_diff'] );
1021 $group = ! empty( $field_data['field']['group'] ) ? $field_data['field']['group'] : '';
1022 $label = $field_data['field']['label'];
1023
1024 $output .= $this->display_header_row( $label, $is_diff, $group );
1025 }
1026
1027 $sub_fields = ! empty( $field_data['fields'] ) ? $field_data['fields'] : array();
1028 foreach ( $sub_fields as $sub_field_data ) {
1029 $sub_field_data['compared_mode'] = $field_data['compared_mode'];
1030 $output .= $this->display_field_data( $sub_field_data );
1031 }
1032
1033 return $output;
1034 }
1035
1036 /**
1037 * The base information.
1038 *
1039 * @since 2.7.4
1040 * @access private
1041 * @return array The base info.
1042 */
1043 private function get_base_info() {
1044 return array(
1045 'screens' => array(
1046 'order' => array(
1047 'orderlist' => array(
1048 'label' => __( 'Order list screen', 'usces' ),
1049 ),
1050 'ordernew' => array(
1051 'label' => __( 'Order new screen', 'usces' ),
1052 ),
1053 'orderedit' => array(
1054 'label' => __( 'Order edit screen', 'usces' ),
1055 ),
1056 ),
1057 'member' => array(
1058 'memberlist' => array(
1059 'label' => __( 'Member list screen', 'usces' ),
1060 ),
1061 'membernew' => array(
1062 'label' => __( 'Member new screen', 'usces' ),
1063 ),
1064 'memberedit' => array(
1065 'label' => __( 'Member edit screen', 'usces' ),
1066 ),
1067 ),
1068 ),
1069 'actions' => array(
1070 'create' => array(
1071 'label' => __( 'Register', 'usces' ),
1072 ),
1073 'update' => array(
1074 'label' => __( 'Update', 'usces' ),
1075 ),
1076 'delete' => array(
1077 'label' => __( 'Delete', 'usces' ),
1078 ),
1079 ),
1080 );
1081 }
1082
1083 /**
1084 * The list of the order screen ids.
1085 *
1086 * @since 2.7.4
1087 * @access private
1088 * @return array The order screen ids
1089 */
1090 private function get_order_screen_ids() {
1091 return array_keys( $this->base_info['screens']['order'] );
1092 }
1093
1094 /**
1095 * The list of the member screen ids.
1096 *
1097 * @since 2.7.4
1098 * @access private
1099 * @return array The member screen ids
1100 */
1101 private function get_member_screen_ids() {
1102 return array_keys( $this->base_info['screens']['member'] );
1103 }
1104
1105 /**
1106 * Render the search form.
1107 *
1108 * @since 2.7.4
1109 * @access private
1110 * @return void
1111 */
1112 private function display_search_form() {
1113 $author = filter_input( INPUT_GET, 'usces_author' );
1114 $action = filter_input( INPUT_GET, 'usces_action' );
1115 $screen = filter_input( INPUT_GET, 'usces_screen' );
1116 $datetime = filter_input( INPUT_GET, 'usces_datetime' );
1117 $entity_id = filter_input( INPUT_GET, 'usces_entity_id' );
1118
1119 $management_users = $this->get_wc_management_users();
1120 $order_screens = $this->base_info['screens']['order'];
1121 $member_screens = $this->base_info['screens']['member'];
1122 $actions = $this->base_info['actions'];
1123 $cancel_url = admin_url( 'admin.php?page=usces_loglist' );
1124 ?>
1125 <div style="float:left;">
1126 <input type="hidden" name="page" value="usces_loglist"/>
1127 <select name="usces_author">
1128 <option value=""><?php esc_attr_e( '--Select an author--', 'usces' ); ?></option>
1129 <?php foreach ( $management_users as $management_user ) : ?>
1130 <option value="<?php echo esc_attr( $management_user ); ?>"<?php selected( $management_user, $author ); ?>>
1131 <?php echo esc_html( $management_user ); ?>
1132 </option>
1133 <?php endforeach; ?>
1134 </select>
1135 <select name="usces_action">
1136 <option value=""><?php esc_attr_e( '--Select action--', 'usces' ); ?></option>
1137 <?php foreach ( $actions as $key => $action_option ) : ?>
1138 <option value="<?php echo esc_attr( $key ); ?>"<?php selected( $key, $action ); ?>>
1139 <?php echo esc_html( $action_option['label'] ); ?>
1140 </option>
1141 <?php endforeach; ?>
1142 </select>
1143 <select name="usces_screen">
1144 <option value=""><?php esc_attr_e( '--Select Screen--', 'usces' ); ?></option>
1145 <?php foreach ( $order_screens as $key => $order_screen ) : ?>
1146 <option value="<?php echo esc_attr( $key ); ?>"<?php selected( $key, $screen ); ?>>
1147 <?php echo esc_html( $order_screen['label'] ); ?>
1148 </option>
1149 <?php endforeach; ?>
1150 <?php foreach ( $member_screens as $key => $member_screen ) : ?>
1151 <option value="<?php echo esc_attr( $key ); ?>"<?php selected( $key, $screen ); ?>>
1152 <?php echo esc_html( $member_screen['label'] ); ?>
1153 </option>
1154 <?php endforeach; ?>
1155 </select>
1156 <input type="text" name="usces_datetime" placeholder="<?php esc_attr_e( 'Enter a datetime', 'usces' ); ?>" value="<?php echo esc_attr( $datetime ); ?>"/>
1157 <input type="text" name="usces_entity_id" placeholder="<?php esc_attr_e( 'Enter an entity id', 'usces' ); ?>" value="<?php echo esc_attr( $entity_id ); ?>"/>
1158 <input type="button" value="<?php esc_attr_e( 'Search', 'usces' ); ?>" class="button logSearchBtn"/>
1159 <a href="<?php echo esc_url( $cancel_url ); ?>" class="button logSearchBtn"><?php esc_attr_e( 'Cancellation', 'usces' ); ?></a>
1160 </div>
1161 <?php
1162 }
1163
1164 /**
1165 * Get the list of the Welcart management ussers.
1166 */
1167 private function get_wc_management_users() {
1168 global $wpdb;
1169 $management_users = array();
1170 $capabilities_meta_key = $wpdb->prefix . 'capabilities';
1171 $args = array(
1172 'meta_query' => array(
1173 'relation' => 'OR',
1174 array(
1175 'key' => $capabilities_meta_key,
1176 'value' => 'level_5',
1177 'compare' => 'LIKE',
1178 ),
1179 array(
1180 'key' => $capabilities_meta_key,
1181 'value' => 'administrator',
1182 'compare' => 'LIKE',
1183 ),
1184 ),
1185 );
1186
1187 $user_query = new WP_User_Query( $args );
1188 $users = $user_query->get_results();
1189
1190 if ( ! empty( $users ) ) {
1191 foreach ( $users as $user ) {
1192 $management_users[] = $user->user_login;
1193 }
1194 }
1195
1196 return $management_users;
1197 }
1198
1199 /**
1200 * Check if the order operator log function is enabled or not.
1201 */
1202 public static function is_order_metabox_enabled() {
1203 return OPERATION_LOG::is_order_metabox_enabled();
1204 }
1205
1206 /**
1207 * Check if the member operator log function is enabled or not.
1208 */
1209 public static function is_member_metabox_enabled() {
1210 return OPERATION_LOG::is_member_metabox_enabled();
1211 }
1212
1213 /**
1214 * Check if the operator log function is enabled or not.
1215 */
1216 public static function is_enabled() {
1217 return OPERATION_LOG::is_enabled();
1218 }
1219
1220 /**
1221 * Get the retention period.
1222 *
1223 * @return string
1224 */
1225 public static function get_retention_period() {
1226 return OPERATION_LOG::get_retention_period();
1227 }
1228
1229 /**
1230 * Render style for the log list table.
1231 *
1232 * @since 2.7.4
1233 * @access private
1234 * @return void
1235 */
1236 private function enqueue_style() {
1237 ?>
1238 <style>
1239 table.compared-table th, table.compared-table td {
1240 border: 1px solid #c3c4c7;
1241 word-wrap: break-word;
1242 min-width: 50px;
1243 max-width: 150px;
1244 }
1245 table.compared-table td h3 {
1246 text-align: center;
1247 font-size: medium;
1248 font-weight: 500;
1249 }
1250 fieldset.display-control {
1251 border: 1px solid #c3c4c7;
1252 margin: auto;
1253 width: 89%;
1254 }
1255 table.control-table {
1256 margin: auto;
1257 padding: 10px;
1258 }
1259 .log-hidden {
1260 display:none;
1261 }
1262 table.compared-table tr.different{
1263 color: red;
1264 }
1265 th.column-message {
1266 width : 35%;
1267 }
1268 .inline-diff table.compared-table tr.different td:nth-child(3){
1269 color: red;
1270 }
1271 </style>
1272 <?php
1273 }
1274
1275 /**
1276 * Render javascript for the log list table.
1277 *
1278 * @since 2.7.4
1279 * @access private
1280 * @return void
1281 */
1282 private function enqueue_script() {
1283 wp_enqueue_script( 'jquery-ui-dialog' );
1284 ?>
1285 <script type="text/javascript">
1286 jQuery( document ).ready( function ( $ ) {
1287 const logListTable = {
1288 start: function () {
1289 this.initPopup();
1290 this.listen();
1291 },
1292 initPopup: function () {
1293 $( '.log-dialog' ).dialog( {
1294 autoOpen: false,
1295 show: { effect: 'blind', duration: 1000 },
1296 hide: { effect: 'explode', duration: 1000 },
1297 width: '40%',
1298 maxHeight: 600,
1299 } );
1300 },
1301 listen: function () {
1302 this.onClickDiffButton();
1303 this.onChangeSelect( 'usces_author' );
1304 this.onChangeSelect( 'usces_screen' );
1305 this.onChangeSelect( 'usces_action' );
1306 this.onChangeTextInput( 'usces_datetime' );
1307 this.onChangeTextInput( 'usces_entity_id' );
1308 this.onChangeTextInput( 'usces_author' );
1309 this.onClickSearchBtn();
1310 this.toggleOpenOrClose();
1311 this.onChangeControlButtons();
1312 },
1313 onChangeControlButtons: function () {
1314 const modeEles = $( 'fieldset.display-control input[name*=display_log_mode]' );
1315 modeEles.on( 'click', function () {
1316 const parentEle = $( this ).parents( '.log-dialog' );
1317 const mode = $( this ).val();
1318 parentEle
1319 .find( 'fieldset.display-control input[name=group]:checked' )
1320 .each( function () {
1321 let group = $( this ).val();
1322 let selector = 'tr.same-row.' + group;
1323 if ( 'all' === mode ) {
1324 selector += ',tr.different.' + group;
1325 parentEle.find( selector ).removeClass('log-hidden');
1326 }
1327
1328 if ( 'diff' === mode ) {
1329 parentEle.find( selector ).addClass('log-hidden');
1330 }
1331 } );
1332 } );
1333
1334 $( 'fieldset.display-control input[name*=display_log_mode]:checked' ).trigger(
1335 'click'
1336 );
1337
1338 $( 'fieldset.display-control input[name=group]' ).on( 'change', function () {
1339 let eleId = 'tr.' + $( this ).val();
1340 const parentEle = $( this ).parents( '.log-dialog' );
1341
1342 if ( $( this ).is( ':checked' ) ) {
1343 const isDiffMode = parentEle
1344 .find(
1345 'fieldset.display-control input[name*=display_log_mode][value=diff]'
1346 )
1347 .is( ':checked' );
1348 if ( isDiffMode ) {
1349 eleId += '.different';
1350 }
1351 parentEle.find( eleId ).removeClass('log-hidden');
1352 } else {
1353 parentEle.find( eleId ).addClass('log-hidden');
1354 }
1355 } );
1356 },
1357 toggleOpenOrClose: function () {
1358 $( 'span.toggle-indicator' ).on( 'click', function () {
1359 $( this ).parents( '.postbox' ).toggleClass( 'closed' );
1360 $( this )
1361 .parents( '.handlediv' )
1362 .attr( 'aria-expanded', function ( _, attr ) {
1363 return ! attr;
1364 } );
1365 } );
1366 },
1367 onClickSearchBtn: function () {
1368 $( '.logSearchBtn' ).on( 'click', function ( e ) {
1369 $( 'input[name=_wp_http_referer]' ).remove();
1370 $( 'input[name=_wpnonce]' ).remove();
1371 $( '#current-page-selector' ).val( 1 );
1372 $( this ).parents( 'form' ).submit();
1373 } );
1374 },
1375 onClickDiffButton: function () {
1376 $( '.log-dialog-button' ).on( 'click', function () {
1377 let a = '#' + $( this ).attr( 'for' );
1378 $( a ).dialog( 'open' );
1379 $( a ).find( 'input[type="radio"]:checked' ).focus();
1380 } );
1381 },
1382 onChangeSelect: function ( name ) {
1383 $( 'select[name="' + name + '"]' ).on( 'change', function () {
1384 const thisEle = $( this );
1385 const isTop = thisEle.parents( '.top' ).length > 0;
1386 const selected = thisEle.val();
1387 let thatEle = null;
1388 if ( isTop ) {
1389 thatEle = $(
1390 '.tablenav.bottom select[name="' + name + '"]'
1391 );
1392 } else {
1393 thatEle = $( '.tablenav.top select[name="' + name + '"]' );
1394 }
1395
1396 thatEle.find( 'option' ).removeProp( 'selected' );
1397 thatEle
1398 .find( 'option[value="' + selected + '"]' )
1399 .prop( 'selected', true );
1400 } );
1401 },
1402 onChangeTextInput: function ( name ) {
1403 $( 'input[name="' + name + '"]' ).on( 'change', function () {
1404 const thisEle = $( this );
1405 const isTop = thisEle.parents( '.top' ).length > 0;
1406 const thisValue = thisEle.val();
1407 let thatEle = null;
1408 if ( isTop ) {
1409 thatEle = $(
1410 '.tablenav.bottom input[name="' + name + '"]'
1411 );
1412 } else {
1413 thatEle = $( '.tablenav.top input[name="' + name + '"]' );
1414 }
1415 thatEle.val( thisValue );
1416 } );
1417 },
1418 };
1419
1420 logListTable.start();
1421 } );
1422 </script>
1423 <?php
1424 }
1425 }
1426