PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.1
6.2.2 6.2.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 All 155 releases
← All changes | class/class-mainwp-logger.php +1109 -725 4.6.0.1 → 6.2.1 View file →
@@ -8,853 +8,1237 @@
8 8 */
9 9
10 10 namespace MainWP\Dashboard;
11 11
12 +// Exit if accessed directly.
13 +if ( ! defined( 'ABSPATH' ) ) {
14 + exit;
15 +}
16 +
12 17 /**
13 18 * Class MainWP_Logger
14 19 *
15 20 * @package MainWP\Dashboard
16 21 */
17 -class MainWP_Logger {
22 +class MainWP_Logger { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
18 23
19 - // phpcs:disable WordPress.WP.AlternativeFunctions -- for custom read/write logging file.
24 + // phpcs:disable WordPress.WP.AlternativeFunctions -- for custom read/write logging file.
20 25
21 - const UPDATE_CHECK_LOG_PRIORITY = 10;
22 - const EXECUTION_TIME_LOG_PRIORITY = 15;
23 - const LOGS_AUTO_PURGE_LOG_PRIORITY = 16;
26 + const UPDATE_CHECK_LOG_PRIORITY = 10;
27 + const EXECUTION_TIME_LOG_PRIORITY = 15;
28 + const LOGS_AUTO_PURGE_LOG_PRIORITY = 16;
29 + const LOGS_REGULAR_SCHEDULE = 18;
30 + const DEBUG_UPDATES_SCHEDULE = 19;
31 + const COST_TRACKER_LOG_PRIORITY = 20230112;
32 + const API_BACKUPS_LOG_PRIORITY = 20240130;
33 + const CONNECT_LOG_PRIORITY = 20241001;
34 + const UPTIME_CHECK_LOG_PRIORITY = 20241017;
35 + const UPTIME_NOTICE_LOG_PRIORITY = 20241106;
36 + const SITES_CHANGES_LOG_PRIORITY = 20250417;
37 + const CACHE_METRICS_LOG_PRIORITY = 20250814;
38 + const DB_QUERIES_LOG_PRIORITY = 20250827;
39 + const UNHOOKS_LOG_PRIORITY = 20250901;
40 + const WARM_CACHE_LOG_PRIORITY = 20250915;
41 + const EXTENSION_UPDATES_CHECK_LOG_PRIORITY = 20260306;
42 + const EXECUTION_SYNC_LOG_PRIORITY = 20260316;
43 + const EXECUTION_SYNC_DETAILS_LOG_PRIORITY = 20260323;
44 + const AUTO_UPDATES_LOG_PRIORITY = 20260707;
24 45
25 46
26 - const DISABLED = - 1;
27 - const LOG = 0;
28 - const WARNING = 1;
29 - const INFO = 2;
30 - const DEBUG = 3;
47 + const DISABLED = - 1;
48 + const LOG = 0;
49 + const WARNING = 1;
50 + const INFO = 2;
51 + const DEBUG = 3;
52 + const NOTICE = 4;
31 53
32 - const LOG_COLOR = '#999999';
33 - const DEBUG_COLOR = '#666666';
34 - const INFO_COLOR = '#276f86';
35 - const WARNING_COLOR = '#9f3a38;';
54 + const LOG_COLOR = '#999999';
55 + const DEBUG_COLOR = '#666666';
56 + const INFO_COLOR = '#276f86';
57 + const NOTICE_COLOR = '#eb7609';
58 + const WARNING_COLOR = '#9f3a38';
36 59
37 - /**
38 - * Private variable to hold time start.
39 - *
40 - * @var int
41 - */
42 - private static $time_start = null;
60 + /**
61 + * Private variable to hold time start.
62 + *
63 + * @var int
64 + */
65 + private static $time_start = null;
43 66
44 - /**
45 - * Private varibale to hold the log file prefix.
46 - *
47 - * @var string Default 'mainwp'
48 - */
49 - private $logFileNamePrefix = 'mainwp';
67 + /**
68 + * Private varibale to hold the log file prefix.
69 + *
70 + * @var string Default 'mainwp'
71 + */
72 + private $logFileNamePrefix = 'mainwp';
50 73
51 - /**
52 - * Private varibale to hold the log file suffix.
53 - *
54 - * @var string Default '.log'
55 - */
56 - private $logFileNameSuffix = '.log';
74 + /**
75 + * Private varibale to hold the log file suffix.
76 + *
77 + * @var string Default '.log'
78 + */
79 + private $logFileNameSuffix = '.log';
57 80
58 - /**
59 - * Private varibale to hold the log file max size.
60 - *
61 - * @var int Default 0.5
62 - */
63 - private $logMaxMB = 0.5;
81 + /**
82 + * Private varibale to hold the log file max size.
83 + *
84 + * @var int Default 0.5
85 + */
86 + private $logMaxMB = 0.5;
64 87
65 - /**
66 - * Private varibale to hold the log file date format.
67 - *
68 - * @var string Default 'Y-m-d H:i:s'
69 - */
70 - private $logDateFormat = 'Y-m-d H:i:s';
88 + /**
89 + * Private varibale to hold the log file date format.
90 + *
91 + * @var string Default 'Y-m-d H:i:s'
92 + */
93 + private $logDateFormat = 'Y-m-d H:i:s';
71 94
72 - /**
73 - * Private varibale to hold the log file output directory.
74 - *
75 - * @var mixed Default null
76 - */
77 - private $logDirectory = null;
95 + /**
96 + * Private varibale to hold the log file output directory.
97 + *
98 + * @var mixed Default null
99 + */
100 + private $logDirectory = null;
78 101
79 - /**
80 - * Private varibale to hold the log file priotrity.
81 - *
82 - * @var string Disabled
83 - */
84 - private $logPriority = self::DISABLED;
102 + /**
103 + * Private varibale to hold the log file priotrity.
104 + *
105 + * @var string Disabled
106 + */
107 + private $logPriority = self::DISABLED;
85 108
86 - /**
87 - * Private varibale to hold the log Specific priotrity.
88 - *
89 - * @var string Disabled
90 - */
91 - private $logSpecific = 0;
109 + /**
110 + * Private varibale to hold the log Specific priotrity.
111 + *
112 + * @var string Disabled
113 + */
114 + private $logSpecific = 0;
92 115
116 + /**
117 + * Private varibale to hold the auto enable logging actions.
118 + *
119 + * @var array Auto enable logging.
120 + */
121 + private $autoEnableLoggingActions = array();
93 122
94 - /**
95 - * Private static varibale to hold the instance.
96 - *
97 - * @var mixed Default null
98 - */
99 - private static $instance = null;
100 123
101 - /**
102 - * Method instance()
103 - *
104 - * Returns new MainWP_Logger instance.
105 - *
106 - * @return self MainWP_Logger
107 - *
108 - * @uses \MainWP\Dashboard\MainWP_Logger
109 - */
110 - public static function instance() {
111 - if ( null === self::$instance ) {
112 - self::$instance = new self();
113 - }
114 - return self::$instance;
115 - }
124 + /**
125 + * Private static varibale to hold the instance.
126 + *
127 + * @var mixed Default null
128 + */
129 + private static $instance = null;
116 130
117 - /**
118 - * MainWP_Logger constructor.
119 - *
120 - * Run each time the class is called.
121 - *
122 - * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir()
123 - */
124 - private function __construct() {
131 + /**
132 + * Method instance()
133 + *
134 + * Returns new MainWP_Logger instance.
135 + *
136 + * @return self MainWP_Logger
137 + *
138 + * @uses \MainWP\Dashboard\MainWP_Logger
139 + */
140 + public static function instance() {
141 + if ( null === static::$instance ) {
142 + static::$instance = new self();
143 + }
144 + return static::$instance;
145 + }
125 146
126 - $enabled = $this->get_log_status();
127 - $specific = $this->get_log_specific();
147 + /**
148 + * MainWP_Logger constructor.
149 + *
150 + * Run each time the class is called.
151 + *
152 + * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir()
153 + */
154 + private function __construct() {
128 155
129 - $enabled = apply_filters( 'mainwp_log_status', $enabled );
130 - $specific = apply_filters( 'mainwp_log_specific', $specific );
156 + add_action( 'init', array( $this, 'init' ) ); // Fix the issue where database tables do not exist.
131 157
132 - $this->set_log_priority( $enabled, $specific );
133 - }
158 + $enabled = $this->get_log_status();
159 + $specific = $this->get_log_specific();
134 160
135 - /**
136 - * Method set_log_priority()
137 - *
138 - * Sets the log priority.
139 - *
140 - * @param mixed $logPriority Log priority value.
141 - * @param mixed $spec_log Specific log.
142 - */
143 - public function set_log_priority( $logPriority, $spec_log = 0 ) {
144 - $this->logPriority = (int) $logPriority;
145 - $this->logSpecific = (int) $spec_log; // 1 - specific log, 0 - not specific log.
146 - }
161 + $enabled = apply_filters( 'mainwp_log_status', $enabled );
162 + $specific = apply_filters( 'mainwp_log_specific', $specific );
147 163
148 - /**
149 - * Method get_log_status()
150 - *
151 - * Get log status.
152 - *
153 - * @return mixed $enabled log status.
154 - */
155 - public function get_log_status() {
156 - $enabled = get_option( 'mainwp_actionlogs' );
164 + $this->set_log_priority( $enabled, $specific );
157 165
158 - if ( false === $enabled ) {
159 - $sites_count = MainWP_DB::instance()->get_websites_count();
160 - if ( empty( $sites_count ) ) {
161 - $enabled = self::DEBUG;
162 - set_transient( 'mainwp_transient_action_logs', true, 2 * WEEK_IN_SECONDS );
163 - } elseif ( get_transient( 'mainwp_transient_action_logs' ) ) {
164 - $enabled = self::DEBUG;
165 - } else {
166 - $enabled = self::DISABLED;
167 - }
168 - }
169 - return $enabled;
170 - }
166 + $this->autoEnableLoggingActions = array(
167 + static::CONNECT_LOG_PRIORITY,
168 + );
169 + add_action( 'mainwp_module_log_record_inserted', array( $this, 'hook_module_log_record_inserted' ), 10, 2 );
170 + add_filter( 'mainwp_custom_log_enabled_log_priority', array( $this, 'hook_is_enabled_log_priority' ), 10, 1 );
171 + }
171 172
173 + /**
174 + * Method init.
175 + */
176 + public function init() {
177 + $enabled = get_option( 'mainwp_actionlogs' );
178 + if ( false === $enabled && ! get_transient( 'mainwp_transient_action_logs' ) ) {
179 + $sites_count = MainWP_DB::instance()->get_websites_count();
180 + if ( empty( $sites_count ) ) {
181 + set_transient( 'mainwp_transient_action_logs', true, 2 * WEEK_IN_SECONDS );
182 + }
183 + }
184 + }
172 185
173 - /**
174 - * Method get_log_specific()
175 - *
176 - * Get log specific status.
177 - *
178 - * @return mixed $enabled log status.
179 - */
180 - public function get_log_specific() {
181 - return get_option( 'mainwp_specific_logs', 0 );
182 - }
186 + /**
187 + * Method set_log_priority()
188 + *
189 + * Sets the log priority.
190 + *
191 + * @param mixed $logPriority Log priority value.
192 + * @param mixed $spec_log Specific log.
193 + */
194 + public function set_log_priority( $logPriority, $spec_log = 0 ) {
195 + $this->logPriority = (int) $logPriority;
196 + $this->logSpecific = (int) $spec_log; // 1 - specific log, 0 - not specific log.
197 + }
183 198
184 - /**
185 - * Method get_log_type_info()
186 - *
187 - * Get log type info.
188 - *
189 - * @param int $type Log type value.
190 - * @param int $logcolor Log color value.
191 - *
192 - * @return int $currentColor log color code.
193 - */
194 - public function get_log_type_info( $type, $logcolor ) {
195 - $currentColor = '';
196 - $prefix = '';
197 - if ( self::DEBUG === $type || self::DEBUG === $logcolor ) {
198 - $currentColor = self::DEBUG_COLOR;
199 - $prefix = '[DEBUG]';
200 - } elseif ( self::INFO === $type || self::INFO === $logcolor ) {
201 - $currentColor = self::INFO_COLOR;
202 - $prefix = '[INFO]';
203 - } elseif ( self::WARNING === $type || self::WARNING === $logcolor ) {
204 - $currentColor = self::WARNING_COLOR;
205 - $prefix = '[WARNING]';
206 - } elseif ( self::LOG === $type || self::LOG === $logcolor ) {
207 - $currentColor = self::LOG_COLOR;
208 - $prefix = '[LOG]';
209 - }
210 - return array(
211 - 'log_color' => $currentColor,
212 - 'log_prefix' => $prefix,
213 - );
214 - }
215 199
216 - /**
217 - * Method debug()
218 - *
219 - * Grab debug.
220 - *
221 - * @param string $text Debug message text.
222 - *
223 - * @return string Log debug message.
224 - */
225 - public function debug( $text ) {
226 - return $this->log( $text, self::DEBUG );
227 - }
200 + /**
201 + * Method enable_log_priority()
202 + *
203 + * Sets the log priority.
204 + *
205 + * @param mixed $logPriority Log priority value.
206 + * @param mixed $spec_log Specific log.
207 + */
208 + public function enable_log_priority( $logPriority, $spec_log = 1 ) {
209 + $spec_log = $spec_log ? 1 : 0;
210 + $logPriority = intval( $logPriority );
211 + MainWP_Utility::update_option( 'mainwp_specific_logs', $spec_log );
212 + MainWP_Utility::update_option( 'mainwp_actionlogs', $logPriority );
213 + MainWP_Utility::update_option( 'mainwp_actionlogs_enabled_timestamp', time() );
214 + $this->log_action( 'Action logs set to: ' . $this->get_log_text( $logPriority ), ( $spec_log ? $logPriority : static::LOG ), 2, true );
215 + $this->set_log_priority( $logPriority, $spec_log );
216 + }
228 217
229 - /**
230 - * Method info()
231 - *
232 - * Grab info.
233 - *
234 - * @param string $text Info message text.
235 - *
236 - * @return string Log info message.
237 - */
238 - public function info( $text ) {
239 - return $this->log( $text, self::INFO );
240 - }
241 218
242 - /**
243 - * Method warning()
244 - *
245 - * Grab warning information.
246 - *
247 - * @param string $text Warning message text.
248 - *
249 - * @return string Log warning message.
250 - */
251 - public function warning( $text ) {
252 - return $this->log( $text, self::WARNING );
253 - }
219 + /**
220 + * Method get_log_status()
221 + *
222 + * Get log status.
223 + *
224 + * @return mixed $enabled log status.
225 + */
226 + public function get_log_status() {
227 + $enabled = get_option( 'mainwp_actionlogs' );
228 + if ( false === $enabled ) {
229 + if ( get_transient( 'mainwp_transient_action_logs' ) ) {
230 + $enabled = self::DEBUG;
231 + } else {
232 + $enabled = static::DISABLED;
233 + }
234 + }
235 + return $enabled;
236 + }
254 237
255 - /**
256 - * Method actions()
257 - *
258 - * Grab actions information.
259 - *
260 - * @param string $text Warning message text.
261 - * @param int $priority priority message.
262 - * @param int $log_color Set color: 0 - LOG, 1 - WARNING, 2 - INFO, 3- DEBUG.
263 - * @param bool $forced forced logging.
264 - *
265 - * @return string Log warning message.
266 - */
267 - public function log_action( $text, $priority, $log_color = 0, $forced = false ) {
268 - return $this->log( $text, $priority, $log_color, $forced );
269 - }
270 238
239 + /**
240 + * Method get_log_specific()
241 + *
242 + * Get log specific status.
243 + *
244 + * @return mixed $enabled log status.
245 + */
246 + public function get_log_specific() {
247 + return get_option( 'mainwp_specific_logs', 0 );
248 + }
271 249
272 - /**
273 - * Method log_update_check().
274 - *
275 - * @param string $text Log update check.
276 - */
277 - public function log_update_check( $text = '' ) {
278 - $this->log_action( $text, self::UPDATE_CHECK_LOG_PRIORITY );
279 - }
250 + /**
251 + * Method get_log_type_info()
252 + *
253 + * Get log type info.
254 + *
255 + * @param int $type Log type value.
256 + * @param int $logcolor Log color value.
257 + *
258 + * @return array $currentColor log color code.
259 + */
260 + public function get_log_type_info( $type, $logcolor ) {
261 + $currentColor = '';
262 + $prefix = '';
263 + if ( static::DEBUG === $type || static::DEBUG === $logcolor ) {
264 + $currentColor = static::DEBUG_COLOR;
265 + $prefix = '[DEBUG]';
266 + } elseif ( static::INFO === $type || static::INFO === $logcolor ) {
267 + $currentColor = static::INFO_COLOR;
268 + $prefix = '[INFO]';
269 + } elseif ( static::WARNING === $type || static::WARNING === $logcolor ) {
270 + $currentColor = static::WARNING_COLOR;
271 + $prefix = '[WARNING]';
272 + } elseif ( static::LOG === $type || static::LOG === $logcolor ) {
273 + $currentColor = static::LOG_COLOR;
274 + $prefix = '[LOG]';
275 + } elseif ( static::NOTICE === $type || static::NOTICE === $logcolor ) {
276 + $currentColor = static::NOTICE_COLOR;
277 + $prefix = '[NOTICE]';
278 + }
279 + return array(
280 + 'log_color' => $currentColor,
281 + 'log_prefix' => $prefix,
282 + );
283 + }
280 284
281 - /**
282 - * Method debug_for_website()
283 - *
284 - * Grab website debug and info.
285 - *
286 - * @param object $website Child site object.
287 - * @param string $action Performed action.
288 - * @param string $message Debug message.
289 - *
290 - * @return mixed Website debug info.
291 - *
292 - * @uses \MainWP\Dashboard\MainWP_Utility::get_nice_url()
293 - */
294 - public function debug_for_website( $website, $action, $message ) {
295 - if ( empty( $website ) ) {
296 - return $this->log( '[-] [-] ::' . $action . ':: ' . $message, self::DEBUG );
297 - }
285 + /**
286 + * Method debug()
287 + *
288 + * Grab debug.
289 + *
290 + * @param string $text Debug message text.
291 + *
292 + * @return string Log debug message.
293 + */
294 + public function debug( $text ) {
295 + return $this->log( $text, static::DEBUG );
296 + }
298 297
299 - return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, self::DEBUG, 0, false, $website );
300 - }
298 + /**
299 + * Method info()
300 + *
301 + * Grab info.
302 + *
303 + * @param string $text Info message text.
304 + *
305 + * @return string Log info message.
306 + */
307 + public function info( $text ) {
308 + return $this->log( $text, static::INFO );
309 + }
301 310
302 - /**
303 - * Method info_for_website()
304 - *
305 - * Grab Website Info.
306 - *
307 - * @param object $website Child site object.
308 - * @param string $action Performed action.
309 - * @param string $message Info message.
310 - *
311 - * @return mixed Website Info.
312 - *
313 - * @uses \MainWP\Dashboard\MainWP_Utility::get_nice_url()
314 - */
315 - public function info_for_website( $website, $action, $message ) {
316 - if ( empty( $website ) ) {
317 - return $this->log( '[-] [-] ::' . $action . ':: ' . $message, self::INFO );
318 - }
311 + /**
312 + * Method warning()
313 + *
314 + * Grab warning information.
315 + *
316 + * @param string $text Warning message text.
317 + *
318 + * @return string Log warning message.
319 + */
320 + public function warning( $text ) {
321 + return $this->log( $text, static::WARNING );
322 + }
319 323
320 - return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, self::INFO );
321 - }
324 + /**
325 + * Method actions()
326 + *
327 + * Grab actions information.
328 + *
329 + * @param string $text Warning message text.
330 + * @param int $priority priority message.
331 + * @param int $log_color Set color: 0 - LOG, 1 - WARNING, 2 - INFO, 3- DEBUG.
332 + * @param bool $forced forced logging.
333 + * @param int $log_type Log type.
334 + *
335 + * @return string Log warning message.
336 + */
337 + public function log_action( $text, $priority, $log_color = 0, $forced = false, $log_type = 0 ) {
338 + return $this->log( $text, $priority, $log_color, $forced, false, $log_type );
339 + }
322 340
323 - /**
324 - * Method warning_for_website()
325 - *
326 - * Grab Website Warnings.
327 - *
328 - * @param object $website Child site object.
329 - * @param string $action Performed action.
330 - * @param string $message Warning message.
331 - * @param bool $addStackTrace Add or Don't add stack trace.
332 - *
333 - * @return string Website warnings.
334 - */
335 - public function warning_for_website( $website, $action, $message, $addStackTrace = true ) {
336 - $stackTrace = '';
337 - if ( $addStackTrace ) {
338 - ob_start();
339 - // phpcs:ignore -- for debugging.
340 - debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
341 - $stackTrace = "\n" . ob_get_clean();
342 - }
343 - if ( empty( $website ) ) {
344 - return $this->log( '[-] [-] :: ' . $action . ' :: ' . $message . $stackTrace, self::WARNING );
345 - }
346 341
347 - return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message . $stackTrace, self::WARNING );
348 - }
342 + /**
343 + * Method log_events().
344 + *
345 + * @param string $event_name Event name.
346 + * @param string $text Log update check.
347 + * @param mixed $color Log color.
348 + * @param int $log_type Log type.
349 + */
350 + public function log_events( $event_name, $text = '', $color = false, $log_type = false ) {
351 + $events = is_array( $event_name ) ? $event_name : explode( '|', $event_name );
352 + if ( is_array( $events ) ) {
353 + foreach ( $events as $event ) {
354 + switch ( $event ) {
355 + case 'update-check':
356 + $this->log_action( '[Update Checks] :: ' . $text, static::UPDATE_CHECK_LOG_PRIORITY );
357 + break;
358 + case 'regular-schedule':
359 + $this->log_action( '[Regular Schedule] :: ' . $text, static::LOGS_REGULAR_SCHEDULE );
360 + break;
361 + case 'debug-updates-crons':
362 + $this->log_action( '[Debug updates crons] :: ' . $text, static::DEBUG_UPDATES_SCHEDULE );
363 + break;
364 + case 'sites-changes':
365 + $this->log_action( '[Sites Changes] :: ' . $text, static::SITES_CHANGES_LOG_PRIORITY );
366 + break;
367 + case 'cache-metrics':
368 + $this->log_action( '[MainWP Cache] :: ' . $text, static::CACHE_METRICS_LOG_PRIORITY );
369 + break;
370 + case 'db-queries':
371 + $this->log_action( '[DB Queries] :: ' . $text, static::DB_QUERIES_LOG_PRIORITY );
372 + break;
373 + case 'unhooks':
374 + $this->log_action( '[Unhooks infor] :: ' . $text, static::UNHOOKS_LOG_PRIORITY, $color );
375 + break;
376 + case 'execution-time':
377 + $this->log_action( '[Execution time] :: ' . $text, static::EXECUTION_TIME_LOG_PRIORITY, $color );
378 + break;
379 + case 'execution-sync':
380 + $this->log_action( '[Execution Sync] :: ' . $text, static::EXECUTION_SYNC_LOG_PRIORITY, $color, false, $log_type );
381 + break;
382 + case 'execution-sync-details':
383 + $this->log_action( '[Execution Sync] :: ' . $text, static::EXECUTION_SYNC_DETAILS_LOG_PRIORITY, $color, false, $log_type );
384 + break;
385 + case 'warm-cache':
386 + $this->log_action( '[Warm cache] :: ' . $text, static::WARM_CACHE_LOG_PRIORITY, $color );
387 + break;
388 + case 'extension-updates-check':
389 + $this->log_action( '[Extension Updates Check] :: ' . $text, static::EXTENSION_UPDATES_CHECK_LOG_PRIORITY, $color );
390 + break;
391 + case 'auto-updates':
392 + $this->log_action( '[Auto Updates] :: ' . $text, static::AUTO_UPDATES_LOG_PRIORITY );
393 + break;
394 + default:
395 + break;
396 + }
397 + }
398 + }
399 + }
349 400
350 - /**
351 - * Method log_to_db()
352 - *
353 - * Log to database.
354 - *
355 - * @param string $text Log record text.
356 - * @param int $priority Set priority.
357 - * @param int $log_color Set color.
358 - * @param bool $forced forced logging.
359 - * @param mixed $website website object.
360 - *
361 - * @return bool true|false Default is False.
362 - */
363 - private function log_to_db( $text, $priority, $log_color = 0, $forced = false, $website = false ) {
401 + /**
402 + * Method log_update_check().
403 + *
404 + * @param string $text Log update check.
405 + */
406 + public function log_update_check( $text = '' ) {
407 + $this->log_action( $text, static::UPDATE_CHECK_LOG_PRIORITY );
408 + }
364 409
365 - if ( self::DISABLED === $this->logPriority ) {
366 - return;
367 - }
410 + /**
411 + * Method log_update_check().
412 + *
413 + * @param string $text Log update check.
414 + */
415 + public function log_uptime_check( $text = '' ) {
416 + $this->log_action( $text, static::UPTIME_CHECK_LOG_PRIORITY );
417 + }
368 418
369 - $priority = (int) apply_filters( 'mainwp_log_to_db_priority', $priority, $website );
419 + /**
420 + * Method log_uptime_notice().
421 + *
422 + * @param string $text Log update check.
423 + */
424 + public function log_uptime_notice( $text = '' ) {
425 + $this->log_action( $text, static::UPTIME_NOTICE_LOG_PRIORITY );
426 + }
370 427
371 - $do_log = false;
428 + /**
429 + * Method debug_for_website()
430 + *
431 + * Grab website debug and info.
432 + *
433 + * @param object $website Child site object.
434 + * @param string $action Performed action.
435 + * @param string $message Debug message.
436 + *
437 + * @return mixed Website debug info.
438 + *
439 + * @uses \MainWP\Dashboard\MainWP_Utility::get_nice_url()
440 + */
441 + public function debug_for_website( $website, $action, $message ) {
442 + if ( empty( $website ) ) {
443 + return $this->log( '[-] [-] ::' . $action . ':: ' . $message, static::DEBUG );
444 + }
372 445
373 - if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
374 - if ( $this->logPriority === $priority ) { // specific priority number saved setting.
375 - $do_log = true;
376 - }
377 - } elseif ( $this->logPriority >= $priority ) {
378 - $do_log = true;
379 - }
446 + return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, static::DEBUG, 0, false, $website );
447 + }
380 448
381 - $do_log = apply_filters( 'mainwp_log_do_to_db', $do_log, $website );
449 + /**
450 + * Method info_for_website()
451 + *
452 + * Grab Website Info.
453 + *
454 + * @param object $website Child site object.
455 + * @param string $action Performed action.
456 + * @param string $message Info message.
457 + *
458 + * @return mixed Website Info.
459 + *
460 + * @uses \MainWP\Dashboard\MainWP_Utility::get_nice_url()
461 + */
462 + public function info_for_website( $website, $action, $message ) {
463 + if ( empty( $website ) ) {
464 + return $this->log( '[-] [-] ::' . $action . ':: ' . $message, static::INFO );
465 + }
382 466
383 - $text = $this->prepare_log_info( $text );
467 + return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, static::INFO );
468 + }
384 469
385 - if ( $forced || $do_log ) {
470 + /**
471 + * Method warning_for_website()
472 + *
473 + * Grab Website Warnings.
474 + *
475 + * @param object $website Child site object.
476 + * @param string $action Performed action.
477 + * @param string $message Warning message.
478 + * @param bool $addStackTrace Add or Don't add stack trace.
479 + *
480 + * @return string Website warnings.
481 + */
482 + public function warning_for_website( $website, $action, $message, $addStackTrace = true ) {
483 + $stackTrace = '';
484 + if ( $addStackTrace ) {
485 + ob_start();
486 + // phpcs:ignore -- for debugging.
487 + debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
488 + $stackTrace = "\n" . ob_get_clean();
489 + }
490 + if ( empty( $website ) ) {
491 + return $this->log( '[-] [-] :: ' . $action . ' :: ' . $message . $stackTrace, static::WARNING );
492 + }
386 493
387 - $time = gmdate( $this->logDateFormat );
494 + return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message . $stackTrace, static::WARNING );
495 + }
388 496
389 - /**
390 - * Current user global.
391 - *
392 - * @global string
393 - */
394 - global $current_user;
497 + /**
498 + * Method log_to_db()
499 + *
500 + * Log to database.
501 + *
502 + * @param string $text Log record text.
503 + * @param int $priority Set priority.
504 + * @param int $log_color Set color.
505 + * @param bool $forced forced logging.
506 + * @param mixed $website website object.
507 + * @param int $log_type Log type.
508 + *
509 + * @return bool true|false Default is False.
510 + */
511 + private function log_to_db( $text, $priority, $log_color = 0, $forced = false, $website = false, $log_type = false ) {
395 512
396 - $user = '';
397 - if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
398 - $user = $current_user->user_login;
399 - } elseif ( defined( 'WP_CLI' ) ) {
400 - $user = 'WP_CLI';
401 - } elseif ( defined( 'DOING_CRON' ) ) {
402 - $user = 'DOING_CRON';
403 - }
513 + if ( static::DISABLED === $this->logPriority ) {
514 + return false;
515 + }
404 516
405 - $data = array();
517 + $priority = (int) apply_filters( 'mainwp_log_to_db_priority', $priority, $website );
406 518
407 - $data['log_content'] = $text;
408 - $data['log_user'] = $user;
409 - $data['log_type'] = $priority;
410 - $data['log_color'] = intval( $log_color );
411 - $data['log_timestamp'] = time();
519 + $do_log = false;
412 520
413 - $data = apply_filters( 'mainwp_log_to_db_data', $data );
521 + if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
522 + if ( $this->logPriority === $priority ) { // specific priority number saved setting.
523 + $do_log = true;
524 + }
525 + } elseif ( $this->logPriority >= $priority ) {
526 + $do_log = true;
527 + }
414 528
415 - MainWP_DB_Common::instance()->insert_action_log( $data );
529 + $do_log = apply_filters( 'mainwp_log_do_to_db', $do_log, $website );
416 530
417 - return true;
418 - }
419 - return false;
420 - }
531 + if ( ! $forced && ! $do_log ) {
532 + return false;
533 + }
421 534
422 - /**
423 - * Method log()
424 - *
425 - * Create Log File.
426 - *
427 - * @param string $text Log record text.
428 - * @param int $priority Set priority.
429 - * @param int $log_color Set color.
430 - * @param bool $forced forced logging.
431 - * @param mixed $website Site object.
432 - *
433 - * @return bool true|false Default is False.
434 - */
435 - private function log( $text, $priority, $log_color = 0, $forced = false, $website = false ) { // phpcs:ignore -- complex function.
535 + $text = $this->prepare_log_info( $text );
436 536
437 - if ( self::DISABLED === $this->logPriority ) {
438 - return;
439 - }
537 + do_action( 'mainwp_before_log_data', $text, $priority, $log_color );
440 538
441 - $log_to_db = apply_filters( 'mainwp_logger_to_db', true, $website );
539 + if ( defined( 'DOING_CRON' ) && DOING_CRON && 'CRON' !== strtoupper( substr( $text, 0, 4 ) ) ) {
540 + $text = 'CRON :: ' . $text;
541 + }
442 542
443 - if ( $log_to_db ) {
444 - return $this->log_to_db( $text, $priority, $log_color, $forced, $website );
445 - }
543 + /**
544 + * Current user global.
545 + *
546 + * @global string
547 + */
548 + global $current_user;
446 549
447 - $text = $this->prepare_log_info( $text );
550 + $user = '';
551 + if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
552 + $user = $current_user->user_login;
553 + } elseif ( defined( 'WP_CLI' ) ) {
554 + $user = 'WP_CLI';
555 + } elseif ( defined( 'DOING_CRON' ) ) {
556 + $user = 'DOING_CRON';
557 + }
448 558
449 - $do_log = false;
450 - if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
451 - if ( $this->logPriority === $priority ) { // specific priority number saved setting.
452 - $do_log = true;
453 - }
454 - } elseif ( $this->logPriority >= $priority ) {
455 - $do_log = true;
456 - }
559 + $data = array();
457 560
458 - if ( $do_log ) {
459 - $this->logCurrentFile = $this->get_log_file();
460 - $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
561 + $type = false !== $log_type ? (int) $log_type : (int) $priority;
461 562
462 - if ( $logCurrentHandle ) {
463 - $time = gmdate( $this->logDateFormat );
464 - $prefix = '[' . $this->get_log_text( $priority ) . ']';
563 + $data['log_content'] = $text;
564 + $data['log_user'] = $user;
565 + $data['log_type'] = $type;
465 566
466 - /**
467 - * Current user global.
468 - *
469 - * @global string
470 - */
471 - global $current_user;
567 + if ( is_int( $log_color ) || ctype_digit( (string) $log_color ) ) {
568 + $data['log_color'] = (int) $log_color;
569 + } else {
570 + $hex = sanitize_hex_color( $log_color );
571 + $data['log_color'] = $hex ? $hex : '';
572 + }
472 573
473 - if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
474 - $prefix .= ' [administrator]';
475 - }
574 + $data['log_timestamp'] = time();
476 575
477 - fwrite( $logCurrentHandle, $time . ' ' . $prefix . ' ' . $text . "\n" );
478 - fclose( $logCurrentHandle );
479 - }
576 + $data = apply_filters( 'mainwp_log_to_db_data', $data );
480 577
481 - if ( filesize( $this->logCurrentFile ) > ( $this->logMaxMB * 1048576 ) ) {
482 - $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
483 - if ( $logCurrentHandle ) {
484 - fseek( $logCurrentHandle, 0 );
485 - $newLogFile = $this->logCurrentFile . '.tmp';
486 - $newLogHandle = false;
487 - $chunkSize = filesize( $this->logCurrentFile ) - ( $this->logMaxMB * 1048576 );
488 - while ( is_resource( $logCurrentHandle ) && ! feof( $logCurrentHandle ) && ( $chunkSize > 0 ) ) {
489 - $content = fread( $logCurrentHandle, $chunkSize );
490 - if ( false === $content ) {
491 - break;
492 - }
493 - $pos = strrpos( $content, "\n" );
494 - if ( $newLogHandle ) {
495 - fwrite( $newLogHandle, $content );
496 - } elseif ( $pos ) {
497 - if ( ! $newLogHandle ) {
498 - $newLogHandle = fopen( $newLogFile, 'w+' );
499 - }
500 - fwrite( $newLogHandle, substr( $content, $pos + 1 ) );
501 - }
502 - }
578 + MainWP_DB_Common::instance()->insert_action_log( $data );
503 579
504 - if ( is_resource( $logCurrentHandle ) ) {
505 - fclose( $logCurrentHandle );
506 - }
580 + return true;
581 + }
507 582
508 - if ( $newLogHandle ) {
509 - fclose( $newLogHandle );
510 - wp_delete_file( $this->logCurrentFile );
511 - if ( file_exists( $newLogFile ) ) {
512 - rename( $newLogFile, $this->logCurrentFile );
513 - }
514 - }
515 - }
516 - }
583 + /**
584 + * Method hook_is_enabled_log_priority().
585 + *
586 + * @param int $priority Log priority.
587 + *
588 + * @return bool true|false True if enabled log for priority.
589 + */
590 + public function hook_is_enabled_log_priority( $priority ) {
591 + return $this->enabled_log_priority( $priority );
592 + }
517 593
518 - return true;
519 - }
594 + /**
595 + * Method enabled_log_priority()
596 + *
597 + * @param int $priority Set priority.
598 + *
599 + * @return bool true|false Default is False.
600 + */
601 + public function enabled_log_priority( $priority ) {
520 602
521 - return false;
522 - }
603 + if ( static::DISABLED === $this->logPriority ) {
604 + return false;
605 + }
523 606
607 + $priority = (int) apply_filters( 'mainwp_log_to_db_priority', $priority );
608 + $do_log = false;
609 + if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
610 + if ( $this->logPriority === $priority ) { // specific priority number saved setting.
611 + $do_log = true;
612 + }
613 + } elseif ( $this->logPriority >= $priority ) {
614 + $do_log = true;
615 + }
616 + return $do_log;
617 + }
524 618
525 - /**
526 - * Method prepare_log_info()
527 - *
528 - * Prepare log data.
529 - *
530 - * @param mixed $data Log data.
531 - *
532 - * @return mixed $data filtered data.
533 - */
534 - public function prepare_log_info( $data ) {
535 - $patterns[0] = '/user=([^\&]+)\&/';
536 - $replacement[0] = 'user=xxxxxx&';
537 - $patterns[1] = '/alt_user=([^\&]+)\&/';
538 - $replacement[1] = 'alt_user=xxxxxx&';
539 - $patterns[2] = '/\&server=([^\&]+)\&/';
540 - $replacement[2] = '&server=xxxxxx&';
541 - $data = preg_replace( $patterns, $replacement, $data );
542 - return $data;
543 - }
619 + /**
620 + * Method log()
621 + *
622 + * Create Log File.
623 + *
624 + * @param string $text Log record text.
625 + * @param int $priority Set priority.
626 + * @param int $log_color Set color.
627 + * @param bool $forced forced logging.
628 + * @param mixed $website Site object.
629 + * @param int $log_type Log type.
630 + *
631 + * @return bool true|false Default is False.
632 + */
633 + private function log( $text, $priority, $log_color = 0, $forced = false, $website = false, $log_type = false ) { // phpcs:ignore -- NOSONAR - complex function.
544 634
545 - /**
546 - * Method prepend()
547 - *
548 - * Prepend content to log file.
549 - *
550 - * @param mixed $str Custom string.
551 - * @param mixed $filename Filename.
552 - */
553 - public function prepend( $str, $filename ) {
554 - $context = stream_context_create();
555 - $fp = fopen( $filename, 'r', 1, $context );
556 - $tmpname = md5( $str );
557 - file_put_contents( $tmpname, $str );
558 - file_put_contents( $tmpname, $fp, FILE_APPEND );
559 - fclose( $fp );
560 - wp_delete_file( $filename );
561 - rename( $tmpname, $filename );
562 - }
635 + if ( in_array( $priority, $this->autoEnableLoggingActions ) && (int) $this->logPriority !== (int) $priority ) {
636 + $this->enable_log_priority( $priority, 1 );
637 + }
563 638
564 - /**
565 - * Method init_execution_time().
566 - *
567 - * @param string $time_index index for timer.
568 - *
569 - * Init execution time start value.
570 - */
571 - public function init_execution_time( $time_index = '' ) {
572 - if ( null === self::$time_start || ! is_array( self::$time_start ) ) {
573 - self::$time_start = array( 'start' => microtime( true ) );
574 - $this->log_action( 'execution time :: init :: [start]', self::EXECUTION_TIME_LOG_PRIORITY );
575 - }
639 + if ( static::DISABLED === $this->logPriority ) {
640 + return false;
641 + }
576 642
577 - if ( ! empty( $time_index ) && is_string( $time_index ) && 'start' !== $time_index ) {
578 - self::$time_start[ $time_index ] = microtime( true );
579 - $this->log_action( 'execution time :: init :: [' . $time_index . ']', self::EXECUTION_TIME_LOG_PRIORITY );
580 - }
581 - }
643 + $log_to_db = apply_filters( 'mainwp_logger_to_db', true, $website );
582 644
583 - /**
584 - * Method log_execution_time().
585 - *
586 - * @param string $text Log record text.
587 - *
588 - * Log the execution time value.
589 - */
590 - public function log_execution_time( $text = '' ) {
591 - $exec_time = $this->get_execution_time();
592 - $this->log_action( 'execution time :: ' . ( ! empty( $text ) ? (string) $text : '<empty>' ) . ' :: [time=' . round( $exec_time, 4 ) . '](seconds)', self::EXECUTION_TIME_LOG_PRIORITY );
593 - }
645 + if ( $log_to_db ) {
646 + return $this->log_to_db( $text, $priority, $log_color, $forced, $website, $log_type );
647 + }
594 648
649 + $text = $this->prepare_log_info( $text );
595 650
596 - /**
597 - * Method get_execution_time().
598 - *
599 - * Get the execution time value.
600 - *
601 - * @param string $time_index Index for timer.
602 - *
603 - * @return int execution time.
604 - */
605 - private function get_execution_time( $time_index = '' ) {
651 + $do_log = false;
652 + if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
653 + if ( $this->logPriority === $priority ) { // specific priority number saved setting.
654 + $do_log = true;
655 + }
656 + } elseif ( $this->logPriority >= $priority ) {
657 + $do_log = true;
658 + }
606 659
607 - if ( empty( self::$time_start ) ) {
608 - return 0;
609 - }
660 + if ( $do_log ) {
661 + $this->logCurrentFile = $this->get_log_file();
662 + $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
610 663
611 - $start = 0;
612 - if ( ! empty( $time_index ) ) {
613 - $start = is_array( self::$time_start ) && isset( self::$time_start[ $time_index ] ) ? self::$time_start[ $time_index ] : 0;
614 - }
664 + if ( $logCurrentHandle ) {
665 + $time = gmdate( $this->logDateFormat );
666 + $prefix = '[' . $this->get_log_text( $priority ) . ']';
615 667
616 - if ( empty( $start ) ) {
617 - $start = is_array( self::$time_start ) && isset( self::$time_start['start'] ) ? self::$time_start['start'] : 0;
618 - }
668 + /**
669 + * Current user global.
670 + *
671 + * @global string
672 + */
673 + global $current_user;
619 674
620 - if ( empty( $start ) ) {
621 - return 0;
622 - }
623 - return microtime( true ) - $start; // seconds.
624 - }
675 + if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
676 + $prefix .= ' [administrator]';
677 + }
625 678
626 - /**
627 - * Method get_log_file()
628 - *
629 - * Grab Log File.
630 - *
631 - * @return mixed Log File.
632 - */
633 - public function get_log_file() {
634 - if ( empty( $this->logDirectory ) ) {
635 - $this->logDirectory = MainWP_System_Utility::get_mainwp_dir();
636 - $this->logDirectory = $this->logDirectory[0];
637 - }
638 - return $this->logDirectory . $this->logFileNamePrefix . $this->logFileNameSuffix;
639 - }
679 + fwrite( $logCurrentHandle, $time . ' ' . $prefix . ' ' . $text . "\n" );
680 + fclose( $logCurrentHandle );
681 + }
640 682
641 - /**
642 - * Method get_log_text()
643 - *
644 - * Grab what type of log entry.
645 - *
646 - * @param mixed $priority Set priority.
647 - *
648 - * @return string LOG -OR- DISABLED|DEBUG|INFO|WARNING|INFO UPDATE
649 - */
650 - public function get_log_text( $priority ) {
651 - switch ( $priority ) {
652 - case self::DISABLED:
653 - return 'DISABLED';
654 - case self::DEBUG:
655 - return 'DEBUG';
656 - case self::INFO:
657 - return 'INFO';
658 - case self::WARNING:
659 - return 'WARNING';
660 - default:
661 - return 'SPEC LOG';
662 - }
663 - }
683 + if ( filesize( $this->logCurrentFile ) > ( $this->logMaxMB * 1048576 ) ) {
684 + $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
685 + if ( $logCurrentHandle ) {
686 + fseek( $logCurrentHandle, 0 );
687 + $newLogFile = $this->logCurrentFile . '.tmp';
688 + $newLogHandle = false;
689 + $chunkSize = filesize( $this->logCurrentFile ) - ( $this->logMaxMB * 1048576 );
690 + while ( is_resource( $logCurrentHandle ) && ! feof( $logCurrentHandle ) && ( $chunkSize > 0 ) ) {
691 + $content = fread( $logCurrentHandle, $chunkSize );
692 + if ( false === $content ) {
693 + break;
694 + }
695 + $pos = strrpos( $content, "\n" );
696 + if ( $newLogHandle ) {
697 + fwrite( $newLogHandle, $content );
698 + } elseif ( $pos ) {
699 + if ( ! $newLogHandle ) {
700 + $newLogHandle = fopen( $newLogFile, 'w+' );
701 + }
702 + fwrite( $newLogHandle, substr( $content, $pos + 1 ) );
703 + }
704 + }
664 705
665 - /**
666 - * Method check_log_daily()
667 - *
668 - * Daily checks to clear the log file.
669 - */
670 - public function check_log_daily() {
671 - $status = (int) $this->get_log_status();
672 - if ( 0 >= $status ) {
673 - return;
674 - }
706 + if ( is_resource( $logCurrentHandle ) ) {
707 + fclose( $logCurrentHandle );
708 + }
675 709
676 - $today_m_y = date_i18n( 'd/m/Y' ); //phpcs:ignore -- local time.
677 - // one time per day.
678 - if ( get_option( 'mainwp_logger_check_daily' ) !== $today_m_y ) {
679 - $num_days = apply_filters( 'mainwp_logger_keep_days', 7 );
680 - MainWP_DB_Common::instance()->delete_action_log( $num_days );
681 - MainWP_Utility::update_option( 'mainwp_logger_check_daily', $today_m_y );
710 + if ( $newLogHandle ) {
711 + fclose( $newLogHandle );
712 + wp_delete_file( $this->logCurrentFile );
713 + if ( file_exists( $newLogFile ) ) {
714 + rename( $newLogFile, $this->logCurrentFile );
715 + }
716 + }
717 + }
718 + }
682 719
683 - $enabled_time = get_option( 'mainwp_actionlogs_enabled_timestamp', false );
684 - if ( false === $enabled_time ) {
685 - MainWP_Utility::update_option( 'mainwp_actionlogs_enabled_timestamp', time() );
686 - } elseif ( $enabled_time + $num_days * DAY_IN_SECONDS < time() ) {
687 - MainWP_Utility::update_option( 'mainwp_actionlogs', self::DISABLED );
688 - }
689 - }
690 - }
720 + return true;
721 + }
691 722
692 - /**
693 - * Method clear_log_db()
694 - *
695 - * Clear the log file.
696 - */
697 - public function clear_log_db() {
698 - MainWP_DB_Common::instance()->delete_action_log();
699 - }
723 + return false;
724 + }
700 725
701 - /**
702 - * Method clear_log()
703 - *
704 - * Clear the log file.
705 - */
706 - public function clear_log() {
707 - $logFile = $this->get_log_file();
708 - wp_delete_file( $logFile );
709 - $fh = fopen( $logFile, 'w' );
710 - if ( false === $fh ) {
711 - return;
712 - }
713 - fclose( $fh );
714 - }
715 726
716 - /**
717 - * Method show_log_db()
718 - *
719 - * Grab log file and build output to screen.
720 - */
721 - public function show_log_db() {
727 + /**
728 + * Method prepare_log_info()
729 + *
730 + * Prepare log data.
731 + *
732 + * @param mixed $data Log data.
733 + *
734 + * @return mixed $data filtered data.
735 + */
736 + public function prepare_log_info( $data ) {
737 + $patterns[] = '/user=([^\&]+)\&/';
738 + $replacement[] = 'user=xxxxxx&';
739 + $patterns[] = '/alt_user=([^\&]+)\&/';
740 + $replacement[] = 'alt_user=xxxxxx&';
741 + $patterns[] = '/\&server=([^\&]+)\&/';
742 + $replacement[] = '&server=xxxxxx&';
743 + $patterns[] = '/(^|[?&])data_signature=[^&]*/';
744 + $replacement[] = '$1data_signature=xxxxxx';
745 + $patterns[] = '/(^|[?&])mainwpsignature=[^&]*/';
746 + $replacement[] = '$mainwpsignature=xxxxxx';
747 + $patterns[] = '/(^|[?&])nonce=[^&]*/';
748 + $replacement[] = '$nonce=xxxxxx';
749 + $patterns[] = '/(^|[?&])req_id=[^&]*/';
750 + $replacement[] = '$req_id=xxxxxx';
751 + $patterns[] = '/(^|[?&])mainwpsignature_adv=[^&]*/';
752 + $replacement[] = '$mainwpsignature_adv=xxxxxx';
753 + $patterns[] = '/(^|[?&])wp_http_user=[^&]*/';
754 + $replacement[] = '$wp_http_user=xxxxxx';
755 + $patterns[] = '/(^|[?&])wp_http_pass=[^&]*/';
756 + $replacement[] = '$wp_http_pass=xxxxxx';
757 + $data = preg_replace( $patterns, $replacement, $data );
758 + return $data;
759 + }
722 760
723 - echo '<div class="ui hidden divider"></div>';
724 - echo '<div class="ui divided padded relaxed list" local-datetime="' . date( 'Y-m-d H:i:s' ) . '">'; // phpcs:ignore -- local time.
761 + /**
762 + * Method prepend()
763 + *
764 + * Prepend content to log file.
765 + *
766 + * @param mixed $str Custom string.
767 + * @param mixed $filename Filename.
768 + */
769 + public function prepend( $str, $filename ) {
770 + $context = stream_context_create();
771 + $fp = fopen( $filename, 'r', 1, $context );
772 + $tmpname = md5( $str ); // NOSONAR - safe for salt file name.
773 + file_put_contents( $tmpname, $str );
774 + file_put_contents( $tmpname, $fp, FILE_APPEND );
775 + fclose( $fp );
776 + wp_delete_file( $filename );
777 + rename( $tmpname, $filename );
778 + }
725 779
726 - $rows = MainWP_DB::instance()->query( MainWP_DB_Common::instance()->get_sql_log() );
780 + /**
781 + * Method init_execution_time().
782 + *
783 + * @param string $time_index index for timer.
784 + *
785 + * Init execution time start value.
786 + */
787 + public function init_execution_time( $time_index = '' ) {
788 + if ( null === static::$time_start || ! is_array( static::$time_start ) ) {
789 + static::$time_start = array( 'start' => microtime( true ) );
790 + $this->log_action( 'execution time :: init :: [start]', static::EXECUTION_TIME_LOG_PRIORITY );
791 + }
727 792
728 - $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;">';
729 - $end_wrapper = '</div>';
793 + if ( ! empty( $time_index ) && is_string( $time_index ) && 'start' !== $time_index ) {
794 + static::$time_start[ $time_index ] = microtime( true );
795 + $this->log_action( 'execution time :: init :: [' . $time_index . ']', static::EXECUTION_TIME_LOG_PRIORITY );
796 + }
797 + }
730 798
731 - while ( $rows && ( $row = MainWP_DB::fetch_object( $rows ) ) ) {
732 - $type = $row->log_type;
733 - $line = $row->log_content;
734 - if ( 120 * 1024 < strlen( $line ) ) {
735 - $line = '[Data row too long]';
736 - }
799 + /**
800 + * Method log_execution_time().
801 + *
802 + * @param string $text Log record text.
803 + *
804 + * Log the execution time value.
805 + */
806 + public function log_execution_time( $text = '' ) {
807 + $exec_time = $this->get_execution_time();
808 + $this->log_action( 'execution time :: ' . ( ! empty( $text ) ? (string) $text . ' :: ' : '' ) . ' [time=' . round( $exec_time, 4 ) . '](seconds)', static::EXECUTION_TIME_LOG_PRIORITY );
809 + }
737 810
738 - $time = gmdate( $this->logDateFormat, $row->log_timestamp );
811 + /**
812 + * Method log_execution_sync().
813 + *
814 + * @param string $progress Log progress value.
815 + * @param string $text Log record text.
816 + * @param mixed $website Website data, default false.
817 + *
818 + * Log the execution sync time value.
819 + */
820 + public function log_execution_sync( $progress = '', $text = '', $website = false ) { // phpcs:ignore -- NOSONAR -complex.
739 821
740 - $showInfo = $this->get_log_type_info( $row->log_type, $row->log_color );
741 - $currentColor = $showInfo['log_color'];
822 + if ( 1 !== $this->logSpecific || ( static::EXECUTION_SYNC_LOG_PRIORITY !== $this->logPriority && static::EXECUTION_SYNC_DETAILS_LOG_PRIORITY !== $this->logPriority ) ) { // 1 - specific log, 0 - not specific log.
823 + return;
824 + }
742 825
743 - $prefix = $time . ' ' . $showInfo['log_prefix'];
826 + static $initialized = false;
744 827
745 - $line = htmlentities( $line );
828 + if ( 'init' === $progress && ! $initialized ) {
829 + $initialized = true;
830 + MainWP_Execution_Helper::init_http_call_track();
831 + }
746 832
747 - if ( false !== strpos( $line, '[data-start]' ) ) {
748 - $line = str_replace( '[data-start]', $start_wrapper, $line );
749 - $line = str_replace( '[data-end]', $end_wrapper, $line );
750 - }
833 + // If the process has ended and the sync event log is not initialized, do not log.
834 + if ( 'end' === $progress && ! $initialized ) {
835 + return;
836 + }
751 837
752 - echo '<div class="item" style="color:' . esc_html( $currentColor ) . '"><div class="mainwpactionlogsline">';
838 + $text = 'init' === $progress && empty( $text ) ? 'Init' : $text;
839 + $text = 'end' === $progress && empty( $text ) ? 'End' : $text;
753 840
754 - echo $prefix . ' ' . $line; // phpcs:ignore WordPress.Security.EscapeOutput
841 + $exec_time = $this->get_execution_time();
842 + $exec_time = round( $exec_time, 4 );
755 843
756 - echo '</div></div>';
757 - }
844 + if ( ! empty( $text ) ) {
845 + $text = $text . ' :: ';
846 + }
758 847
759 - echo '</div></div>';
848 + $id = '';
760 849
761 - echo '</div>';
850 + if ( ! empty( $website ) ) {
762 851
763 - ?>
764 - <div class="ui large modal" id="mainwp-action-log-response-modal">
765 - <div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div>
766 - <div class="content">
767 - <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' ); ?>
768 - </div>
769 - </div>
770 - <div class="scrolling content content-response"></div>
771 - <div class="actions">
772 - <button class="ui green button mainwp-response-copy-button"><?php esc_html_e( 'Copy Response', 'mainwp' ); ?></button>
773 - <div class="ui cancel button mainwp-reload"><?php esc_html_e( 'Close', 'mainwp' ); ?></div>
774 - </div>
775 - </div>
776 - <?php
777 - }
852 + if ( is_int( $website ) || ctype_digit( $website ) ) {
853 + $id = (int) $website;
854 + } elseif ( is_array( $website ) && ! empty( $website['id'] ) ) {
855 + $id = $website['id'];
856 + } elseif ( is_object( $website ) && property_exists( $website, 'id' ) ) {
857 + $id = $website->id;
858 + }
859 + } else {
860 + $id = MainWP_System_Utility::get_current_wpid();
861 + }
778 862
779 - /**
780 - * Method show_log_file()
781 - *
782 - * Grab log file and build output to screen.
783 - */
784 - public function show_log_file() {
785 - $logFile = $this->get_log_file();
863 + if ( ! empty( $id ) ) {
864 + $text .= '[siteid=' . $id . '] :: ';
865 + }
786 866
787 - if ( ! file_exists( $logFile ) ) {
788 - return;
789 - }
867 + $log = $text . '[total runtime=' . $exec_time . '](sec)';
790 868
791 - $fh = fopen( $logFile, 'r' );
792 - if ( false === $fh ) {
793 - return;
794 - }
869 + $mem = '';
795 870
796 - $previousColor = '';
797 - $fontOpen = false;
798 - $firstLinePassedProcessed = false;
799 - echo '<div class="ui hidden divider"></div>';
800 - echo '<div class="ui divided padded relaxed list">';
801 - while ( false !== ( $line = fgets( $fh ) ) ) {
802 - $currentColor = $previousColor;
803 - if ( stristr( $line, '[DEBUG]' ) ) {
804 - $currentColor = self::DEBUG_COLOR;
805 - $firstLinePassed = true;
806 - } elseif ( stristr( $line, '[INFO]' ) ) {
807 - $currentColor = self::INFO_COLOR;
808 - $firstLinePassed = true;
809 - } elseif ( stristr( $line, '[WARNING]' ) ) {
810 - $currentColor = self::WARNING_COLOR;
811 - $firstLinePassed = true;
812 - } elseif ( stristr( $line, '[LOG]' ) ) {
813 - $currentColor = self::LOG_COLOR;
814 - $firstLinePassed = true;
815 - } else {
816 - $firstLinePassed = false;
817 - }
871 + if ( function_exists( 'memory_get_usage' ) && is_callable( 'memory_get_usage' ) ) {
872 + $mem = round( memory_get_usage() / 1024 / 1024, 2 );
873 + } else {
874 + $mem = 'N/A';
875 + }
818 876
819 - if ( $firstLinePassedProcessed && ! $firstLinePassed ) {
820 - 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;">';
821 - }
877 + if ( ! empty( $mem ) ) {
878 + $log .= ' :: [memory usage=' . $mem . '](MB)';
879 + }
822 880
823 - $firstLinePassedProcessed = $firstLinePassed;
881 + if ( 'end' === $progress ) {
882 + $dbusage = MainWP_Execution_Helper::get_queries_stats();
883 + if ( is_array( $dbusage ) ) {
884 + if ( isset( $dbusage['total_queries'] ) ) {
885 + $log .= ' :: [total queries=' . (int) $dbusage['total_queries'] . ']';
886 + }
887 + if ( isset( $dbusage['total_runtime'] ) ) {
888 + $log .= ' :: [total runtime queries=' . sprintf( '%.5f', $dbusage['total_runtime'] ) . '](sec)';
889 + }
890 + }
824 891
825 - if ( $currentColor !== $previousColor ) {
826 - if ( $fontOpen ) {
827 - echo '</div></div>';
828 - }
892 + $callstats = MainWP_Execution_Helper::get_exec_call_stats();
829 893
830 - echo '<div class="item" style="color:' . esc_html( $currentColor ) . '"><div class="mainwpactionlogsline">';
831 - $fontOpen = true;
832 - }
894 + $rows_details = array();
833 895
834 - echo esc_html( htmlentities( $line ) );
835 - }
896 + if ( is_array( $callstats ) ) {
897 + if ( isset( $callstats['check_count'] ) ) {
898 + $log .= ' :: [total run check=' . (int) $callstats['check_count'] . ']';
899 + }
900 + if ( isset( $callstats['exec_time'] ) && is_array( $callstats['exec_time'] ) ) {
901 + foreach ( $callstats['exec_time'] as $idx => $t ) {
902 + $rows_details[] = '[check runtime=' . sprintf( '%.3f', $t ) . '](sec) :: [run desc=' . ( ! empty( $callstats['check_desc'][ $idx ] ) ? (string) $callstats['check_desc'][ $idx ] : '' ) . ']';
903 + if ( static::EXECUTION_SYNC_DETAILS_LOG_PRIORITY === $this->logPriority ) {
904 + $rows_details[] = '[run data=' . ( ! empty( $callstats['check_data'][ $idx ] ) && is_array( $callstats['check_data'][ $idx ] ) ? wp_json_encode( $callstats['check_data'][ $idx ] ) : '' ) . ']';
905 + }
906 + }
907 + }
908 + }
909 + }
836 910
837 - if ( $fontOpen ) {
838 - echo '</div></div>';
839 - }
911 + $log .= ' :: [ver=' . MainWP_System::get_mainwp_version() . ']';
840 912
841 - echo '</div>';
913 + $lg_type = (int) $exec_time >= 50 ? static::NOTICE : static::INFO;
914 + $lg_type = (int) $exec_time >= 80 ? static::WARNING : $lg_type;
842 915
843 - ?>
844 - <div class="ui large modal" id="mainwp-action-log-response-modal">
845 - <div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div>
846 - <div class="content">
847 - <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' ); ?>
848 - </div>
849 - </div>
850 - <div class="scrolling content content-response"></div>
851 - <div class="actions">
852 - <button class="ui green button mainwp-response-copy-button"><?php esc_html_e( 'Copy Response', 'mainwp' ); ?></button>
853 - <div class="ui cancel button mainwp-reload"><?php esc_html_e( 'Close', 'mainwp' ); ?></div>
854 - </div>
855 - </div>
856 - <?php
916 + $event_name = static::EXECUTION_SYNC_DETAILS_LOG_PRIORITY === $this->logPriority ? 'execution-sync-details' : 'execution-sync';
917 + $this->log_events( $event_name, $log, false, $lg_type );
857 918
858 - fclose( $fh );
859 - }
919 + if ( ! empty( $rows_details ) ) {
920 + foreach ( $rows_details as $log_detail ) {
921 + $this->log_events( $event_name, $log_detail, false, static::LOG );
922 + }
923 + }
924 + }
925 +
926 + /**
927 + * Method get_execution_time().
928 + *
929 + * Get the execution time value.
930 + *
931 + * @param string $time_index Index for timer.
932 + *
933 + * @return int execution time.
934 + */
935 + private function get_execution_time( $time_index = '' ) {
936 +
937 + if ( empty( static::$time_start ) ) {
938 + return 0;
939 + }
940 +
941 + $start = 0;
942 + if ( ! empty( $time_index ) ) {
943 + $start = is_array( static::$time_start ) && isset( static::$time_start[ $time_index ] ) ? static::$time_start[ $time_index ] : 0;
944 + }
945 +
946 + if ( empty( $start ) ) {
947 + $start = is_array( static::$time_start ) && isset( static::$time_start['start'] ) ? static::$time_start['start'] : 0;
948 + }
949 +
950 + if ( empty( $start ) ) {
951 + return 0;
952 + }
953 + return microtime( true ) - $start; // seconds.
954 + }
955 +
956 + /**
957 + * Method get_log_file()
958 + *
959 + * Grab Log File.
960 + *
961 + * @return mixed Log File.
962 + */
963 + public function get_log_file() {
964 + if ( empty( $this->logDirectory ) ) {
965 + $this->logDirectory = MainWP_System_Utility::get_mainwp_dir();
966 + $this->logDirectory = $this->logDirectory[0];
967 + }
968 + return $this->logDirectory . $this->logFileNamePrefix . $this->logFileNameSuffix;
969 + }
970 +
971 + /**
972 + * Method get_log_text()
973 + *
974 + * Grab what type of log entry.
975 + *
976 + * @param mixed $priority Set priority.
977 + *
978 + * @return string LOG -OR- DISABLED|DEBUG|INFO|WARNING|INFO UPDATE
979 + */
980 + public function get_log_text( $priority ) {
981 + switch ( $priority ) {
982 + case static::DISABLED:
983 + return 'DISABLED';
984 + case static::DEBUG:
985 + return 'DEBUG';
986 + case static::INFO:
987 + return 'INFO';
988 + case static::WARNING:
989 + return 'WARNING';
990 + default:
991 + return 'SPEC LOG';
992 + }
993 + }
994 +
995 + /**
996 + * Method check_log_daily()
997 + *
998 + * Daily checks to clear the log file.
999 + */
1000 + public function check_log_daily() {
1001 + $status = (int) $this->get_log_status();
1002 + if ( 0 >= $status ) {
1003 + return;
1004 + }
1005 +
1006 + $today_m_y = date_i18n( 'd/m/Y' ); //phpcs:ignore -- local time.
1007 + // one time per day.
1008 + if ( get_option( 'mainwp_logger_check_daily' ) !== $today_m_y ) {
1009 + $num_days = apply_filters( 'mainwp_logger_keep_days', 7 );
1010 + MainWP_DB_Common::instance()->delete_action_log( $num_days );
1011 + MainWP_Utility::update_option( 'mainwp_logger_check_daily', $today_m_y );
1012 +
1013 + $enabled_time = get_option( 'mainwp_actionlogs_enabled_timestamp', false );
1014 + if ( false === $enabled_time ) {
1015 + MainWP_Utility::update_option( 'mainwp_actionlogs_enabled_timestamp', time() );
1016 + } elseif ( $enabled_time + $num_days * DAY_IN_SECONDS < time() ) {
1017 + MainWP_Utility::update_option( 'mainwp_actionlogs', static::DISABLED );
1018 + }
1019 + }
1020 + }
1021 +
1022 + /**
1023 + * Method clear_log_db()
1024 + *
1025 + * Clear the log file.
1026 + */
1027 + public function clear_log_db() {
1028 + MainWP_DB_Common::instance()->delete_action_log();
1029 + }
1030 +
1031 + /**
1032 + * Method clear_log()
1033 + *
1034 + * Clear the log file.
1035 + */
1036 + public function clear_log() {
1037 + $logFile = $this->get_log_file();
1038 + wp_delete_file( $logFile );
1039 + $fh = fopen( $logFile, 'w' );
1040 + if ( false === $fh ) {
1041 + return;
1042 + }
1043 + fclose( $fh );
1044 + }
1045 +
1046 + /**
1047 + * Method show_log_db()
1048 + *
1049 + * Grab log file and build output to screen.
1050 + */
1051 + public function show_log_db() { //phpcs:ignore -- NOSONAR - complexity.
1052 +
1053 + echo '<div class="ui hidden divider"></div>';
1054 + echo '<div class="ui divided padded relaxed list" local-datetime="' . date( 'Y-m-d H:i:s' ) . '">'; // phpcs:ignore -- local time.
1055 +
1056 + $limit = 500;
1057 +
1058 + //phpcs:disable WordPress.Security.NonceVerification
1059 + $paged = isset( $_GET['paged'] ) ? intval( $_GET['paged'] ) : 0; //phpcs:ignore -- NOSONAR -ok.
1060 +
1061 + if ( $paged <= 0 ) {
1062 + $paged = 0;
1063 + } else {
1064 + --$paged;
1065 + }
1066 +
1067 + $params = array();
1068 +
1069 + if ( isset( $_GET['hour'] ) && ! empty( $_GET['hour'] ) ) { // phpcs:ignore -- local time.
1070 + $params['hour'] = intval( $_GET['hour'] ); // phpcs:ignore -- local time.
1071 + } else {
1072 + $params['hour'] = $limit;
1073 + }
1074 +
1075 + $order = isset( $_GET['order'] ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : ''; //phpcs:ignore -- NOSONAR -ok.
1076 +
1077 + $total = MainWP_DB::instance()->get_var_field( MainWP_DB_Common::instance()->get_sql_log( $paged, $order, array( 'count' => true ) ) );
1078 +
1079 + $rows = MainWP_DB::instance()->query( MainWP_DB_Common::instance()->get_sql_log( $paged, $order, $params ) );
1080 +
1081 + $count = $rows ? MainWP_DB::num_rows( $rows ) : 0;
1082 +
1083 + $show_info = '';
1084 +
1085 + if ( isset( $_GET['hour'] ) ) {
1086 + $show_info = $count . ' latest items from a total of ' . $total;
1087 + } elseif ( isset( $_GET['paged'] ) ) { //phpcs:ignore -- NOSONAR -ok.
1088 + $from = $limit * $paged;
1089 + $show_info = $count . ' items, from ' . $from . ' - ' . ( $from + $limit ) . ' of ' . $total . ' total.';
1090 + }
1091 +
1092 + if ( ! empty( $show_info ) ) {
1093 + echo '<p><strong>' . esc_html__( 'Showing ', 'mainwp' ) . ':</strong> ' . $show_info; //phpcs:ignore -- NOSONAR ok.
1094 + }
1095 + //phpcs:enable WordPress.Security.NonceVerification
1096 +
1097 + $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;">';
1098 + $end_wrapper = '</div>';
1099 +
1100 + while ( $rows && ( $row = MainWP_DB::fetch_object( $rows ) ) ) {
1101 + $line = $row->log_content;
1102 + if ( strlen( $line ) > 120 * KB_IN_BYTES ) {
1103 + $size_kb = round( strlen( $line ) / KB_IN_BYTES, 1 );
1104 + $line = sprintf( '[Data row too long] :: [size=%s KB]', $size_kb );
1105 + }
1106 +
1107 + $time = gmdate( $this->logDateFormat, MainWP_Utility::get_timestamp( $row->log_timestamp ) );
1108 +
1109 + $showInfo = $this->get_log_type_info( (int) $row->log_type, $row->log_color );
1110 +
1111 + $currentColor = $showInfo['log_color'];
1112 +
1113 + $prefix = $time . ' ' . $showInfo['log_prefix'];
1114 +
1115 + $line = nl2br( htmlentities( $line ) );
1116 +
1117 + if ( false !== strpos( $line, '[data-start]' ) ) {
1118 + $line = str_replace( '[data-start]', $start_wrapper, $line );
1119 + $line = str_replace( '[data-end]', $end_wrapper, $line );
1120 + }
1121 +
1122 + echo '<div class="item" style="color:' . esc_attr( $currentColor ) . '"><div class="mainwpactionlogsline">';
1123 +
1124 + echo $prefix . ' ' . $line; // phpcs:ignore WordPress.Security.EscapeOutput
1125 +
1126 + echo '</div></div>';
1127 + }
1128 +
1129 + echo '</div></div>';
1130 +
1131 + echo '</div>';
1132 +
1133 + ?>
1134 + <div class="ui large modal" id="mainwp-action-log-response-modal">
1135 + <i class="close icon mainwp-reload"></i>
1136 + <div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div>
1137 + <div class="content">
1138 + <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' ); ?>
1139 + </div>
1140 + </div>
1141 + <div class="scrolling content content-response"></div>
1142 + <div class="actions">
1143 + <button class="ui green button mainwp-response-copy-button"><?php esc_html_e( 'Copy Response', 'mainwp' ); ?></button>
1144 + </div>
1145 + </div>
1146 + <?php
1147 + }
1148 +
1149 + /**
1150 + * Method show_log_file()
1151 + *
1152 + * Grab log file and build output to screen.
1153 + */
1154 + public function show_log_file() { // phpcs:ignore -- NOSONAR - complex.
1155 + $logFile = $this->get_log_file();
1156 +
1157 + if ( ! file_exists( $logFile ) ) {
1158 + return;
1159 + }
1160 +
1161 + $fh = fopen( $logFile, 'r' );
1162 + if ( false === $fh ) {
1163 + return;
1164 + }
1165 +
1166 + $previousColor = '';
1167 + $fontOpen = false;
1168 + $firstLinePassedProcessed = false;
1169 + echo '<div class="ui hidden divider"></div>';
1170 + echo '<div class="ui divided padded relaxed list">';
1171 + while ( false !== ( $line = fgets( $fh ) ) ) {
1172 + $currentColor = $previousColor;
1173 + if ( stristr( $line, '[DEBUG]' ) ) {
1174 + $currentColor = static::DEBUG_COLOR;
1175 + $firstLinePassed = true;
1176 + } elseif ( stristr( $line, '[INFO]' ) ) {
1177 + $currentColor = static::INFO_COLOR;
1178 + $firstLinePassed = true;
1179 + } elseif ( stristr( $line, '[WARNING]' ) ) {
1180 + $currentColor = static::WARNING_COLOR;
1181 + $firstLinePassed = true;
1182 + } elseif ( stristr( $line, '[LOG]' ) ) {
1183 + $currentColor = static::LOG_COLOR;
1184 + $firstLinePassed = true;
1185 + } else {
1186 + $firstLinePassed = false;
1187 + }
1188 +
1189 + if ( $firstLinePassedProcessed && ! $firstLinePassed ) {
1190 + 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;">';
1191 + }
1192 +
1193 + $firstLinePassedProcessed = $firstLinePassed;
1194 +
1195 + if ( $currentColor !== $previousColor ) {
1196 + if ( $fontOpen ) {
1197 + echo '</div></div>';
1198 + }
1199 +
1200 + echo '<div class="item" style="color:' . esc_html( $currentColor ) . '"><div class="mainwpactionlogsline">';
1201 + $fontOpen = true;
1202 + }
1203 +
1204 + echo esc_html( htmlentities( $line ) );
1205 + }
1206 +
1207 + if ( $fontOpen ) {
1208 + echo '</div></div>';
1209 + }
1210 +
1211 + echo '</div>';
1212 +
1213 + ?>
1214 + <div class="ui large modal" id="mainwp-action-log-response-modal">
1215 + <i class="close icon mainwp-reload"></i>
1216 + <div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div>
1217 + <div class="content">
1218 + <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' ); ?>
1219 + </div>
1220 + </div>
1221 + <div class="scrolling content content-response"></div>
1222 + <div class="actions">
1223 + <button class="ui green button mainwp-response-copy-button"><?php esc_html_e( 'Copy Response', 'mainwp' ); ?></button>
1224 + </div>
1225 + </div>
1226 + <?php
1227 +
1228 + fclose( $fh );
1229 + }
1230 +
1231 + /**
1232 + * Method hook_module_log_record_inserted()
1233 + *
1234 + * @param int $record_id Log id.
1235 + * @param array $record Log data.
1236 + *
1237 + * @return void
1238 + */
1239 + public function hook_module_log_record_inserted( $record_id = false, $record = false ) {
1240 + if ( $record_id && is_array( $record ) && isset( $record['connector'] ) && isset( $record['action'] ) && isset( $record['item'] ) && isset( $record['context'] ) ) {
1241 + $this->log_events( 'sites-changes', 'Logging info :: [site_id=' . ( isset( $record['site_id'] ) ? $record['site_id'] : 0 ) . '] :: [log_id=' . $record_id . '] :: [log_type_id=' . ( isset( $record['log_type_id'] ) ? $record['log_type_id'] : 0 ) . '] :: [item=' . $record['item'] . '] :: [connector=' . $record['connector'] . '] :: [context=' . $record['context'] . '] :: [action=' . $record['action'] . ']' );
1242 + }
1243 + }
860 1244 }