30,
'max_memory_limit' => 256,
'log_batch_size' => 1000,
'action_scheduler_batches' => 1,
'otto_rate_limit' => 10,
'queue_cleanup_days' => 31
);
if (empty($settings)) {
return isset($defaults[$key]) ? $defaults[$key] : $default;
}
return isset($settings[$key]) ? $settings[$key] : (isset($defaults[$key]) ? $defaults[$key] : $default);
}
// ------------------------------------------------------------------
// Error-log page (standalone page)
// ------------------------------------------------------------------
/**
* Display the standalone Error Log admin page.
*
* @param Metasync_Admin $admin The admin instance (needed for header/nav rendering).
*/
public function metasync_display_error_log($admin) {
$log_file = WP_CONTENT_DIR . '/metasync_data/plugin_errors.log';
if (!Metasync::current_user_has_plugin_access()) {
return;
}
if (isset($_POST['wp_debug_log_enabled']) &&
isset($_POST['wp_debug_enabled']) &&
isset($_POST['wp_debug_display_enabled']) &&
isset($_POST['wp_debug_nonce']) &&
wp_verify_nonce($_POST['wp_debug_nonce'], 'metasync_wp_debug_settings')) {
$wp_debug = in_array($_POST['wp_debug_enabled'], ['true', 'false']) ? $_POST['wp_debug_enabled'] : 'false';
$wp_debug_log = in_array($_POST['wp_debug_log_enabled'], ['true', 'false']) ? $_POST['wp_debug_log_enabled'] : 'false';
$wp_debug_display = in_array($_POST['wp_debug_display_enabled'], ['true', 'false']) ? $_POST['wp_debug_display_enabled'] : 'false';
update_option('wp_debug_enabled', $wp_debug);
update_option('wp_debug_log_enabled', $wp_debug_log);
update_option('wp_debug_display_enabled', $wp_debug_display);
$data = new ConfigControllerMetaSync();
$data->store();
add_settings_error(
'metasync_messages',
'metasync_message',
'WordPress debug settings updated successfully.',
'updated'
);
} elseif (isset($_POST['wp_debug_nonce']) && !wp_verify_nonce($_POST['wp_debug_nonce'], 'metasync_wp_debug_settings')) {
add_settings_error(
'metasync_messages',
'metasync_message',
'Security verification failed. Please try again.',
'error'
);
}
$log_enabled = get_option('metasync_log_enabled', 'yes');
$wp_debug_enabled = get_option('wp_debug_enabled', 'false');
$wp_debug_log_enabled = get_option('wp_debug_log_enabled', 'false');
$wp_debug_display_enabled = get_option('wp_debug_display_enabled', 'false');
?>
render_layout_open('Error Logs', 'error_log', 'View and manage WordPress error logs and debug settings.'); ?>
Error Log Management
Clear WordPress error logs to free up space and remove old entries.
Error Log Contents
View the current error log entries for troubleshooting and monitoring.
';
echo '
';
echo esc_html($log_content);
echo '';
echo '
';
} else {
echo '';
echo '
โ
Log file is empty - no errors recorded.
';
echo '
';
}
} else {
echo '';
echo '
๐ No log file found. Error logging may not be enabled.
';
echo '
';
}
?>
render_layout_close(); ?>
โ ๏ธ Debug Mode Manager is not available. Please ensure the plugin is properly installed.
get_status();
?>
Configuration Details
| Maximum Log Size |
|
| Auto-Disable Duration |
24 hours |
| Log Rotation |
Automatic when size limit reached |
| Rotated Files Kept |
1 (current + 1 old) |
| Check Frequency |
Hourly (via WP Cron) |
| Log File Path |
|
Error Summary
View categorized error statistics with counts and last occurrence times.
| Error Category |
Error Code |
Count |
Last Occurred |
Message |
$error): ?>
|
|
|
|
(' . $time_diff . ' ago)';
?>
|
|
โ
No errors recorded yet. Error summary will appear here once errors are logged.
โ ๏ธ Error Logger class not available. Please ensure the plugin is properly loaded.
Clear Error Logs
Clear WordPress error logs to free up space and remove old entries.
WordPress Debug Configuration
Configure WordPress debug settings to control error logging and display.
Error Log Contents
View the current error log entries for troubleshooting and monitoring.
can_show_error_logs()):
$log_content = $error_logs->get_error_logs(50);
if (!empty(trim($log_content))):
$error_logs->show_copy_button();
$error_logs->show_logs();
$error_logs->show_info();
else: ?>
โ
Log file is empty - no errors recorded.
get_error_message();
if (!empty($error_message)): ?>
โ ๏ธ Unable to access error log file. Please check permissions.
get_page_slug() . '&tab=advanced&debug_error=1');
wp_redirect($redirect_url);
exit;
}
if (!current_user_can('manage_options')) {
wp_die('Unauthorized');
}
if (!class_exists('Metasync_Debug_Mode_Manager')) {
$redirect_url = admin_url('admin.php?page=' . $this->get_page_slug() . '&tab=advanced&debug_error=1&msg=manager_not_available');
wp_redirect($redirect_url);
exit;
}
$debug_manager = Metasync_Debug_Mode_Manager::get_instance();
$action = sanitize_text_field($_POST['action_type'] ?? '');
$redirect_url = admin_url('admin.php?page=' . $this->get_page_slug() . '&tab=advanced');
switch ($action) {
case 'enable':
$indefinite = isset($_POST['indefinite']) && $_POST['indefinite'] === '1';
$result = $debug_manager->enable_debug_mode($indefinite);
$redirect_url = add_query_arg('debug_mode_enabled', '1', $redirect_url);
if ($indefinite) {
$redirect_url = add_query_arg('indefinite', '1', $redirect_url);
}
break;
case 'disable':
$result = $debug_manager->disable_debug_mode('manual');
if ($result) {
$redirect_url = add_query_arg('debug_mode_disabled', '1', $redirect_url);
} else {
$redirect_url = add_query_arg('debug_error', '1', $redirect_url);
}
break;
case 'extend':
$result = $debug_manager->extend_debug_mode();
$redirect_url = add_query_arg('debug_mode_extended', '1', $redirect_url);
break;
default:
$redirect_url = add_query_arg('debug_error', '1', $redirect_url);
break;
}
wp_redirect($redirect_url);
exit;
}
}
/**
* Handle error log operations (clear).
*/
public function handle_error_log_operations()
{
if (isset($_POST['clear_log'])) {
if (wp_verify_nonce($_POST['clear_log_nonce'], 'metasync_clear_log_nonce')) {
$log_file = WP_CONTENT_DIR . '/metasync_data/plugin_errors.log';
if (file_exists($log_file)) {
file_put_contents($log_file, '');
$backup_files = glob(WP_CONTENT_DIR . '/metasync_data/plugin_errors.log.old.*');
if ($backup_files) {
foreach ($backup_files as $backup_file) {
@unlink($backup_file);
}
}
}
$redirect_url = admin_url('admin.php?page=' . $this->get_page_slug() . '&tab=advanced&log_cleared=1');
wp_redirect($redirect_url);
exit;
} else {
$redirect_url = admin_url('admin.php?page=' . $this->get_page_slug() . '&tab=advanced&clear_error=1');
wp_redirect($redirect_url);
exit;
}
}
if (isset($_POST['clear_error_summary']) && isset($_POST['clear_error_summary_nonce'])) {
if (wp_verify_nonce($_POST['clear_error_summary_nonce'], 'metasync_clear_error_summary_nonce')) {
if (class_exists('Metasync_Error_Logger')) {
Metasync_Error_Logger::clear_error_summary();
$redirect_url = admin_url('admin.php?page=' . $this->get_page_slug() . '&tab=advanced&error_summary_cleared=1');
wp_redirect($redirect_url);
exit;
} else {
$redirect_url = admin_url('admin.php?page=' . $this->get_page_slug() . '&tab=advanced&error_summary_error=1');
wp_redirect($redirect_url);
exit;
}
} else {
$redirect_url = admin_url('admin.php?page=' . $this->get_page_slug() . '&tab=advanced&error_summary_error=1');
wp_redirect($redirect_url);
exit;
}
}
}
/**
* Handle clear all settings operations.
*/
public function handle_clear_all_settings()
{
if (isset($_POST['clear_all_settings'])) {
if (wp_verify_nonce($_POST['clear_all_settings_nonce'], 'metasync_clear_all_settings_nonce')) {
$metasync_options_to_clear = [
'metasync_options',
'metasync_options_instant_indexing',
'metasync_options_bing_instant_indexing',
'metasync_otto_crawldata',
'metasync_logging_data',
'metasync_wp_sa_connect_token',
'wp_debug_enabled',
'wp_debug_log_enabled',
'wp_debug_display_enabled',
// Media Optimization settings & cache
'metasync_media_optimization',
'metasync_batch_optimize_queue',
'metasync_batch_optimize_progress',
'metasync_batch_optimize_settings',
// Code Minification settings
'metasync_code_minification',
];
$cleared_count = 0;
foreach ($metasync_options_to_clear as $option_name) {
if (get_option($option_name) !== false) {
delete_option($option_name);
$cleared_count++;
}
}
$transients_to_clear = [
'metasync_heartbeat_status_cache',
];
foreach ($transients_to_clear as $transient_name) {
delete_transient($transient_name);
}
$cron_hooks_to_clear = [
'metasync_heartbeat_cron_check',
'metasync_media_batch_optimize_cron',
];
foreach ($cron_hooks_to_clear as $cron_hook) {
$timestamp = wp_next_scheduled($cron_hook);
if ($timestamp) {
wp_unschedule_event($timestamp, $cron_hook);
}
}
$new_plugin_auth_token = wp_generate_password(32, false, false);
$fresh_options = [
'general' => [
'apikey' => $new_plugin_auth_token
]
];
update_option('metasync_options', $fresh_options);
Metasync::log_api_key_event('settings_reset', 'plugin_auth_token', array(
'options_cleared_count' => $cleared_count,
'new_token_prefix' => substr($new_plugin_auth_token, 0, 8) . '...',
'triggered_by' => 'settings_reset_action'
), 'info');
$redirect_url = admin_url('admin.php?page=' . $this->get_page_slug() . '&tab=advanced&settings_cleared=1');
wp_redirect($redirect_url);
exit;
} else {
$redirect_url = admin_url('admin.php?page=' . $this->get_page_slug() . '&tab=advanced&clear_settings_error=1');
wp_redirect($redirect_url);
exit;
}
}
}
// ------------------------------------------------------------------
// Log-file helpers
// ------------------------------------------------------------------
/**
* Get error log content for display.
*/
public function get_error_log_content()
{
$execution_time = $this->get_execution_setting('max_execution_time');
if (function_exists('set_time_limit')) {
@set_time_limit($execution_time);
}
$log_file = WP_CONTENT_DIR . '/debug.log';
if (!file_exists($log_file) || !is_readable($log_file)) {
return false;
}
$batch_size = $this->get_execution_setting('log_batch_size');
$file_size = filesize($log_file);
if ($file_size > 10 * 1024 * 1024) {
return $this->get_log_tail($log_file, $batch_size);
}
$content = file_get_contents($log_file);
if ($content === false) {
return false;
}
$lines = explode("\n", $content);
$recent_lines = array_slice($lines, -$batch_size);
return implode("\n", $recent_lines);
}
/**
* Memory-efficient function to get last N lines from a large file.
*/
public function get_log_tail($file_path, $lines = null)
{
$execution_time = $this->get_execution_setting('max_execution_time');
if (function_exists('set_time_limit')) {
@set_time_limit($execution_time);
}
if ($lines === null) {
$lines = $this->get_execution_setting('log_batch_size');
}
$handle = fopen($file_path, 'r');
if (!$handle) {
return false;
}
fseek($handle, -1, SEEK_END);
$result_lines = array();
$line = '';
$line_count = 0;
while (ftell($handle) > 0 && $line_count < $lines) {
$char = fgetc($handle);
if ($char === "\n") {
if (!empty($line)) {
array_unshift($result_lines, strrev($line));
$line = '';
$line_count++;
}
} else {
$line .= $char;
}
fseek($handle, -2, SEEK_CUR);
}
if (!empty($line) && $line_count < $lines) {
array_unshift($result_lines, strrev($line));
}
fclose($handle);
return implode("\n", $result_lines);
}
}