Skip to content

Instantly share code, notes, and snippets.

@bonny
Created April 8, 2025 06:49
Show Gist options
  • Save bonny/bbef255345b03df48c7a4828b7eba758 to your computer and use it in GitHub Desktop.
Save bonny/bbef255345b03df48c7a4828b7eba758 to your computer and use it in GitHub Desktop.
<?php
// phpcs:ignoreFile
namespace Simple_History\ExampleCodeSnippets;
/**
* Support thread:
* https://wordpress.org/support/topic/logging-options-table-activity/
*
* Log when any of the options in an array are updated.
* Uses filter `update_option` to catch the update.
*/
// Register all hooks.
add_action( 'update_option', __NAMESPACE__ . '\log_option_update', 10, 3 );
add_action( 'delete_option', __NAMESPACE__ . '\log_option_delete', 10, 1 );
add_action( 'add_option', __NAMESPACE__ . '\log_option_add', 10, 1 );
/**
* Returns an array of option names to log when updated.
*
* @return array Option names to monitor.
*/
function get_options_to_log() {
return [
'blogname',
'blogdescription',
'admin_email',
];
}
/**
* Gets a simplified backtrace for logging purposes.
*
* @return array Backtrace information including the backtrace summary string.
*/
function get_backtrace_info() {
// Get the full backtrace
$backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 5 );
$trace = array();
// Skip the first two entries which would be this function and the logger function
for ( $i = 2; $i < count( $backtrace ) && $i < 5; $i++ ) {
$item = $backtrace[$i];
$trace[] = array(
'file' => isset( $item['file'] ) ? basename( $item['file'] ) : 'unknown',
'line' => isset( $item['line'] ) ? $item['line'] : 0,
'function' => isset( $item['function'] ) ? $item['function'] : 'unknown',
'class' => isset( $item['class'] ) ? $item['class'] : '',
);
}
// Get a summary using WordPress built-in function
$summary = '';
if ( function_exists( 'wp_debug_backtrace_summary' ) ) {
$summary = wp_debug_backtrace_summary( null, 0, true );
}
return array(
'trace' => $trace,
'summary' => $summary,
);
}
/**
* Fires immediately before an option value is updated.
*
* @param string $option Name of the option to update.
* @param mixed $old_value The old option value.
* @param mixed $value The new option value.
*/
function log_option_update( $option, $old_value, $value ) {
if ( ! in_array( $option, get_options_to_log() ) ) {
return;
}
// Check if SimpleLogger exists before using it.
if ( ! function_exists( '\SimpleLogger' ) ) {
return;
}
// Get backtrace information
$backtrace_info = get_backtrace_info();
// Log the update
\SimpleLogger()->info(
sprintf( 'Option "%s" updated from "%s" to "%s"', $option, $old_value, $value ),
[
'context' => 'options',
'option' => $option,
'old_value' => $old_value,
'new_value' => $value,
'backtrace' => $backtrace_info['trace'],
'backtrace_summary' => $backtrace_info['summary'],
]
);
return $backtrace_info;
}
/**
* Log when an option is deleted.
*
* @param string $option Name of the option to delete.
*/
function log_option_delete( $option ) {
if ( ! in_array( $option, get_options_to_log() ) ) {
return;
}
// Check if SimpleLogger exists before using it.
if ( ! function_exists( '\SimpleLogger' ) ) {
return;
}
// Get backtrace information
$backtrace_info = get_backtrace_info();
// Log the deletion
\SimpleLogger()->info(
sprintf( 'Option "%s" deleted', $option ),
[
'context' => 'options',
'option' => $option,
'backtrace' => $backtrace_info['trace'],
'backtrace_summary' => $backtrace_info['summary'],
]
);
return $backtrace_info;
}
/**
* Log when an option is added.
*
* @param string $option Name of the option to add.
*/
function log_option_add( $option ) {
if ( ! in_array( $option, get_options_to_log() ) ) {
return;
}
// Check if SimpleLogger exists before using it.
if ( ! function_exists( '\SimpleLogger' ) ) {
return;
}
// Get backtrace information
$backtrace_info = get_backtrace_info();
// Log the addition
\SimpleLogger()->info(
sprintf( 'Option "%s" added', $option ),
[
'context' => 'options',
'option' => $option,
'backtrace' => $backtrace_info['trace'],
'backtrace_summary' => $backtrace_info['summary'],
]
);
return $backtrace_info;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment