PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 5.2.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v5.2.2
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / class / class-mainwp-logger.php

class-mainwp-logger.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 5.2.2, at class/class-mainwp-logger.php

865 lines 26.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Logger
4 *
5 * For custom read/write logging file.
6 *
7 * @package MainWP/Dashboard
8 */
9
10 namespace MainWP\Dashboard;
11
12 /**
13 * Class MainWP_Logger
14 *
15 * @package MainWP\Dashboard
16 */
17 class MainWP_Logger { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
18
19 // phpcs:disable WordPress.WP.AlternativeFunctions -- for custom read/write logging file.
20
21 const UPDATE_CHECK_LOG_PRIORITY = 10;
22 const EXECUTION_TIME_LOG_PRIORITY = 15;
23 const LOGS_AUTO_PURGE_LOG_PRIORITY = 16;
24 const COST_TRACKER_LOG_PRIORITY = 20230112;
25 const API_BACKUPS_LOG_PRIORITY = 20240130;
26
27 const DISABLED = - 1;
28 const LOG = 0;
29 const WARNING = 1;
30 const INFO = 2;
31 const DEBUG = 3;
32
33 const LOG_COLOR = '#999999';
34 const DEBUG_COLOR = '#666666';
35 const INFO_COLOR = '#276f86';
36 const WARNING_COLOR = '#9f3a38;';
37
38 /**
39 * Private variable to hold time start.
40 *
41 * @var int
42 */
43 private static $time_start = null;
44
45 /**
46 * Private varibale to hold the log file prefix.
47 *
48 * @var string Default 'mainwp'
49 */
50 private $logFileNamePrefix = 'mainwp';
51
52 /**
53 * Private varibale to hold the log file suffix.
54 *
55 * @var string Default '.log'
56 */
57 private $logFileNameSuffix = '.log';
58
59 /**
60 * Private varibale to hold the log file max size.
61 *
62 * @var int Default 0.5
63 */
64 private $logMaxMB = 0.5;
65
66 /**
67 * Private varibale to hold the log file date format.
68 *
69 * @var string Default 'Y-m-d H:i:s'
70 */
71 private $logDateFormat = 'Y-m-d H:i:s';
72
73 /**
74 * Private varibale to hold the log file output directory.
75 *
76 * @var mixed Default null
77 */
78 private $logDirectory = null;
79
80 /**
81 * Private varibale to hold the log file priotrity.
82 *
83 * @var string Disabled
84 */
85 private $logPriority = self::DISABLED;
86
87 /**
88 * Private varibale to hold the log Specific priotrity.
89 *
90 * @var string Disabled
91 */
92 private $logSpecific = 0;
93
94
95 /**
96 * Private static varibale to hold the instance.
97 *
98 * @var mixed Default null
99 */
100 private static $instance = null;
101
102 /**
103 * Method instance()
104 *
105 * Returns new MainWP_Logger instance.
106 *
107 * @return self MainWP_Logger
108 *
109 * @uses \MainWP\Dashboard\MainWP_Logger
110 */
111 public static function instance() {
112 if ( null === static::$instance ) {
113 static::$instance = new self();
114 }
115 return static::$instance;
116 }
117
118 /**
119 * MainWP_Logger constructor.
120 *
121 * Run each time the class is called.
122 *
123 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir()
124 */
125 private function __construct() {
126
127 $enabled = $this->get_log_status();
128 $specific = $this->get_log_specific();
129
130 $enabled = apply_filters( 'mainwp_log_status', $enabled );
131 $specific = apply_filters( 'mainwp_log_specific', $specific );
132
133 $this->set_log_priority( $enabled, $specific );
134 }
135
136 /**
137 * Method set_log_priority()
138 *
139 * Sets the log priority.
140 *
141 * @param mixed $logPriority Log priority value.
142 * @param mixed $spec_log Specific log.
143 */
144 public function set_log_priority( $logPriority, $spec_log = 0 ) {
145 $this->logPriority = (int) $logPriority;
146 $this->logSpecific = (int) $spec_log; // 1 - specific log, 0 - not specific log.
147 }
148
149 /**
150 * Method get_log_status()
151 *
152 * Get log status.
153 *
154 * @return mixed $enabled log status.
155 */
156 public function get_log_status() {
157 $enabled = get_option( 'mainwp_actionlogs' );
158
159 if ( false === $enabled ) {
160 $sites_count = MainWP_DB::instance()->get_websites_count();
161 if ( empty( $sites_count ) ) {
162 $enabled = self::DEBUG;
163 set_transient( 'mainwp_transient_action_logs', true, 2 * WEEK_IN_SECONDS );
164 } elseif ( get_transient( 'mainwp_transient_action_logs' ) ) {
165 $enabled = self::DEBUG;
166 } else {
167 $enabled = static::DISABLED;
168 }
169 }
170 return $enabled;
171 }
172
173
174 /**
175 * Method get_log_specific()
176 *
177 * Get log specific status.
178 *
179 * @return mixed $enabled log status.
180 */
181 public function get_log_specific() {
182 return get_option( 'mainwp_specific_logs', 0 );
183 }
184
185 /**
186 * Method get_log_type_info()
187 *
188 * Get log type info.
189 *
190 * @param int $type Log type value.
191 * @param int $logcolor Log color value.
192 *
193 * @return int $currentColor log color code.
194 */
195 public function get_log_type_info( $type, $logcolor ) {
196 $currentColor = '';
197 $prefix = '';
198 if ( static::DEBUG === $type || static::DEBUG === $logcolor ) {
199 $currentColor = static::DEBUG_COLOR;
200 $prefix = '[DEBUG]';
201 } elseif ( static::INFO === $type || static::INFO === $logcolor ) {
202 $currentColor = static::INFO_COLOR;
203 $prefix = '[INFO]';
204 } elseif ( static::WARNING === $type || static::WARNING === $logcolor ) {
205 $currentColor = static::WARNING_COLOR;
206 $prefix = '[WARNING]';
207 } elseif ( static::LOG === $type || static::LOG === $logcolor ) {
208 $currentColor = static::LOG_COLOR;
209 $prefix = '[LOG]';
210 }
211 return array(
212 'log_color' => $currentColor,
213 'log_prefix' => $prefix,
214 );
215 }
216
217 /**
218 * Method debug()
219 *
220 * Grab debug.
221 *
222 * @param string $text Debug message text.
223 *
224 * @return string Log debug message.
225 */
226 public function debug( $text ) {
227 return $this->log( $text, static::DEBUG );
228 }
229
230 /**
231 * Method info()
232 *
233 * Grab info.
234 *
235 * @param string $text Info message text.
236 *
237 * @return string Log info message.
238 */
239 public function info( $text ) {
240 return $this->log( $text, static::INFO );
241 }
242
243 /**
244 * Method warning()
245 *
246 * Grab warning information.
247 *
248 * @param string $text Warning message text.
249 *
250 * @return string Log warning message.
251 */
252 public function warning( $text ) {
253 return $this->log( $text, static::WARNING );
254 }
255
256 /**
257 * Method actions()
258 *
259 * Grab actions information.
260 *
261 * @param string $text Warning message text.
262 * @param int $priority priority message.
263 * @param int $log_color Set color: 0 - LOG, 1 - WARNING, 2 - INFO, 3- DEBUG.
264 * @param bool $forced forced logging.
265 *
266 * @return string Log warning message.
267 */
268 public function log_action( $text, $priority, $log_color = 0, $forced = false ) {
269 return $this->log( $text, $priority, $log_color, $forced );
270 }
271
272
273 /**
274 * Method log_update_check().
275 *
276 * @param string $text Log update check.
277 */
278 public function log_update_check( $text = '' ) {
279 $this->log_action( $text, static::UPDATE_CHECK_LOG_PRIORITY );
280 }
281
282 /**
283 * Method debug_for_website()
284 *
285 * Grab website debug and info.
286 *
287 * @param object $website Child site object.
288 * @param string $action Performed action.
289 * @param string $message Debug message.
290 *
291 * @return mixed Website debug info.
292 *
293 * @uses \MainWP\Dashboard\MainWP_Utility::get_nice_url()
294 */
295 public function debug_for_website( $website, $action, $message ) {
296 if ( empty( $website ) ) {
297 return $this->log( '[-] [-] ::' . $action . ':: ' . $message, static::DEBUG );
298 }
299
300 return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, static::DEBUG, 0, false, $website );
301 }
302
303 /**
304 * Method info_for_website()
305 *
306 * Grab Website Info.
307 *
308 * @param object $website Child site object.
309 * @param string $action Performed action.
310 * @param string $message Info message.
311 *
312 * @return mixed Website Info.
313 *
314 * @uses \MainWP\Dashboard\MainWP_Utility::get_nice_url()
315 */
316 public function info_for_website( $website, $action, $message ) {
317 if ( empty( $website ) ) {
318 return $this->log( '[-] [-] ::' . $action . ':: ' . $message, static::INFO );
319 }
320
321 return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, static::INFO );
322 }
323
324 /**
325 * Method warning_for_website()
326 *
327 * Grab Website Warnings.
328 *
329 * @param object $website Child site object.
330 * @param string $action Performed action.
331 * @param string $message Warning message.
332 * @param bool $addStackTrace Add or Don't add stack trace.
333 *
334 * @return string Website warnings.
335 */
336 public function warning_for_website( $website, $action, $message, $addStackTrace = true ) {
337 $stackTrace = '';
338 if ( $addStackTrace ) {
339 ob_start();
340 // phpcs:ignore -- for debugging.
341 debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
342 $stackTrace = "\n" . ob_get_clean();
343 }
344 if ( empty( $website ) ) {
345 return $this->log( '[-] [-] :: ' . $action . ' :: ' . $message . $stackTrace, static::WARNING );
346 }
347
348 return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message . $stackTrace, static::WARNING );
349 }
350
351 /**
352 * Method log_to_db()
353 *
354 * Log to database.
355 *
356 * @param string $text Log record text.
357 * @param int $priority Set priority.
358 * @param int $log_color Set color.
359 * @param bool $forced forced logging.
360 * @param mixed $website website object.
361 *
362 * @return bool true|false Default is False.
363 */
364 private function log_to_db( $text, $priority, $log_color = 0, $forced = false, $website = false ) {
365
366 if ( static::DISABLED === $this->logPriority ) {
367 return false;
368 }
369
370 $priority = (int) apply_filters( 'mainwp_log_to_db_priority', $priority, $website );
371
372 $do_log = false;
373
374 if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
375 if ( $this->logPriority === $priority ) { // specific priority number saved setting.
376 $do_log = true;
377 }
378 } elseif ( $this->logPriority >= $priority ) {
379 $do_log = true;
380 }
381
382 $do_log = apply_filters( 'mainwp_log_do_to_db', $do_log, $website );
383
384 $text = $this->prepare_log_info( $text );
385
386 do_action( 'mainwp_before_log_data', $text, $priority, $log_color );
387
388 if ( defined( 'DOING_CRON' ) && DOING_CRON && 'CRON' !== strtoupper( substr( $text, 0, 4 ) ) ) {
389 $text = 'CRON :: ' . $text;
390 }
391
392 if ( $forced || $do_log ) {
393
394 /**
395 * Current user global.
396 *
397 * @global string
398 */
399 global $current_user;
400
401 $user = '';
402 if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
403 $user = $current_user->user_login;
404 } elseif ( defined( 'WP_CLI' ) ) {
405 $user = 'WP_CLI';
406 } elseif ( defined( 'DOING_CRON' ) ) {
407 $user = 'DOING_CRON';
408 }
409
410 $data = array();
411
412 $data['log_content'] = $text;
413 $data['log_user'] = $user;
414 $data['log_type'] = $priority;
415 $data['log_color'] = intval( $log_color );
416 $data['log_timestamp'] = time();
417
418 $data = apply_filters( 'mainwp_log_to_db_data', $data );
419
420 MainWP_DB_Common::instance()->insert_action_log( $data );
421
422 return true;
423 }
424 return false;
425 }
426
427 /**
428 * Method log()
429 *
430 * Create Log File.
431 *
432 * @param string $text Log record text.
433 * @param int $priority Set priority.
434 * @param int $log_color Set color.
435 * @param bool $forced forced logging.
436 * @param mixed $website Site object.
437 *
438 * @return bool true|false Default is False.
439 */
440 private function log( $text, $priority, $log_color = 0, $forced = false, $website = false ) { // phpcs:ignore -- NOSONAR - complex function.
441
442 if ( static::DISABLED === $this->logPriority ) {
443 return;
444 }
445
446 $log_to_db = apply_filters( 'mainwp_logger_to_db', true, $website );
447
448 if ( $log_to_db ) {
449 return $this->log_to_db( $text, $priority, $log_color, $forced, $website );
450 }
451
452 $text = $this->prepare_log_info( $text );
453
454 $do_log = false;
455 if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
456 if ( $this->logPriority === $priority ) { // specific priority number saved setting.
457 $do_log = true;
458 }
459 } elseif ( $this->logPriority >= $priority ) {
460 $do_log = true;
461 }
462
463 if ( $do_log ) {
464 $this->logCurrentFile = $this->get_log_file();
465 $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
466
467 if ( $logCurrentHandle ) {
468 $time = gmdate( $this->logDateFormat );
469 $prefix = '[' . $this->get_log_text( $priority ) . ']';
470
471 /**
472 * Current user global.
473 *
474 * @global string
475 */
476 global $current_user;
477
478 if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
479 $prefix .= ' [administrator]';
480 }
481
482 fwrite( $logCurrentHandle, $time . ' ' . $prefix . ' ' . $text . "\n" );
483 fclose( $logCurrentHandle );
484 }
485
486 if ( filesize( $this->logCurrentFile ) > ( $this->logMaxMB * 1048576 ) ) {
487 $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
488 if ( $logCurrentHandle ) {
489 fseek( $logCurrentHandle, 0 );
490 $newLogFile = $this->logCurrentFile . '.tmp';
491 $newLogHandle = false;
492 $chunkSize = filesize( $this->logCurrentFile ) - ( $this->logMaxMB * 1048576 );
493 while ( is_resource( $logCurrentHandle ) && ! feof( $logCurrentHandle ) && ( $chunkSize > 0 ) ) {
494 $content = fread( $logCurrentHandle, $chunkSize );
495 if ( false === $content ) {
496 break;
497 }
498 $pos = strrpos( $content, "\n" );
499 if ( $newLogHandle ) {
500 fwrite( $newLogHandle, $content );
501 } elseif ( $pos ) {
502 if ( ! $newLogHandle ) {
503 $newLogHandle = fopen( $newLogFile, 'w+' );
504 }
505 fwrite( $newLogHandle, substr( $content, $pos + 1 ) );
506 }
507 }
508
509 if ( is_resource( $logCurrentHandle ) ) {
510 fclose( $logCurrentHandle );
511 }
512
513 if ( $newLogHandle ) {
514 fclose( $newLogHandle );
515 wp_delete_file( $this->logCurrentFile );
516 if ( file_exists( $newLogFile ) ) {
517 rename( $newLogFile, $this->logCurrentFile );
518 }
519 }
520 }
521 }
522
523 return true;
524 }
525
526 return false;
527 }
528
529
530 /**
531 * Method prepare_log_info()
532 *
533 * Prepare log data.
534 *
535 * @param mixed $data Log data.
536 *
537 * @return mixed $data filtered data.
538 */
539 public function prepare_log_info( $data ) {
540 $patterns[0] = '/user=([^\&]+)\&/';
541 $replacement[0] = 'user=xxxxxx&';
542 $patterns[1] = '/alt_user=([^\&]+)\&/';
543 $replacement[1] = 'alt_user=xxxxxx&';
544 $patterns[2] = '/\&server=([^\&]+)\&/';
545 $replacement[2] = '&server=xxxxxx&';
546 $data = preg_replace( $patterns, $replacement, $data );
547 return $data;
548 }
549
550 /**
551 * Method prepend()
552 *
553 * Prepend content to log file.
554 *
555 * @param mixed $str Custom string.
556 * @param mixed $filename Filename.
557 */
558 public function prepend( $str, $filename ) {
559 $context = stream_context_create();
560 $fp = fopen( $filename, 'r', 1, $context );
561 $tmpname = md5( $str ); // NOSONAR - safe for salt file name.
562 file_put_contents( $tmpname, $str );
563 file_put_contents( $tmpname, $fp, FILE_APPEND );
564 fclose( $fp );
565 wp_delete_file( $filename );
566 rename( $tmpname, $filename );
567 }
568
569 /**
570 * Method init_execution_time().
571 *
572 * @param string $time_index index for timer.
573 *
574 * Init execution time start value.
575 */
576 public function init_execution_time( $time_index = '' ) {
577 if ( null === static::$time_start || ! is_array( static::$time_start ) ) {
578 static::$time_start = array( 'start' => microtime( true ) );
579 $this->log_action( 'execution time :: init :: [start]', static::EXECUTION_TIME_LOG_PRIORITY );
580 }
581
582 if ( ! empty( $time_index ) && is_string( $time_index ) && 'start' !== $time_index ) {
583 static::$time_start[ $time_index ] = microtime( true );
584 $this->log_action( 'execution time :: init :: [' . $time_index . ']', static::EXECUTION_TIME_LOG_PRIORITY );
585 }
586 }
587
588 /**
589 * Method log_execution_time().
590 *
591 * @param string $text Log record text.
592 *
593 * Log the execution time value.
594 */
595 public function log_execution_time( $text = '' ) {
596 $exec_time = $this->get_execution_time();
597 $this->log_action( 'execution time :: ' . ( ! empty( $text ) ? (string) $text : '<empty>' ) . ' :: [time=' . round( $exec_time, 4 ) . '](seconds)', static::EXECUTION_TIME_LOG_PRIORITY );
598 }
599
600
601 /**
602 * Method get_execution_time().
603 *
604 * Get the execution time value.
605 *
606 * @param string $time_index Index for timer.
607 *
608 * @return int execution time.
609 */
610 private function get_execution_time( $time_index = '' ) {
611
612 if ( empty( static::$time_start ) ) {
613 return 0;
614 }
615
616 $start = 0;
617 if ( ! empty( $time_index ) ) {
618 $start = is_array( static::$time_start ) && isset( static::$time_start[ $time_index ] ) ? static::$time_start[ $time_index ] : 0;
619 }
620
621 if ( empty( $start ) ) {
622 $start = is_array( static::$time_start ) && isset( static::$time_start['start'] ) ? static::$time_start['start'] : 0;
623 }
624
625 if ( empty( $start ) ) {
626 return 0;
627 }
628 return microtime( true ) - $start; // seconds.
629 }
630
631 /**
632 * Method get_log_file()
633 *
634 * Grab Log File.
635 *
636 * @return mixed Log File.
637 */
638 public function get_log_file() {
639 if ( empty( $this->logDirectory ) ) {
640 $this->logDirectory = MainWP_System_Utility::get_mainwp_dir();
641 $this->logDirectory = $this->logDirectory[0];
642 }
643 return $this->logDirectory . $this->logFileNamePrefix . $this->logFileNameSuffix;
644 }
645
646 /**
647 * Method get_log_text()
648 *
649 * Grab what type of log entry.
650 *
651 * @param mixed $priority Set priority.
652 *
653 * @return string LOG -OR- DISABLED|DEBUG|INFO|WARNING|INFO UPDATE
654 */
655 public function get_log_text( $priority ) {
656 switch ( $priority ) {
657 case static::DISABLED:
658 return 'DISABLED';
659 case static::DEBUG:
660 return 'DEBUG';
661 case static::INFO:
662 return 'INFO';
663 case static::WARNING:
664 return 'WARNING';
665 default:
666 return 'SPEC LOG';
667 }
668 }
669
670 /**
671 * Method check_log_daily()
672 *
673 * Daily checks to clear the log file.
674 */
675 public function check_log_daily() {
676 $status = (int) $this->get_log_status();
677 if ( 0 >= $status ) {
678 return;
679 }
680
681 $today_m_y = date_i18n( 'd/m/Y' ); //phpcs:ignore -- local time.
682 // one time per day.
683 if ( get_option( 'mainwp_logger_check_daily' ) !== $today_m_y ) {
684 $num_days = apply_filters( 'mainwp_logger_keep_days', 7 );
685 MainWP_DB_Common::instance()->delete_action_log( $num_days );
686 MainWP_Utility::update_option( 'mainwp_logger_check_daily', $today_m_y );
687
688 $enabled_time = get_option( 'mainwp_actionlogs_enabled_timestamp', false );
689 if ( false === $enabled_time ) {
690 MainWP_Utility::update_option( 'mainwp_actionlogs_enabled_timestamp', time() );
691 } elseif ( $enabled_time + $num_days * DAY_IN_SECONDS < time() ) {
692 MainWP_Utility::update_option( 'mainwp_actionlogs', static::DISABLED );
693 }
694 }
695 }
696
697 /**
698 * Method clear_log_db()
699 *
700 * Clear the log file.
701 */
702 public function clear_log_db() {
703 MainWP_DB_Common::instance()->delete_action_log();
704 }
705
706 /**
707 * Method clear_log()
708 *
709 * Clear the log file.
710 */
711 public function clear_log() {
712 $logFile = $this->get_log_file();
713 wp_delete_file( $logFile );
714 $fh = fopen( $logFile, 'w' );
715 if ( false === $fh ) {
716 return;
717 }
718 fclose( $fh );
719 }
720
721 /**
722 * Method show_log_db()
723 *
724 * Grab log file and build output to screen.
725 */
726 public function show_log_db() {
727
728 echo '<div class="ui hidden divider"></div>';
729 echo '<div class="ui divided padded relaxed list" local-datetime="' . date( 'Y-m-d H:i:s' ) . '">'; // phpcs:ignore -- local time.
730
731 $rows = MainWP_DB::instance()->query( MainWP_DB_Common::instance()->get_sql_log() );
732
733 $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;">';
734 $end_wrapper = '</div>';
735
736 while ( $rows && ( $row = MainWP_DB::fetch_object( $rows ) ) ) {
737 $line = $row->log_content;
738 if ( 120 * 1024 < strlen( $line ) ) {
739 $line = '[Data row too long]';
740 }
741
742 $time = gmdate( $this->logDateFormat, $row->log_timestamp );
743
744 $showInfo = $this->get_log_type_info( $row->log_type, $row->log_color );
745 $currentColor = $showInfo['log_color'];
746
747 $prefix = $time . ' ' . $showInfo['log_prefix'];
748
749 $line = htmlentities( $line );
750
751 if ( false !== strpos( $line, '[data-start]' ) ) {
752 $line = str_replace( '[data-start]', $start_wrapper, $line );
753 $line = str_replace( '[data-end]', $end_wrapper, $line );
754 }
755
756 echo '<div class="item" style="color:' . esc_html( $currentColor ) . '"><div class="mainwpactionlogsline">';
757
758 echo $prefix . ' ' . $line; // phpcs:ignore WordPress.Security.EscapeOutput
759
760 echo '</div></div>';
761 }
762
763 echo '</div></div>';
764
765 echo '</div>';
766
767 ?>
768 <div class="ui large modal" id="mainwp-action-log-response-modal">
769 <i class="close icon mainwp-reload"></i>
770 <div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div>
771 <div class="content">
772 <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' ); ?>
773 </div>
774 </div>
775 <div class="scrolling content content-response"></div>
776 <div class="actions">
777 <button class="ui green button mainwp-response-copy-button"><?php esc_html_e( 'Copy Response', 'mainwp' ); ?></button>
778 </div>
779 </div>
780 <?php
781 }
782
783 /**
784 * Method show_log_file()
785 *
786 * Grab log file and build output to screen.
787 */
788 public function show_log_file() { // phpcs:ignore -- NOSONAR - complex.
789 $logFile = $this->get_log_file();
790
791 if ( ! file_exists( $logFile ) ) {
792 return;
793 }
794
795 $fh = fopen( $logFile, 'r' );
796 if ( false === $fh ) {
797 return;
798 }
799
800 $previousColor = '';
801 $fontOpen = false;
802 $firstLinePassedProcessed = false;
803 echo '<div class="ui hidden divider"></div>';
804 echo '<div class="ui divided padded relaxed list">';
805 while ( false !== ( $line = fgets( $fh ) ) ) {
806 $currentColor = $previousColor;
807 if ( stristr( $line, '[DEBUG]' ) ) {
808 $currentColor = static::DEBUG_COLOR;
809 $firstLinePassed = true;
810 } elseif ( stristr( $line, '[INFO]' ) ) {
811 $currentColor = static::INFO_COLOR;
812 $firstLinePassed = true;
813 } elseif ( stristr( $line, '[WARNING]' ) ) {
814 $currentColor = static::WARNING_COLOR;
815 $firstLinePassed = true;
816 } elseif ( stristr( $line, '[LOG]' ) ) {
817 $currentColor = static::LOG_COLOR;
818 $firstLinePassed = true;
819 } else {
820 $firstLinePassed = false;
821 }
822
823 if ( $firstLinePassedProcessed && ! $firstLinePassed ) {
824 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;">';
825 }
826
827 $firstLinePassedProcessed = $firstLinePassed;
828
829 if ( $currentColor !== $previousColor ) {
830 if ( $fontOpen ) {
831 echo '</div></div>';
832 }
833
834 echo '<div class="item" style="color:' . esc_html( $currentColor ) . '"><div class="mainwpactionlogsline">';
835 $fontOpen = true;
836 }
837
838 echo esc_html( htmlentities( $line ) );
839 }
840
841 if ( $fontOpen ) {
842 echo '</div></div>';
843 }
844
845 echo '</div>';
846
847 ?>
848 <div class="ui large modal" id="mainwp-action-log-response-modal">
849 <i class="close icon mainwp-reload"></i>
850 <div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div>
851 <div class="content">
852 <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' ); ?>
853 </div>
854 </div>
855 <div class="scrolling content content-response"></div>
856 <div class="actions">
857 <button class="ui green button mainwp-response-copy-button"><?php esc_html_e( 'Copy Response', 'mainwp' ); ?></button>
858 </div>
859 </div>
860 <?php
861
862 fclose( $fh );
863 }
864 }
865