Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 40 of the Intermediate WordPress Plugins: REST API & React Admin course
WordPressJune 26, 20263 min read

Implementing Activity Logging: Auditing REST API Changes in WordPress

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.

WordPressREST APIReactAuditDatabasephpplugin-development

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.

The Architecture of an Audit Log

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:

  1. The Hook: Intercepting the rest_after_insert_{$post_type} action to capture data changes.
  2. The Storage: A custom SQL table (wp_kb_activity_logs) to store immutable events.
  3. The UI: A new endpoint and React component to fetch and display this history.

Step 1: Creating the Custom Audit Table

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.

PHP
function 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);
}

Step 2: Hooking into REST API Updates

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.

PHP
add_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.

Step 3: Exposing Logs to the React Dashboard

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.

PHP
register_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
    ));
}

Hands-on Exercise

  1. Migrate: Add the kb_create_activity_log_table function to your plugin activation hook.
  2. Log: Implement the kb_log_post_update hook in your main plugin file.
  3. Fetch: Create a new service function in your service.js file (following the patterns in building the Knowledge Base service layer) that calls the /logs/{id} endpoint.
  4. Display: Create a LogView component that renders a list of these entries in your React dashboard.

Common Pitfalls

  • Performance Impact: Never run heavy queries inside the rest_after_insert hook. The database insertion should be a simple, indexed write.
  • Missing Context: Logging that an update happened is good, but logging what changed is better. For production, consider serializing a diff of the post content into a details column in your table.
  • Security: Always ensure your 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.

Recap

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.

Previous lessonBuilding a Modal Confirmation SystemNext lesson Using Webpack Aliases
Back to Blog

Similar Posts

WordPressJune 26, 20263 min read

Implementing Real-time Updates with Web: WordPress Strategies

Learn to implement real-time updates in your WordPress plugin using efficient polling strategies to keep your React admin dashboard data perfectly synced.

Read more
WordPressJune 26, 20263 min read

Building a Modal Confirmation System for WordPress Plugins

Learn to build a safe, user-centric Modal confirmation system in your WordPress React admin UI to prevent accidental data loss during API operations.

Part of the course

Intermediate WordPress Plugins: REST API & React Admin

intermediate · Lesson 40 of 45

  1. 1

    Setting up the WordPress Development Environment

    3 min
  2. 2

    Introduction to @wordpress/scripts

    3 min
  3. 3

    Configuring ESLint and Prettier

    3 min
Read more
WordPressJune 26, 20264 min read

Handling Conflict Resolution: Optimistic Locking in WordPress

Prevent data overwrites and ensure data integrity in your WordPress plugins by implementing optimistic locking, handling concurrency, and improving UX.

Read more
4

Localizing Data for JavaScript

3 min
  • 5

    Anatomy of a REST API Endpoint

    3 min
  • 6

    Implementing REST API Permission Callbacks

    3 min
  • 7

    Handling GET Requests in REST API

    3 min
  • 8

    Validating and Sanitizing API Arguments

    4 min
  • 9

    Creating POST Endpoints for Data Submission

    3 min
  • 10

    Updating Existing API Resources

    3 min
  • 11

    Handling Asynchronous State in React

    3 min
  • 12

    Building the Knowledge Base Service Layer

    3 min
  • 13

    Scaffolding the React Admin Dashboard

    3 min
  • 14

    Working with @wordpress/components

    3 min
  • 15

    Creating a React Form for Submissions

    3 min
  • 16

    Implementing CRUD in the Admin UI

    3 min
  • 17

    Understanding WordPress Data Store Architecture

    4 min
  • 18

    Registering a Custom Data Store

    3 min
  • 19

    Writing Selectors for Data Access

    3 min
  • 20

    Defining Actions and Reducers

    3 min
  • 21

    Implementing Resolvers for Data Fetching

    3 min
  • 22

    Optimizing Performance with Selectors

    3 min
  • 23

    Handling Complex State Dependencies

    4 min
  • 24

    Implementing Nonce Verification

    4 min
  • 25

    Advanced Sanitization Techniques

    3 min
  • 26

    Input Validation and Error Handling

    3 min
  • 27

    Protecting Admin Screens

    3 min
  • 28

    Production Build Pipeline

    3 min
  • 29

    Debugging React in the WordPress Admin

    4 min
  • 30

    Building Search and Filter Functionality

    3 min
  • 31

    Internationalization in React

    3 min
  • 32

    Managing File Uploads via REST API

    3 min
  • 33

    Optimizing API Response Times

    3 min
  • 34

    Working with Date and Time in React

    3 min
  • 35

    Implementing Drag-and-Drop Sorting

    3 min
  • 36

    Creating Custom Hooks for API Logic

    3 min
  • 37

    Integrating with Gutenberg Blocks

    4 min
  • 38

    Handling Conflict Resolution

    4 min
  • 39

    Building a Modal Confirmation System

    3 min
  • 40

    Implementing Activity Logging

    3 min
  • 41

    Using Webpack Aliases

    3 min
  • 42

    Unit Testing API Endpoints

    3 min
  • 43

    Unit Testing React Components

    3 min
  • 44

    Handling Large Datasets with GraphQL

    3 min
  • 45

    Implementing Real-time Updates with Web

    3 min
  • View full course