mode = $mode; $this->base_info = $this->get_base_info(); $this->admin_log_table = $wpdb->prefix . $this->admin_log_table; $this->populate_screen_options(); parent::__construct(); } /** * Create the instance of the "Log_List_Table" class. * * @since 2.7.4 * @access public */ public static function get_instance() { return new self(); } /** * Create the admin submenu under the "usces_orderlist" menu * * @since 2.7.4 * @access public */ public static function add_submenu_page() { if ( self::is_enabled() ) { $log_list = self::get_instance(); $admin_log_screen_id = add_submenu_page( 'usces_orderlist', __( 'Operation log', 'usces' ), __( 'Operation log', 'usces' ), 'wel_manage_order', 'usces_loglist', array( $log_list, 'display' ) ); $log_list->screen_id = $admin_log_screen_id; add_action( "load-{$admin_log_screen_id}", array( $log_list, 'add_screen_options' ) ); add_filter( 'screen_settings', array( $log_list, 'display_screen_options' ), 10, 2 ); } } /** * Implementation of the hook "set_screen_option_{option}" * Handle saving the log screen options. * * @see includes/default_filter.php: add_filter('set_screen_option_usces_admin_log_screen_options') * @since 2.7.4 * @access public * @param string $status The status. * @param string $option The option name. * @param string $value The option value. * @return array The screen option. */ public static function set_screen_options( $status, $option, $value ) { $usces_admin_log_options = filter_input_array( INPUT_POST, array( 'usces_admin_log_screen_options' => array( 'view_mode' => array( 'filter' => FILTER_DEFAULT, ), 'items_per_page' => array( 'filter' => FILTER_VALIDATE_INT, ), 'flags' => FILTER_REQUIRE_ARRAY, ), ) ); return $usces_admin_log_options['usces_admin_log_screen_options']; } /** * Add the meta box on the editing member screen. * * @since 2.7.4 * @access public * @param string $member_action The member action. */ public static function add_member_meta_box( $member_action ) { if ( self::is_member_metabox_enabled() ) { $allowed_member_actions = array( 'editpost', 'newpost', 'edit' ); if ( in_array( $member_action, $allowed_member_actions, true ) ) { $log_list = new self( 'member' ); add_meta_box( 'member-logs', __( 'Operation log', 'usces' ), array( $log_list, 'display' ), 'member', 'edit' ); } } } /** * Add the meta box on the editing order screen. * * @since 2.7.4 * @access public * @param string $order_action The order action. * @return void */ public static function add_order_meta_box( $order_action ) { if ( self::is_order_metabox_enabled() ) { $allowed_order_actions = array( 'editpost', 'newpost', 'edit' ); if ( in_array( $order_action, $allowed_order_actions, true ) ) { $log_list = new self( 'order' ); add_meta_box( 'order-logs', __( 'Operation log', 'usces' ), array( $log_list, 'display' ), 'order', 'edit' ); } } } /** * Clear up the admin log by the period set. * * @since 2.7.4 * @see functions\utility.php: usces_cron_do() * @access public * @return void */ public static function clearup() { if ( self::is_enabled() ) { global $usces, $wpdb; $period = '-' . self::get_retention_period(); $period_ago_datetime = get_date_from_gmt( gmdate( 'Y-m-d 00:00:00', strtotime( $period ) ) ); $table = $wpdb->prefix . 'usces_admin_log'; $res = $wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE `datetime` < %s", $period_ago_datetime ) ); } } /** * Override: WP_List_Table::display() * * @since 2.7.4 */ public function display() { $this->enqueue_script(); $this->enqueue_style(); $this->prepare_items(); if ( $this->is_all_mode() ) { $total_items = $this->count_logs(); $per_page = $this->items_per_page; $this->set_pagination_args( array( 'total_items' => $total_items, 'per_page' => $per_page, ) ); } $this->set_anchor(); $wrapper_ele_id = "{$this->mode}-log-table"; ?>
is_all_mode() ) : ?>

Welcart Management

Version

start_form(); ?> end_form(); ?>
__( 'Number of items per page:' ), 'default' => $this->items_per_page, 'option' => 'items_per_page', ) ); add_screen_option( 'view_mode', array( 'label' => __( 'View mode' ), 'default' => $this->view_mode, 'option' => 'view_mode', ) ); } /** * Implementation of the hook "screen_settings" * Render the html markup of the screen options in the log list page. * * @since 2.7.4 * @access public * @param string $screen_settings The screen settings. * @param Object $current_screen The Wp_Screen. * @return string The html markup. */ public function display_screen_options( $screen_settings, $current_screen ) { if ( $this->screen_id === $current_screen->id ) { $options = $current_screen->get_options(); ob_start(); ?>
/> />

__( 'ID', 'usces' ), 'author' => __( 'Author', 'usces' ), 'datetime' => __( 'Datetime', 'usces' ), 'action' => __( 'Action', 'usces' ), 'screen' => __( 'Screen', 'usces' ), 'entity_id' => __( 'Entity', 'usces' ), 'message' => __( 'Message', 'usces' ), ); return $columns; } /** * Override: WP_List_Table::prepare_items() * * @since 2.7.4 */ public function prepare_items() { $columns = $this->get_columns(); $hidden = array(); $sortable = $this->get_sortable_columns(); $this->_column_headers = array( $columns, $hidden, $sortable ); $logs = $this->get_logs(); $this->items = array(); foreach ( $logs as $log ) { $this->items[] = array( 'ID' => $log->ID, 'author' => $log->author, 'message' => $log->message, 'screen' => $log->screen, 'entity_id' => $log->entity_id, 'action' => $log->action, 'data' => $log->data, 'datetime' => $log->datetime, ); } } /** * Override: WP_List_Table::extra_tablenav() * * @since 2.7.4 * @param string $which The top or bottom. */ protected function extra_tablenav( $which ) { if ( $this->is_all_mode() ) { $this->display_search_form(); } } /** * Override: WP_List_Table::column_default() * * @since 2.7.4 * @param array $item The item. * @param string $column_name The column name. * @return string $output The output. */ public function column_default( $item, $column_name ) { switch ( $column_name ) { case 'message': $output = $item[ $column_name ]; $output .= $this->display_data_popup( $item ); break; case 'author': $author_login = $item[ $column_name ]; $author = get_user_by( 'login', $author_login ); $author_url = get_edit_user_link( $author->ID ); $output = "{$author_login}"; break; case 'entity_id': $entity_id = $item['entity_id']; $deleted = 'delete' === $item['action']; if ( $this->is_order_mode() || $this->is_member_mode() || $deleted ) { $output = $entity_id; } else { $edit_entity_url = '#'; if ( $this->is_order_screen( $item['screen'] ) ) { $edit_entity_url = $this->get_edit_order_url( $entity_id ); } if ( $this->is_member_screen( $item['screen'] ) ) { $edit_entity_url = $this->get_edit_member_url( $entity_id ); } $output = "{$entity_id}"; } break; case 'screen': $output = $this->get_display_label( $item[ $column_name ] ); break; case 'action': $output = $this->get_display_label( $item[ $column_name ] ); break; default: $output = $item[ $column_name ]; } return $output; } /** * Override: WP_List_Table::get_sortable_columns(). * * @since 2.7.4 * @return array $sortable_columns The sortable columns. */ public function get_sortable_columns() { $sortable_columns = array( 'ID' => array( 'ID', false ), 'author' => array( 'author', false ), 'screen' => array( 'screen', false ), 'entity_id' => array( 'entity_id', false ), 'action' => array( 'action', false ), 'datetime' => array( 'datetime', false ), ); return $sortable_columns; } /** * Populate screen options to this instance. */ private function populate_screen_options() { $screen_options = get_user_meta( get_current_user_id(), 'usces_admin_log_screen_options', array( 'view_mode' => 'compact', 'items_per_page' => 50, ) ); $this->view_mode = isset( $screen_options['view_mode'] ) ? $screen_options['view_mode'] : 'compact_view'; $this->items_per_page = isset( $screen_options['items_per_page'] ) ? $screen_options['items_per_page'] : 50; } /** * Get the display label. * * @access private * @param string $label_key The label key. * @return string The label. */ private function get_display_label( $label_key ) { if ( isset( $this->base_info['screens']['order'][ $label_key ] ['label'] ) ) { return $this->base_info['screens']['order'][ $label_key ]['label']; } elseif ( isset( $this->base_info['screens']['member'][ $label_key ]['label'] ) ) { return $this->base_info['screens']['member'][ $label_key ]['label']; } elseif ( isset( $this->base_info['actions'][ $label_key ]['label'] ) ) { return $this->base_info['actions'][ $label_key ]['label']; } else { return ''; } } /** * Check if the screent is order screen or not. * * @access private * @param string $screen_id The screen id. * @return boolean true/false */ private function is_order_screen( $screen_id ) { return isset( $this->base_info['screens']['order'][ $screen_id ] ); } /** * Check if the screent is member screen or not. * * @access private * @param string $screen_id The screen id. * @return boolean true/false */ private function is_member_screen( $screen_id ) { return isset( $this->base_info['screens']['member'][ $screen_id ] ); } /** * Get list of logs. * * @since 2.7.4 * @access private * @return array $logs The logs. */ private function get_logs() { global $wpdb; $sql = "SELECT * FROM {$this->admin_log_table}"; $sql .= $this->get_sql_where_clause(); $sql .= $this->get_sql_order_clause(); if ( $this->is_all_mode() ) { $current_page = max( filter_input( INPUT_GET, 'paged' ), 1 ); $from = ( $current_page - 1 ) * $this->items_per_page; } else { $from = 0; $this->items_per_page = 1000; } $sql .= " LIMIT {$from}, {$this->items_per_page}"; $logs = $wpdb->get_results( $sql ); if ( ! empty( $logs ) ) { return $logs; } else { return array(); } } /** * Count the total of logs. * * @since 2.7.4 * @access private * @return integer $total The total. */ private function count_logs() { global $wpdb; $sql = "SELECT COUNT(id) FROM {$this->admin_log_table}"; $sql .= $this->get_sql_where_clause(); $total = $wpdb->get_var( $sql ); return $total; } /** * Render open tag
* * @since 2.7.4 * @access private * @return void */ private function start_form() { if ( $this->is_all_mode() ) { echo ''; } } /** * Render end tag * * @since 2.7.4 * @access private * @return void */ private function end_form() { if ( $this->is_all_mode() ) { echo '
'; } } /** * Generate the SQL order clause. * * @since 2.7.4 * @access private * @return string $sql The SQL order clause. */ private function get_sql_order_clause() { global $wpdb; $sql = ''; $orderby = filter_input( INPUT_GET, 'orderby' ); $order = filter_input( INPUT_GET, 'order' ); if ( empty( $orderby ) ) { $orderby = 'ID'; } else { if ( ! array_key_exists( $orderby, $this->get_columns() ) ) { $orderby = 'ID'; } } if ( empty( $order ) ) { $order = 'DESC'; } else { if ( 'DESC' !== strtoupper( $order ) && 'ASC' !== strtoupper( $order ) ) { $order = 'DESC'; } } $sql = $wpdb->prepare( ' ORDER BY %s %s', esc_sql( $orderby ), esc_sql( $order ) ); $sql = str_replace( "'", '', stripslashes( $sql ) ); return $sql; } /** * Generate the SQL where clause. * * @since 2.7.4 * @access private * @return string $sql The SQL where clause. */ private function get_sql_where_clause() { global $wpdb; $sql = ''; if ( $this->is_all_mode() ) { $screen = filter_input( INPUT_GET, 'usces_screen' ); $authors = filter_input( INPUT_GET, 'usces_author' ); $action = filter_input( INPUT_GET, 'usces_action' ); $datetime = filter_input( INPUT_GET, 'usces_datetime' ); $entity_id = filter_input( INPUT_GET, 'usces_entity_id' ); $where = array(); if ( ! empty( $authors ) ) { $where[] = $wpdb->prepare( 'author = %s', esc_sql( $authors ) ); } if ( ! empty( $action ) ) { $where[] = $wpdb->prepare( 'action = %s', esc_sql( $action ) ); } if ( ! empty( $screen ) ) { $where[] = $wpdb->prepare( 'screen = %s', esc_sql( $screen ) ); } if ( ! empty( $datetime ) ) { $datetime = trim( $datetime ); $where[] = $wpdb->prepare( 'datetime LIKE %s', esc_sql( $datetime ) . '%' ); } if ( ! empty( $entity_id ) ) { $entity_id = trim( $entity_id ); $where[] = $wpdb->prepare( 'entity_id = %s', esc_sql( $entity_id ) ); } } elseif ( $this->is_order_mode() ) { $order_id = $this->get_context_entity_id( 'order_id' ); $where[] = $wpdb->prepare( 'screen IN ( %s )', implode( "','", $this->get_order_screen_ids() ) ); $where[] = $wpdb->prepare( 'entity_id = %s', esc_sql( $order_id ) ); } elseif ( $this->is_member_mode() ) { $member_id = $this->get_context_entity_id( 'member_id' ); $where[] = $wpdb->prepare( 'screen IN ( %s )', implode( "','", $this->get_member_screen_ids() ) ); $where[] = $wpdb->prepare( 'entity_id = %s', esc_sql( $member_id ) ); } if ( ! empty( $where ) ) { $sql .= ' WHERE ' . implode( ' AND ', $where ); $sql = stripslashes( $sql ); } return $sql; } /** * Get entity id on the editing entity screen. * * @since 2.7.4 * @access private * @param string $name The name of variable. * @return integer $order_id The SQL where clause. */ private function get_context_entity_id( $name ) { $entity_id = filter_input( INPUT_GET, $name ); if ( empty( $entity_id ) ) { $entity_id = filter_input( INPUT_POST, $name ); } return (int) $entity_id; } /** * Set anchor. * * @since 2.7.4 * @access private * @return void */ private function set_anchor() { $anchor = "#{$this->mode}-log-table"; $_SERVER['REQUEST_URI'] = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) . $anchor; } /** * Check if the mode is member mode or not * * @since 2.7.4 * @access private * @return boolean true/false */ private function is_member_mode() { return 'member' === $this->mode; } /** * Check if the mode is order mode or not * * @since 2.7.4 * @access private * @return boolean true/false */ private function is_order_mode() { return 'order' === $this->mode; } /** * Check if the mode is all mode or not * * @since 2.7.4 * @access private * @return boolean true/false */ private function is_all_mode() { return 'all' === $this->mode; } /** * Generate the edit order link. * * @since 2.7.4 * @access private * @param integer $order_id The order id. * @return string $url The edit order link. */ private function get_edit_order_url( $order_id ) { $url = esc_url( USCES_ADMIN_URL . "?page=usces_orderlist&order_action=edit&order_id={$order_id}&wc_nonce=" . wp_create_nonce( 'order_edit' ) ); return $url; } /** * Generate the edit order link. * * @since 2.7.4 * @access private * @param integer $member_id The order id. * @return string $url The edit order link. */ private function get_edit_member_url( $member_id ) { $url = esc_url( USCES_ADMIN_URL . "?page=usces_memberlist&member_action=edit&member_id={$member_id}&wc_nonce=" . wp_create_nonce( 'member_list' ) ); return $url; } /** * Display data. * * @since 2.7.4 * @access private * @param array $item The log. * @return string $output The output. */ private function display_data_popup( $item ) { $output = ''; $data = wel_safe_maybe_unserialize( $item['data'] ); $compared_mode = ! empty( $data['differed'] ); $item['mode'] = ( $compared_mode ) ? 'diff' : 'all'; $diff_ele_id = 'log-dialog-' . $item['ID']; $output .= '

' . __( 'More Details' ) . '

'; $output .= ''; $output .= $display_table; $inline_showed = $this->is_expanded_view_mode() && $compared_mode; if ( $inline_showed ) { $output = '

' . __( 'Detailed information', 'usces' ) . '

' . $display_table . '
' . $output; } return $output; } /** * Check if the view mode is expanded or not. * * @return boolean true/false. */ private function is_expanded_view_mode() { return 'expanded_view' === $this->view_mode; } /** * Display the control button. * * @since 2.7.4 * @access private * @param array $item The log. * @return string $output The output. */ private function display_control_buttons( $item ) { $display_log_mode_id = 'display_log_mode_' . $item['ID']; $screen = $item['screen']; $output = '
' . __( 'Display control', 'usces' ) . ''; $output .= ''; $output .= ''; $output .= ''; $output .= ''; $output .= ''; if ( $this->is_order_screen( $screen ) ) { $output .= ''; } elseif ( $this->is_member_screen( $screen ) ) { $output .= ''; } $output .= ''; $output .= '
' . __( 'Mode', 'usces' ) . '
' . __( 'Fields', 'usces' ) . ''; $output .= '
'; $output .= ''; $output .= '
'; $output .= '
'; $output .= '
'; $output .= '
'; $output .= '
'; $output .= '
'; $output .= '
'; $output .= ''; $output .= '
'; $output .= '
'; $output .= '
'; $output .= '

'; return $output; } /** * Render the field data. * * @since 2.7.4 * @access private * @param array $field_data The field data. * @return string $output The output. */ private function display_field_data( $field_data ) { $output = ''; $is_repeater_field = ! empty( $field_data['is_repeater'] ); $is_group_field = ! empty( $field_data['is_group'] ); if ( $is_repeater_field ) { $output .= $this->display_repeater_field( $field_data ); } elseif ( $is_group_field ) { $output .= $this->display_group_field( $field_data ); } else { $output .= $this->display_plain_field( $field_data ); } return $output; } /** * Get classes for the field row. * * @param boolean $is_diff The field is different or not. * @param string $group The field group. * @return array $classes The list of classes. */ private function get_row_classes( $is_diff = false, $group = '' ) { $classes = array(); if ( ! empty( $group ) ) { $classes[] = $group; } if ( $is_diff ) { $classes[] = 'different'; } else { $classes[] = 'same-row'; $classes[] = 'log-hidden'; } return $classes; } /** * Render the repeater field data. * * @since 2.7.4 * @access private * @param array $field_data The field data. * @return string $output The output. */ private function display_repeater_field( $field_data ) { $is_diff = ! empty( $field_data['is_diff'] ); $group = ! empty( $field_data['field']['group'] ) ? $field_data['field']['group'] : ''; $label = $field_data['field']['label']; $compared_mode = ! empty( $field_data['compared_mode'] ); $is_key_and_value = ! empty( $field_data['is_key_and_value'] ); $output = $this->display_header_row( $label, $is_diff, $group ); $rows = ! empty( $field_data['rows'] ) ? $field_data['rows'] : array(); $index = 1; foreach ( $rows as $row ) { $has_row_label = isset( $field_data['field']['row_label'] ); if ( $has_row_label ) { $is_row_diff = false; if ( $is_key_and_value ) { $is_row_diff = ! empty( $row['is_diff'] ); } else { foreach ( $row as $col ) { $is_row_diff = $is_row_diff || ! empty( $col['is_diff'] ); } } $row_label = $field_data['field']['row_label'] . ' ' . $index; $output .= $this->display_header_row( $row_label, $is_row_diff, $group ); } if ( $is_key_and_value ) { $row['compared_mode'] = $compared_mode; $output .= $this->display_field_data( $row ); } else { foreach ( $row as $key => $col ) { if ( ! empty( $col ) ) { $col['compared_mode'] = $compared_mode; } $output .= $this->display_field_data( $col ); } } $index++; } return $output; } /** * Display header row for the field. * * @param string $label The label. * @param boolean $is_diff The field is different or not. * @param string $group The field group. * @return string The html of the header. */ private function display_header_row( $label, $is_diff, $group = '' ) { $output = ''; if ( ! empty( $label ) ) { $classes = $this->get_row_classes( $is_diff, $group ); $row_class = implode( ' ', $classes ); $style = ( $is_diff ) ? '' : ' style="display:none;"'; $output = '

' . esc_html( $label ) . '

'; } return $output; } /** * Render the plain field data. * * @since 2.7.4 * @access private * @param array $field_data The field data. * @return string $output The output. */ private function display_plain_field( $field_data ) { if ( empty( $field_data ) ) { return ''; } else { $compared_mode = ! empty( $field_data['compared_mode'] ); $group = ! empty( $field_data['field']['group'] ) ? $field_data['field']['group'] : ''; $is_diff = ! empty( $field_data['is_diff'] ); $row_classes = $this->get_row_classes( $is_diff, $group ); $classes = implode( ' ', $row_classes ); $label = ( ! empty( $field_data['field']['label'] ) ) ? $field_data['field']['label'] : ''; $output = ''; $output .= '' . esc_html( $label ) . ''; if ( $compared_mode ) { $output .= '' . esc_html( $field_data['before'] ) . ''; $output .= '' . esc_html( $field_data['after'] ) . ''; } else { $field_value = ( ! empty( $field_data['after'] ) ) ? $field_data['after'] : $field_data['before']; $output .= '' . esc_html( $field_value ) . ''; } $output .= ''; return $output; } } /** * Render the group field data. * * @since 2.7.4 * @access private * @param array $field_data The field data. * @return string $output The output. */ private function display_group_field( $field_data ) { $output = ''; if ( ! empty( $field_data['field']['label'] ) ) { $is_diff = ! empty( $field_data['is_diff'] ); $group = ! empty( $field_data['field']['group'] ) ? $field_data['field']['group'] : ''; $label = $field_data['field']['label']; $output .= $this->display_header_row( $label, $is_diff, $group ); } $sub_fields = ! empty( $field_data['fields'] ) ? $field_data['fields'] : array(); foreach ( $sub_fields as $sub_field_data ) { $sub_field_data['compared_mode'] = $field_data['compared_mode']; $output .= $this->display_field_data( $sub_field_data ); } return $output; } /** * The base information. * * @since 2.7.4 * @access private * @return array The base info. */ private function get_base_info() { return array( 'screens' => array( 'order' => array( 'orderlist' => array( 'label' => __( 'Order list screen', 'usces' ), ), 'ordernew' => array( 'label' => __( 'Order new screen', 'usces' ), ), 'orderedit' => array( 'label' => __( 'Order edit screen', 'usces' ), ), ), 'member' => array( 'memberlist' => array( 'label' => __( 'Member list screen', 'usces' ), ), 'membernew' => array( 'label' => __( 'Member new screen', 'usces' ), ), 'memberedit' => array( 'label' => __( 'Member edit screen', 'usces' ), ), ), ), 'actions' => array( 'create' => array( 'label' => __( 'Register', 'usces' ), ), 'update' => array( 'label' => __( 'Update', 'usces' ), ), 'delete' => array( 'label' => __( 'Delete', 'usces' ), ), ), ); } /** * The list of the order screen ids. * * @since 2.7.4 * @access private * @return array The order screen ids */ private function get_order_screen_ids() { return array_keys( $this->base_info['screens']['order'] ); } /** * The list of the member screen ids. * * @since 2.7.4 * @access private * @return array The member screen ids */ private function get_member_screen_ids() { return array_keys( $this->base_info['screens']['member'] ); } /** * Render the search form. * * @since 2.7.4 * @access private * @return void */ private function display_search_form() { $author = filter_input( INPUT_GET, 'usces_author' ); $action = filter_input( INPUT_GET, 'usces_action' ); $screen = filter_input( INPUT_GET, 'usces_screen' ); $datetime = filter_input( INPUT_GET, 'usces_datetime' ); $entity_id = filter_input( INPUT_GET, 'usces_entity_id' ); $management_users = $this->get_wc_management_users(); $order_screens = $this->base_info['screens']['order']; $member_screens = $this->base_info['screens']['member']; $actions = $this->base_info['actions']; $cancel_url = admin_url( 'admin.php?page=usces_loglist' ); ?>
prefix . 'capabilities'; $args = array( 'meta_query' => array( 'relation' => 'OR', array( 'key' => $capabilities_meta_key, 'value' => 'level_5', 'compare' => 'LIKE', ), array( 'key' => $capabilities_meta_key, 'value' => 'administrator', 'compare' => 'LIKE', ), ), ); $user_query = new WP_User_Query( $args ); $users = $user_query->get_results(); if ( ! empty( $users ) ) { foreach ( $users as $user ) { $management_users[] = $user->user_login; } } return $management_users; } /** * Check if the order operator log function is enabled or not. */ public static function is_order_metabox_enabled() { return OPERATION_LOG::is_order_metabox_enabled(); } /** * Check if the member operator log function is enabled or not. */ public static function is_member_metabox_enabled() { return OPERATION_LOG::is_member_metabox_enabled(); } /** * Check if the operator log function is enabled or not. */ public static function is_enabled() { return OPERATION_LOG::is_enabled(); } /** * Get the retention period. * * @return string */ public static function get_retention_period() { return OPERATION_LOG::get_retention_period(); } /** * Render style for the log list table. * * @since 2.7.4 * @access private * @return void */ private function enqueue_style() { ?>