PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 4.0.5
MainWP Dashboard: Self-hosted WordPress Management for Agencies v4.0.5
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
← All changes | class/class-mainwp-logger.php +215 -812 5.14.0.5 View file →
@@ -1,864 +1,267 @@
1 1 <?php
2 -/**
3 - * MainWP Logger
4 - *
5 - * For custom read/write logging file.
6 - *
7 - * @package MainWP/Dashboard
8 - */
9 2
10 -namespace MainWP\Dashboard;
3 +class MainWP_Logger {
11 4
12 -/**
13 - * Class MainWP_Logger
14 - *
15 - * @package MainWP\Dashboard
16 - */
17 -class MainWP_Logger { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
5 + const DISABLED = - 1;
6 + const LOG = 0;
7 + const WARNING = 1;
8 + const INFO = 2;
9 + const DEBUG = 3;
10 + const INFO_UPDATE = 10;
18 11
19 - // phpcs:disable WordPress.WP.AlternativeFunctions -- for custom read/write logging file.
12 + const LOG_COLOR = 'black';
13 + const DEBUG_COLOR = 'gray';
14 + const INFO_COLOR = 'gray';
15 + const WARNING_COLOR = 'red';
20 16
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;
17 + private $logFileNamePrefix = 'mainwp';
18 + private $logFileNameSuffix = '.log';
19 + // private $logMaxFiles = 5; //todo: future add log rotation
20 + private $logMaxMB = 0.5;
21 + private $logDateFormat = 'Y-m-d H:i:s';
22 + private $logDirectory = null;
23 + private $logPriority = MainWP_Logger::DISABLED; //default
24 + private static $instance = null;
26 25
27 - const DISABLED = - 1;
28 - const LOG = 0;
29 - const WARNING = 1;
30 - const INFO = 2;
31 - const DEBUG = 3;
26 + /**
27 + * @return MainWP_Logger
28 + */
29 + static function Instance() {
30 + if ( MainWP_Logger::$instance == null ) {
31 + MainWP_Logger::$instance = new MainWP_Logger();
32 + }
32 33
33 - const LOG_COLOR = '#999999';
34 - const DEBUG_COLOR = '#666666';
35 - const INFO_COLOR = '#276f86';
36 - const WARNING_COLOR = '#9f3a38;';
34 + return MainWP_Logger::$instance;
35 + }
37 36
38 - /**
39 - * Private variable to hold time start.
40 - *
41 - * @var int
42 - */
43 - private static $time_start = null;
37 + private function __construct() {
38 + $this->logDirectory = MainWP_Utility::getMainWPDir();
39 + $this->logDirectory = $this->logDirectory[ 0 ];
44 40
45 - /**
46 - * Private varibale to hold the log file prefix.
47 - *
48 - * @var string Default 'mainwp'
49 - */
50 - private $logFileNamePrefix = 'mainwp';
41 + $enabled = get_option( 'mainwp_actionlogs' );
42 + if ( $enabled === false ) {
43 + $enabled = MainWP_Logger::DISABLED;
44 + }
51 45
52 - /**
53 - * Private varibale to hold the log file suffix.
54 - *
55 - * @var string Default '.log'
56 - */
57 - private $logFileNameSuffix = '.log';
46 + $this->setLogPriority( $enabled );
47 + }
58 48
59 - /**
60 - * Private varibale to hold the log file max size.
61 - *
62 - * @var int Default 0.5
63 - */
64 - private $logMaxMB = 0.5;
49 + public function setLogPriority( $pLogPriority ) {
50 + $this->logPriority = $pLogPriority;
51 + }
65 52
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';
53 + public function debug( $pText ) {
54 + return $this->log( $pText, self::DEBUG );
55 + }
72 56
73 - /**
74 - * Private varibale to hold the log file output directory.
75 - *
76 - * @var mixed Default null
77 - */
78 - private $logDirectory = null;
57 + public function info( $pText ) {
58 + return $this->log( $pText, self::INFO );
59 + }
79 60
80 - /**
81 - * Private varibale to hold the log file priotrity.
82 - *
83 - * @var string Disabled
84 - */
85 - private $logPriority = self::DISABLED;
61 + public function warning( $pText ) {
62 + return $this->log( $pText, self::WARNING );
63 + }
86 64
87 - /**
88 - * Private varibale to hold the log Specific priotrity.
89 - *
90 - * @var string Disabled
91 - */
92 - private $logSpecific = 0;
65 + public function info_update( $pText ) {
66 + return $this->log( $pText, self::INFO_UPDATE );
67 + }
93 68
69 + public function debugForWebsite( $pWebsite, $pAction, $pMessage ) {
70 + if ( empty( $pWebsite ) ) {
71 + return $this->log( '[-] [-] ::' . $pAction . ':: ' . $pMessage, self::DEBUG );
72 + }
94 73
95 - /**
96 - * Private static varibale to hold the instance.
97 - *
98 - * @var mixed Default null
99 - */
100 - private static $instance = null;
74 + return $this->log( '[' . $pWebsite->name . '] [' . MainWP_Utility::getNiceURL( $pWebsite->url ) . '] ::' . $pAction . ':: ' . $pMessage, self::DEBUG );
75 + }
101 76
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 - }
77 + public function infoForWebsite( $pWebsite, $pAction, $pMessage ) {
78 + if ( empty( $pWebsite ) ) {
79 + return $this->log( '[-] [-] ::' . $pAction . ':: ' . $pMessage, self::INFO );
80 + }
117 81
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() {
82 + return $this->log( '[' . $pWebsite->name . '] [' . MainWP_Utility::getNiceURL( $pWebsite->url ) . '] ::' . $pAction . ':: ' . $pMessage, self::INFO );
83 + }
126 84
127 - $enabled = $this->get_log_status();
128 - $specific = $this->get_log_specific();
85 + public function warningForWebsite( $pWebsite, $pAction, $pMessage, $addStackTrace = true ) {
86 + $stackTrace = '';
87 + if ( $addStackTrace ) {
88 + @ob_start();
89 + @debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
90 + $stackTrace = "\n" . @ob_get_clean();
91 + }
92 + if ( empty( $pWebsite ) ) {
93 + return $this->log( '[-] [-] ::' . $pAction . ':: ' . $pMessage . $stackTrace, self::WARNING );
94 + }
129 95
130 - $enabled = apply_filters( 'mainwp_log_status', $enabled );
131 - $specific = apply_filters( 'mainwp_log_specific', $specific );
96 + return $this->log( '[' . $pWebsite->name . '] [' . MainWP_Utility::getNiceURL( $pWebsite->url ) . '] ::' . $pAction . ':: ' . $pMessage . $stackTrace, self::WARNING );
97 + }
132 98
133 - $this->set_log_priority( $enabled, $specific );
134 - }
99 + public function log( $pText, $pPriority ) {
135 100
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 ) {
101 + $do_log = false;
102 + if ( ( $pPriority == self::INFO_UPDATE && $this->logPriority == self::INFO_UPDATE ) ||
103 + ( $pPriority != self::INFO_UPDATE && $this->logPriority >= $pPriority ) )
104 + {
379 105 $do_log = true;
380 106 }
381 107
382 - $do_log = apply_filters( 'mainwp_log_do_to_db', $do_log, $website );
108 + if ( $do_log ) {
109 + $this->logCurrentFile = $this->logDirectory . $this->logFileNamePrefix . $this->logFileNameSuffix;
110 + $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
383 111
384 - $text = $this->prepare_log_info( $text );
112 + if ( $logCurrentHandle ) {
113 + $time = date( $this->logDateFormat );
114 + $prefix = '[' . $this->getLogText( $pPriority ) . ']';
385 115
386 - do_action( 'mainwp_before_log_data', $text, $priority, $log_color );
116 + global $current_user;
387 117
388 - if ( defined( 'DOING_CRON' ) && DOING_CRON && 'CRON' !== strtoupper( substr( $text, 0, 4 ) ) ) {
389 - $text = 'CRON :: ' . $text;
390 - }
118 + if ( !empty( $current_user ) && !empty( $current_user->user_login ) ) {
119 + $prefix .= ' [' . $current_user->user_login . ']';
120 + }
391 121
392 - if ( $forced || $do_log ) {
122 + fwrite( $logCurrentHandle, $time . ' ' . $prefix . ' ' . $pText . "\n" );
123 + fclose( $logCurrentHandle );
124 + }
393 125
394 - /**
395 - * Current user global.
396 - *
397 - * @global string
398 - */
399 - global $current_user;
126 + if ( filesize( $this->logCurrentFile ) > ( $this->logMaxMB * 1048576 ) ) {
127 + $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
128 + if ( $logCurrentHandle ) {
129 + fseek( $logCurrentHandle, 0 );
130 + $newLogFile = $this->logCurrentFile . '.tmp';
131 + $newLogHandle = false;
132 + $chunkSize = filesize( $this->logCurrentFile ) - ( $this->logMaxMB * 1048576 );
133 + while ( is_resource( $logCurrentHandle ) && !feof( $logCurrentHandle ) && ( $chunkSize > 0 ) ) {
134 + $content = fread( $logCurrentHandle, $chunkSize );
135 + if ( $content === false ) {
136 + break;
137 + }
400 138
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 - }
139 + if ( $newLogHandle ) {
140 + fwrite( $newLogHandle, $content );
141 + } else if ( $pos = strrpos( $content, "\n" ) ) {
142 + if ( !$newLogHandle ) {
143 + $newLogHandle = fopen( $newLogFile, 'w+' );
144 + }
145 + fwrite( $newLogHandle, substr( $content, $pos + 1 ) );
146 + }
147 + }
409 148
410 - $data = array();
149 + if ( is_resource( $logCurrentHandle ) ) {
150 + fclose( $logCurrentHandle );
151 + }
411 152
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 ) ) {
153 + if ( $newLogHandle ) {
154 + fclose( $newLogHandle );
155 + unlink( $this->logCurrentFile );
156 + if (file_exists($newLogFile))
517 157 rename( $newLogFile, $this->logCurrentFile );
518 - }
519 - }
520 - }
521 - }
158 + }
159 + }
160 + }
522 161
523 - return true;
524 - }
162 + return true;
163 + }
525 164
526 - return false;
527 - }
165 + return false;
166 + }
528 167
168 + function prepend( $string, $filename ) {
169 + $context = stream_context_create();
170 + $fp = fopen( $filename, 'r', 1, $context );
171 + $tmpname = md5( $string );
172 + file_put_contents( $tmpname, $string );
173 + file_put_contents( $tmpname, $fp, FILE_APPEND );
174 + fclose( $fp );
175 + unlink( $filename );
176 + rename( $tmpname, $filename );
177 + }
529 178
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 - }
179 + function getLogFile() {
180 + return $this->logDirectory . $this->logFileNamePrefix . $this->logFileNameSuffix;
181 + }
549 182
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 - }
183 + public function getLogText( $pPriority ) {
184 + switch ( $pPriority ) {
185 + case self::DISABLED:
186 + return 'DISABLED';
187 + case self::DEBUG:
188 + return 'DEBUG';
189 + case self::INFO:
190 + return 'INFO';
191 + case self::WARNING:
192 + return 'WARNING';
193 + case self::INFO_UPDATE:
194 + return 'INFO UPDATE';
195 + default:
196 + return 'LOG';
197 + }
198 + }
568 199
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 - }
200 + public static function clearLog() {
201 + $logFile = MainWP_Logger::Instance()->getLogFile();
202 + if ( !@unlink( $logFile, 'r' ) ) {
203 + $fh = @fopen( $logFile, 'w' );
204 + if ( $fh === false ) {
205 + return;
206 + }
581 207
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 - }
208 + @fclose( $fh );
209 + }
210 + }
587 211
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 - }
212 + public static function showLog() {
213 + $logFile = MainWP_Logger::Instance()->getLogFile();
214 + $fh = @fopen( $logFile, 'r' );
215 + if ( $fh === false ) {
216 + return;
217 + }
599 218
219 + $previousColor = ''; //self::LOG_COLOR;
220 + $fontOpen = false;
221 + $firstLinePassedProcessed = false;
222 + while ( ( $line = fgets( $fh ) ) !== false ) {
223 + $currentColor = $previousColor;
224 + if ( stristr( $line, '[DEBUG]' ) ) {
225 + $currentColor = self::DEBUG_COLOR;
226 + $firstLinePassed = true;
227 + } else if ( stristr( $line, '[INFO]' ) ) {
228 + $currentColor = self::INFO_COLOR;
229 + $firstLinePassed = true;
230 + } else if ( stristr( $line, '[WARNING]' ) ) {
231 + $currentColor = self::WARNING_COLOR;
232 + $firstLinePassed = true;
233 + } else if ( stristr( $line, '[LOG]' ) ) {
234 + $currentColor = self::LOG_COLOR;
235 + $firstLinePassed = true;
236 + } else {
237 + $firstLinePassed = false;
238 + }
600 239
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 = '' ) {
240 + if ( $firstLinePassedProcessed && !$firstLinePassed ) {
241 + echo ' <strong><span class="mainwp-green">[multiline, click to read full]</span></strong></div><div style="display: none;">';
242 + } else {
243 + echo '<br />';
244 + }
245 + $firstLinePassedProcessed = $firstLinePassed;
611 246
612 - if ( empty( static::$time_start ) ) {
613 - return 0;
614 - }
247 + if ( $currentColor != $previousColor ) {
248 + if ( $fontOpen ) {
249 + echo '</div></font>';
250 + }
615 251
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 - }
252 + echo '<font color="' . $currentColor . '"><div class="mainwpactionlogsline">';
253 + $fontOpen = true;
254 + }
620 255
621 - if ( empty( $start ) ) {
622 - $start = is_array( static::$time_start ) && isset( static::$time_start['start'] ) ? static::$time_start['start'] : 0;
623 - }
256 + // process the line read.
257 + echo htmlentities( $line );
258 + }
624 259
625 - if ( empty( $start ) ) {
626 - return 0;
627 - }
628 - return microtime( true ) - $start; // seconds.
629 - }
260 + if ( $fontOpen ) {
261 + echo '</div></font>';
262 + }
630 263
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 - }
264 + @fclose( $fh );
265 + }
645 266
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 267 }