PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 4.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v4.1
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 4.1, at class/class-mainwp-logger.php

461 lines 10.6 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 {
18
19 // phpcs:disable WordPress.WP.AlternativeFunctions -- for custom read/write logging file.
20
21 const DISABLED = - 1;
22 const LOG = 0;
23 const WARNING = 1;
24 const INFO = 2;
25 const DEBUG = 3;
26 const INFO_UPDATE = 10;
27
28 const LOG_COLOR = 'black';
29 const DEBUG_COLOR = 'gray';
30 const INFO_COLOR = 'gray';
31 const WARNING_COLOR = 'red';
32
33 /**
34 * Private varibale to hold the log file prefix.
35 *
36 * @var string Default 'mainwp'
37 */
38 private $logFileNamePrefix = 'mainwp';
39
40 /**
41 * Private varibale to hold the log file suffix.
42 *
43 * @var string Default '.log'
44 */
45 private $logFileNameSuffix = '.log';
46
47 /**
48 * Private varibale to hold the log file max size.
49 *
50 * @var int Default 0.5
51 */
52 private $logMaxMB = 0.5;
53
54 /**
55 * Private varibale to hold the log file date format.
56 *
57 * @var string Default 'Y-m-d H:i:s'
58 */
59 private $logDateFormat = 'Y-m-d H:i:s';
60
61 /**
62 * Private varibale to hold the log file output directory.
63 *
64 * @var mixed Default null
65 */
66 private $logDirectory = null;
67
68 /**
69 * Private varibale to hold the log file priotrity.
70 *
71 * @var string Disabled
72 */
73 private $logPriority = self::DISABLED;
74
75 /**
76 * Private static varibale to hold the instance.
77 *
78 * @var mixed Default null
79 */
80 private static $instance = null;
81
82 /**
83 * Method instance()
84 *
85 * Returns new MainWP_Logger instance.
86 *
87 * @return self MainWP_Logger
88 */
89 public static function instance() {
90 if ( null == self::$instance ) {
91 self::$instance = new MainWP_Logger();
92 }
93
94 return self::$instance;
95 }
96
97 /**
98 * MainWP_Logger constructor.
99 *
100 * Run each time the class is called.
101 */
102 private function __construct() {
103 $this->logDirectory = MainWP_System_Utility::get_mainwp_dir();
104 $this->logDirectory = $this->logDirectory[0];
105
106 $enabled = get_option( 'mainwp_actionlogs' );
107 if ( false === $enabled ) {
108 $enabled = self::DISABLED;
109 }
110
111 $this->set_log_priority( $enabled );
112 }
113
114 /**
115 * Method set_log_priority()
116 *
117 * Sets the log priority.
118 *
119 * @param mixed $logPriority Log priority value.
120 */
121 public function set_log_priority( $logPriority ) {
122 $this->logPriority = $logPriority;
123 }
124
125 /**
126 * Method debug()
127 *
128 * Grab debug.
129 *
130 * @param string $text Debug message text.
131 *
132 * @return string Log debug message.
133 */
134 public function debug( $text ) {
135 return $this->log( $text, self::DEBUG );
136 }
137
138 /**
139 * Method info()
140 *
141 * Grab info.
142 *
143 * @param string $text Info message text.
144 *
145 * @return string Log info message.
146 */
147 public function info( $text ) {
148 return $this->log( $text, self::INFO );
149 }
150
151 /**
152 * Method warning()
153 *
154 * Grab warning information.
155 *
156 * @param string $text Warning message text.
157 *
158 * @return string Log warning message.
159 */
160 public function warning( $text ) {
161 return $this->log( $text, self::WARNING );
162 }
163
164 /**
165 * Method info_update()
166 *
167 * Grab info update
168 *
169 * @param string $text Info Update message text.
170 *
171 * @return string Log info update message.
172 */
173 public function info_update( $text ) {
174 return $this->log( $text, self::INFO_UPDATE );
175 }
176
177
178 /**
179 * Method debug_for_website()
180 *
181 * Grab website debug and info.
182 *
183 * @param object $website Child site object.
184 * @param string $action Performed action.
185 * @param string $message Debug message.
186 *
187 * @return mixed Website debug info.
188 */
189 public function debug_for_website( $website, $action, $message ) {
190 if ( empty( $website ) ) {
191 return $this->log( '[-] [-] ::' . $action . ':: ' . $message, self::DEBUG );
192 }
193
194 return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, self::DEBUG );
195 }
196
197 /**
198 * Method info_for_website()
199 *
200 * Grab Website Info.
201 *
202 * @param object $website Child site object.
203 * @param string $action Performed action.
204 * @param string $message Info message.
205 *
206 * @return mixed Website Info.
207 */
208 public function info_for_website( $website, $action, $message ) {
209 if ( empty( $website ) ) {
210 return $this->log( '[-] [-] ::' . $action . ':: ' . $message, self::INFO );
211 }
212
213 return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, self::INFO );
214 }
215
216 /**
217 * Method warning_for_website()
218 *
219 * Grab Website Warnings.
220 *
221 * @param object $website Child site object.
222 * @param string $action Performed action.
223 * @param string $message Warning message.
224 * @param bool $addStackTrace Add or Don't add stack trace.
225 *
226 * @return string Website warnings.
227 */
228 public function warning_for_website( $website, $action, $message, $addStackTrace = true ) {
229 $stackTrace = '';
230 if ( $addStackTrace ) {
231 ob_start();
232 // phpcs:ignore -- for debugging.
233 debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
234 $stackTrace = "\n" . ob_get_clean();
235 }
236 if ( empty( $website ) ) {
237 return $this->log( '[-] [-] ::' . $action . ':: ' . $message . $stackTrace, self::WARNING );
238 }
239
240 return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message . $stackTrace, self::WARNING );
241 }
242
243
244 /**
245 * Method log()
246 *
247 * Create Log File.
248 *
249 * @param string $text Log record text.
250 * @param int $priority Set priority.
251 *
252 * @return booleen True|False Default is False.
253 */
254 public function log( $text, $priority ) {
255
256 $do_log = false;
257 if ( ( self::INFO_UPDATE == $priority && self::INFO_UPDATE == $this->logPriority ) ||
258 ( self::INFO_UPDATE != $priority && $this->logPriority >= $priority ) ) {
259 $do_log = true;
260 }
261
262 if ( $do_log ) {
263 $this->logCurrentFile = $this->logDirectory . $this->logFileNamePrefix . $this->logFileNameSuffix;
264 $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
265
266 if ( $logCurrentHandle ) {
267 $time = gmdate( $this->logDateFormat );
268 $prefix = '[' . $this->get_log_text( $priority ) . ']';
269
270 /**
271 * Current user global.
272 *
273 * @global string
274 */
275 global $current_user;
276
277 if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
278 $prefix .= ' [' . $current_user->user_login . ']';
279 }
280
281 fwrite( $logCurrentHandle, $time . ' ' . $prefix . ' ' . $text . "\n" );
282 fclose( $logCurrentHandle );
283 }
284
285 if ( filesize( $this->logCurrentFile ) > ( $this->logMaxMB * 1048576 ) ) {
286 $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
287 if ( $logCurrentHandle ) {
288 fseek( $logCurrentHandle, 0 );
289 $newLogFile = $this->logCurrentFile . '.tmp';
290 $newLogHandle = false;
291 $chunkSize = filesize( $this->logCurrentFile ) - ( $this->logMaxMB * 1048576 );
292 while ( is_resource( $logCurrentHandle ) && ! feof( $logCurrentHandle ) && ( $chunkSize > 0 ) ) {
293 $content = fread( $logCurrentHandle, $chunkSize );
294 if ( false === $content ) {
295 break;
296 }
297 $pos = strrpos( $content, "\n" );
298 if ( $newLogHandle ) {
299 fwrite( $newLogHandle, $content );
300 } elseif ( $pos ) {
301 if ( ! $newLogHandle ) {
302 $newLogHandle = fopen( $newLogFile, 'w+' );
303 }
304 fwrite( $newLogHandle, substr( $content, $pos + 1 ) );
305 }
306 }
307
308 if ( is_resource( $logCurrentHandle ) ) {
309 fclose( $logCurrentHandle );
310 }
311
312 if ( $newLogHandle ) {
313 fclose( $newLogHandle );
314 unlink( $this->logCurrentFile );
315 if ( file_exists( $newLogFile ) ) {
316 rename( $newLogFile, $this->logCurrentFile );
317 }
318 }
319 }
320 }
321
322 return true;
323 }
324
325 return false;
326 }
327
328 /**
329 * Method prepend()
330 *
331 * Prepend content to log file.
332 *
333 * @param mixed $string Custom string.
334 * @param mixed $filename Filename.
335 */
336 public function prepend( $string, $filename ) {
337 $context = stream_context_create();
338 $fp = fopen( $filename, 'r', 1, $context );
339 $tmpname = md5( $string );
340 file_put_contents( $tmpname, $string );
341 file_put_contents( $tmpname, $fp, FILE_APPEND );
342 fclose( $fp );
343 unlink( $filename );
344 rename( $tmpname, $filename );
345 }
346
347 /**
348 * Method get_log_file()
349 *
350 * Grab Log File.
351 *
352 * @return mixed Log File.
353 */
354 public function get_log_file() {
355 return $this->logDirectory . $this->logFileNamePrefix . $this->logFileNameSuffix;
356 }
357
358 /**
359 * Method get_log_text()
360 *
361 * Grab what type of log entry.
362 *
363 * @param mixed $priority Set priority.
364 *
365 * @return string LOG -OR- DISABLED|DEBUG|INFO|WARNING|INFO UPDATE
366 */
367 public function get_log_text( $priority ) {
368 switch ( $priority ) {
369 case self::DISABLED:
370 return 'DISABLED';
371 case self::DEBUG:
372 return 'DEBUG';
373 case self::INFO:
374 return 'INFO';
375 case self::WARNING:
376 return 'WARNING';
377 case self::INFO_UPDATE:
378 return 'INFO UPDATE';
379 default:
380 return 'LOG';
381 }
382 }
383
384 /**
385 * Method clear_log()
386 *
387 * Clear the log file.
388 */
389 public static function clear_log() {
390 $logFile = self::instance()->get_log_file();
391 if ( ! unlink( $logFile, 'r' ) ) {
392 $fh = fopen( $logFile, 'w' );
393 if ( false === $fh ) {
394 return;
395 }
396
397 fclose( $fh );
398 }
399 }
400
401 /**
402 * Method show_log()
403 *
404 * Grab log file and build output to screen.
405 */
406 public static function show_log() {
407 $logFile = self::instance()->get_log_file();
408 $fh = fopen( $logFile, 'r' );
409 if ( false === $fh ) {
410 return;
411 }
412
413 $previousColor = '';
414 $fontOpen = false;
415 $firstLinePassedProcessed = false;
416 while ( false !== ( $line = fgets( $fh ) ) ) {
417 $currentColor = $previousColor;
418 if ( stristr( $line, '[DEBUG]' ) ) {
419 $currentColor = self::DEBUG_COLOR;
420 $firstLinePassed = true;
421 } elseif ( stristr( $line, '[INFO]' ) ) {
422 $currentColor = self::INFO_COLOR;
423 $firstLinePassed = true;
424 } elseif ( stristr( $line, '[WARNING]' ) ) {
425 $currentColor = self::WARNING_COLOR;
426 $firstLinePassed = true;
427 } elseif ( stristr( $line, '[LOG]' ) ) {
428 $currentColor = self::LOG_COLOR;
429 $firstLinePassed = true;
430 } else {
431 $firstLinePassed = false;
432 }
433
434 if ( $firstLinePassedProcessed && ! $firstLinePassed ) {
435 echo ' <strong><span class="mainwp-green">[multiline, click to read full]</span></strong></div><div style="display: none;">';
436 } else {
437 echo '<br />';
438 }
439 $firstLinePassedProcessed = $firstLinePassed;
440
441 if ( $currentColor != $previousColor ) {
442 if ( $fontOpen ) {
443 echo '</div></font>';
444 }
445
446 echo '<font color="' . $currentColor . '"><div class="mainwpactionlogsline">';
447 $fontOpen = true;
448 }
449
450 echo htmlentities( $line );
451 }
452
453 if ( $fontOpen ) {
454 echo '</div></font>';
455 }
456
457 fclose( $fh );
458 }
459
460 }
461