Opis
„Which plugin just broke my site?” — answered automatically.
Existing tools show you that an error occurred. Conflict Detective tells you which plugin caused it by correlating the plugin change timeline with the error log — and gives you a confidence score.
Features
Dashboard
Live overview of your WordPress/PHP version, active plugins, active theme, memory limit, debug mode, recent changes, and latest errors — all on one screen.
Error Log Viewer
Reads debug.log and the server PHP error log automatically. Each entry is attributed to the plugin that owns the file where the error occurred. Filter by Fatal / Warning / Notice / Deprecated.
Change History
Full audit trail of every plugin activation, deactivation, update, and deletion — with exact timestamps and version diffs (e.g. 8.3.0 → 8.4.0).
Health Scan
On-demand scan that detects:
- Duplicate plugin functionality (multiple SEO, caching, security, or backup plugins)
- Known incompatibilities between specific plugin pairs
- Outdated plugins (not updated in more than 2 years)
- Missing theme files or a missing parent theme
- PHP version, memory limit, and
max_execution_timemisconfigurations - Pending WordPress core updates
Conflict Scanner
Automatically correlates plugin update timestamps with error spikes and reports a suspect plugin with a confidence percentage. Detected conflicts are stored in the database and can be marked as resolved with one click.
Safe Testing Mode
Disable any plugin for your own admin session while visitors remain completely unaffected. Cookie-isolated — the live site is never touched.
Conflict Wizard
Step-by-step guided diagnosis. Choose your symptom (white screen, login problem, WooCommerce issue, slow site, broken admin, front-end error, or other) and the wizard automatically analyses recent changes and errors to produce a tailored action plan.
Performance Monitor (new in 2.6.0)
Tracks the estimated load time, memory delta, and database query count for every active plugin during the current page load. Results are color-coded as Fast / Slow / Heavy and refreshed on demand.
Cron Monitor (new in 2.6.0)
Lists all scheduled WordPress Cron events with their next run time and interval. Overdue events are highlighted in red. Each event can be triggered manually via a „Run Now” button — validated against the live WP-Cron schedule before execution.
AJAX / REST Monitor (new in 2.6.0)
Automatically logs slow AJAX and REST API calls (those taking more than 500 ms) to a dedicated database table. Filter by All / AJAX / REST / Slow to quickly identify bottleneck endpoints.
Plugin Interaction Map (new in 2.6.0)
Visualises your plugins grouped into known ecosystem clusters (WooCommerce, Elementor, Yoast SEO, Jetpack, ACF, Gravity Forms, and more). Highlights declared plugin dependencies and shows active/inactive state at a glance. Plugins that don’t belong to a known ecosystem are listed separately as Standalone Plugins.
Agency Edition (new in 2.7.0)
Multi-site monitoring dashboard
Monitor up to 50 client sites from one WordPress install. Each row shows the site’s status (All clear / Warning / Critical), open conflicts with the top suspect, fatal errors in the last 24 hours, critical health issues and when it was last checked. Sites are polled automatically every 5, 15 or 60 minutes, or on demand.
Read-only API keys
Each monitored site generates its own key under Agency Remote Access. Keys are shown once, stored only as a SHA-256 hash, can expire after 30/90/365 days, and can be rotated or revoked instantly. A key can only read status counts — it cannot change anything.
Email alerts
An hourly digest email when something new happens: fatal errors, conflicts with 50 %+ confidence, or critical health issues. Choose the severity (critical / high / everything) and up to 10 recipients. The same conflict or issue is never emailed twice, and switching alerts on does not email the existing backlog.
External services
Conflict Detective does not contact the plugin author or any third-party service. Two optional features, both off by default and configured by an administrator, send data elsewhere:
- Agency hub — when you add a remote site under Agency Monitored Sites, this site sends an HTTPS GET request to that site’s
/wp-json/tahhan-cd/v1/statusendpoint at the interval you choose. The request contains the remote site’s API key (in theX-Tahcd-Keyheader) and the user agentTahhanConflictDetective/<version>. Only sites you add are contacted; their own terms and privacy policies apply. - Email alerts — when enabled, digest emails are sent through your site’s
wp_mail()configuration to the recipients you enter. They contain error-log excerpts, plugin names and health-scan messages from this site.
Zrzuty ekranu







Instalacja
- Upload the
tahhan-conflict-detectivefolder to the/wp-content/plugins/directory. - Activate the plugin through the Plugins menu in WordPress.
- Navigate to Conflict Detective in the WordPress admin sidebar.
No configuration is required for the diagnostic tools — all scanning is done on demand inside the admin area. The optional Agency features (remote monitoring, email alerts) are off until you enable them under Conflict Detective Agency.
Najczęściej zadawane pytania
-
Does this plugin slow down my site?
-
No. All analysis runs on demand inside the WordPress admin. The Performance Monitor records a few timestamps while plugins load, and the slow-request monitor only writes to the database when a request takes longer than 500 ms. Agency features run in WP-Cron and only when you enable them.
-
What log files does it read?
-
wp-content/debug.log and the server PHP
error_logpath returned byini_get('error_log'). -
Do I need to configure anything?
-
No. Optionally, enable
WP_DEBUGandWP_DEBUG_LOGinwp-config.phpto populate the error log. -
Does Safe Testing Mode affect my visitors?
-
Never. Safe Testing Mode uses a session cookie that is only present for your admin session. Visitors always see the live site.
-
What happens if I install the plugin via FTP?
-
The plugin detects missing database tables on every request and recreates them automatically — no activation hook required.
-
Is this plugin compatible with Multisite?
-
Yes, per site. Because the PHP error log is shared by every site on a network, the Error Log, email alerts and the Agency hub are only available to network (super) administrators. Site administrators keep access to the other tools.
-
How does the Performance Monitor work?
-
Performance Monitor hooks into WordPress’s
plugin_loadedaction, which fires once for every plugin that loads. It records a snapshot of the PHP execution time, memory usage, and database query count immediately before and after each plugin loads, then computes the delta. The results are stored in a 5-minute transient and can be refreshed on demand. Because measurements happen at request time, values vary between requests — treat them as estimates rather than precise benchmarks. -
Does the AJAX / REST Monitor log every request?
-
No. Only requests that take longer than 500 ms are written to the database. The log is automatically trimmed to the most recent 500 entries.
-
Can I manually trigger a WordPress Cron event?
-
Yes. Go to Conflict Detective Cron Monitor and click the „Run Now” button next to any event. The plugin validates the hook name against the live WP-Cron schedule before execution so arbitrary code cannot be triggered via this interface.
-
What is the Plugin Interaction Map?
-
The Interaction Map groups your installed plugins into known ecosystem clusters (WooCommerce, Elementor, Yoast SEO, Jetpack, ACF, Gravity Forms, Contact Form 7, WPML, LearnDash, Divi, WP Rocket, and more). Plugins within the same ecosystem are more likely to interact and potentially conflict with each other. The map also reads the
Requires Pluginsheader introduced in WordPress 6.5 to show explicit declared dependencies. -
What does the remote status endpoint expose?
-
GET /wp-json/tahhan-cd/v1/status returns counts only: number of open conflicts and the top suspect’s plugin name and confidence, total and last-24h fatal errors, health-scan issue counts, the last plugin change, the site name, and the WordPress, PHP and Conflict Detective versions. No file paths, log messages or personal data. It only answers requests that send a valid key in the
X-Tahcd-Keyheader — never in the URL. It is disabled until you generate a key. -
How are API keys protected?
-
On the monitored site only a SHA-256 hash of the key is stored. On the agency site, keys of remote sites are encrypted with libsodium using a key derived from your
AUTH_KEYsalt — if you change your salts, re-add the remote sites. After 10 failed attempts in 15 minutes an IP is throttled; a request with a valid key is always accepted. -
Why is HTTPS required for remote sites?
-
The API key travels in a request header. Remote URLs must use HTTPS on port 443; local, private-network, link-local and reserved addresses are refused to prevent server-side request forgery. Developers can allow plain HTTP on a test network with the
tahcd_allow_insecure_remotefilter. Known limitations: remote sites must have an IPv4 (A) record, and monitoring is disabled while an outbound HTTP proxy (WP_PROXY_HOST) is configured, because the destination could then not be verified. -
My site is behind Cloudflare or a reverse proxy. Does throttling still work?
-
Yes. A valid key is never throttled. If you want throttling to use the real visitor IP, map it with the
tahcd_rest_client_ipfilter from a header your proxy sets. -
Do email alerts need a real cron job?
-
Alerts and remote polling run through WP-Cron, which runs when your site receives traffic. On low-traffic sites, configure a system cron that calls
wp-cron.phpfor timely alerts.
Recenzje
Wtyczka nie ma jeszcze żadnej recenzji.
Kontrybutorzy i deweloperzy
„Tahhan Conflict Detective” jest oprogramowaniem open source. Poniższe osoby miały wkład w rozwój wtyczki.
ZaangażowaniPrzetłumacz wtyczkę “Tahhan Conflict Detective” na swój język.
Interesuje cię rozwój wtyczki?
Przeglądaj kod, sprawdź repozytorium SVN lub czytaj dziennik rozwoju przez RSS.
Rejestr zmian
2.7.0
- New: Agency hub — monitor up to 50 Conflict Detective sites from one dashboard, polled every 5/15/60 minutes or on demand.
- New: Read-only REST endpoint
GET /wp-json/tahhan-cd/v1/status, protected by a per-site API key (hash-only storage, expiry, rotation, revocation, per-IP throttling of failed attempts). - New: Email alerts — hourly digest of new fatal errors, conflicts and critical health issues, with severity levels, deduplication and a test button.
- Security: Outbound requests resolve every A/AAAA record, refuse private/link-local/reserved/CGNAT addresses, pin the connection to the vetted IP, allow HTTPS on port 443 only and follow no redirects.
- Security: Remote sites’ API keys are encrypted at rest with libsodium.
- Security: On multisite the shared error log (Error Log tab, dashboard card, Conflict Wizard timeline), email alerts and agency hub are restricted to network administrators.
- Fix: The activation hook was registered too late (inside
plugins_loaded) and never ran on activation; tables were only created on the next request. - Fix: Error logs larger than 50 MB were skipped entirely; the newest entries are now always read (memory is bounded at 2 MB).
- Uninstall now also removes the new options, cron events and transients on every site.
2.6.6
- Fix:
Error_Log::tail()—fread()return now checked; read errors no longer inject the word „false” into parsed log entries. - Fix:
Conflict_Scanner::get_recent_changes()—$wpdb->get_results()null return now guarded; prevents TypeError on DB failure. - Fix:
Dashboard::render_dashboard()—strtotime()false guard on culprit banner timestamp; corrupt dates no longer show „01-01-1970”. - Fix:
Dashboard::render_scanner()— same false guard applied to suspect card timestamps. - Performance:
Dashboard::render_dashboard()— eliminated one redundant log-file parse and one extra DB query; both data sources now fetched once.
2.6.5
- Fix:
Safe_Mode::ajax_toggle_plugin()— hardcoded 'Forbidden’ string now translatable via__(). - Fix:
Dashboard::ajax_clear_log()— missingreturnafter error response when log file does not exist. - Fix:
Dashboard::ajax_clear_log()— missingreturnafter error response whenput_contents()fails. - Fix:
Cron_Monitor::ajax_run_cron_event()— missingreturnafter error response for unknown-hook validation;run_event()would execute despite the error already being sent.
2.6.4
- Fix:
cd_ajax_log.created_atschema now includesDEFAULT CURRENT_TIMESTAMP— prevents INSERT failure under MySQL strict mode. - Fix:
cd_conflicts.changed_atschema changed toDEFAULT NULL— prevents INSERT failure if the column is omitted in strict mode. - Fix:
drop_tables()now also deletes thetahcd_main_table_existstransient on uninstall — no orphaned wp_options row. - Fix:
tables_exist()now checks bothcd_plugin_changes(v1) andcd_ajax_log(v3) — a partial install is correctly detected. - Fix:
Health_Scan::run()checks$wpdb->insert()return value and setsdb_errorflag in result on failure. - Fix:
Health_Scan::run()scanned_atin the returned array now uses the same UTC timestamp stored in the database — was returning local time while the DB row held UTC. - Fix:
scan_theme()guardsget_site_transient('update_themes')withis_object()before property access. - Fix:
scan_server()guardsget_site_transient('update_core')withis_object()before property access. - Fix:
Change_History::get_recent()returns an empty array on DB error instead of propagatingnull(which violated the declaredarrayreturn type). - Fix:
Change_History::on_update()option key for previous-version tracking now usesmd5()instead ofsanitize_key()—sanitize_key()strips/and., causing path collisions between plugins with similar names. - Fix:
Change_History::write()now returnsboolso callers can check whether the DB insert succeeded. - Fix:
Change_History::on_update()only advances the previous-version baseline (update_option) when the audit-log write actually succeeded.
2.6.3
- Fix:
get_site_transient('update_plugins')return value guarded withis_object()before property access — prevents PHP 8.x warning on fresh installs. - Fix:
WP_Filesystem()return value checked before callingput_contents()— prevents fatal on FTP/SSH filesystem environments. - Fix: AJAX log timestamps stored as UTC (
current_time('mysql', true)) instead of local WordPress time — fixes time-correlation bugs on non-UTC sites. - Fix:
verify_token()result cached with a static variable — prevents a duplicate DB query per request when Safe Mode is active. - Fix:
on_deletehook now correctly reads plugin data before deletion (fires ondelete_plugin, notdeleted_plugin). - Fix:
read_plugin_data()validates path stays withinWP_PLUGIN_DIRviarealpath()— path-traversal hardening. - Fix:
get_plugins()cached with a static variable inattribute_to_plugin()— eliminates N+1 calls when attributing log entries. - Fix:
strtotime()return value validated inscore_plugin()— avoids incorrect confidence scores from invalid timestamps. - Fix:
usortcomparator in Wizard timeline uses<=>instead of integer subtraction — prevents overflow on 32-bit PHP. - Fix: Plugin name in Wizard advice string escaped with
esc_html()before interpolation. - Fix:
str_replace('.php', …)in Interaction Map now only removes the trailing extension, not mid-name occurrences. - Fix: Missing
returnafterwp_send_json_error()added to all AJAX capability-check guards. - Fix: Hard-coded 'Forbidden’, 'Invalid plugin.’, 'Unknown plugin.’ strings now passed through
__(). - Fix: Cron Monitor
displaykey access guarded withisset(). - Fix: SHOW TABLES query in
maybe_upgrade()cached with a 1-hour transient — eliminates a raw DB query on every page load. - Fix: Multisite uninstall now iterates all sub-sites via
switch_to_blog()/restore_current_blog(). - Fix:
$ajax_startstatic property reset tonullafter logging to prevent duplicate entries.
2.6.2
- Security: plugin path in Safe Mode now validated with
plugin_basename()to prevent path traversal. - Security: AJAX monitor now reads from
$_POSTinstead of$_REQUEST. - Fix: all early-exit AJAX error responses now include
returnfor clarity. - Fix:
filemtime()calls for CSS/JS assets now guarded withfile_exists(). - Fix: Change History table uses null-coalescing guards on DB result properties.
- Fix:
strtok()replaced with statelessexplode()in Error Log file attribution. - Fix: Health Scan issue count now guards against non-array scan section returns.
- Code: Wizard symptom labels moved to a
symptoms()method so they are translatable. - Code: Hardcoded „Plugin:” label in Error Log Viewer is now translatable.
2.6.1
- Updated: Tested up to WordPress 7.0.
2.6.0
- New: Performance Monitor tab — tracks per-plugin load time, memory delta, and DB query count during page load; color-coded Fast / Slow / Heavy badges; Refresh Data button.
- New: Cron Monitor tab — lists all scheduled WP-Cron events with next run time and overdue detection; „Run Now” button per event; overdue count summary badge at top.
- New: AJAX / REST Monitor tab — logs slow AJAX and REST API calls (>500 ms) to a dedicated DB table; filter bar for All / AJAX / REST / Slow views.
- New: Plugin Interaction Map tab — visualises plugin dependency clusters (WooCommerce, Elementor, Yoast, Jetpack, ACF, etc.) and standalone plugins with active/inactive state.
- Security: cron „Run Now” AJAX handler now validates the hook against the live WP-Cron schedule before execution.
- Security: AJAX monitor REST timing now reads from
$_SERVERdirectly (was using non-standard$GLOBALS['_SERVER']). - Security: AJAX log
get_entries()now selects only required columns instead ofSELECT *. - DB: new
{prefix}cd_ajax_logtable (schema version 3).
2.5.1
- Fixed: uninstall routine now correctly deletes
tahcd_prev_version_*options (was using the stalepcd_prev_version_prefix, leaving orphaned rows in wp_options). - Fixed: Safe Mode plugin list no longer shows Conflict Detective itself (self-exclusion filter used the old slug
conflict-detective/conflict-detective.php). - Docs: readme.txt changelog updated with entries for v2.2.0 through v2.5.0.
2.5.0
- All plugin-specific prefixes standardised to
tahcd_/TAHCD_to satisfy WordPress.org uniqueness requirements (constants, AJAX actions, nonce, user meta, cookie, option keys, script handle, JS data object).
2.4.0
- Plugin renamed to Tahhan Conflict Detective (slug:
tahhan-conflict-detective) for WordPress.org compliance. Namespace changed toTahhanConflictDetective. Text domain changed totahhan-conflict-detective. - Debug log clear handler now uses
WP_Filesystem::put_contents()instead offile_put_contents().
2.3.1
- Fixed critical infinite recursion crash:
maybe_filter_active_plugins()calledget_option('active_plugins')which re-triggered the same filter, causing a stack overflow. Fixed by reading directly from$wpdb.
2.3.0
- CI action SHA pinning for security hardening. Code cleanup in class-dashboard.php and class-error-log.php.
2.2.0
- Safe Mode tab fully functional: Start/Stop button now triggers AJAX and reloads on success.
- Architecture fix:
Safe_Mode::init()andDatabase::maybe_upgrade()moved to file-load time.
2.1.4
- Fixed critical bug: Safe_Mode::init() and Database::maybe_upgrade() were registered inside Plugin::init() on plugins_loaded priority 5, meaning they were never called (priority 1 and 0 already fired). Both are now wired up directly at file load time, outside the Plugin class.
- Safe Mode tab fully redesigned: inactive state shows a card with instructions and a Start button; active state shows an amber banner with plugin count and a Stop button above the plugin toggle list.
- JavaScript Safe Mode toggle now uses delegated event binding ($(document).on) so it works regardless of DOM load order, and reloads the page on success to reflect the new state.
- Added safeModeLoading and safeModeStop localised strings for button feedback during AJAX calls.
- Added CSS for .pcd-safe-mode-banner, .pcd-btn-stop, .pcd-safe-mode-steps, and .pcd-safe-mode-count.
2.1.3
- Added Safe Mode tab UI (render_safe_mode placeholder).
2.1.1
- Security: plugin slug from AJAX request now validated against the installed plugins list before being stored in user meta
- All JavaScript UI strings are now translatable via wp_localize_script — no hardcoded English in JS
- Replaced last remaining emoji with a Dashicon in the Conflict Wizard
- Fixed menu position conflict with WordPress core Plugins menu (changed from 65 to 65.1)
- Added languages/ directory to match the Domain Path declaration in the plugin header
- Fixed navigation instructions in documentation (plugin is a top-level menu, not under Tools)
- LICENSE updated to full GPL-2.0-or-later text including the „or any later version” clause
2.0.0
- Added Conflict Scanner with confidence percentage
- Added Safe Testing Mode (admin-only plugin toggle, visitors unaffected)
- Added Conflict Wizard with 7 symptom categories and automatic analysis
- New database table for storing scanner results
1.0.0
- Initial release — Dashboard, Error Log Viewer, Plugin Change History, Health Scan
