WP Manifestindependent plugin directory
manifest / admin / beqlic-activity-log

Beqlic Activity Log for WP

This is a Wordpress Activity Control plugin

by Beqlic · github.com/becliq-devs/beqlic-activity-log

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/becliq-devs/beqlic-activity-log/archive/refs/heads/main.zip

Readme

Beqlic Activity Log for WP

A self-contained WordPress activity log / audit trail plugin. It records who created, edited or deleted content across your whole site, when (to the second), and exactly what changed — and lets you revert any single action back to its previous state. It can also email you a recurring activity report.

Built as a lightweight, dependency-free alternative to commercial audit-log plugins. Everything lives in one folder; no external services are called.


Features

  • 📋 Full activity log stored in its own database table, shown in a searchable, sortable, paginated admin screen.
  • 👤 Who did it — user name, user ID, role, and IP address for every action.
  • 🕒 Exact timestamp — full date/time plus a human "x ago" hint.
  • 🔍 What changed — field-level diffs (old value → new value) for edits.
  • 🚦 Severity levels — every event is tagged Info / Notice / Warning / Critical and carries a stable numeric event ID, so you can filter and prioritise.
  • ↩️ Per-action Revert — each entry has its own button to restore the previous state. Reverts are themselves logged for a complete audit trail.
  • 🔔 Instant alerts — email someone the moment an event at or above a chosen severity is recorded (independent of the digest).
  • 📊 Dashboard overview — an "at a glance" widget on the WordPress dashboard: totals (24h / 7d / 30d), counts by severity, most active users, and recent warnings/critical events.
  • ✉️ Email reports — send a summary of all activity to any address on a Daily / Weekly / Monthly schedule (or disable). Includes a "send test report now" button.
  • 🗓️ On-demand reports — generate a report for any custom date range, as a formatted, client-ready PDF and/or a CSV. Email it or download it (both formats download as a ZIP).
  • ⬇️ CSV export — download the log (respecting the current filters) for spreadsheets or external retention.
  • 🧹 Retention control — automatically purge entries older than N days.
  • ⚙️ Granular toggles — turn each event category on or off from the settings page.
  • 🔒 Safe by default — capability checks (manage_options), nonces on every revert/export, prepared SQL statements, and output escaping throughout.

Tracked events

Area Events
Posts / Pages / CPTs created · updated · trashed · restored · permanently deleted
Users registered · profile updated · role changed · deleted
Taxonomy terms created · updated · deleted
Media library uploaded · edited · deleted
Comments posted · approved · unapproved · spam · trashed · deleted · edited
Navigation menus created · updated · deleted
Widgets added · settings updated · removed
WooCommerce order created · order status changed · stock quantity changed · stock status changed (only when WooCommerce is active)
Site settings any watched option changed (title, tagline, URLs, admin email, membership, reading, discussion, permalinks…)
Any option (advanced, opt-in) changes to any WordPress option — captures most plugins' settings generically, with transients/locks/internal noise filtered out
Themes switched · installed · updated · deleted
Plugins activated · deactivated · installed · updated · deleted
WordPress core updated
Backups completed · failed (Duplicator / Duplicator Pro)
Authentication login · logout · failed login · login from new IP · password reset requested · password reset

What can be reverted

Action Revert behaviour
Post updated Restores title, content, excerpt, status and slug
Post trashed Restores it from trash
Post deleted Recreates the post with its meta and taxonomy terms (new ID)
User profile updated Restores email, display name, website and roles
Term deleted Recreates the term
Setting changed Restores the previous value of the option
Plugin activated / deactivated Toggles the plugin back to its previous state

Actions like created, login, etc. are intentionally not revertible and show N/A.


Requirements

  • WordPress 5.6+ (uses the wp_after_insert_post hook)
  • PHP 7.2+ (PHP 8.0+ required for the bundled PDF engine; CSV works on any supported version)
  • The PDF report uses the bundled Dompdf library in vendor/ — keep that folder when deploying. If it's missing, the plugin transparently falls back to CSV.

Installation

  1. Copy the beqlic-activity-log folder into wp-content/plugins/. (or download a release zip and upload it via Plugins → Add New → Upload Plugin)
  2. Activate Beqlic Activity Log for WP from the Plugins screen. Activation creates the log table.
  3. Open Activity Log in the admin menu to view events.
  4. Open Activity Log → Settings to configure email reports, retention, and which events to track.

Usage

Viewing activity

wp-admin → Activity Log. Search by keyword, or filter by action, object type and date range. Columns: Date & time, User, Role, Action, Object, What changed, Revert.

Reverting an action

Find a row with a Revert button, click it, confirm the prompt. The item is restored, the row is marked Reverted (so it can't be reverted twice), and a new audit entry records the rollback.

Email reports

In Settings, set a recipient email and pick a frequency. Reports are sent via WP-Cron and contain a summary plus a table of actions for the period. Use Send test report now to confirm delivery.

Advanced option logging ("log any option change")

Settings → What to log → Advanced option logging. Off by default; tick the box to enable.

What it does. Almost every plugin (and WordPress itself) stores its settings as rows in the WordPress options table — Yoast's SEO config, Contact Form 7, WooCommerce settings, your theme options, and so on. Normally Beqlic only records changes to a curated list of important core options (site title, tagline, site URLs, admin email, membership, reading/discussion settings, permalinks…). When you turn on advanced option logging, Beqlic instead watches every option and records a log entry whenever any option's value actually changes.

In practice this gives you generic, cross-plugin settings auditing without writing any plugin-specific code: if a setting changes in roughly any plugin, you'll see who changed it and when — with a before → after comparison.

What each entry looks like.

  • Severity: Info (the curated core settings stay at the higher Notice level, so the important ones still stand out).
  • What changed: a previous value → new value diff (long/array values are shortened for display).
  • Revertible: yes — each entry gets a Revert button that restores the option to its previous value.
  • Event ID: 6002 (any_option_updated), versus 6000 for curated settings.

Noise is filtered automatically. Logging every option would be overwhelming, so Beqlic skips the high-churn / internal ones, including:

  • Transients and site transients (_transient_*, _site_transient_*, anything containing transient).
  • Locks and session data (*_lock, session_tokens, _wp_session_*).
  • WordPress internals that change constantly or are covered elsewhere — e.g. cron, rewrite_rules, recently_edited, recently_activated, and active_plugins (plugin activation/deactivation is already logged as its own event).
  • Beqlic's own options.

When to use it. Leave it off for a clean, high-signal log of the events that matter most. Turn it on when you want deep forensic coverage — for example, to catch a setting being changed by a plugin you don't have a dedicated integration for, or while investigating an incident. It is more verbose, so expect more entries.

Tuning. A few plugins write counter- or timestamp-style options on every page load. If one of those floods your log, you can exclude it with the bal_should_log_option filter (see Developer notes) — return false for the option names you want ignored.


Project structure

beqlic-activity-log/
├── beqlic-activity-log.php      # Main file: constants, bootstrap, activation/deactivation
├── uninstall.php                # Drops the table + options on plugin delete
├── readme.txt                   # WordPress.org-style readme
├── README.md
├── assets/
│   └── admin.css                # Badges, diff styling, layout
├── vendor/                      # Bundled libraries (Dompdf, for PDF reports)
└── includes/
    ├── class-bal-db.php         # Custom table: create / insert / query / export / purge
    ├── class-bal-logger.php     # Hooks into WP events, event registry, records them
    ├── class-bal-revert.php     # Per-action revert handlers
    ├── class-bal-reports.php    # Scheduled + on-demand reports, CSV/PDF, retention
    ├── class-bal-pdf.php        # Formatted PDF report (Dompdf)
    ├── class-bal-alerts.php     # Instant email alerts on high-severity events
    ├── class-bal-dashboard.php  # "At a glance" admin dashboard widget
    ├── class-bal-settings.php   # Settings page (Settings API) + on-demand report tool
    └── class-bal-admin.php      # Admin menu + log viewer (WP_List_Table) + CSV export

How it works

  • A custom table {prefix}_bal_activity_log stores every entry, including its severity, a stable event ID, and an optional JSON snapshot of the previous state used for reverts.
  • Events are captured through native WordPress hooks (wp_after_insert_post, before_delete_post, profile_update, created_term, updated_option, add_attachment, wp_insert_comment, wp_create_nav_menu, switch_theme, upgrader_process_complete, activated_plugin, wp_login, …).
  • Each logical event is defined once in a central registry (BAL_Logger::events()) that maps it to a numeric ID and a default severity, so labels, filtering and alerting stay consistent.
  • The admin list table reads, filters (severity / action / type / date / search) and paginates entries; the revert controller restores state and writes a follow-up audit entry.
  • After every write the logger fires bal_after_log, which the alerts module uses to send an immediate email when the entry meets the configured severity threshold.
  • Reports run on a WP-Cron schedule (daily / custom weekly / monthly), which also performs the retention purge.
  • A version-stamped upgrade routine (bal_maybe_upgrade()) keeps the table schema current on existing installs without a manual reactivation.

Developer notes

  • Skip an entry before it's stored:
    add_filter( 'bal_pre_log_entry', function ( $row ) {
        if ( 'setting' === $row['object_type'] ) {
            return false; // don't log settings changes
        }
        return $row;
    } );
  • React to any logged event (e.g. forward to Slack):
    add_action( 'bal_after_log', function ( $id, $row ) {
        if ( 'critical' === $row['severity'] ) {
            // notify an external service…
        }
    }, 10, 2 );
  • Tune which options "log any option" mode records:
    add_filter( 'bal_should_log_option', function ( $log, $option ) {
        if ( 0 === strpos( $option, 'myplugin_cache_' ) ) {
            return false; // ignore this plugin's churny options
        }
        return $log;
    }, 10, 2 );
  • The event registry (BAL_Logger::events()) returns event_key => array( event_id, severity ). Severities are ordered with BAL_Logger::severity_weight() (info < notice < warning < critical).
  • All settings live under a single option key, bal_settings.
  • Uninstalling the plugin drops the table, deletes the options and clears the cron event.

Security

  • Every admin action checks current_user_can( 'manage_options' ).
  • Revert and test-report requests are protected by nonces.
  • All database access uses $wpdb->prepare(); all output is escaped.

Changelog

1.5.0

  • On-demand reports can now be produced as a formatted, client-ready PDF (bundled Dompdf), a CSV, or both.
  • Each format works for both the Email report and Download buttons; downloading both formats yields a ZIP.
  • PDF includes a branded header, a summary (totals + severity breakdown) and a styled, colour-coded events table; full Unicode/Greek support.

1.4.0

  • Added an opt-in "log any option change" advanced mode: logs changes to any WordPress option (Info severity, revertible), giving generic, cross-plugin settings coverage. Transients, locks, session tokens and other high-churn internals are filtered out, and the list is tunable via the bal_should_log_option filter.

1.3.1

  • On-demand report dates now use dd/mm/yyyy.
  • On-demand report now has two buttons: Email report (HTML + CSV) and Download CSV to my computer (no email).

1.3.0

  • Added an "at a glance" dashboard widget (totals, severity breakdown, top users, recent warnings/critical).
  • Added on-demand reports for a custom date range, emailed with a CSV attachment.
  • Added backup logging for Duplicator / Duplicator Pro (completed & failed builds).

1.2.0

  • Added widget tracking (add / settings update / remove) for classic and block widget areas.
  • Added WooCommerce tracking (order created, order status changed, stock quantity & status changes); only active when WooCommerce is installed. Products and coupons remain covered by the post logger.

Read the full README on GitHub →