{"id":344470,"date":"2026-08-04T07:54:48","date_gmt":"2026-08-04T07:54:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/who-changed-it-activity-log\/"},"modified":"2026-08-04T07:54:14","modified_gmt":"2026-08-04T07:54:14","slug":"who-changed-it","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/who-changed-it\/","author":21069844,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.5.0","stable_tag":"0.5.0","tested":"7.0.2","requires":"6.0","requires_php":"8.1","requires_plugins":null,"header_name":"Who Changed It? \u2013 Activity Log","header_author":"G. Schad","header_description":"Audits administrator and user activity and classifies every event as normal, strange, or dangerous. Filterable log, email alerts, CSV export.","assets_banners_color":"","last_updated":"2026-08-04 07:54:14","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":28,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.5.0":{"tag":"0.5.0","author":"cmdgw","date":"2026-08-04 07:54:14"}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.5.0"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"The activity log: severity badges with icons, per-severity count chips, free-text search, and field-level change diffs shown inline.","2":"Settings: access restriction, log viewers, alert From address.","3":"Settings: retention, event muting, timestamp display, and the reset\/purge danger zone."}},"plugin_section":[],"plugin_tags":[2505,8533,274408,5603,600],"plugin_category":[54],"plugin_contributors":[263741],"plugin_business_model":[],"class_list":["post-344470","plugin","type-plugin","status-publish","hentry","plugin_tags-activity","plugin_tags-audit","plugin_tags-classification","plugin_tags-monitoring","plugin_tags-security","plugin_category-security-and-spam-protection","plugin_contributors-cmdgw","plugin_committers-cmdgw"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/who-changed-it.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Who Changed It? records what happens on your site \u2014 logins, plugin and theme changes, user and role changes, content edits, settings changes, file editor use \u2014 and, unlike a plain activity log, <strong>classifies every event<\/strong>:<\/p>\n\n<ul>\n<li><strong>Normal<\/strong> \u2014 routine operation.<\/li>\n<li><strong>Strange<\/strong> \u2014 unusual but not necessarily harmful (a failed login, a settings change, a login at 3 AM).<\/li>\n<li><strong>Dangerous<\/strong> \u2014 high-risk activity you should look at now (brute-force login bursts, new administrator accounts, theme\/plugin file editor use, open registration being switched on).<\/li>\n<\/ul>\n\n<p>Classification is a two-stage process: every event type has a base severity, and contextual heuristics can escalate it \u2014 logins at unusual hours, logins from IP addresses never seen for that user, bursts of failed logins from one IP, bursts of deletions by one user. Every escalation is stored with a human-readable reason shown in the log and in alert emails.<\/p>\n\n<h4>Features<\/h4>\n\n<ul>\n<li>Color-coded activity log screen with severity icons and per-severity count chips, free-text search, filterable by severity, event type, user, and date range<\/li>\n<li>Field-level change diffs shown inline: see exactly what changed in a post, profile, or setting<\/li>\n<li>Immediate email alerts for dangerous events, throttled so a brute-force attack sends one email, not hundreds<\/li>\n<li>CSV export of the filtered log<\/li>\n<li>Configurable retention: keep everything, or automatically delete events older than a chosen number of days or months<\/li>\n<li>Mute individual event types to keep the log signal-heavy (events about the plugin itself can never be muted)<\/li>\n<li>WooCommerce support: prices, coupons, orders, refunds, store and payment gateway settings<\/li>\n<li>Extensible: log custom events, adjust severities, watch extra options, or forward events to external systems via hooks<\/li>\n<\/ul>\n\n<h4>What gets audited<\/h4>\n\n<p>Authentication (logins, failed logins, logouts, password resets), users and roles, plugin and theme installs\/updates\/activations\/deletions, WordPress core updates, WordPress 7.0 AI connector and feature changes, theme\/plugin file editor use, posts, pages and media (with field-level diffs of what changed), a watched list of sensitive site options, and data exports. On WooCommerce shops: product price changes, coupon amounts, order status changes, refunds, store settings, and payment gateway configuration.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin to <code>\/wp-content\/plugins\/who-changed-it\/<\/code>, or install it through the Plugins screen.<\/li>\n<li>Activate it through the Plugins screen. The log table is created automatically.<\/li>\n<li>Find the log under the new \"Activity Log\" menu item.<\/li>\n<\/ol>\n\n<p>If your site runs behind a reverse proxy or CDN, map the real client IP header via the <code>whochita_client_ip<\/code> filter \u2014 otherwise all events will appear to come from the proxy's address.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20it%20log%20activity%20from%20before%20it%20was%20installed%3F\"><h3>Does it log activity from before it was installed?<\/h3><\/dt>\n<dd><p>No. It records events as they happen, starting at activation.<\/p><\/dd>\n<dt id=\"how%20long%20are%20events%20kept%3F\"><h3>How long are events kept?<\/h3><\/dt>\n<dd><p>3 months by default. Configure the retention window (or keep all data forever) on the settings screen; developers can additionally use the <code>whochita_retention_days<\/code> filter.<\/p><\/dd>\n<dt id=\"can%20i%20change%20how%20events%20are%20classified%3F\"><h3>Can I change how events are classified?<\/h3><\/dt>\n<dd><p>Yes \u2014 override the base severity of any event type with the <code>whochita_base_severity_map<\/code> filter, and extend the list of audited options with <code>whochita_watched_options<\/code>.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20woocommerce%3F\"><h3>Does it work with WooCommerce?<\/h3><\/dt>\n<dd><p>Yes. When WooCommerce is active, the plugin automatically also records product price changes (a price drop of more than 50% raises the severity), coupon amount changes, order status changes, refunds, store settings, and payment gateway configuration changes. Gateway secrets and API keys are never stored in the log.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20send%20any%20data%20to%20external%20services%3F\"><h3>Does the plugin send any data to external services?<\/h3><\/dt>\n<dd><p>No. Everything is stored in your own WordPress database, and the plugin makes no calls to external services.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.5.0<\/h4>\n\n<ul>\n<li>WordPress 7.0 AI connector connections and disconnections are now audited without storing API keys.<\/li>\n<li>AI master-switch and individual WordPress AI plugin feature changes are now audited.<\/li>\n<li>Admin styles and confirmation behavior now load through the WordPress enqueue APIs.<\/li>\n<li>Plugin file metadata now uses WordPress APIs, and file-editor auditing verifies request nonces and permissions.<\/li>\n<li>Internal identifiers now use a unique plugin prefix, filtered database queries are fully prepared, and generated badge markup is escaped at output.<\/li>\n<li>Empty date filters now use valid database date boundaries, preventing MySQL DATETIME warnings on the activity-log screen.<\/li>\n<li>A renamed pre-release predecessor is detected so two installed copies cannot register duplicate menus or audit hooks.<\/li>\n<li>AI connector deletions are audited without reading API-key options, and file-editor auditing now observes the core admin lifecycle hook.<\/li>\n<\/ul>\n\n<h4>0.4.0<\/h4>\n\n<ul>\n<li>Field-level change tracking: post updates now record what changed (title, slug, excerpt, author, content word counts, password protection, parent), profile updates record email\/display name\/website changes, and the log screen displays these diffs inline.<\/li>\n<li>Free-text search across object names, usernames, event types, IPs, and escalation reasons \u2014 the CSV export honors the search too.<\/li>\n<li>Per-event mute list in the settings: uncheck any event type to stop recording it. Events about the plugin itself can never be muted.<\/li>\n<li>WooCommerce support: product price changes (a &gt;50% price drop escalates the severity), coupon amount changes, order status changes, refunds, store settings, and payment gateway configuration changes (classified dangerous; secret values are never stored).<\/li>\n<\/ul>\n\n<h4>0.3.0<\/h4>\n\n<ul>\n<li>Configurable log retention: keep all data, or delete events older than a chosen number of days\/months, with the next scheduled purge shown and a \"Purge Old Data\" button to run it immediately.<\/li>\n<li>Events timestamp setting: display log times in UTC or in the timezone configured on the WordPress site (storage stays UTC).<\/li>\n<li>Factory reset button for the plugin settings (log data untouched) and a purge button that wipes the activity log; the purge is recorded as the first event of the fresh log and classified as dangerous.<\/li>\n<\/ul>\n\n<h4>0.2.0<\/h4>\n\n<ul>\n<li>Settings screen: restrict who can change plugin settings (only me \/ all administrators), grant log viewing to specific users or roles, and customize the From address and display name of alert emails.<\/li>\n<li>Severity badges now carry icons (check \/ caution sign \/ crossed circle) and the log shows clickable per-severity count chips.<\/li>\n<li>Plugin settings changes are themselves logged as auditable events.<\/li>\n<\/ul>\n\n<h4>0.1.1<\/h4>\n\n<ul>\n<li>Neutralize formula-leading values in CSV exports.<\/li>\n<li>Rate-limit failed-login audit records and add the supporting query index.<\/li>\n<li>Apply database schema updates automatically after plugin updates.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Initial release: activity capture, normal\/strange\/dangerous classification with escalation heuristics, log screen, email alerts, CSV export, retention purge.<\/li>\n<\/ul>","raw_excerpt":"Audits administrator and user activity and classifies every event as normal, strange, or dangerous.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/344470","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=344470"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/cmdgw"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=344470"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=344470"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=344470"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=344470"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=344470"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=344470"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}