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 -732 5.0.3 → 6.2.1 View file →
@@ -8,860 +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;
24 - const COST_TRACKER_LOG_PRIORITY = 20230112;
25 - const API_BACKUPS_LOG_PRIORITY = 20240130;
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;
26 45
27 - const DISABLED = - 1;
28 - const LOG = 0;
29 - const WARNING = 1;
30 - const INFO = 2;
31 - const DEBUG = 3;
32 46
33 - const LOG_COLOR = '#999999';
34 - const DEBUG_COLOR = '#666666';
35 - const INFO_COLOR = '#276f86';
36 - const WARNING_COLOR = '#9f3a38;';
47 + const DISABLED = - 1;
48 + const LOG = 0;
49 + const WARNING = 1;
50 + const INFO = 2;
51 + const DEBUG = 3;
52 + const NOTICE = 4;
37 53
38 - /**
39 - * Private variable to hold time start.
40 - *
41 - * @var int
42 - */
43 - private static $time_start = null;
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';
44 59
45 - /**
46 - * Private varibale to hold the log file prefix.
47 - *
48 - * @var string Default 'mainwp'
49 - */
50 - private $logFileNamePrefix = 'mainwp';
60 + /**
61 + * Private variable to hold time start.
62 + *
63 + * @var int
64 + */
65 + private static $time_start = null;
51 66
52 - /**
53 - * Private varibale to hold the log file suffix.
54 - *
55 - * @var string Default '.log'
56 - */
57 - private $logFileNameSuffix = '.log';
67 + /**
68 + * Private varibale to hold the log file prefix.
69 + *
70 + * @var string Default 'mainwp'
71 + */
72 + private $logFileNamePrefix = 'mainwp';
58 73
59 - /**
60 - * Private varibale to hold the log file max size.
61 - *
62 - * @var int Default 0.5
63 - */
64 - private $logMaxMB = 0.5;
74 + /**
75 + * Private varibale to hold the log file suffix.
76 + *
77 + * @var string Default '.log'
78 + */
79 + private $logFileNameSuffix = '.log';
65 80
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';
81 + /**
82 + * Private varibale to hold the log file max size.
83 + *
84 + * @var int Default 0.5
85 + */
86 + private $logMaxMB = 0.5;
72 87
73 - /**
74 - * Private varibale to hold the log file output directory.
75 - *
76 - * @var mixed Default null
77 - */
78 - private $logDirectory = null;
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';
79 94
80 - /**
81 - * Private varibale to hold the log file priotrity.
82 - *
83 - * @var string Disabled
84 - */
85 - private $logPriority = self::DISABLED;
95 + /**
96 + * Private varibale to hold the log file output directory.
97 + *
98 + * @var mixed Default null
99 + */
100 + private $logDirectory = null;
86 101
87 - /**
88 - * Private varibale to hold the log Specific priotrity.
89 - *
90 - * @var string Disabled
91 - */
92 - private $logSpecific = 0;
102 + /**
103 + * Private varibale to hold the log file priotrity.
104 + *
105 + * @var string Disabled
106 + */
107 + private $logPriority = self::DISABLED;
93 108
109 + /**
110 + * Private varibale to hold the log Specific priotrity.
111 + *
112 + * @var string Disabled
113 + */
114 + private $logSpecific = 0;
94 115
95 - /**
96 - * Private static varibale to hold the instance.
97 - *
98 - * @var mixed Default null
99 - */
100 - private static $instance = null;
116 + /**
117 + * Private varibale to hold the auto enable logging actions.
118 + *
119 + * @var array Auto enable logging.
120 + */
121 + private $autoEnableLoggingActions = array();
101 122
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 === self::$instance ) {
113 - self::$instance = new self();
114 - }
115 - return self::$instance;
116 - }
117 123
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() {
124 + /**
125 + * Private static varibale to hold the instance.
126 + *
127 + * @var mixed Default null
128 + */
129 + private static $instance = null;
126 130
127 - $enabled = $this->get_log_status();
128 - $specific = $this->get_log_specific();
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 + }
129 146
130 - $enabled = apply_filters( 'mainwp_log_status', $enabled );
131 - $specific = apply_filters( 'mainwp_log_specific', $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() {
132 155
133 - $this->set_log_priority( $enabled, $specific );
134 - }
156 + add_action( 'init', array( $this, 'init' ) ); // Fix the issue where database tables do not exist.
135 157
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 - }
158 + $enabled = $this->get_log_status();
159 + $specific = $this->get_log_specific();
148 160
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' );
161 + $enabled = apply_filters( 'mainwp_log_status', $enabled );
162 + $specific = apply_filters( 'mainwp_log_specific', $specific );
158 163
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 = self::DISABLED;
168 - }
169 - }
170 - return $enabled;
171 - }
164 + $this->set_log_priority( $enabled, $specific );
172 165
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 + }
173 172
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 - }
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 + }
184 185
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 ( self::DEBUG === $type || self::DEBUG === $logcolor ) {
199 - $currentColor = self::DEBUG_COLOR;
200 - $prefix = '[DEBUG]';
201 - } elseif ( self::INFO === $type || self::INFO === $logcolor ) {
202 - $currentColor = self::INFO_COLOR;
203 - $prefix = '[INFO]';
204 - } elseif ( self::WARNING === $type || self::WARNING === $logcolor ) {
205 - $currentColor = self::WARNING_COLOR;
206 - $prefix = '[WARNING]';
207 - } elseif ( self::LOG === $type || self::LOG === $logcolor ) {
208 - $currentColor = self::LOG_COLOR;
209 - $prefix = '[LOG]';
210 - }
211 - return array(
212 - 'log_color' => $currentColor,
213 - 'log_prefix' => $prefix,
214 - );
215 - }
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 + }
216 198
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, self::DEBUG );
228 - }
229 199
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, self::INFO );
241 - }
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 + }
242 217
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, self::WARNING );
254 - }
255 218
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 - }
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 + }
271 237
272 238
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, self::UPDATE_CHECK_LOG_PRIORITY );
280 - }
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 + }
281 249
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, self::DEBUG );
298 - }
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 + }
299 284
300 - return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, self::DEBUG, 0, false, $website );
301 - }
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 + }
302 297
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, self::INFO );
319 - }
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 + }
320 310
321 - return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, self::INFO );
322 - }
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 + }
323 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, self::WARNING );
346 - }
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 + }
347 340
348 - return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message . $stackTrace, self::WARNING );
349 - }
350 341
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 ) {
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 + }
365 400
366 - if ( self::DISABLED === $this->logPriority ) {
367 - return;
368 - }
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 + }
369 409
370 - $priority = (int) apply_filters( 'mainwp_log_to_db_priority', $priority, $website );
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 + }
371 418
372 - $do_log = false;
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 + }
373 427
374 - if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
375 - if ( $this->logPriority === $priority ) { // specific priority number saved setting.
376 - $do_log = true;
377 - }
378 - } elseif ( $this->logPriority >= $priority ) {
379 - $do_log = true;
380 - }
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 + }
381 445
382 - $do_log = apply_filters( 'mainwp_log_do_to_db', $do_log, $website );
446 + return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, static::DEBUG, 0, false, $website );
447 + }
383 448
384 - $text = $this->prepare_log_info( $text );
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 + }
385 466
386 - if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
387 - if ( 'CRON' !== strtoupper( substr( $text, 0, 4 ) ) ) {
388 - $text = 'CRON :: ' . $text;
389 - }
390 - }
467 + return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message, static::INFO );
468 + }
391 469
392 - 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 + }
393 493
394 - $time = gmdate( $this->logDateFormat );
494 + return $this->log( '[' . $website->name . '] [' . MainWP_Utility::get_nice_url( $website->url ) . '] ::' . $action . ':: ' . $message . $stackTrace, static::WARNING );
495 + }
395 496
396 - /**
397 - * Current user global.
398 - *
399 - * @global string
400 - */
401 - 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 ) {
402 512
403 - $user = '';
404 - if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
405 - $user = $current_user->user_login;
406 - } elseif ( defined( 'WP_CLI' ) ) {
407 - $user = 'WP_CLI';
408 - } elseif ( defined( 'DOING_CRON' ) ) {
409 - $user = 'DOING_CRON';
410 - }
513 + if ( static::DISABLED === $this->logPriority ) {
514 + return false;
515 + }
411 516
412 - $data = array();
517 + $priority = (int) apply_filters( 'mainwp_log_to_db_priority', $priority, $website );
413 518
414 - $data['log_content'] = $text;
415 - $data['log_user'] = $user;
416 - $data['log_type'] = $priority;
417 - $data['log_color'] = intval( $log_color );
418 - $data['log_timestamp'] = time();
519 + $do_log = false;
419 520
420 - $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 + }
421 528
422 - MainWP_DB_Common::instance()->insert_action_log( $data );
529 + $do_log = apply_filters( 'mainwp_log_do_to_db', $do_log, $website );
423 530
424 - return true;
425 - }
426 - return false;
427 - }
531 + if ( ! $forced && ! $do_log ) {
532 + return false;
533 + }
428 534
429 - /**
430 - * Method log()
431 - *
432 - * Create Log File.
433 - *
434 - * @param string $text Log record text.
435 - * @param int $priority Set priority.
436 - * @param int $log_color Set color.
437 - * @param bool $forced forced logging.
438 - * @param mixed $website Site object.
439 - *
440 - * @return bool true|false Default is False.
441 - */
442 - private function log( $text, $priority, $log_color = 0, $forced = false, $website = false ) { // phpcs:ignore -- complex function.
535 + $text = $this->prepare_log_info( $text );
443 536
444 - if ( self::DISABLED === $this->logPriority ) {
445 - return;
446 - }
537 + do_action( 'mainwp_before_log_data', $text, $priority, $log_color );
447 538
448 - $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 + }
449 542
450 - if ( $log_to_db ) {
451 - return $this->log_to_db( $text, $priority, $log_color, $forced, $website );
452 - }
543 + /**
544 + * Current user global.
545 + *
546 + * @global string
547 + */
548 + global $current_user;
453 549
454 - $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 + }
455 558
456 - $do_log = false;
457 - if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
458 - if ( $this->logPriority === $priority ) { // specific priority number saved setting.
459 - $do_log = true;
460 - }
461 - } elseif ( $this->logPriority >= $priority ) {
462 - $do_log = true;
463 - }
559 + $data = array();
464 560
465 - if ( $do_log ) {
466 - $this->logCurrentFile = $this->get_log_file();
467 - $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
561 + $type = false !== $log_type ? (int) $log_type : (int) $priority;
468 562
469 - if ( $logCurrentHandle ) {
470 - $time = gmdate( $this->logDateFormat );
471 - $prefix = '[' . $this->get_log_text( $priority ) . ']';
563 + $data['log_content'] = $text;
564 + $data['log_user'] = $user;
565 + $data['log_type'] = $type;
472 566
473 - /**
474 - * Current user global.
475 - *
476 - * @global string
477 - */
478 - 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 + }
479 573
480 - if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
481 - $prefix .= ' [administrator]';
482 - }
574 + $data['log_timestamp'] = time();
483 575
484 - fwrite( $logCurrentHandle, $time . ' ' . $prefix . ' ' . $text . "\n" );
485 - fclose( $logCurrentHandle );
486 - }
576 + $data = apply_filters( 'mainwp_log_to_db_data', $data );
487 577
488 - if ( filesize( $this->logCurrentFile ) > ( $this->logMaxMB * 1048576 ) ) {
489 - $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
490 - if ( $logCurrentHandle ) {
491 - fseek( $logCurrentHandle, 0 );
492 - $newLogFile = $this->logCurrentFile . '.tmp';
493 - $newLogHandle = false;
494 - $chunkSize = filesize( $this->logCurrentFile ) - ( $this->logMaxMB * 1048576 );
495 - while ( is_resource( $logCurrentHandle ) && ! feof( $logCurrentHandle ) && ( $chunkSize > 0 ) ) {
496 - $content = fread( $logCurrentHandle, $chunkSize );
497 - if ( false === $content ) {
498 - break;
499 - }
500 - $pos = strrpos( $content, "\n" );
501 - if ( $newLogHandle ) {
502 - fwrite( $newLogHandle, $content );
503 - } elseif ( $pos ) {
504 - if ( ! $newLogHandle ) {
505 - $newLogHandle = fopen( $newLogFile, 'w+' );
506 - }
507 - fwrite( $newLogHandle, substr( $content, $pos + 1 ) );
508 - }
509 - }
578 + MainWP_DB_Common::instance()->insert_action_log( $data );
510 579
511 - if ( is_resource( $logCurrentHandle ) ) {
512 - fclose( $logCurrentHandle );
513 - }
580 + return true;
581 + }
514 582
515 - if ( $newLogHandle ) {
516 - fclose( $newLogHandle );
517 - wp_delete_file( $this->logCurrentFile );
518 - if ( file_exists( $newLogFile ) ) {
519 - rename( $newLogFile, $this->logCurrentFile );
520 - }
521 - }
522 - }
523 - }
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 + }
524 593
525 - return true;
526 - }
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 ) {
527 602
528 - return false;
529 - }
603 + if ( static::DISABLED === $this->logPriority ) {
604 + return false;
605 + }
530 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 + }
531 618
532 - /**
533 - * Method prepare_log_info()
534 - *
535 - * Prepare log data.
536 - *
537 - * @param mixed $data Log data.
538 - *
539 - * @return mixed $data filtered data.
540 - */
541 - public function prepare_log_info( $data ) {
542 - $patterns[0] = '/user=([^\&]+)\&/';
543 - $replacement[0] = 'user=xxxxxx&';
544 - $patterns[1] = '/alt_user=([^\&]+)\&/';
545 - $replacement[1] = 'alt_user=xxxxxx&';
546 - $patterns[2] = '/\&server=([^\&]+)\&/';
547 - $replacement[2] = '&server=xxxxxx&';
548 - $data = preg_replace( $patterns, $replacement, $data );
549 - return $data;
550 - }
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.
551 634
552 - /**
553 - * Method prepend()
554 - *
555 - * Prepend content to log file.
556 - *
557 - * @param mixed $str Custom string.
558 - * @param mixed $filename Filename.
559 - */
560 - public function prepend( $str, $filename ) {
561 - $context = stream_context_create();
562 - $fp = fopen( $filename, 'r', 1, $context );
563 - $tmpname = md5( $str );
564 - file_put_contents( $tmpname, $str );
565 - file_put_contents( $tmpname, $fp, FILE_APPEND );
566 - fclose( $fp );
567 - wp_delete_file( $filename );
568 - rename( $tmpname, $filename );
569 - }
635 + if ( in_array( $priority, $this->autoEnableLoggingActions ) && (int) $this->logPriority !== (int) $priority ) {
636 + $this->enable_log_priority( $priority, 1 );
637 + }
570 638
571 - /**
572 - * Method init_execution_time().
573 - *
574 - * @param string $time_index index for timer.
575 - *
576 - * Init execution time start value.
577 - */
578 - public function init_execution_time( $time_index = '' ) {
579 - if ( null === self::$time_start || ! is_array( self::$time_start ) ) {
580 - self::$time_start = array( 'start' => microtime( true ) );
581 - $this->log_action( 'execution time :: init :: [start]', self::EXECUTION_TIME_LOG_PRIORITY );
582 - }
639 + if ( static::DISABLED === $this->logPriority ) {
640 + return false;
641 + }
583 642
584 - if ( ! empty( $time_index ) && is_string( $time_index ) && 'start' !== $time_index ) {
585 - self::$time_start[ $time_index ] = microtime( true );
586 - $this->log_action( 'execution time :: init :: [' . $time_index . ']', self::EXECUTION_TIME_LOG_PRIORITY );
587 - }
588 - }
643 + $log_to_db = apply_filters( 'mainwp_logger_to_db', true, $website );
589 644
590 - /**
591 - * Method log_execution_time().
592 - *
593 - * @param string $text Log record text.
594 - *
595 - * Log the execution time value.
596 - */
597 - public function log_execution_time( $text = '' ) {
598 - $exec_time = $this->get_execution_time();
599 - $this->log_action( 'execution time :: ' . ( ! empty( $text ) ? (string) $text : '<empty>' ) . ' :: [time=' . round( $exec_time, 4 ) . '](seconds)', self::EXECUTION_TIME_LOG_PRIORITY );
600 - }
645 + if ( $log_to_db ) {
646 + return $this->log_to_db( $text, $priority, $log_color, $forced, $website, $log_type );
647 + }
601 648
649 + $text = $this->prepare_log_info( $text );
602 650
603 - /**
604 - * Method get_execution_time().
605 - *
606 - * Get the execution time value.
607 - *
608 - * @param string $time_index Index for timer.
609 - *
610 - * @return int execution time.
611 - */
612 - 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 + }
613 659
614 - if ( empty( self::$time_start ) ) {
615 - return 0;
616 - }
660 + if ( $do_log ) {
661 + $this->logCurrentFile = $this->get_log_file();
662 + $logCurrentHandle = fopen( $this->logCurrentFile, 'a+' );
617 663
618 - $start = 0;
619 - if ( ! empty( $time_index ) ) {
620 - $start = is_array( self::$time_start ) && isset( self::$time_start[ $time_index ] ) ? self::$time_start[ $time_index ] : 0;
621 - }
664 + if ( $logCurrentHandle ) {
665 + $time = gmdate( $this->logDateFormat );
666 + $prefix = '[' . $this->get_log_text( $priority ) . ']';
622 667
623 - if ( empty( $start ) ) {
624 - $start = is_array( self::$time_start ) && isset( self::$time_start['start'] ) ? self::$time_start['start'] : 0;
625 - }
668 + /**
669 + * Current user global.
670 + *
671 + * @global string
672 + */
673 + global $current_user;
626 674
627 - if ( empty( $start ) ) {
628 - return 0;
629 - }
630 - return microtime( true ) - $start; // seconds.
631 - }
675 + if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
676 + $prefix .= ' [administrator]';
677 + }
632 678
633 - /**
634 - * Method get_log_file()
635 - *
636 - * Grab Log File.
637 - *
638 - * @return mixed Log File.
639 - */
640 - public function get_log_file() {
641 - if ( empty( $this->logDirectory ) ) {
642 - $this->logDirectory = MainWP_System_Utility::get_mainwp_dir();
643 - $this->logDirectory = $this->logDirectory[0];
644 - }
645 - return $this->logDirectory . $this->logFileNamePrefix . $this->logFileNameSuffix;
646 - }
679 + fwrite( $logCurrentHandle, $time . ' ' . $prefix . ' ' . $text . "\n" );
680 + fclose( $logCurrentHandle );
681 + }
647 682
648 - /**
649 - * Method get_log_text()
650 - *
651 - * Grab what type of log entry.
652 - *
653 - * @param mixed $priority Set priority.
654 - *
655 - * @return string LOG -OR- DISABLED|DEBUG|INFO|WARNING|INFO UPDATE
656 - */
657 - public function get_log_text( $priority ) {
658 - switch ( $priority ) {
659 - case self::DISABLED:
660 - return 'DISABLED';
661 - case self::DEBUG:
662 - return 'DEBUG';
663 - case self::INFO:
664 - return 'INFO';
665 - case self::WARNING:
666 - return 'WARNING';
667 - default:
668 - return 'SPEC LOG';
669 - }
670 - }
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 + }
671 705
672 - /**
673 - * Method check_log_daily()
674 - *
675 - * Daily checks to clear the log file.
676 - */
677 - public function check_log_daily() {
678 - $status = (int) $this->get_log_status();
679 - if ( 0 >= $status ) {
680 - return;
681 - }
706 + if ( is_resource( $logCurrentHandle ) ) {
707 + fclose( $logCurrentHandle );
708 + }
682 709
683 - $today_m_y = date_i18n( 'd/m/Y' ); //phpcs:ignore -- local time.
684 - // one time per day.
685 - if ( get_option( 'mainwp_logger_check_daily' ) !== $today_m_y ) {
686 - $num_days = apply_filters( 'mainwp_logger_keep_days', 7 );
687 - MainWP_DB_Common::instance()->delete_action_log( $num_days );
688 - 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 + }
689 719
690 - $enabled_time = get_option( 'mainwp_actionlogs_enabled_timestamp', false );
691 - if ( false === $enabled_time ) {
692 - MainWP_Utility::update_option( 'mainwp_actionlogs_enabled_timestamp', time() );
693 - } elseif ( $enabled_time + $num_days * DAY_IN_SECONDS < time() ) {
694 - MainWP_Utility::update_option( 'mainwp_actionlogs', self::DISABLED );
695 - }
696 - }
697 - }
720 + return true;
721 + }
698 722
699 - /**
700 - * Method clear_log_db()
701 - *
702 - * Clear the log file.
703 - */
704 - public function clear_log_db() {
705 - MainWP_DB_Common::instance()->delete_action_log();
706 - }
723 + return false;
724 + }
707 725
708 - /**
709 - * Method clear_log()
710 - *
711 - * Clear the log file.
712 - */
713 - public function clear_log() {
714 - $logFile = $this->get_log_file();
715 - wp_delete_file( $logFile );
716 - $fh = fopen( $logFile, 'w' );
717 - if ( false === $fh ) {
718 - return;
719 - }
720 - fclose( $fh );
721 - }
722 726
723 - /**
724 - * Method show_log_db()
725 - *
726 - * Grab log file and build output to screen.
727 - */
728 - 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 + }
729 760
730 - echo '<div class="ui hidden divider"></div>';
731 - 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 + }
732 779
733 - $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 + }
734 792
735 - $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;">';
736 - $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 + }
737 798
738 - while ( $rows && ( $row = MainWP_DB::fetch_object( $rows ) ) ) {
739 - $type = $row->log_type;
740 - $line = $row->log_content;
741 - if ( 120 * 1024 < strlen( $line ) ) {
742 - $line = '[Data row too long]';
743 - }
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 + }
744 810
745 - $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.
746 821
747 - $showInfo = $this->get_log_type_info( $row->log_type, $row->log_color );
748 - $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 + }
749 825
750 - $prefix = $time . ' ' . $showInfo['log_prefix'];
826 + static $initialized = false;
751 827
752 - $line = htmlentities( $line );
828 + if ( 'init' === $progress && ! $initialized ) {
829 + $initialized = true;
830 + MainWP_Execution_Helper::init_http_call_track();
831 + }
753 832
754 - if ( false !== strpos( $line, '[data-start]' ) ) {
755 - $line = str_replace( '[data-start]', $start_wrapper, $line );
756 - $line = str_replace( '[data-end]', $end_wrapper, $line );
757 - }
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 + }
758 837
759 - 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;
760 840
761 - echo $prefix . ' ' . $line; // phpcs:ignore WordPress.Security.EscapeOutput
841 + $exec_time = $this->get_execution_time();
842 + $exec_time = round( $exec_time, 4 );
762 843
763 - echo '</div></div>';
764 - }
844 + if ( ! empty( $text ) ) {
845 + $text = $text . ' :: ';
846 + }
765 847
766 - echo '</div></div>';
848 + $id = '';
767 849
768 - echo '</div>';
850 + if ( ! empty( $website ) ) {
769 851
770 - ?>
771 - <div class="ui large modal" id="mainwp-action-log-response-modal">
772 - <i class="close icon mainwp-reload"></i>
773 - <div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div>
774 - <div class="content">
775 - <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' ); ?>
776 - </div>
777 - </div>
778 - <div class="scrolling content content-response"></div>
779 - <div class="actions">
780 - <button class="ui green button mainwp-response-copy-button"><?php esc_html_e( 'Copy Response', 'mainwp' ); ?></button>
781 - </div>
782 - </div>
783 - <?php
784 - }
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 + }
785 862
786 - /**
787 - * Method show_log_file()
788 - *
789 - * Grab log file and build output to screen.
790 - */
791 - public function show_log_file() {
792 - $logFile = $this->get_log_file();
863 + if ( ! empty( $id ) ) {
864 + $text .= '[siteid=' . $id . '] :: ';
865 + }
793 866
794 - if ( ! file_exists( $logFile ) ) {
795 - return;
796 - }
867 + $log = $text . '[total runtime=' . $exec_time . '](sec)';
797 868
798 - $fh = fopen( $logFile, 'r' );
799 - if ( false === $fh ) {
800 - return;
801 - }
869 + $mem = '';
802 870
803 - $previousColor = '';
804 - $fontOpen = false;
805 - $firstLinePassedProcessed = false;
806 - echo '<div class="ui hidden divider"></div>';
807 - echo '<div class="ui divided padded relaxed list">';
808 - while ( false !== ( $line = fgets( $fh ) ) ) {
809 - $currentColor = $previousColor;
810 - if ( stristr( $line, '[DEBUG]' ) ) {
811 - $currentColor = self::DEBUG_COLOR;
812 - $firstLinePassed = true;
813 - } elseif ( stristr( $line, '[INFO]' ) ) {
814 - $currentColor = self::INFO_COLOR;
815 - $firstLinePassed = true;
816 - } elseif ( stristr( $line, '[WARNING]' ) ) {
817 - $currentColor = self::WARNING_COLOR;
818 - $firstLinePassed = true;
819 - } elseif ( stristr( $line, '[LOG]' ) ) {
820 - $currentColor = self::LOG_COLOR;
821 - $firstLinePassed = true;
822 - } else {
823 - $firstLinePassed = false;
824 - }
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 + }
825 876
826 - if ( $firstLinePassedProcessed && ! $firstLinePassed ) {
827 - 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;">';
828 - }
877 + if ( ! empty( $mem ) ) {
878 + $log .= ' :: [memory usage=' . $mem . '](MB)';
879 + }
829 880
830 - $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 + }
831 891
832 - if ( $currentColor !== $previousColor ) {
833 - if ( $fontOpen ) {
834 - echo '</div></div>';
835 - }
892 + $callstats = MainWP_Execution_Helper::get_exec_call_stats();
836 893
837 - echo '<div class="item" style="color:' . esc_html( $currentColor ) . '"><div class="mainwpactionlogsline">';
838 - $fontOpen = true;
839 - }
894 + $rows_details = array();
840 895
841 - echo esc_html( htmlentities( $line ) );
842 - }
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 + }
843 910
844 - if ( $fontOpen ) {
845 - echo '</div></div>';
846 - }
911 + $log .= ' :: [ver=' . MainWP_System::get_mainwp_version() . ']';
847 912
848 - echo '</div>';
913 + $lg_type = (int) $exec_time >= 50 ? static::NOTICE : static::INFO;
914 + $lg_type = (int) $exec_time >= 80 ? static::WARNING : $lg_type;
849 915
850 - ?>
851 - <div class="ui large modal" id="mainwp-action-log-response-modal">
852 - <i class="close icon mainwp-reload"></i>
853 - <div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div>
854 - <div class="content">
855 - <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' ); ?>
856 - </div>
857 - </div>
858 - <div class="scrolling content content-response"></div>
859 - <div class="actions">
860 - <button class="ui green button mainwp-response-copy-button"><?php esc_html_e( 'Copy Response', 'mainwp' ); ?></button>
861 - </div>
862 - </div>
863 - <?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 );
864 918
865 - fclose( $fh );
866 - }
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 + }
867 1244 }