| 1 |
<?php |
| 2 |
|
| 3 |
use ISC\Plugin; |
| 4 |
|
| 5 |
/** |
| 6 |
* Log events when creating the image source lists |
| 7 |
*/ |
| 8 |
class ISC_Log { |
| 9 |
|
| 10 |
/** |
| 11 |
* Get the name of the log file |
| 12 |
* |
| 13 |
* @return string |
| 14 |
*/ |
| 15 |
public static function get_file_name(): string { |
| 16 |
// Hash the AUTH_KEY to create a unique but persistent filename |
| 17 |
return 'image-source-control_' . hash( 'crc32', AUTH_KEY ) . '.log'; |
| 18 |
} |
| 19 |
|
| 20 |
/** |
| 21 |
* Check the log type |
| 22 |
* |
| 23 |
* @param string $type Type of the log depth. |
| 24 |
* |
| 25 |
* @return bool |
| 26 |
*/ |
| 27 |
public static function is_type( string $type ): bool { |
| 28 |
return self::get_type() === $type; |
| 29 |
} |
| 30 |
|
| 31 |
/** |
| 32 |
* Return the log type |
| 33 |
* |
| 34 |
* Type of the log depth |
| 35 |
* - default |
| 36 |
* - content - logs the content |
| 37 |
* - backtrace - logs the function backtrace |
| 38 |
*/ |
| 39 |
private static function get_type(): string { |
| 40 |
$accepted_types = [ 'default', 'content', 'backtrace' ]; |
| 41 |
|
| 42 |
// phpcs:ignore WordPress.Security.NonceVerification |
| 43 |
$isc_log = sanitize_key( wp_unslash( $_GET['isc-log'] ?? '' ) ); |
| 44 |
|
| 45 |
return in_array( $isc_log, $accepted_types, true ) ? $isc_log : 'default'; |
| 46 |
} |
| 47 |
|
| 48 |
/** |
| 49 |
* Check if the log feature is enabled |
| 50 |
* |
| 51 |
* @param array $args optional arguments. |
| 52 |
* |
| 53 |
* @return bool |
| 54 |
*/ |
| 55 |
public static function enabled( array $args = [] ): bool { |
| 56 |
// true if the Debug Log option is enabled and either ?isc-log is set or force_without_parameter is provided |
| 57 |
// phpcs:ignore WordPress.Security.NonceVerification |
| 58 |
return ( ! empty( Plugin::get_options()['enable_log'] ) && ( isset( $_REQUEST['isc-log'] ) || ! empty( $args['force_without_parameter'] ) ) ); |
| 59 |
} |
| 60 |
|
| 61 |
/** |
| 62 |
* Log image source extraction into a separate file |
| 63 |
* can be used for debugging |
| 64 |
* set define( 'ISC_LOG', true ); in wp-config.php to enable it |
| 65 |
* |
| 66 |
* @param string|array $message log message. Arrays will be converted into strings. |
| 67 |
* @param array $args optional arguments. |
| 68 |
*/ |
| 69 |
public static function log( $message = '', array $args = [] ) { |
| 70 |
|
| 71 |
if ( ! self::enabled( $args ) || null === $message ) { |
| 72 |
return; |
| 73 |
} |
| 74 |
|
| 75 |
// get the current function name |
| 76 |
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace |
| 77 |
$backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2 ); |
| 78 |
$method = sprintf( '%s:%s', $backtrace[1]['class'] ?? '', $backtrace[1]['function'] ); |
| 79 |
|
| 80 |
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r |
| 81 |
$message = is_array( $message ) ? print_r( $message, true ) : $message; |
| 82 |
|
| 83 |
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log |
| 84 |
error_log( '[' . date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) ) . "] $method: $message\n", 3, self::get_log_file_path() ); |
| 85 |
} |
| 86 |
|
| 87 |
/** |
| 88 |
* Log the current plugin settings on request. |
| 89 |
*/ |
| 90 |
public static function maybe_log_settings() { |
| 91 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 92 |
if ( ! self::enabled() || ! isset( $_GET['isc-settings'] ) ) { |
| 93 |
return; |
| 94 |
} |
| 95 |
|
| 96 |
$options = Plugin::get_options(); |
| 97 |
unset( $options['license-key'] ); |
| 98 |
|
| 99 |
self::log( '=== ISC SETTINGS ===' ); |
| 100 |
self::log( $options ); |
| 101 |
|
| 102 |
$license_status = get_option( 'isc_license_status', '' ); |
| 103 |
|
| 104 |
if ( '' === $license_status || false === $license_status || null === $license_status ) { |
| 105 |
$license_status = '-'; |
| 106 |
} |
| 107 |
|
| 108 |
self::log( 'isc_license_status: ' . $license_status ); |
| 109 |
} |
| 110 |
|
| 111 |
/** |
| 112 |
* Delete the log file without any conditions |
| 113 |
*/ |
| 114 |
public static function delete_log_file() { |
| 115 |
wp_delete_file( self::get_log_file_path() ); |
| 116 |
} |
| 117 |
|
| 118 |
/** |
| 119 |
* Get the URL to the log file |
| 120 |
* |
| 121 |
* @return string |
| 122 |
*/ |
| 123 |
public static function get_log_file_url(): string { |
| 124 |
$upload_dir = wp_upload_dir(); |
| 125 |
return $upload_dir['baseurl'] . '/' . self::get_file_name(); |
| 126 |
} |
| 127 |
|
| 128 |
/** |
| 129 |
* Get the path to the log file |
| 130 |
* |
| 131 |
* @return string |
| 132 |
*/ |
| 133 |
public static function get_log_file_path(): string { |
| 134 |
$upload_dir = wp_upload_dir(); |
| 135 |
return $upload_dir['basedir'] . '/' . self::get_file_name(); |
| 136 |
} |
| 137 |
|
| 138 |
/** |
| 139 |
* Check if the log file exists |
| 140 |
* |
| 141 |
* @return bool |
| 142 |
*/ |
| 143 |
public static function log_file_exists(): bool { |
| 144 |
return file_exists( self::get_log_file_path() ); |
| 145 |
} |
| 146 |
|
| 147 |
/** |
| 148 |
* Return true if internal caches should be ignored |
| 149 |
* only works in combination with an activated log |
| 150 |
*/ |
| 151 |
public static function ignore_caches(): bool { |
| 152 |
// phpcs:ignore WordPress.Security.NonceVerification |
| 153 |
return self::enabled() && isset( $_GET['isc-ignore-cache'] ); |
| 154 |
} |
| 155 |
|
| 156 |
/** |
| 157 |
* Return true if existing indexer data (Pro) should be ignored |
| 158 |
* only works in combination with an activated log |
| 159 |
*/ |
| 160 |
public static function ignore_index(): bool { |
| 161 |
// phpcs:ignore WordPress.Security.NonceVerification |
| 162 |
return self::enabled() && isset( $_GET['isc-ignore-index'] ); |
| 163 |
} |
| 164 |
|
| 165 |
/** |
| 166 |
* Return true if the log should be cleared automatically before writing |
| 167 |
*/ |
| 168 |
public static function clear_log(): bool { |
| 169 |
// phpcs:ignore WordPress.Security.NonceVerification |
| 170 |
return self::enabled() && isset( $_GET['isc-clear-log'] ); |
| 171 |
} |
| 172 |
|
| 173 |
/** |
| 174 |
* Print a concise stack trace in the log |
| 175 |
*/ |
| 176 |
public static function log_stack_trace() { |
| 177 |
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace |
| 178 |
$backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); |
| 179 |
|
| 180 |
// remove the "args" key to reduce the output size |
| 181 |
foreach ( $backtrace as $key => $trace ) { |
| 182 |
unset( $backtrace[ $key ]['args'] ); |
| 183 |
} |
| 184 |
|
| 185 |
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r |
| 186 |
self::log( 'Stack trace: ' . "\n - " . print_r( $backtrace, true ) ); |
| 187 |
} |
| 188 |
} |
| 189 |
|