Learn to build a robust audit system by hooking into the WordPress REST API, logging changes to a custom table, and displaying the history in your React UI.
Previously in this course, we explored handling conflict resolution to ensure data integrity. In this lesson, we take that a step further by implementing a persistent audit trail. Tracking every change made via the REST API is essential for compliance, debugging, and user accountability.
When building professional-grade plugins, you shouldn't rely on the standard wp_posts revisions system for everything. For a dedicated Knowledge Base, we want a lightweight, queryable audit log stored in a custom database table.
This approach involves three distinct layers:
rest_after_insert_{$post_type} action to capture data changes.wp_kb_activity_logs) to store immutable events.First, we need a place to store the data. Using a dedicated table keeps our audit logs separate from the heavy lifting of post metadata.
PHPfunction kb_create_activity_log_table() { global $wpdb; $table_name = $wpdb->prefix . 'kb_activity_logs'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, post_id mediumint(9) NOT NULL, user_id mediumint(9) NOT NULL, action varchar(20) NOT NULL, timestamp datetime DEFAULT CURRENT_TIMESTAMP NOT NULL, PRIMARY KEY(id) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); }
WordPress provides the rest_after_insert_{$post_type} hook, which triggers after a post has been saved via the REST API. This is the perfect moment to log the action.
PHPadd_action('rest_after_insert_knowledge_base', 'kb_log_post_update', 10, 3); function kb_log_post_update($post, $request, $creating) { global $wpdb; $table_name = $wpdb->prefix . 'kb_activity_logs'; $wpdb->insert($table_name, [ 'post_id' => $post->ID, 'user_id' => get_current_user_id(), 'action' => $creating ? 'created' : 'updated', 'timestamp' => current_time('mysql') ]); }
Note: We rely on the $creating boolean provided by the hook to distinguish between new entries and updates.
To display these logs, register a new read-only endpoint. As we discussed in implementing REST API permission callbacks, ensure you restrict this to users who have the capability to edit knowledge base items.
PHPregister_rest_route('kb/v1', '/logs/(?P<id>\d+)', [ 'methods' => 'GET', 'callback' => 'kb_get_post_logs', 'permission_callback' => fn() => current_user_can('edit_posts'), ]); function kb_get_post_logs($request) { global $wpdb; $post_id = $request['id']; $table = $wpdb->prefix . 'kb_activity_logs'; return $wpdb->get_results($wpdb->prepare( "SELECT * FROM $table WHERE post_id = %d ORDER BY timestamp DESC", $post_id )); }
kb_create_activity_log_table function to your plugin activation hook.kb_log_post_update hook in your main plugin file.service.js file (following the patterns in building the Knowledge Base service layer) that calls the /logs/{id} endpoint.LogView component that renders a list of these entries in your React dashboard.rest_after_insert hook. The database insertion should be a simple, indexed write.details column in your table.GET endpoint for logs is protected. Audit logs can inadvertently leak sensitive information if accessible to unauthorized users.As mentioned in our API architecture audit logs discussion, logs should be treated as immutable records of truth. Once written, they should rarely be modified.
We've successfully hooked into the WordPress REST API lifecycle, created a custom table for persistent data, and exposed that data via a secure endpoint. This audit trail is now a core part of our plugin's reliability.
Up next: We will learn how to use Webpack Aliases to clean up our import paths and simplify our project structure.
Learn to implement real-time updates in your WordPress plugin using efficient polling strategies to keep your React admin dashboard data perfectly synced.
Read moreLearn to build a safe, user-centric Modal confirmation system in your WordPress React admin UI to prevent accidental data loss during API operations.
Implementing Activity Logging