38217-vm/wp-content/plugins/mainwp/class/class-mainwp-logger.php
2026-02-05 17:08:59 +03:00

994 lines
32 KiB
PHP

<?php
/**
* MainWP Logger
*
* For custom read/write logging file.
*
* @package MainWP/Dashboard
*/
namespace MainWP\Dashboard;
/**
* Class MainWP_Logger
*
* @package MainWP\Dashboard
*/
class MainWP_Logger { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
// phpcs:disable WordPress.WP.AlternativeFunctions -- for custom read/write logging file.
const UPDATE_CHECK_LOG_PRIORITY = 10;
const EXECUTION_TIME_LOG_PRIORITY = 15;
const LOGS_AUTO_PURGE_LOG_PRIORITY = 16;
const LOGS_REGULAR_SCHEDULE = 18;
const DEBUG_UPDATES_SCHEDULE = 19;
const COST_TRACKER_LOG_PRIORITY = 20230112;
const API_BACKUPS_LOG_PRIORITY = 20240130;
const CONNECT_LOG_PRIORITY = 20241001;
const UPTIME_CHECK_LOG_PRIORITY = 20241017;
const UPTIME_NOTICE_LOG_PRIORITY = 202411106;
const DISABLED = - 1;
const LOG = 0;
const WARNING = 1;
const INFO = 2;
const DEBUG = 3;
const LOG_COLOR = '#999999';
const DEBUG_COLOR = '#666666';
const INFO_COLOR = '#276f86';
const WARNING_COLOR = '#9f3a38;';
/**
* Private variable to hold time start.
*
* @var int
*/
private static $time_start = null;
/**
* Private varibale to hold the log file prefix.
*
* @var string Default 'mainwp'
*/
private $logFileNamePrefix = 'mainwp';
/**
* Private varibale to hold the log file suffix.
*
* @var string Default '.log'
*/
private $logFileNameSuffix = '.log';
/**
* Private varibale to hold the log file max size.
*
* @var int Default 0.5
*/
private $logMaxMB = 0.5;
/**
* Private varibale to hold the log file date format.
*
* @var string Default 'Y-m-d H:i:s'
*/
private $logDateFormat = 'Y-m-d H:i:s';
/**
* Private varibale to hold the log file output directory.
*
* @var mixed Default null
*/
private $logDirectory = null;
/**
* Private varibale to hold the log file priotrity.
*
* @var string Disabled
*/
private $logPriority = self::DISABLED;
/**
* Private varibale to hold the log Specific priotrity.
*
* @var string Disabled
*/
private $logSpecific = 0;
/**
* Private varibale to hold the auto enable logging actions.
*
* @var array Auto enable logging.
*/
private $autoEnableLoggingActions = array();
/**
* Private static varibale to hold the instance.
*
* @var mixed Default null
*/
private static $instance = null;
/**
* Method instance()
*
* Returns new MainWP_Logger instance.
*
* @return self MainWP_Logger
*
* @uses \MainWP\Dashboard\MainWP_Logger
*/
public static function instance() {
if ( null === static::$instance ) {
static::$instance = new self();
}
return static::$instance;
}
/**
* MainWP_Logger constructor.
*
* Run each time the class is called.
*
* @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir()
*/
private function __construct() {
add_action( 'init', array( $this, 'init' ) ); // Fix the issue where database tables do not exist.
$enabled = $this->get_log_status();
$specific = $this->get_log_specific();
$enabled = apply_filters( 'mainwp_log_status', $enabled );
$specific = apply_filters( 'mainwp_log_specific', $specific );
$this->set_log_priority( $enabled, $specific );
$this->autoEnableLoggingActions = array(
static::CONNECT_LOG_PRIORITY,
);
}
/**
* Method init.
*/
public function init() {
$enabled = get_option( 'mainwp_actionlogs' );
if ( false === $enabled && ! get_transient( 'mainwp_transient_action_logs' ) ) {
$sites_count = MainWP_DB::instance()->get_websites_count();
if ( empty( $sites_count ) ) {
set_transient( 'mainwp_transient_action_logs', true, 2 * WEEK_IN_SECONDS );
}
}
}
/**
* Method set_log_priority()
*
* Sets the log priority.
*
* @param mixed $logPriority Log priority value.
* @param mixed $spec_log Specific log.
*/
public function set_log_priority( $logPriority, $spec_log = 0 ) {
$this->logPriority = (int) $logPriority;
$this->logSpecific = (int) $spec_log; // 1 - specific log, 0 - not specific log.
}
/**
* Method enable_log_priority()
*
* Sets the log priority.
*
* @param mixed $logPriority Log priority value.
* @param mixed $spec_log Specific log.
*/
public function enable_log_priority( $logPriority, $spec_log = 1 ) {
$spec_log = $spec_log ? 1 : 0;
$logPriority = intval( $logPriority );
MainWP_Utility::update_option( 'mainwp_specific_logs', $spec_log );
MainWP_Utility::update_option( 'mainwp_actionlogs', $logPriority );
MainWP_Utility::update_option( 'mainwp_actionlogs_enabled_timestamp', time() );
$this->log_action( 'Action logs set to: ' . $this->get_log_text( $logPriority ), ( $spec_log ? $logPriority : static::LOG ), 2, true );
$this->set_log_priority( $logPriority, $spec_log );
}
/**
* Method get_log_status()
*
* Get log status.
*
* @return mixed $enabled log status.
*/
public function get_log_status() {
$enabled = get_option( 'mainwp_actionlogs' );
if ( false === $enabled ) {
if ( get_transient( 'mainwp_transient_action_logs' ) ) {
$enabled = self::DEBUG;
} else {
$enabled = static::DISABLED;
}
}
return $enabled;
}
/**
* Method get_log_specific()
*
* Get log specific status.
*
* @return mixed $enabled log status.
*/
public function get_log_specific() {
return get_option( 'mainwp_specific_logs', 0 );
}
/**
* Method get_log_type_info()
*
* Get log type info.
*
* @param int $type Log type value.
* @param int $logcolor Log color value.
*
* @return int $currentColor log color code.
*/
public function get_log_type_info( $type, $logcolor ) {
$currentColor = '';
$prefix = '';
if ( static::DEBUG === $type || static::DEBUG === $logcolor ) {
$currentColor = static::DEBUG_COLOR;
$prefix = '[DEBUG]';
} elseif ( static::INFO === $type || static::INFO === $logcolor ) {
$currentColor = static::INFO_COLOR;
$prefix = '[INFO]';
} elseif ( static::WARNING === $type || static::WARNING === $logcolor ) {
$currentColor = static::WARNING_COLOR;
$prefix = '[WARNING]';
} elseif ( static::LOG === $type || static::LOG === $logcolor ) {
$currentColor = static::LOG_COLOR;
$prefix = '[LOG]';
}
return array(
'log_color' => $currentColor,
'log_prefix' => $prefix,
);
}
/**
* Method debug()
*
* Grab debug.
*
* @param string $text Debug message text.
*
* @return string Log debug message.
*/
public function debug( $text ) {
return $this->log( $text, static::DEBUG );
}
/**
* Method info()
*
* Grab info.
*
* @param string $text Info message text.
*
* @return string Log info message.
*/
public function info( $text ) {
return $this->log( $text, static::INFO );
}
/**
* Method warning()
*
* Grab warning information.
*
* @param string $text Warning message text.
*
* @return string Log warning message.
*/
public function warning( $text ) {
return $this->log( $text, static::WARNING );
}
/**
* Method actions()
*
* Grab actions information.
*
* @param string $text Warning message text.
* @param int $priority priority message.
* @param int $log_color Set color: 0 - LOG, 1 - WARNING, 2 - INFO, 3- DEBUG.
* @param bool $forced forced logging.
*
* @return string Log warning message.
*/
public function log_action( $text, $priority, $log_color = 0, $forced = false ) {
return $this->log( $text, $priority, $log_color, $forced );
}
/**
* Method log_events().
*
* @param string $event_name Event name.
* @param string $text Log update check.
*/
public function log_events( $event_name, $text = '' ) {
switch ( $event_name ) {
case 'update-check':
$this->log_action( '[Update Checks] :: ' . $text, static::UPDATE_CHECK_LOG_PRIORITY );
break;
case 'regular-schedule':
$this->log_action( '[Regular Schedule] :: ' . $text, static::LOGS_REGULAR_SCHEDULE );
break;
case 'debug-updates-crons':
$this->log_action( '[Debug updates crons] :: ' . $text, static::DEBUG_UPDATES_SCHEDULE );
break;
default:
break;
}
}
/**
* Method log_update_check().
*
* @param string $text Log update check.
*/
public function log_update_check( $text = '' ) {
$this->log_action( $text, static::UPDATE_CHECK_LOG_PRIORITY );
}
/**
* Method log_update_check().
*
* @param string $text Log update check.
*/
public function log_uptime_check( $text = '' ) {
$this->log_action( $text, static::UPTIME_CHECK_LOG_PRIORITY );
}
/**
* Method log_uptime_notice().
*
* @param string $text Log update check.
*/
public function log_uptime_notice( $text = '' ) {
$this->log_action( $text, static::UPTIME_NOTICE_LOG_PRIORITY );
}
/**
* Method debug_for_website()
*
* Grab website debug and info.
*
* @param object $website Child site object.
* @param string $action Performed action.
* @param string $message Debug message.
*
* @return mixed Website debug info.
*
* @uses \MainWP\Dashboard\MainWP_Utility::get_nice_url()
*/
public function debug_for_website( $website, $action, $message ) {
if ( empty( $website ) ) {
return $this->log( '[-] [-] ::' . $action . ':: ' . $message, static::DEBUG );
}
return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, static::DEBUG, 0, false, $website );
}
/**
* Method info_for_website()
*
* Grab Website Info.
*
* @param object $website Child site object.
* @param string $action Performed action.
* @param string $message Info message.
*
* @return mixed Website Info.
*
* @uses \MainWP\Dashboard\MainWP_Utility::get_nice_url()
*/
public function info_for_website( $website, $action, $message ) {
if ( empty( $website ) ) {
return $this->log( '[-] [-] ::' . $action . ':: ' . $message, static::INFO );
}
return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, static::INFO );
}
/**
* Method warning_for_website()
*
* Grab Website Warnings.
*
* @param object $website Child site object.
* @param string $action Performed action.
* @param string $message Warning message.
* @param bool $addStackTrace Add or Don't add stack trace.
*
* @return string Website warnings.
*/
public function warning_for_website( $website, $action, $message, $addStackTrace = true ) {
$stackTrace = '';
if ( $addStackTrace ) {
ob_start();
// phpcs:ignore -- for debugging.
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
$stackTrace = "\n" . ob_get_clean();
}
if ( empty( $website ) ) {
return $this->log( '[-] [-] :: ' . $action . ' :: ' . $message . $stackTrace, static::WARNING );
}
return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message . $stackTrace, static::WARNING );
}
/**
* Method log_to_db()
*
* Log to database.
*
* @param string $text Log record text.
* @param int $priority Set priority.
* @param int $log_color Set color.
* @param bool $forced forced logging.
* @param mixed $website website object.
*
* @return bool true|false Default is False.
*/
private function log_to_db( $text, $priority, $log_color = 0, $forced = false, $website = false ) {
if ( static::DISABLED === $this->logPriority ) {
return false;
}
$priority = (int) apply_filters( 'mainwp_log_to_db_priority', $priority, $website );
$do_log = false;
if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
if ( $this->logPriority === $priority ) { // specific priority number saved setting.
$do_log = true;
}
} elseif ( $this->logPriority >= $priority ) {
$do_log = true;
}
$do_log = apply_filters( 'mainwp_log_do_to_db', $do_log, $website );
if ( ! $forced && ! $do_log ) {
return false;
}
$text = $this->prepare_log_info( $text );
do_action( 'mainwp_before_log_data', $text, $priority, $log_color );
if ( defined( 'DOING_CRON' ) && DOING_CRON && 'CRON' !== strtoupper( substr( $text, 0, 4 ) ) ) {
$text = 'CRON :: ' . $text;
}
/**
* Current user global.
*
* @global string
*/
global $current_user;
$user = '';
if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
$user = $current_user->user_login;
} elseif ( defined( 'WP_CLI' ) ) {
$user = 'WP_CLI';
} elseif ( defined( 'DOING_CRON' ) ) {
$user = 'DOING_CRON';
}
$data = array();
$data['log_content'] = $text;
$data['log_user'] = $user;
$data['log_type'] = $priority;
$data['log_color'] = intval( $log_color );
$data['log_timestamp'] = time();
$data = apply_filters( 'mainwp_log_to_db_data', $data );
MainWP_DB_Common::instance()->insert_action_log( $data );
return true;
}
/**
* Method log()
*
* Create Log File.
*
* @param string $text Log record text.
* @param int $priority Set priority.
* @param int $log_color Set color.
* @param bool $forced forced logging.
* @param mixed $website Site object.
*
* @return bool true|false Default is False.
*/
private function log( $text, $priority, $log_color = 0, $forced = false, $website = false ) { // phpcs:ignore -- NOSONAR - complex function.
if ( in_array( $priority, $this->autoEnableLoggingActions ) && (int) $this->logPriority !== (int) $priority ) {
$this->enable_log_priority( $priority, 1 );
}
if ( static::DISABLED === $this->logPriority ) {
return false;
}
$log_to_db = apply_filters( 'mainwp_logger_to_db', true, $website );
if ( $log_to_db ) {
return $this->log_to_db( $text, $priority, $log_color, $forced, $website );
}
$text = $this->prepare_log_info( $text );
$do_log = false;
if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
if ( $this->logPriority === $priority ) { // specific priority number saved setting.
$do_log = true;
}
} elseif ( $this->logPriority >= $priority ) {
$do_log = true;
}
if ( $do_log ) {
$this->logCurrentFile = $this->get_log_file();
$logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
if ( $logCurrentHandle ) {
$time = gmdate( $this->logDateFormat );
$prefix = '[' . $this->get_log_text( $priority ) . ']';
/**
* Current user global.
*
* @global string
*/
global $current_user;
if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
$prefix .= ' [administrator]';
}
fwrite( $logCurrentHandle, $time . ' ' . $prefix . ' ' . $text . "\n" );
fclose( $logCurrentHandle );
}
if ( filesize( $this->logCurrentFile ) > ( $this->logMaxMB * 1048576 ) ) {
$logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
if ( $logCurrentHandle ) {
fseek( $logCurrentHandle, 0 );
$newLogFile = $this->logCurrentFile . '.tmp';
$newLogHandle = false;
$chunkSize = filesize( $this->logCurrentFile ) - ( $this->logMaxMB * 1048576 );
while ( is_resource( $logCurrentHandle ) && ! feof( $logCurrentHandle ) && ( $chunkSize > 0 ) ) {
$content = fread( $logCurrentHandle, $chunkSize );
if ( false === $content ) {
break;
}
$pos = strrpos( $content, "\n" );
if ( $newLogHandle ) {
fwrite( $newLogHandle, $content );
} elseif ( $pos ) {
if ( ! $newLogHandle ) {
$newLogHandle = fopen( $newLogFile, 'w+' );
}
fwrite( $newLogHandle, substr( $content, $pos + 1 ) );
}
}
if ( is_resource( $logCurrentHandle ) ) {
fclose( $logCurrentHandle );
}
if ( $newLogHandle ) {
fclose( $newLogHandle );
wp_delete_file( $this->logCurrentFile );
if ( file_exists( $newLogFile ) ) {
rename( $newLogFile, $this->logCurrentFile );
}
}
}
}
return true;
}
return false;
}
/**
* Method prepare_log_info()
*
* Prepare log data.
*
* @param mixed $data Log data.
*
* @return mixed $data filtered data.
*/
public function prepare_log_info( $data ) {
$patterns[0] = '/user=([^\&]+)\&/';
$replacement[0] = 'user=xxxxxx&';
$patterns[1] = '/alt_user=([^\&]+)\&/';
$replacement[1] = 'alt_user=xxxxxx&';
$patterns[2] = '/\&server=([^\&]+)\&/';
$replacement[2] = '&server=xxxxxx&';
$data = preg_replace( $patterns, $replacement, $data );
return $data;
}
/**
* Method prepend()
*
* Prepend content to log file.
*
* @param mixed $str Custom string.
* @param mixed $filename Filename.
*/
public function prepend( $str, $filename ) {
$context = stream_context_create();
$fp = fopen( $filename, 'r', 1, $context );
$tmpname = md5( $str ); // NOSONAR - safe for salt file name.
file_put_contents( $tmpname, $str );
file_put_contents( $tmpname, $fp, FILE_APPEND );
fclose( $fp );
wp_delete_file( $filename );
rename( $tmpname, $filename );
}
/**
* Method init_execution_time().
*
* @param string $time_index index for timer.
*
* Init execution time start value.
*/
public function init_execution_time( $time_index = '' ) {
if ( null === static::$time_start || ! is_array( static::$time_start ) ) {
static::$time_start = array( 'start' => microtime( true ) );
$this->log_action( 'execution time :: init :: [start]', static::EXECUTION_TIME_LOG_PRIORITY );
}
if ( ! empty( $time_index ) && is_string( $time_index ) && 'start' !== $time_index ) {
static::$time_start[ $time_index ] = microtime( true );
$this->log_action( 'execution time :: init :: [' . $time_index . ']', static::EXECUTION_TIME_LOG_PRIORITY );
}
}
/**
* Method log_execution_time().
*
* @param string $text Log record text.
*
* Log the execution time value.
*/
public function log_execution_time( $text = '' ) {
$exec_time = $this->get_execution_time();
$this->log_action( 'execution time :: ' . ( ! empty( $text ) ? (string) $text : '<empty>' ) . ' :: [time=' . round( $exec_time, 4 ) . '](seconds)', static::EXECUTION_TIME_LOG_PRIORITY );
}
/**
* Method get_execution_time().
*
* Get the execution time value.
*
* @param string $time_index Index for timer.
*
* @return int execution time.
*/
private function get_execution_time( $time_index = '' ) {
if ( empty( static::$time_start ) ) {
return 0;
}
$start = 0;
if ( ! empty( $time_index ) ) {
$start = is_array( static::$time_start ) && isset( static::$time_start[ $time_index ] ) ? static::$time_start[ $time_index ] : 0;
}
if ( empty( $start ) ) {
$start = is_array( static::$time_start ) && isset( static::$time_start['start'] ) ? static::$time_start['start'] : 0;
}
if ( empty( $start ) ) {
return 0;
}
return microtime( true ) - $start; // seconds.
}
/**
* Method get_log_file()
*
* Grab Log File.
*
* @return mixed Log File.
*/
public function get_log_file() {
if ( empty( $this->logDirectory ) ) {
$this->logDirectory = MainWP_System_Utility::get_mainwp_dir();
$this->logDirectory = $this->logDirectory[0];
}
return $this->logDirectory . $this->logFileNamePrefix . $this->logFileNameSuffix;
}
/**
* Method get_log_text()
*
* Grab what type of log entry.
*
* @param mixed $priority Set priority.
*
* @return string LOG -OR- DISABLED|DEBUG|INFO|WARNING|INFO UPDATE
*/
public function get_log_text( $priority ) {
switch ( $priority ) {
case static::DISABLED:
return 'DISABLED';
case static::DEBUG:
return 'DEBUG';
case static::INFO:
return 'INFO';
case static::WARNING:
return 'WARNING';
default:
return 'SPEC LOG';
}
}
/**
* Method check_log_daily()
*
* Daily checks to clear the log file.
*/
public function check_log_daily() {
$status = (int) $this->get_log_status();
if ( 0 >= $status ) {
return;
}
$today_m_y = date_i18n( 'd/m/Y' ); //phpcs:ignore -- local time.
// one time per day.
if ( get_option( 'mainwp_logger_check_daily' ) !== $today_m_y ) {
$num_days = apply_filters( 'mainwp_logger_keep_days', 7 );
MainWP_DB_Common::instance()->delete_action_log( $num_days );
MainWP_Utility::update_option( 'mainwp_logger_check_daily', $today_m_y );
$enabled_time = get_option( 'mainwp_actionlogs_enabled_timestamp', false );
if ( false === $enabled_time ) {
MainWP_Utility::update_option( 'mainwp_actionlogs_enabled_timestamp', time() );
} elseif ( $enabled_time + $num_days * DAY_IN_SECONDS < time() ) {
MainWP_Utility::update_option( 'mainwp_actionlogs', static::DISABLED );
}
}
}
/**
* Method clear_log_db()
*
* Clear the log file.
*/
public function clear_log_db() {
MainWP_DB_Common::instance()->delete_action_log();
}
/**
* Method clear_log()
*
* Clear the log file.
*/
public function clear_log() {
$logFile = $this->get_log_file();
wp_delete_file( $logFile );
$fh = fopen( $logFile, 'w' );
if ( false === $fh ) {
return;
}
fclose( $fh );
}
/**
* Method show_log_db()
*
* Grab log file and build output to screen.
*/
public function show_log_db() { //phpcs:ignore -- NOSONAR - complexity.
echo '<div class="ui hidden divider"></div>';
echo '<div class="ui divided padded relaxed list" local-datetime="' . date( 'Y-m-d H:i:s' ) . '">'; // phpcs:ignore -- local time.
$limit = 500;
//phpcs:disable WordPress.Security.NonceVerification
$paged = isset( $_GET['paged'] ) ? intval( $_GET['paged'] ) : 0; //phpcs:ignore -- NOSONAR -ok.
if ( $paged <= 0 ) {
$paged = 0;
} else {
--$paged;
}
$params = array();
if ( isset( $_GET['hour'] ) && ! empty( $_GET['hour'] ) ) { // phpcs:ignore -- local time.
$params['hour'] = intval( $_GET['hour'] ); // phpcs:ignore -- local time.
} else {
$params['hour'] = $limit;
}
$order = isset( $_GET['order'] ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : ''; //phpcs:ignore -- NOSONAR -ok.
$total = MainWP_DB::instance()->get_var_field( MainWP_DB_Common::instance()->get_sql_log( $paged, $order, array( 'count' => true ) ) );
$rows = MainWP_DB::instance()->query( MainWP_DB_Common::instance()->get_sql_log( $paged, $order, $params ) );
$count = $rows ? MainWP_DB::num_rows( $rows ) : 0;
$show_info = '';
if ( isset( $_GET['hour'] ) ) {
$show_info = $count . ' latest items from a total of ' . $total;
} elseif ( isset( $_GET['paged'] ) ) { //phpcs:ignore -- NOSONAR -ok.
$from = $limit * $paged;
$show_info = $count . ' items, from ' . $from . ' - ' . ( $from + $limit ) . ' of ' . $total . ' total.';
}
if ( ! empty( $show_info ) ) {
echo '<p><strong>' . esc_html__( 'Showing ', 'mainwp' ) . ':</strong> ' . $show_info; //phpcs:ignore -- NOSONAR ok.
}
//phpcs:enable WordPress.Security.NonceVerification
$start_wrapper = '<span class="ui mini label mainwp-action-log-show-more">Click to See Response</span><div class="mainwp-action-log-site-response" style="display: none;">';
$end_wrapper = '</div>';
while ( $rows && ( $row = MainWP_DB::fetch_object( $rows ) ) ) {
$line = $row->log_content;
if ( 120 * 1024 < strlen( $line ) ) {
$line = '[Data row too long]';
}
$time = gmdate( $this->logDateFormat, MainWP_Utility::get_timestamp( $row->log_timestamp ) );
$showInfo = $this->get_log_type_info( $row->log_type, $row->log_color );
$currentColor = $showInfo['log_color'];
$prefix = $time . ' ' . $showInfo['log_prefix'];
$line = htmlentities( $line );
if ( false !== strpos( $line, '[data-start]' ) ) {
$line = str_replace( '[data-start]', $start_wrapper, $line );
$line = str_replace( '[data-end]', $end_wrapper, $line );
}
echo '<div class="item" style="color:' . esc_html( $currentColor ) . '"><div class="mainwpactionlogsline">';
echo $prefix . ' ' . $line; // phpcs:ignore WordPress.Security.EscapeOutput
echo '</div></div>';
}
echo '</div></div>';
echo '</div>';
?>
<div class="ui large modal" id="mainwp-action-log-response-modal">
<i class="close icon mainwp-reload"></i>
<div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div>
<div class="content">
<div class="ui info message"><?php esc_html_e( 'To see the response in a more readable way, you can copy it and paste it into some HTML render tool, such as Codepen.io.', 'mainwp' ); ?>
</div>
</div>
<div class="scrolling content content-response"></div>
<div class="actions">
<button class="ui green button mainwp-response-copy-button"><?php esc_html_e( 'Copy Response', 'mainwp' ); ?></button>
</div>
</div>
<?php
}
/**
* Method show_log_file()
*
* Grab log file and build output to screen.
*/
public function show_log_file() { // phpcs:ignore -- NOSONAR - complex.
$logFile = $this->get_log_file();
if ( ! file_exists( $logFile ) ) {
return;
}
$fh = fopen( $logFile, 'r' );
if ( false === $fh ) {
return;
}
$previousColor = '';
$fontOpen = false;
$firstLinePassedProcessed = false;
echo '<div class="ui hidden divider"></div>';
echo '<div class="ui divided padded relaxed list">';
while ( false !== ( $line = fgets( $fh ) ) ) {
$currentColor = $previousColor;
if ( stristr( $line, '[DEBUG]' ) ) {
$currentColor = static::DEBUG_COLOR;
$firstLinePassed = true;
} elseif ( stristr( $line, '[INFO]' ) ) {
$currentColor = static::INFO_COLOR;
$firstLinePassed = true;
} elseif ( stristr( $line, '[WARNING]' ) ) {
$currentColor = static::WARNING_COLOR;
$firstLinePassed = true;
} elseif ( stristr( $line, '[LOG]' ) ) {
$currentColor = static::LOG_COLOR;
$firstLinePassed = true;
} else {
$firstLinePassed = false;
}
if ( $firstLinePassedProcessed && ! $firstLinePassed ) {
echo ' <span class="ui mini label mainwp-action-log-show-more">Click to See Response</span></div><div class="mainwp-action-log-site-response" style="display: none;">';
}
$firstLinePassedProcessed = $firstLinePassed;
if ( $currentColor !== $previousColor ) {
if ( $fontOpen ) {
echo '</div></div>';
}
echo '<div class="item" style="color:' . esc_html( $currentColor ) . '"><div class="mainwpactionlogsline">';
$fontOpen = true;
}
echo esc_html( htmlentities( $line ) );
}
if ( $fontOpen ) {
echo '</div></div>';
}
echo '</div>';
?>
<div class="ui large modal" id="mainwp-action-log-response-modal">
<i class="close icon mainwp-reload"></i>
<div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div>
<div class="content">
<div class="ui info message"><?php esc_html_e( 'To see the response in a more readable way, you can copy it and paste it into some HTML render tool, such as Codepen.io.', 'mainwp' ); ?>
</div>
</div>
<div class="scrolling content content-response"></div>
<div class="actions">
<button class="ui green button mainwp-response-copy-button"><?php esc_html_e( 'Copy Response', 'mainwp' ); ?></button>
</div>
</div>
<?php
fclose( $fh );
}
}