The Table Viewer Module provides a full-featured database table browser and editor within the WordPress admin. It allows administrators to inspect, search, edit, insert, and delete rows in any database table — including WordPress core tables and custom tables created by plugins or themes.
Key Capabilities
Browse all database tables with a searchable dropdown selector
View row details in a modal overlay via REST API
Add new rows with type-aware, auto-generated form fields
Edit existing rows with pre-filled values and column-type detection
Delete individual rows or use bulk delete
Full-text search across all columns using SQL LIKE matching
Sort by any column (ascending/descending)
CSV export with progress bar and cancellation support
Table information modal (structure, indexes, foreign keys, health)
Table optimization (reclaim fragmented space)
Truncate and drop non-core tables with confirmation
The form is dynamically generated by iterating over Common_Table::get_columns_info(). Auto-increment columns are automatically skipped. Each column’s MySQL type is inspected via regex to render the appropriate HTML input type.
Uses the same form field generation as Add New. Pre-fills values from Common_Table::load_row_data(). Displays a serialization warning notice before the form.
Enables/disables the Table Viewer module. When disabled, the sub-menu is hidden and no table operations are accessible.
4. Core Classes
4.1 ADVAN\Lists\Table_List
Extends Abstract_List (which extends WP_List_Table). Handles the table data admin list rendering, column management, sorting, searching, pagination, bulk operations, CSV export, and table information modals.
Accepts a table name, initializes Common_Table with it, and calls the parent constructor with plural/singular labels set to the table name.
Key Methods
Method
Description
hooks_init()
Registers admin_post handlers for switch, update, and insert actions
menu_add()
Registers the “Table viewer” submenu page under Error Logs (position 7)
process_actions_load()
Runs on load-{hook} phase to handle bulk delete before output
prepare_items()
Queries the database, populates rows, sets pagination; validates and allowlists orderby/order
fetch_table_data(array $args)
Builds and executes SQL with search, sort, and pagination; counts total rows
get_columns()
Returns columns from Common_Table::manage_columns()
get_sortable_columns()
Makes all columns sortable (derived from column info)
column_default($item, $column_name)
Renders cell — primary key column includes row actions; other columns truncate at 100 chars
column_cb($item)
Renders checkbox for bulk selection
handle_table_actions()
Processes bulk delete with nonce verification and redirect
extra_tablenav($which)
Renders table dropdown, Info button, CSV Export button, and table info modal HTML
Column Rendering
Primary key column: Shows raw value + row actions (View, Edit, Delete)
Other columns: Values wrapped in <code> tags, truncated to 100 characters with […] indicator
4.2 ADVAN\Lists\Views\Table_View
Handles page rendering for all table screens (list, add, edit) and processes form submissions. All methods are static.
Public Static Methods
Method
Description
analytics_table_page()
Main page router — renders list, add form, or edit form based on action parameter. Enforces manage_options capability. Enqueues ThickBox, media-views, and wp-api-fetch.
switch_action()
Handles table switching via the dropdown. Validates nonce (switch_advan_table), verifies table exists, and redirects.
page_load()
Removes _wp_http_referer from URL on page load to keep URLs clean.
update_table()
Processes row update form submission. Enforces manage_options, validates nonce, collects form data, calls Common_Table::insert_row_record() with $where for update, then redirects.
insert_table()
Processes row insert form submission. Enforces manage_options, validates nonce, collects form data (skipping auto-increment), calls Common_Table::insert_row_record() without $where for insert, then redirects.
add_help_content_table()
Returns help text for the Help tab in Screen Options.
add_config_content_table()
Returns config panel with table metadata (engine, version, row format, row count, sizes, etc.) and Truncate/Drop buttons.
Modal View (Inline JavaScript)
The View action triggers a REST API call via wp.apiFetch() to retrieve full row data. The response HTML is injected into the modal overlay. The modal also supports:
Copy to clipboard — copies raw HTML of row data via navigator.clipboard
Share — uses the navigator.share Web Share API (falls back gracefully)
4.3 ADVAN\Entities_Global\Common_Table
Central utility class for all database table operations. Handles table inspection, CRUD, schema analysis, health monitoring, and type-aware data normalization. All methods are static.
Formats values for display: decodes JSON, unserializes PHP, pretty-prints arrays
prepare_full_where(array $where_clause, ...)
array
Builds parameterized WHERE clause from field data
5. Column Type Detection & Form Generation
Both the Add and Edit forms use regex-based column type detection to generate appropriate HTML input elements. The detection is performed inline in Table_View::analytics_table_page().
Type-to-Input Mapping
Regex Pattern
Matches
HTML Input
/int|decimal|float|double|real|bit|bool/i
All numeric types
<input type="number" step="any">
/char|varchar/i
CHAR, VARCHAR
<input type="text" maxlength="255">
/text|tinytext|mediumtext|longtext/i
All text types
<textarea rows="10">
/date$/i
DATE
<input type="date">
/datetime|timestamp/i
DATETIME, TIMESTAMP
<input type="datetime-local">
/time$/i
TIME
<input type="time">
/year/i
YEAR
<input type="number" min="1900" max="2100">
/enum\((.+)\)/i
ENUM
<select> with extracted options
/set\((.+)\)/i
SET
Multiple <input type="checkbox">
/json/i
JSON
<textarea> with JSON placeholder
insert_row_record() Type Normalization
The insert_row_record() method performs comprehensive type normalization when writing data. It inspects each column’s type and converts values accordingly:
Integer types — Cast to int, handle booleans as 0/1, use %d format
Float types — Cast to float, use %f format
Date/time types — Accept DateTime objects, Unix timestamps, or string dates; format to MySQL standard
JSON — Encode arrays/objects to JSON string
ENUM/SET — Validate against allowed values, reject invalid entries
BINARY/BLOB — Store binary data as-is; encode complex structures to base64
VARCHAR(n) — Enforce max length via mb_strcut() (UTF-8 safe)
Text/default — Cast to string; arrays/objects JSON-encoded
Insert vs Update: When $where is provided, insert_row_record() performs an UPDATE using $wpdb->update(). Without $where, it performs a REPLACE using $wpdb->replace().
6. REST API Endpoints
All endpoints are registered under the 0-day/v1 namespace. Every endpoint requires manage_options capability.
400 if core table, 403 if insufficient permissions
Drop Table DELETE
Route
/0-day/v1/drop_table/{table_name}/
Method
DELETE
Handler
Common_Table::drop_table()
Parameters
table_name (string, required)
Response
{ success: true }
Errors
400 if core table, 403 if insufficient permissions
7. Hooks & Actions
Admin Post Actions ACTION
Action
Handler
Description
admin_post_switch_advan_table
Table_View::switch_action
Switch to a different database table
admin_post_advan_table_update
Table_View::update_table
Update an existing row
admin_post_advan_table_insert
Table_View::insert_table
Insert a new row
WordPress Hooks Used ACTION
Hook
Priority
Description
load-{page_slug}
5
Processes bulk actions and table action redirects before output
load-{page_slug}
default
Removes _wp_http_referer from URL, adds common help tabs
8. Settings Reference
Settings are on the Tables Options tab within the main settings page.
PHP
<?php
// Check if the Table Viewer module is enabled$enabled = Settings::get_option( 'tables_module_enabled' );
Settings Builder Usage
PHP
<?php
// How the settings are defined in table-list.php
Settings::build_option(
array(
'title' => esc_html__( 'Tables Options', '0-day-analytics' ),
'id' => 'options-settings-tab',
'type' => 'tab-title',
)
);
Settings::build_option(
array(
'title' => esc_html__( 'Tables list options', '0-day-analytics' ),
'id' => 'table-settings-options',
'type' => 'header',
)
);
Settings::build_option(
array(
'name' => esc_html__( 'Enable tables module', '0-day-analytics' ),
'id' => 'tables_module_enabled',
'type' => 'checkbox',
'hint' => esc_html__( 'If you disable this, the entire plugin tables module will be disabled...', '0-day-analytics' ),
'default' => Settings::get_option( 'tables_module_enabled' ),
)
);
9. List Table Columns & Sorting
Columns
Columns are dynamically generated from the database schema of the selected table via Common_Table::get_column_names_admin(). Each column header displays the column name and its MySQL data type.
Key
Header
Sortable
Description
cb
☐
No
Bulk selection checkbox
Dynamic
column_name + type
Yes
All columns from the table are shown and sortable
Search
The search box filters across all columns using LIKE %term% for each column (OR logic). Query parameter: s
Default Sort
By primary key column in DESC order. The primary key is auto-detected via SHOW KEYS WHERE Key_name = 'PRIMARY', falling back to any index, then the first column.
Pagination
Default items per page: 20. Configurable via Screen Options. Uses LIMIT/OFFSET SQL pagination.
10. Bulk & Row Actions
Row Actions
Action
Method
Description
View
REST API (AJAX modal)
Opens modal showing full row data via wp.apiFetch()
Edit
Page redirect
Opens the Edit Row form with pre-filled values
Delete
Page redirect
Deletes the row after JavaScript confirm() dialog
Bulk Actions
Action
Description
Delete
Permanently delete all selected rows
Destructive Table Actions (Config Help Tab)
Action
Method
Core Tables
Description
Truncate Table
REST API (DELETE)
Blocked
Removes all rows, keeps structure. JavaScript confirm required.
Drop Table
REST API (DELETE)
Hidden
Permanently removes table and data. JavaScript confirm required.
Optimize Table
Info modal button
Allowed
Reclaims fragmented space via OPTIMIZE TABLE
11. Security Model
Capability Checks
manage_options enforced on: page rendering, row edit/delete/insert, table dropdown switch, bulk operations, REST API endpoints
Menu visibility optionally restricted by menu_admins_only setting
Nonce Verification
Context
Nonce Action
Table switch
switch_advan_table
Add row (URL)
add-row
Edit row (URL)
edit-row
Add/Edit form
advana_table_manager
Bulk delete
bulk-{table_name} (WP_List_Table auto-generated)
Input Validation
Table names — validated with /^[A-Za-z0-9_]+$/ regex to prevent cross-database references and SQL injection via dots/backticks
Order/orderby — allowlisted against actual column names; order restricted to ASC/DESC
Search terms — escaped via $wpdb->esc_like() and parameterized with %s
WHERE operators — restricted to allowlisted set: =, !=, >, <, LIKE, etc.
Form data — all values processed through wp_unslash() and type-normalized by insert_row_record()
Core Table Protections
WordPress core tables (via $wpdb->tables('all')) cannot be truncated or dropped
The “Drop Table” button is hidden for core tables in the Config help tab
REST API endpoints return WP_Error with 400 status for core table truncate/drop attempts
12. Code Examples
Example 1: Check If a Table Exists
PHP
<?php
use ADVAN\Entities_Global\Common_Table;
$table_name = 'wp_custom_logs';
if ( Common_Table::check_table_exists( $table_name ) ) {
echo'Table exists!';
} else {
echo'Table does not exist.';
}
<?php
use ADVAN\Entities_Global\Common_Table;
Common_Table::init( 'wp_custom_data' );
// Creates a copy named wp_custom_data{YmdHis}
Common_Table::backup_table();
// Now safe to perform destructive operations
Common_Table::truncate_table( null, 'wp_custom_data' );
Need User Guide documentation?
See Table Module User Guide for more details about configuration, practical usage and information.