Skip to content

Instantly share code, notes, and snippets.

@devkabir
Last active October 10, 2024 17:25
Show Gist options
  • Select an option

  • Save devkabir/78ae9d52ce6faa6f639292ebe48eae17 to your computer and use it in GitHub Desktop.

Select an option

Save devkabir/78ae9d52ce6faa6f639292ebe48eae17 to your computer and use it in GitHub Desktop.
Custom Logger and Mock HTTP Interceptor for WordPress Developers
<?php
/**
* Plugin Name: Custom Logger and Mock HTTP Interceptor
* Description: Writes logs and provides mock HTTP responses for specific URLs.
* Version: 1.0
* Author: Your Name
*/
/**
* Writes a log message to a specified directory.
*
* @param mixed $message The message to be logged.
* @param bool $trace Whether to log the backtrace.
* @param string $dir The directory where the log file will be written.
* @return void
*/
function write_log( $message, $trace = false, string $dir = WP_CONTENT_DIR ) {
$log_file = $dir . '/wp-debugger.log';
if ( file_exists( $log_file ) && filesize( $log_file ) > 1 * 1024 * 1024 ) {
file_put_contents( $log_file, '' );
}
$message = format_message( $message );
error_log( $message . PHP_EOL, 3, $log_file ); // phpcs:ignore
if ( $trace ) {
error_log( format_message( array_column( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), 'file', 'function' ) ) . PHP_EOL, 3, $log_file ); // phpcs:ignore
}
}
/**
* Formats a message with the current timestamp.
*
* @param mixed $message The message to be formatted.
* @return string The formatted message with the timestamp.
*/
function format_message( $message ) {
if ( is_array( $message ) || is_object( $message ) || is_iterable( $message ) ) {
$message = wp_json_encode( $message, 128 );
} else {
$decoded = json_decode( $message, true );
if ( JSON_ERROR_NONE === json_last_error() && is_array( $decoded ) ) {
$message = wp_json_encode( $decoded, 128 );
}
}
return gmdate( 'Y-m-d H:i:s' ) . ' - ' . $message;
}
/**
* Writes the current filter hook to a log file.
*
* @global string[] $wp_current_filter Stores the list of current filters with the current one last
* @return void
*/
function write_hook() {
global $wp_current_filter;
write_log( implode( ' > ', $wp_current_filter ) );
}
/**
* Writes the last SQL query error, query, and result to a log file.
*
* @param string $dir The directory where the log file will be written.
* @return void
*/
function write_query( string $dir = WP_CONTENT_DIR ) {
global $wpdb;
write_log(
array(
'error' => $wpdb->last_error,
'query' => $wpdb->last_query,
'result' => $wpdb->last_result,
),
false,
$dir
);
}
// Check if the plugin should be enabled based on the constant in wp-config.php
if ( defined( 'ENABLE_MOCK_HTTP_PLUGIN' ) && ENABLE_MOCK_HTTP_PLUGIN ) {
/**
* Intercepts outgoing HTTP requests and serves mock responses for specified URLs.
* Stores POST request data in a transient for testing purposes.
*
* @param bool|array $preempt The preemptive response to return if available.
* @param array $args Array of HTTP request arguments, including method and body.
* @param string $url The URL of the outgoing HTTP request.
*
* @return array|bool If a matching URL is found in the predefined mock responses, an
* associative array containing mock response details is returned.
* Otherwise, `false` is returned, allowing the original request to proceed.
*/
function serve_mock_http_response( $preempt, $args, $url ) {
if ( strpos( $url, 'https://wpmudev.com/api/' ) === false ) {
return $preempt;
}
// Ensure the mock logs directory exists.
$mock_logs_dir = WP_CONTENT_DIR . '/mock-logs';
if ( ! is_dir( $mock_logs_dir ) ) {
wp_mkdir_p( $mock_logs_dir );
}
write_log( $url, false, $mock_logs_dir );
$mock_urls = array(
'https://api.example.com/v1/data' => json_encode(
array(
'message' => 'Mock Data Response',
'status' => 'success',
)
),
);
foreach ( $mock_urls as $mock_url => $mock_response ) {
if ( strpos( $url, $mock_url ) !== false ) {
if ( isset( $args['method'] ) && strtoupper( $args['method'] ) === 'POST' && isset( $args['body'] ) ) {
$post_data = wp_parse_args( $args['body'] );
$transient_key = 'mock_post_data_' . md5( $url . $args['method'] );
set_transient( $transient_key, $post_data, 60 * 60 ); // Store for 1 hour
}
return array(
'body' => $mock_response,
'response' => array(
'code' => 200,
'message' => 'OK',
),
'headers' => array(),
'cookies' => array(),
'http_response' => null,
);
}
}
return $preempt;
}
add_filter( 'pre_http_request', 'serve_mock_http_response', 10, 3 );
}
# Install Custom Logger and Mock HTTP Interceptor Plugin
This PowerShell script will install the "Custom Logger and Mock HTTP Interceptor" mu-plugin into your WordPress installation.
## Prerequisites
- Ensure you have the correct permissions to write to the `wp-content` directory.
- PowerShell 5.0 or later.
## Installation
1. Copy the script below to a `.ps1` file (e.g., `install-mu-plugin.ps1`).
2. Open PowerShell and navigate to the directory where the script is saved.
3. Run the script using the command: `.\install-mu-plugin.ps1`.
### PowerShell Script
```powershell
# Define the path to the wp-content directory
$wpContentDir = "C:\path\to\your\wordpress\wp-content" # Change this to your WordPress installation path
# Define the path to the mu-plugins directory
$muPluginsDir = Join-Path -Path $wpContentDir -ChildPath "mu-plugins"
# Check if the mu-plugins directory exists, create it if it doesn't
if (-not (Test-Path -Path $muPluginsDir)) {
New-Item -ItemType Directory -Path $muPluginsDir
}
# Define the plugin file path
$pluginFilePath = Join-Path -Path $muPluginsDir -ChildPath "custom-logger.php"
# Define the plugin code
$pluginCode = @'
<?php
/**
* Plugin Name: Custom Logger and Mock HTTP Interceptor
* Description: Writes logs and provides mock HTTP responses for specific URLs.
* Version: 1.0
* Author: Your Name
*/
/**
* Writes a log message to a specified directory.
*
* @param mixed $message The message to be logged.
* @param bool $trace Whether to log the backtrace.
* @param string $dir The directory where the log file will be written.
* @return void
*/
function write_log( $message, $trace = false, string $dir = WP_CONTENT_DIR ) {
$message = format_message( $message );
error_log( $message . PHP_EOL, 3, $dir . '/wp-debugger.log' ); // phpcs:ignore
if ( $trace ) {
error_log( format_message( array_column( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), 'file', 'function' ) ) . PHP_EOL, 3, $dir . '/wp-debugger.log' ); // phpcs:ignore
}
}
/**
* Formats a message with the current timestamp.
*
* @param mixed $message The message to be formatted.
* @return string The formatted message with the timestamp.
*/
function format_message( $message ) {
if ( is_array( $message ) || is_object( $message ) || is_iterable( $message ) ) {
$message = wp_json_encode( $message, 128 );
} else {
$decoded = json_decode( $message, true );
if ( JSON_ERROR_NONE === json_last_error() && is_array( $decoded ) ) {
$message = wp_json_encode( $decoded, 128 );
}
}
return gmdate( 'Y-m-d H:i:s' ) . ' - ' . $message;
}
/**
* Writes the last SQL query error, query, and result to a log file.
*
* @param string $dir The directory where the log file will be written.
* @return void
*/
function write_query( string $dir = WP_CONTENT_DIR ) {
global $wpdb;
write_log(
array(
'error' => $wpdb->last_error,
'query' => $wpdb->last_query,
'result' => $wpdb->last_result,
),
false,
$dir
);
}
// Check if the plugin should be enabled based on the constant in wp-config.php
if ( defined( 'ENABLE_MOCK_HTTP_PLUGIN' ) && ENABLE_MOCK_HTTP_PLUGIN ) {
/**
* Intercepts outgoing HTTP requests and serves mock responses for specified URLs.
* Stores POST request data in a transient for testing purposes.
*
* @param bool|array $preempt The preemptive response to return if available.
* @param array $args Array of HTTP request arguments, including method and body.
* @param string $url The URL of the outgoing HTTP request.
*
* @return array|bool If a matching URL is found in the predefined mock responses, an
* associative array containing mock response details is returned.
* Otherwise, `false` is returned, allowing the original request to proceed.
*/
function serve_mock_http_response( $preempt, $args, $url ) {
$mock_urls = array(
'https://api.example.com/v1/data' => json_encode( array( 'message' => 'Mock Data Response', 'status' => 'success' ) ),
'https://api.example.com/v1/user' => json_encode( array( 'user' => 'John Doe', 'id' => 1234 ) ),
'https://api.example.com/v1/error' => json_encode( array( 'error' => 'This is a mock error response' ) ),
);
foreach ( $mock_urls as $mock_url => $mock_response ) {
if ( strpos( $url, $mock_url ) !== false ) {
if ( isset( $args['method'] ) && strtoupper( $args['method'] ) === 'POST' && isset( $args['body'] ) ) {
$post_data = wp_parse_args( $args['body'] );
$transient_key = 'mock_post_data_' . md5( $url . $args['method'] );
set_transient( $transient_key, $post_data, 60 * 60 ); // Store for 1 hour
}
return array(
'body' => $mock_response,
'response' => array(
'code' => 200,
'message' => 'OK',
),
'headers' => array(),
'cookies' => array(),
'http_response' => null,
);
}
}
return false;
}
add_filter( 'pre_http_request', 'serve_mock_http_response', 10, 3 );
}
'@
# Write the plugin code to the plugin file
Set-Content -Path $pluginFilePath -Value $pluginCode -Force
Write-Host "Mu-plugin installed successfully at $pluginFilePath"
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment