wp_config = new WP_Config_Transformer; // already in the DLM\Classes namespace, so, no need to repeat
}
/**
* Get status of WP_DEBUG
*
* @since 1.0.0
*/
public function get_status() {
// If non-existent, create an empty index to prevent directory browsing and download of the debug log file
$uploads_path = wp_upload_dir()['basedir'] . '/debug-log-manager';
if ( ! is_file( $uploads_path . '/index.php' ) ) {
file_put_contents( $uploads_path . '/index.php', '' . esc_html__( 'Error Logging', 'debug-log-manager' ) . ': ' . ucfirst( esc_html__( 'enabled', 'debug-log-manager' ) ) . ' ' . esc_html__( 'on', 'debug-log-manager' ) . ' ' . esc_html( $date_time ) . '';
} elseif ( 'disabled' == $status ) {
return '
' . esc_html__( 'Error Logging', 'debug-log-manager' ) . ': ' . ucfirst( esc_html__( 'disabled', 'debug-log-manager' ) ) . ' ' . esc_html__( 'on', 'debug-log-manager' ) . ' ' . esc_html( $date_time ) . '
';
} else {}
}
/**
* Get log auto-refresh status
*
* @since 1.3.0
*/
public function get_autorefresh_status() {
if ( false !== get_option( 'debug_log_manager_autorefresh' ) ) {
$autorefresh_status = get_option( 'debug_log_manager_autorefresh' );
} else {
$autorefresh_status = 'disabled';
update_option( 'debug_log_manager_autorefresh', $autorefresh_status, false );
}
if ( 'enabled' == $autorefresh_status ) {
return 'Auto-Refresh: ' . ucfirst( esc_html__( 'enabled', 'debug-log-manager' ) ) . '
';
} elseif ( 'disabled' == $autorefresh_status ) {
return 'Auto-Refresh: ' . ucfirst( esc_html__( 'disabled', 'debug-log-manager' ) ) . '
';
}
}
/**
* Enable / disable WP_DEBUG
*
* @since 1.0.0
*/
public function toggle_debugging() {
if ( isset( $_REQUEST ) ) {
$log_info = get_option( 'debug_log_manager' );
$dlm_debug_log_file_path = get_option( 'debug_log_manager_file_path' );
if ( function_exists( 'wp_date' ) ) {
$date_time = wp_date( 'M j, Y - H:i:s' ); // Localized according to WP timezone settings
} else {
$date_time = date_i18n( 'M j, Y - H:i:s' );
}
$date_time_for_option = date( 'M j, Y H:i:s' ); // in UTC
if ( 'disabled' == $log_info['status'] ) {
$option_value = array(
'status' => 'enabled',
'on' => $date_time_for_option,
);
update_option( 'debug_log_manager', $option_value, false );
// If WP_DEBUG_LOG is defined, copy content of existing debug.log file into the log file created by this plugin
if ( $this->wp_config->exists( 'constant', 'WP_DEBUG_LOG' ) ) {
$wp_debug_log_const = $this->wp_config->get_value( 'constant', 'WP_DEBUG_LOG' );
if ( in_array( $wp_debug_log_const, array( 'true', 'false' ), true ) ) {
$wp_debug_log_const = (bool) $wp_debug_log_const;
}
if ( is_bool( $wp_debug_log_const ) ) {
// WP_DEBUG_LOG is true or false. Log file is in default location of /wp-content/debug.log.
if ( is_file( WP_CONTENT_DIR . '/debug.log' ) ) {
// Copy existing debug log content to this plugin's debug log.
$default_debug_log_content = file_get_contents( WP_CONTENT_DIR . '/debug.log' );
file_put_contents( $dlm_debug_log_file_path, $default_debug_log_content );
unlink( realpath( WP_CONTENT_DIR . '/debug.log' ) ); // delete existing debug log
}
} elseif ( is_string( $wp_debug_log_const ) ) {
// WP_DEBUG_LOG is custom path to log file. Copy existing debug log content to this plugin's debug log.
if ( is_file( $wp_debug_log_const ) && ( $wp_debug_log_const != $dlm_debug_log_file_path ) ) {
$custom_debug_log_content = file_get_contents( $wp_debug_log_const );
file_put_contents( $dlm_debug_log_file_path, $custom_debug_log_content );
unlink( $wp_debug_log_const ); // delete existing debug log
}
}
$copy = true; // existing debug.log file's entries are copied to this plugin's debug.log file
} else {
$copy = false; // existing debug.log file's entries are NOT copied to this plugin's debug.log file
}
// Define Debug constants in wp-config.php
$options = array(
'add' => true, // Add the config if missing.
'raw' => true, // Display value in raw format without quotes.
'normalize' => false, // Normalize config output using WP Coding Standards.
);
$this->wp_config->update( 'constant', 'WP_DEBUG', 'true', $options );
$options = array(
'add' => true, // Add the config if missing.
'raw' => true, // Display value in raw format without quotes.
'normalize' => false, // Normalize config output using WP Coding Standards.
);
$this->wp_config->update( 'constant', 'SCRIPT_DEBUG', 'true', $options );
$options = array(
'add' => true, // Add the config if missing.
'raw' => false, // Display value in raw format without quotes.
'normalize' => false, // Normalize config output using WP Coding Standards.
);
$this->wp_config->update( 'constant', 'WP_DEBUG_LOG', get_option( 'debug_log_manager_file_path' ), $options );
$options = array(
'add' => true, // Add the config if missing.
'raw' => true, // Display value in raw format without quotes.
'normalize' => false, // Normalize config output using WP Coding Standards.
);
$this->wp_config->update( 'constant', 'WP_DEBUG_DISPLAY', 'false', $options );
$options = array(
'add' => true, // Add the config if missing.
'raw' => true, // Display value in raw format without quotes.
'normalize' => false, // Normalize config output using WP Coding Standards.
);
$this->wp_config->update( 'constant', 'DISALLOW_FILE_EDIT', 'false', $options );
// Get the debug.log file size
$log_file_path = get_option( 'debug_log_manager_file_path' );
$log_file_shortpath = str_replace( sanitize_text_field( $_SERVER['DOCUMENT_ROOT'] ), "", $log_file_path );
$file_size = size_format( (int) filesize( $log_file_path ) );
// Prepare entries from the debug log for the data table
$errors_master_list = json_decode( $this->get_processed_entries(), true );
$n = 1;
$entries = array();
foreach ( $errors_master_list as $error ) {
if ( function_exists( 'wp_date' ) ) {
$localized_timestamp = wp_date( 'M j, Y - H:i:s', strtotime( $error['occurrences'][0] ) ); // last occurrence
} else {
$localized_timestamp = date_i18n( 'M j, Y - H:i:s', strtotime( $error['occurrences'][0] ) );
}
$occurrence_count = count( $error['occurrences'] );
$entry = array(
$n,
$error['type'],
$error['details'],
$localized_timestamp . '
(' . sprintf( _n( '%s occurrence logged', '%s occurrences logged', $occurrence_count, 'debug-log-manager' ), number_format_i18n( $occurrence_count ) ) . ')',
);
$entries[] = $entry;
$n++;
}
// Assemble data to return
$data = array(
'status' => 'enabled',
'copy' => $copy,
'message' => '' . esc_html__( 'Error Logging', 'debug-log-manager' ) . ': ' . esc_html__( 'Enabled on', 'debug-log-manager' ) . ' ' . esc_html( $date_time ),
'entries' => $entries,
'size' => $file_size,
);
echo json_encode( $data );
} elseif ( 'enabled' == $log_info['status'] ) {
$option_value = array(
'status' => 'disabled',
'on' => $date_time_for_option,
);
update_option( 'debug_log_manager', $option_value, false );
// Remove Debug constants in wp-config.php
$this->wp_config->remove( 'constant', 'WP_DEBUG' );
$this->wp_config->remove( 'constant', 'SCRIPT_DEBUG' );
$this->wp_config->remove( 'constant', 'WP_DEBUG_LOG' );
$this->wp_config->remove( 'constant', 'WP_DEBUG_DISPLAY' );
$this->wp_config->remove( 'constant', 'DISALLOW_FILE_EDIT' );
// Assemble data to return
$data = array(
'status' => 'disabled',
'copy' => false,
'message' => '' . esc_html__( 'Error Logging', 'debug-log-manager' ) . ': ' . esc_html__( 'Disabled on', 'debug-log-manager' ) . ' ' . esc_html( $date_time ),
'entries' => '',
'size' => '',
);
echo json_encode( $data );
} else {}
}
}
/**
* Toggle auto-refresh of entries table
*
* @since 1.3.0
*/
public function toggle_autorefresh() {
if ( isset( $_REQUEST ) ) {
$autorefresh_status = get_option( 'debug_log_manager_autorefresh' );
if ( $autorefresh_status == 'disabled' ) {
update_option( 'debug_log_manager_autorefresh', 'enabled', false );
$data = array(
'status' => 'enabled',
'message' => '' . esc_html__( 'Auto-Refresh', 'debug-log-manager' ) . ': ' . esc_html__( 'Enabled', 'debug-log-manager' ),
);
echo json_encode( $data );
} elseif ( $autorefresh_status == 'enabled' ) {
update_option( 'debug_log_manager_autorefresh', 'disabled', false );
$data = array(
'status' => 'disabled',
'message' => '' . esc_html__( 'Auto-Refresh', 'debug-log-manager' ) . ': ' . esc_html__( 'Disabled', 'debug-log-manager' ),
);
echo json_encode( $data );
} else {}
}
}
/**
* Get the processed debug log data
*
* @return string $errors_master_list The processed error log entries
* @since 1.2.0
*/
public function get_processed_entries() {
$debug_log_file_path = get_option( 'debug_log_manager_file_path' );
// Read the errors log file
$log = file_get_contents( $debug_log_file_path );
$log = str_replace( "[\\", "^\\", $log ); // certain error message contains the '[\' string, which will make the following split via explode() to split lines at places in the message it's not supposed to. So, we temporarily replace those with '^\'
$log = str_replace( "[\"", "^\"", $log ); // certain error message contains the '["' string, which will make the following split via explode() to split lines at places in the message it's not supposed to. So, we temporarily replace those with '^"'
$log = str_replace( "[internal function]", "^internal function^", $log );
// We are splitting the log file not using PHP_EOL to preserve the stack traces for PHP Fatal Errors among other things
$lines = explode("[", $log);
$prepended_lines = array();
// Pluck out the last 100k entries, the newest entry is last
// To pluck out the first 100000 entries, use array_slice( $lines, 0, 100000 )
$lines = array_slice( $lines, -100000 );
foreach ( $lines as $line ) {
if ( !empty($line) ) {
$line = str_replace( "UTC]", "UTC]@@@", $line ); // add '@@@' as marker/separator after time stamp
$line = str_replace( "Stack trace:", "
Stack trace:", $line ); // add line break for stack trace section
if ( strpos( $line, 'PHP Fatal' ) !== false ) {
$line = str_replace( "#", "
#", $line ); // add line break on PHP Fatal error's stack trace lines
}
$line = str_replace( "Argument
#", "Argument #", $line ); // remove hr on certain error message
$line = str_replace( "parameter
#", "parameter #", $line ); // remove hr on certain error message
$line = str_replace( "the
#", "the #", $line ); // remove hr on certain error message
$line = str_replace( "^\\", "[\\", $line ); // reverse the temporary replacement of '[\' with '^\'
$line = str_replace( "^\"", "[\"", $line ); // reverse the temporary replacement of '["' with '^"'
$line = str_replace( "^internal function^", "[internal function]", $line );
$prepended_line = '[' . $line; // Put back the missing '[' after explode operation
$prepended_lines[] = $prepended_line;
}
}
// Reverse the order of the entries, so the newest entry is first
$latest_lines = array_reverse( $prepended_lines );
// Will hold error details types
$errors_master_list = array();
foreach( $latest_lines as $line ) {
$line = explode("@@@ ", trim( $line ) ); // split the line using the '@@@' marker/separator defined earlier. '@@@' will be deleted by explode().
$timestamp = str_replace( [ "[", "]" ], "", $line[0] );
// Initialize error-related variables
$error = '';
$error_source = '';
$error_file = '';
$error_file_path = '';
$error_file_line = '';
if ( array_key_exists('1', $line) ) {
$error = $line[1];
// Check if there is a file path to pluck out of the error line
if ( false !== strpos( $error, ABSPATH ) ) {
// Separata file path and error line from error message
// Handling for PHP Fatal errors with stack trace included
if ( false !== strpos( $error, 'Stack trace:' ) ) {
$error_parts = explode( 'Stack trace:', $error );
$error_message = str_replace( '
', '', $error_parts[0] );
if ( isset( $error_parts[1] ) ) {
$error_stack_trace = ' ' . $error_parts[1];
}
$error_message_parts = explode( ' in /', $error_message );
// Reconstruct the error details without error file path and line info
$error = $error_message_parts[0] . '
Stack trace:' . $error_stack_trace;
// Shorten the file path in the error details
$error = str_replace( ABSPATH, '/', $error );
if ( isset( $error_message_parts[1] ) ) {
$error_file = '/' . $error_message_parts[1];
$error_file_info = explode ( ':', $error_file );
$error_file_path = $error_file_info[0];
if ( array_key_exists('1', $error_file_info) ) {
$error_file_line = $error_file_info[1];
}
}
} else {
$error_message_parts = explode( ' in /', $error );
$error = $error_message_parts[0];
if ( isset( $error_message_parts[1] ) ) {
$error_file = '/' . $error_message_parts[1];
$error_file_info = explode ( ' on line ', $error_file );
$error_file_path = $error_file_info[0];
if ( array_key_exists('1', $error_file_info) ) {
$error_file_line = $error_file_info[1];
}
}
}
// Shorten the file path where the error occurred
$error_file_path = str_replace( ABSPATH, '/', $error_file_path );
// Define whether source of error is WP Core, Theme, Plugin or Other
if ( ( false !== strpos( $error_file, '/wp-admin/' ) ) ||
( false !== strpos( $error_file, '/wp-includes/' ) ) ) {
$error_source = __( 'WordPress core', 'debug-log-manager' );
} elseif ( ( false !== strpos( $error_file, '/wp-content/themes/' ) ) ) {
$error_source = __( 'Theme', 'debug-log-manager' );
} elseif ( ( false !== strpos( $error_file, '/wp-content/plugins/' ) ) ) {
$error_source = __( 'Plugin', 'debug-log-manager' );
} else {
$error_source = '';
}
// Get plugin/theme directory name of error file when error source is plugin or theme
if ( ( 'Plugin' == $error_source ) || ( 'Theme' == $error_source ) ) {
$error_file_path_parts = explode( '/', $error_file_path );
$error_file_directory = $error_file_path_parts[3];
}
// Get plugin name
$plugins = get_plugins();
if ( 'Plugin' == $error_source ) {
foreach ( $plugins as $plugin_path_file => $plugin_info ) {
if ( false !== strpos( $plugin_path_file, $error_file_directory ) ) {
$error_source_plugin_path_file = $plugin_path_file;
$error_source_plugin_name = $plugin_info['Name'];
$error_source_plugin_uri = $plugin_info['PluginURI'];
// $error_source_plugin_version = $plugin_info['Version'];
}
}
}
// Get theme name
if ( 'Theme' == $error_source ) {
$theme = wp_get_theme( $error_file_directory );
if ( $theme->exists() ) {
$error_source_theme_dir = $error_file_directory;
$error_source_theme_name = $theme->get( 'Name' );
$error_source_theme_uri = $theme->get( 'ThemeURI' );
// $error_source_theme_version = $theme->get( 'Version' );
} else {
$error_source_theme_name = $error_file_directory;
}
}
}
} else {
$error = __( 'No error message specified...', 'debug-log-manager' );
}
if ( ( false !== strpos( $error, 'PHP Fatal' )) || ( false !== strpos( $error, 'FATAL' ) ) || ( false !== strpos( $error, 'E_ERROR' ) ) ) {
$error_type = __( 'PHP Fatal', 'debug-log-manager' );
$error_details = str_replace( "PHP Fatal error: ", "", $error );
$error_details = str_replace( "PHP Fatal: ", "", $error_details );
$error_details = str_replace( "FATAL ", "", $error_details );
$error_details = str_replace( "E_ERROR: ", "", $error_details );
} elseif ( ( false !== strpos( $error, 'PHP Warning' ) ) || ( false !== strpos( $error, 'E_WARNING' ) ) ) {
$error_type = __( 'PHP Warning', 'debug-log-manager' );
$error_details = str_replace( "PHP Warning: ", "", $error );
$error_details = str_replace( "E_WARNING: ", "", $error_details );
} elseif ( ( false !== strpos( $error, 'PHP Notice' ) ) || ( false !== strpos( $error, 'E_NOTICE' ) ) ) {
$error_type = __( 'PHP Notice', 'debug-log-manager' );
$error_details = str_replace( "PHP Notice: ", "", $error );
$error_details = str_replace( "E_NOTICE: ", "", $error_details );
} elseif ( false !== strpos( $error, 'PHP Deprecated' ) ) {
$error_type = __( 'PHP Deprecated', 'debug-log-manager' );
$error_details = str_replace( "PHP Deprecated: ", "", $error );
} elseif ( ( false !== strpos( $error, 'PHP Parse' ) ) || ( false !== strpos( $error, 'E_PARSE' ) ) ) {
$error_type = __( 'PHP Parse', 'debug-log-manager' );
$error_details = str_replace( "PHP Parse error: ", "", $error );
$error_details = str_replace( "E_PARSE: ", "", $error_details );
} elseif ( false !== strpos( $error, 'EXCEPTION:' ) ) {
$error_type = __( 'PHP Exception', 'debug-log-manager' );
$error_details = str_replace( "EXCEPTION: ", "", $error );
} elseif ( false !== strpos( $error, 'WordPress database error' ) ) {
$error_type = __( 'Database', 'debug-log-manager' );
$error_details = str_replace( "WordPress database error ", "", $error );
} elseif ( false !== strpos( $error, 'JavaScript Error' ) ) {
$error_type = __( 'JavaScript', 'debug-log-manager' );
$error_details = str_replace( "JavaScript Error: ", "", $error );
} else {
$error_type = __( 'Other', 'debug-log-manager' );
$error_details = $error;
if ( $this->is_json( $error_details ) ) {
// For JSON string in error message, originally added via error_log( json_encode( $variable ) )
// This will output said JSON string as well-formated array in the log entries table
$error_details = '' . print_r( json_decode( $error_details, true ), true ) . '
';
}
}
// Append error source, file path and line number info to error details. If core plugin/theme editor is not disabled, link file path to the editor view.
if ( ! empty( $error_source ) ) {
if ( 'WordPress core' == $error_source ) {
$wp_version = get_bloginfo( 'version' );
$file_viewer_url = 'https://github.com/WordPress/wordpress-develop/blob/' . $wp_version . '/src' . $error_file_path;
$error_details = '' . $error_details . '
' . $error_source . '
' . __( 'File', 'debug-log-manager' ) . ': ' . $error_file_path . '
' . __( 'Line', 'debug-log-manager' ) . ': ' . $error_file_line;
} elseif ( 'Theme' == $error_source ) {
if ( ! defined( 'DISALLOW_FILE_EDIT' ) || ( false === constant( 'DISALLOW_FILE_EDIT' ) ) ) {
$file_viewer_url = get_admin_url() . 'theme-editor.php?file=' . urlencode( str_replace( '/wp-content/themes/', '', $error_file_path ) ) . '&theme=' . $error_source_theme_dir;
$error_details = '' . $error_details . '
' . $error_source . ': ' . $error_source_theme_name . '
' . __( 'File', 'debug-log-manager' ) . ': ' . $error_file_path . '
' . __( 'Line', 'debug-log-manager' ) . ': ' . $error_file_line;
}
if ( defined( 'DISALLOW_FILE_EDIT' ) && ( true === constant( 'DISALLOW_FILE_EDIT' ) ) ) {
$error_details = '' . $error_details . '
' . $error_source . ': ' . $error_source_theme_name . '
' . __( 'File', 'debug-log-manager' ) . ': ' . $error_file_path . '
' . __( 'Line', 'debug-log-manager' ) . ': ' . $error_file_line;
}
} elseif ( 'Plugin' == $error_source ) {
if ( ! defined( 'DISALLOW_FILE_EDIT' ) || ( false === constant( 'DISALLOW_FILE_EDIT' ) ) ) {
$file_viewer_url = get_admin_url() . 'plugin-editor.php?file=' . urlencode( str_replace( '/wp-content/plugins/', '', $error_file_path ) ) . '&plugin=' . urlencode( $error_source_plugin_path_file );
$error_details = '' . $error_details . '
' . $error_source . ': ' . $error_source_plugin_name . '
' . __( 'File', 'debug-log-manager' ) . ': ' . $error_file_path . '
' . __( 'Line', 'debug-log-manager' ) . ': ' . $error_file_line;
}
if ( defined( 'DISALLOW_FILE_EDIT' ) && ( true === constant( 'DISALLOW_FILE_EDIT' ) ) ) {
$error_details = '' . $error_details . '
' . $error_source . ': ' . $error_source_plugin_name . '
' . __( 'File', 'debug-log-manager' ) . ': ' . $error_file_path . '
' . __( 'Line', 'debug-log-manager' ) . ': ' . $error_file_line;
}
}
}
// https://www.php.net/manual/en/function.array-search.php#120784
if ( array_search( trim( $error_details ), array_column( $errors_master_list, 'details' ) ) === false ) {
$errors_master_list[] = array(
'type' => $error_type,
'details' => trim( $error_details ),
'occurrences' => array( $timestamp ),
);
} else {
$error_position = array_search( trim( $error_details ), array_column( $errors_master_list, 'details' ) ); // integer
array_push( $errors_master_list[$error_position]['occurrences'], $timestamp );
}
}
return json_encode( $errors_master_list );
}
/**
* Get the latest entries for auto-refresh feature
*
* @since 1.0.0
*/
public function get_latest_entries() {
$errors_master_list = json_decode( $this->get_processed_entries(), true );
$n = 1;
$entries = array();
foreach ( $errors_master_list as $error ) {
if ( function_exists( 'wp_date' ) ) {
$localized_timestamp = wp_date( 'M j, Y - H:i:s', strtotime( $error['occurrences'][0] ) ); // last occurrence
} else {
$localized_timestamp = date_i18n( 'M j, Y - H:i:s', strtotime( $error['occurrences'][0] ) );
}
$occurrence_count = count( $error['occurrences'] );
$entry = array(
$n,
$error['type'],
$error['details'],
$localized_timestamp . '
(' . sprintf( _n( '%s occurrence logged', '%s occurrences logged', $occurrence_count, 'debug-log-manager' ), number_format_i18n( $occurrence_count ) ) . ')',
);
$entries[] = $entry;
$n++;
}
$data = array(
'entries' => $entries,
);
echo json_encode( $data );
}
/**
* Get debug log in data table format
*
* @since 1.0.0
*/
public function get_entries_datatable() {
?>
| # |
|
|
|
get_processed_entries(), true );
$n = 1;
foreach ( $errors_master_list as $error ) {
if ( function_exists( 'wp_date' ) ) {
$localized_timestamp = wp_date( 'M j, Y - H:i:s', strtotime( $error['occurrences'][0] ) ); // last occurrence
} else {
$localized_timestamp = date_i18n( 'M j, Y - H:i:s', strtotime( $error['occurrences'][0] ) );
}
$occurrence_count = count( $error['occurrences'] );
?>
|
|
|
() |
get_processed_entries(), true );
$n = 1;
$entries_to_show = 5;
?>
true, // Add the config if missing.
'raw' => true, // Display value in raw format without quotes.
'normalize' => false, // Normalize config output using WP Coding Standards.
);
$this->wp_config->update( 'constant', 'DISALLOW_FILE_EDIT', 'true', $options );
// Prepare entries from the debug log for the data table
$errors_master_list = json_decode( $this->get_processed_entries(), true );
$n = 1;
$entries = array();
foreach ( $errors_master_list as $error ) {
if ( function_exists( 'wp_date' ) ) {
$localized_timestamp = wp_date( 'M j, Y - H:i:s', strtotime( $error['occurrences'][0] ) ); // last occurrence
} else {
$localized_timestamp = date_i18n( 'M j, Y - H:i:s', strtotime( $error['occurrences'][0] ) );
}
$occurrence_count = count( $error['occurrences'] );
$entry = array(
$n,
$error['type'],
$error['details'],
$localized_timestamp . '
(' . sprintf( _n( '%s occurrence logged', '%s occurrences logged', $occurrence_count, 'debug-log-manager' ), number_format_i18n( $occurrence_count ) ) . ')',
);
$entries[] = $entry;
$n++;
}
// Assemble data to return
$data = array(
'status' => 'disabled', // Plugin/theme editor
'entries' => $entries, // To parse data table with unlinked plugin/theme file paths
);
echo json_encode( $data );
}
/**
* Log javascript errors
*
* @since 1.4.0
*/
public function log_js_errors() {
// Since we are using XHR for the js error logging, JSON data comes in via php://input
$request = json_decode(urldecode(file_get_contents('php://input')), true); // an array
// Verify error content and nonce and then log the JS error
// Source: https://plugins.svn.wordpress.org/lh-javascript-error-log/trunk/lh-javascript-error-log.php
if ( isset( $request['message'] ) && isset( $request['script'] ) && isset( $request['lineNo'] ) && isset( $request['columnNo'] ) && ! empty( $request['nonce'] ) && wp_verify_nonce( $request['nonce'], DLM_SLUG ) ) {
error_log( 'JavaScript Error: ' . $request['message'] . ' in ' . $request['script'] . ' on line ' . $request['lineNo'] . ' column ' . $request['columnNo'] . ' at ' . get_site_url() . $request['pageUrl'] );
} else {
wp_die();
}
}
/**
* Check if a string is valid JSON
*
* @link https://stackoverflow.com/a/6041773
* @since 2.1.0
*/
public function is_json( $string ) {
json_decode( $string );
return json_last_error() === JSON_ERROR_NONE;
}
}