'item', // singular name of the listed records 'plural' => 'items', // plural name of the listed records 'ajax' => false // does this table support ajax? )); } /** * Returns the default column item * * @param object $item - item from which column data is returned * @param string $column_name - column name to be fetched from item * @return string */ public function column_default($item, $column_name) { return $item[$column_name]; } /** * Returns cb column html to be rendered. * * @param array $item - data for the columns on the current row * * @return string - the html to be rendered */ public function column_cb($item) { return sprintf( '', /* $1%s */ $this->_args['singular'], // Let's simply repurpose the table's singular label /* $2%s */ $item['id'] // The value of the checkbox should be the record's id ); } /** * Returns created column html to be rendered. * * @param array $item Data for the columns on the current row. * * @return string The html to be rendered. */ public function column_created($item) { $actions = array( 'delete' => '' . esc_html__('Delete', 'all-in-one-wp-security-and-firewall') . '' ); return AIOWPSecurity_Utility::convert_timestamp($item['created']) . '' . $this->row_actions($actions); } /** * Returns ip column html to be rendered. * * @global AIO_WP_Security $aio_wp_security * * @param array $item Data for the columns on the current row. * * @return string The html to be rendered. */ public function column_ip($item) { global $aio_wp_security; $ip = $item['ip']; $unblacklist_ip_warning_translation = __('Are you sure you want to unblacklist this IP address?', 'all-in-one-wp-security-and-firewall'); $unlock_ip_warning_translation = __('Are you sure you want to unlock this IP address?', 'all-in-one-wp-security-and-firewall'); $lock_ip_warning_translation = __('Are you sure you want to temporarily lock this IP address?', 'all-in-one-wp-security-and-firewall'); $blacklist_ip_warning_translation = __('Are you sure you want to blacklist this IP address?', 'all-in-one-wp-security-and-firewall'); // Build row actions. if (false !== strpos($aio_wp_security->configs->get_value('aiowps_banned_ip_addresses'), $ip)) { $actions = array( 'unblacklist' => '' . esc_html__('Unblacklist', 'all-in-one-wp-security-and-firewall') . '', ); } elseif (AIOWPSecurity_Utility::check_locked_ip($ip, 'audit-log')) { $actions = array( 'unlock' => '' . esc_html__('Unlock', 'all-in-one-wp-security-and-firewall') . '', ); } else { $actions = array( 'lock_ip' => '' . esc_html__('Lock IP', 'all-in-one-wp-security-and-firewall') . '', 'blacklist_ip' => '' . esc_html__('Blacklist IP', 'all-in-one-wp-security-and-firewall') . '', ); } return $ip . '' . $this->row_actions($actions); } /** * Returns event type column html to be rendered. * * @param array $item - data for the columns on the current row * * @return string - the html to be rendered */ public function column_event_type($item) { if (empty($item['event_type'])) return __('No event type available.', 'all-in-one-wp-security-and-firewall'); $output = isset(AIOWPSecurity_Audit_Events::$event_types[$item['event_type']]) ? AIOWPSecurity_Audit_Events::$event_types[$item['event_type']] : $item['event_type']; return $output; } /** * Returns details column html to be rendered. * * @param array $item - data for the columns on the current row * * @return string - the html to be rendered */ public function column_details($item) { $details = json_decode($item['details'], true); if (!is_array($details)) return $item['details']; $key = array_keys($details)[0]; if (method_exists("AIOWPSecurity_Audit_Text_Handler", "{$key}_to_text")) { return call_user_func("AIOWPSecurity_Audit_Text_Handler::{$key}_to_text", $details[$key]); } return $item['details']; } /** * Returns stack trace column html to be rendered. * * @param array $item - data for the columns on the current row * * @return string - the html to be rendered */ public function column_stacktrace($item) { if (empty($item['stacktrace'])) return __('No stack trace available.', 'all-in-one-wp-security-and-firewall'); $stacktrace = maybe_unserialize($item['stacktrace']); ob_start(); var_dump($stacktrace); $stacktrace_output = ob_get_contents(); ob_end_clean(); $output = sprintf('%s', $item['id'], esc_html__('Stack trace', 'all-in-one-wp-security-and-firewall'), esc_html__('Show trace', 'all-in-one-wp-security-and-firewall')); $output .= sprintf('
', $item['id'], htmlspecialchars($stacktrace_output)); return $output; } /** * Sets the columns for the table * * @return array */ public function get_columns() { $columns = array( 'cb' => '', //Render a checkbox 'id' => 'ID', 'created' => __('Date and time', 'all-in-one-wp-security-and-firewall'), 'level' => __('Level', 'all-in-one-wp-security-and-firewall'), 'network_id' => __('Network ID', 'all-in-one-wp-security-and-firewall'), 'site_id' => __('Site ID', 'all-in-one-wp-security-and-firewall'), 'username' => __('Username', 'all-in-one-wp-security-and-firewall'), 'ip' => __('IP', 'all-in-one-wp-security-and-firewall'), 'event_type' => __('Event', 'all-in-one-wp-security-and-firewall'), 'details' => __('Details', 'all-in-one-wp-security-and-firewall'), 'stacktrace' => __('Stack trace', 'all-in-one-wp-security-and-firewall') ); return $columns; } /** * Sets which of the columns the table data can be sorted by * * @return array */ public function get_sortable_columns() { $sortable_columns = array( 'created' => array('created', false), 'network_id' => array('network_id', false), 'site_id' => array('site_id', false), 'level' => array('level', false), 'username' => array('username', false), 'ip' => array('ip', false), 'event_type' => array('event_type', false), 'details' => array('details', false), 'stacktrace' => array('stacktrace', false) ); return $sortable_columns; } /** * This function will display a list of bulk actions for the list table * * @return array */ public function get_bulk_actions() { $actions = array( 'delete_all' => __('Delete all', 'all-in-one-wp-security-and-firewall'), 'delete_selected' => __('Delete selected', 'all-in-one-wp-security-and-firewall'), 'delete_filtered' => __('Delete filtered', 'all-in-one-wp-security-and-firewall') ); return $actions; } /** * This function will process the bulk action request, $search_term and $filters are only used if the user is trying to bulk delete the filtered items * * @param string $search_term - the search string * @param array $filters - the filters * * @return void */ private function process_bulk_action($search_term, $filters) { if (empty($_REQUEST['_wpnonce']) || !isset($_REQUEST['_wp_http_referer'])) return; $result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($_REQUEST['_wpnonce'], 'bulk-items'); if (is_wp_error($result)) return; global $wpdb; $audit_log_tbl = AIOWPSEC_TBL_AUDIT_LOG; if ('delete_all' === $this->current_action()) { // Process delete bulk actions $this->delete_audit_event_records(array(), true); } elseif ('delete_selected' === $this->current_action()) { if (!isset($_REQUEST['item'])) { AIOWPSecurity_Admin_Menu::show_msg_error_st(__('Please select some records using the checkboxes', 'all-in-one-wp-security-and-firewall')); } else { $this->delete_audit_event_records($_REQUEST['item']); } } elseif ('delete_filtered' === $this->current_action()) { $where_sql = $this->get_audit_list_where_sql($search_term, $filters); $results = $wpdb->get_results("SELECT id FROM {$audit_log_tbl} {$where_sql}", 'ARRAY_A'); $items = array_column($results, 'id'); $this->delete_audit_event_records($items); } } /** * Outputs extra controls to be displayed between bulk actions and pagination * * @param string $which - where we are outputting content (top or bottom) * * @return void */ protected function extra_tablenav($which) { switch ($which) { case 'top': ?>