267 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			267 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Plugin logging class.
 | |
|  *
 | |
|  * @package   OpenID_Connect_Generic
 | |
|  * @category  Logging
 | |
|  * @author    Jonathan Daggerhart <jonathan@daggerhart.com>
 | |
|  * @copyright 2015-2023 daggerhart
 | |
|  * @license   http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * OpenID_Connect_Generic_Option_Logger class.
 | |
|  *
 | |
|  * Simple class for logging messages to the options table.
 | |
|  *
 | |
|  * @package  OpenID_Connect_Generic
 | |
|  * @category Logging
 | |
|  */
 | |
| class OpenID_Connect_Generic_Option_Logger {
 | |
| 
 | |
| 	/**
 | |
| 	 * Thw WordPress option name/key.
 | |
| 	 *
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	const OPTION_NAME = 'openid-connect-generic-logs';
 | |
| 
 | |
| 	/**
 | |
| 	 * The default message type.
 | |
| 	 *
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	private $default_message_type = 'none';
 | |
| 
 | |
| 	/**
 | |
| 	 * The number of items to keep in the log.
 | |
| 	 *
 | |
| 	 * @var int
 | |
| 	 */
 | |
| 	private $log_limit = 1000;
 | |
| 
 | |
| 	/**
 | |
| 	 * Whether or not logging is enabled.
 | |
| 	 *
 | |
| 	 * @var bool
 | |
| 	 */
 | |
| 	private $logging_enabled = true;
 | |
| 
 | |
| 	/**
 | |
| 	 * Internal cache of logs.
 | |
| 	 *
 | |
| 	 * @var array
 | |
| 	 */
 | |
| 	private $logs;
 | |
| 
 | |
| 	/**
 | |
| 	 * Setup the logger according to the needs of the instance.
 | |
| 	 *
 | |
| 	 * @param string|null    $default_message_type The log message type.
 | |
| 	 * @param bool|TRUE|null $logging_enabled      Whether logging is enabled.
 | |
| 	 * @param int|null       $log_limit            The log entry limit.
 | |
| 	 */
 | |
| 	public function __construct( $default_message_type = null, $logging_enabled = null, $log_limit = null ) {
 | |
| 		if ( ! is_null( $default_message_type ) ) {
 | |
| 			$this->default_message_type = $default_message_type;
 | |
| 		}
 | |
| 		if ( ! is_null( $logging_enabled ) ) {
 | |
| 			$this->logging_enabled = boolval( $logging_enabled );
 | |
| 		}
 | |
| 		if ( ! is_null( $log_limit ) ) {
 | |
| 			$this->log_limit = intval( $log_limit );
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Save an array of data to the logs.
 | |
| 	 *
 | |
| 	 * @param string|array<string, string>|WP_Error $data            The log message data.
 | |
| 	 * @param string|null                           $type            The log message type.
 | |
| 	 * @param float|null                            $processing_time Optional event processing time.
 | |
| 	 * @param int|null                              $time            The log message timestamp (default: time()).
 | |
| 	 * @param int|null                              $user_ID         The current WordPress user ID (default: get_current_user_id()).
 | |
| 	 * @param string|null                           $request_uri     The related HTTP request URI (default: $_SERVER['REQUEST_URI']|'Unknown').
 | |
| 	 *
 | |
| 	 * @return bool
 | |
| 	 */
 | |
| 	public function log( $data, $type = null, $processing_time = null, $time = null, $user_ID = null, $request_uri = null ) {
 | |
| 		if ( boolval( $this->logging_enabled ) ) {
 | |
| 			$logs = $this->get_logs();
 | |
| 			$logs[] = $this->make_message( $data, $type, $processing_time, $time, $user_ID, $request_uri );
 | |
| 			$logs = $this->upkeep_logs( $logs );
 | |
| 			return $this->save_logs( $logs );
 | |
| 		}
 | |
| 
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve all log messages.
 | |
| 	 *
 | |
| 	 * @return array
 | |
| 	 */
 | |
| 	public function get_logs() {
 | |
| 		if ( empty( $this->logs ) ) {
 | |
| 			$this->logs = get_option( self::OPTION_NAME, array() );
 | |
| 		}
 | |
| 
 | |
| 		// Call the upkeep_logs function to give the appearance that logs have been reduced to the $this->log_limit.
 | |
| 		// The logs are actually limited during a logging action but the logger isn't available during a simple settings update.
 | |
| 		return $this->upkeep_logs( $this->logs );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Get the name of the option where this log is stored.
 | |
| 	 *
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	public function get_option_name() {
 | |
| 		return self::OPTION_NAME;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Create a message array containing the data and other information.
 | |
| 	 *
 | |
| 	 * @param string|array<string, string>|WP_Error $data            The log message data.
 | |
| 	 * @param string|null                           $type            The log message type.
 | |
| 	 * @param float|null                            $processing_time Optional event processing time.
 | |
| 	 * @param int|null                              $time            The log message timestamp (default: time()).
 | |
| 	 * @param int|null                              $user_ID         The current WordPress user ID (default: get_current_user_id()).
 | |
| 	 * @param string|null                           $request_uri     The related HTTP request URI (default: $_SERVER['REQUEST_URI']|'Unknown').
 | |
| 	 *
 | |
| 	 * @return array
 | |
| 	 */
 | |
| 	private function make_message( $data, $type, $processing_time, $time, $user_ID, $request_uri ) {
 | |
| 		// Determine the type of message.
 | |
| 		if ( empty( $type ) ) {
 | |
| 			$type = $this->default_message_type;
 | |
| 
 | |
| 			if ( is_array( $data ) && isset( $data['type'] ) ) {
 | |
| 				$type = $data['type'];
 | |
| 				unset( $data['type'] );
 | |
| 			}
 | |
| 
 | |
| 			if ( is_wp_error( $data ) ) {
 | |
| 				$type = $data->get_error_code();
 | |
| 				$data = $data->get_error_message( $type );
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		if ( empty( $request_uri ) ) {
 | |
| 			$request_uri = ( ! empty( $_SERVER['REQUEST_URI'] ) ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : 'Unknown';
 | |
| 			$request_uri = preg_replace( '/code=([^&]+)/i', 'code=', $request_uri );
 | |
| 		}
 | |
| 
 | |
| 		// Construct the message.
 | |
| 		$message = array(
 | |
| 			'type'            => $type,
 | |
| 			'time'            => ! empty( $time ) ? $time : time(),
 | |
| 			'user_ID'         => ! is_null( $user_ID ) ? $user_ID : get_current_user_id(),
 | |
| 			'uri'             => $request_uri,
 | |
| 			'data'            => $data,
 | |
| 			'processing_time' => $processing_time,
 | |
| 		);
 | |
| 
 | |
| 		return $message;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Keep the log count under the limit.
 | |
| 	 *
 | |
| 	 * @param array $logs The plugin logs.
 | |
| 	 *
 | |
| 	 * @return array
 | |
| 	 */
 | |
| 	private function upkeep_logs( $logs ) {
 | |
| 		$items_to_remove = count( $logs ) - $this->log_limit;
 | |
| 
 | |
| 		if ( $items_to_remove > 0 ) {
 | |
| 			// Only keep the last $log_limit messages from the end.
 | |
| 			$logs = array_slice( $logs, $items_to_remove );
 | |
| 		}
 | |
| 
 | |
| 		return $logs;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Save the log messages.
 | |
| 	 *
 | |
| 	 * @param array $logs The array of log messages.
 | |
| 	 *
 | |
| 	 * @return bool
 | |
| 	 */
 | |
| 	private function save_logs( $logs ) {
 | |
| 		// Save the logs.
 | |
| 		$this->logs = $logs;
 | |
| 		return update_option( self::OPTION_NAME, $logs, false );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Clear all log messages.
 | |
| 	 *
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public function clear_logs() {
 | |
| 		$this->save_logs( array() );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Get a simple html table of all the logs.
 | |
| 	 *
 | |
| 	 * @param array $logs The array of log messages.
 | |
| 	 *
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	public function get_logs_table( $logs = array() ) {
 | |
| 		if ( empty( $logs ) ) {
 | |
| 			$logs = $this->get_logs();
 | |
| 		}
 | |
| 		$logs = array_reverse( $logs );
 | |
| 
 | |
| 		ini_set( 'xdebug.var_display_max_depth', '-1' );
 | |
| 
 | |
| 		ob_start();
 | |
| 		?>
 | |
| 		<table id="logger-table" class="wp-list-table widefat fixed striped posts">
 | |
| 			<thead>
 | |
| 				<th class="col-details"><?php esc_html_e( 'Details', 'daggerhart-openid-connect-generic' ); ?></th>
 | |
| 				<th class="col-data"><?php esc_html_e( 'Data', 'daggerhart-openid-connect-generic' ); ?></th>
 | |
| 			</thead>
 | |
| 			<tbody>
 | |
| 			<?php foreach ( $logs as $log ) { ?>
 | |
| 				<tr>
 | |
| 					<td class="col-details">
 | |
| 						<div>
 | |
| 							<label><?php esc_html_e( 'Date', 'daggerhart-openid-connect-generic' ); ?></label>
 | |
| 							<?php print esc_html( ! empty( $log['time'] ) ? gmdate( 'Y-m-d H:i:s', $log['time'] ) : '' ); ?>
 | |
| 						</div>
 | |
| 						<div>
 | |
| 							<label><?php esc_html_e( 'Type', 'daggerhart-openid-connect-generic' ); ?></label>
 | |
| 							<?php print esc_html( ! empty( $log['type'] ) ? $log['type'] : '' ); ?>
 | |
| 						</div>
 | |
| 						<div>
 | |
| 							<label><?php esc_html_e( 'User', 'daggerhart-openid-connect-generic' ); ?>: </label>
 | |
| 							<?php print esc_html( ( get_userdata( $log['user_ID'] ) ) ? get_userdata( $log['user_ID'] )->user_login : '0' ); ?>
 | |
| 						</div>
 | |
| 						<div>
 | |
| 							<label><?php esc_html_e( 'URI ', 'daggerhart-openid-connect-generic' ); ?>: </label>
 | |
| 							<?php print esc_url( ! empty( $log['uri'] ) ? $log['uri'] : '' ); ?>
 | |
| 						</div>
 | |
| 						<div>
 | |
| 							<label><?php esc_html_e( 'Response Time (sec)', 'daggerhart-openid-connect-generic' ); ?></label>
 | |
| 							<?php print esc_html( ! empty( $log['response_time'] ) ? $log['response_time'] : '' ); ?>
 | |
| 						</div>
 | |
| 					</td>
 | |
| 					<td class="col-data"><pre><?php var_dump( ! empty( $log['data'] ) ? $log['data'] : '' ); ?></pre></td>
 | |
| 				</tr>
 | |
| 			<?php } ?>
 | |
| 			</tbody>
 | |
| 		</table>
 | |
| 		<?php
 | |
| 		$output = ob_get_clean();
 | |
| 
 | |
| 		return $output;
 | |
| 	}
 | |
| }
 |