| 开发者 | mustafatahhan |
|---|---|
| 更新时间 | 2026年9月14日 21:03 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 7.0 |
| 版权: | GPL-2.0-or-later |
| 版权网址: | 版权信息 |
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:
max_execution_time misconfigurationstahhan-conflict-detective folder to the /wp-content/plugins/ directory.No. All analysis runs on demand inside the WordPress admin. There is zero front-end overhead.
wp-content/debug.log and the server PHP error_log path returned by ini_get('error_log').
No. Optionally, enable WP_DEBUG and WP_DEBUG_LOG in wp-config.php to populate the error log.
Never. Safe Testing Mode uses a session cookie that is only present for your admin session. Visitors always see the live site.
The plugin detects missing database tables on every request and recreates them automatically — no activation hook required.
The plugin monitors the current site only. It is not a network-wide tool in this version.
Performance Monitor hooks into WordPress's plugin_loaded action, 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.
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.
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.
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 Plugins header introduced in WordPress 6.5 to show explicit declared dependencies.
Safe_Mode::ajax_toggle_plugin() — hardcoded 'Forbidden' string now translatable via __().Dashboard::ajax_clear_log() — missing return after error response when log file does not exist.Dashboard::ajax_clear_log() — missing return after error response when put_contents() fails.Cron_Monitor::ajax_run_cron_event() — missing return after error response for unknown-hook validation; run_event() would execute despite the error already being sent.cd_ajax_log.created_at schema now includes DEFAULT CURRENT_TIMESTAMP — prevents INSERT failure under MySQL strict mode.cd_conflicts.changed_at schema changed to DEFAULT NULL — prevents INSERT failure if the column is omitted in strict mode.drop_tables() now also deletes the tahcd_main_table_exists transient on uninstall — no orphaned wp_options row.tables_exist() now checks both cd_plugin_changes (v1) and cd_ajax_log (v3) — a partial install is correctly detected.Health_Scan::run() checks $wpdb->insert() return value and sets db_error flag in result on failure.Health_Scan::run() scanned_at in the returned array now uses the same UTC timestamp stored in the database — was returning local time while the DB row held UTC.scan_theme() guards get_site_transient('update_themes') with is_object() before property access.scan_server() guards get_site_transient('update_core') with is_object() before property access.Change_History::get_recent() returns an empty array on DB error instead of propagating null (which violated the declared array return type).Change_History::on_update() option key for previous-version tracking now uses md5() instead of sanitize_key() — sanitize_key() strips / and ., causing path collisions between plugins with similar names.Change_History::write() now returns bool so callers can check whether the DB insert succeeded.Change_History::on_update() only advances the previous-version baseline (update_option) when the audit-log write actually succeeded.get_site_transient('update_plugins') return value guarded with is_object() before property access — prevents PHP 8.x warning on fresh installs.WP_Filesystem() return value checked before calling put_contents() — prevents fatal on FTP/SSH filesystem environments.current_time('mysql', true)) instead of local WordPress time — fixes time-correlation bugs on non-UTC sites.verify_token() result cached with a static variable — prevents a duplicate DB query per request when Safe Mode is active.on_delete hook now correctly reads plugin data before deletion (fires on delete_plugin, not deleted_plugin).read_plugin_data() validates path stays within WP_PLUGIN_DIR via realpath() — path-traversal hardening.get_plugins() cached with a static variable in attribute_to_plugin() — eliminates N+1 calls when attributing log entries.strtotime() return value validated in score_plugin() — avoids incorrect confidence scores from invalid timestamps.usort comparator in Wizard timeline uses <=> instead of integer subtraction — prevents overflow on 32-bit PHP.esc_html() before interpolation.str_replace('.php', …) in Interaction Map now only removes the trailing extension, not mid-name occurrences.return after wp_send_json_error() added to all AJAX capability-check guards.__().display key access guarded with isset().maybe_upgrade() cached with a 1-hour transient — eliminates a raw DB query on every page load.switch_to_blog() / restore_current_blog().$ajax_start static property reset to null after logging to prevent duplicate entries.plugin_basename() to prevent path traversal.$_POST instead of $_REQUEST.return for clarity.filemtime() calls for CSS/JS assets now guarded with file_exists().strtok() replaced with stateless explode() in Error Log file attribution.symptoms() method so they are translatable.$_SERVER directly (was using non-standard $GLOBALS['_SERVER']).get_entries() now selects only required columns instead of SELECT *.{prefix}cd_ajax_log table (schema version 3).tahcd_prev_version_* options (was using the stale pcd_prev_version_ prefix, leaving orphaned rows in wp_options).conflict-detective/conflict-detective.php).tahcd_ / TAHCD_ to satisfy WordPress.org uniqueness requirements (constants, AJAX actions, nonce, user meta, cookie, option keys, script handle, JS data object).tahhan-conflict-detective) for WordPress.org compliance. Namespace changed to TahhanConflictDetective. Text domain changed to tahhan-conflict-detective.WP_Filesystem::put_contents() instead of file_put_contents().maybe_filter_active_plugins() called get_option('active_plugins') which re-triggered the same filter, causing a stack overflow. Fixed by reading directly from $wpdb.Safe_Mode::init() and Database::maybe_upgrade() moved to file-load time.