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 | modules/logs/classes/class-log.php +204 -163 5.0.3 → 6.2.1 View file →
@@ -8,213 +8,254 @@
8 8 */
9 9
10 10 namespace MainWP\Dashboard\Module\Log;
11 11
12 +use MainWP\Dashboard\MainWP_Execution_Helper;
13 +
14 +// Exit if accessed directly.
15 +if ( ! defined( 'ABSPATH' ) ) {
16 + exit;
17 +}
18 +
12 19 /**
13 20 * Class Logs
14 21 */
15 22 class Log {
16 23
17 - /**
18 - * Log_Manager
19 - *
20 - * @var manager Hold Log_Manager class
21 - * */
22 - public $manager;
24 + /**
25 + * Log_Manager
26 + *
27 + * @var manager Hold Log_Manager class
28 + * */
29 + public $manager;
23 30
24 - /**
25 - * Hold Current visitors IP Address.
26 - *
27 - * @var string Hold Current visitors IP Address.
28 - * */
29 - private $ip_address;
31 + /**
32 + * Log constructor.
33 + *
34 + * Run each time the class is called.
35 + *
36 + * @param Log_Manager $manager The main manager class.
37 + */
38 + public function __construct( $manager ) {
39 + $this->manager = $manager;
40 + }
30 41
31 42
32 - /**
33 - * Log constructor.
34 - *
35 - * Run each time the class is called.
36 - *
37 - * @param Log_Manager $manager The main manager class.
38 - */
39 - public function __construct( $manager ) {
40 - $this->manager = $manager;
41 - }
43 + /**
44 + * Log handler.
45 + *
46 + * @param Connector $connector Connector responsible for logging the event.
47 + * @param string $message sprintf-ready error message string.
48 + * @param array $args sprintf (and extra) arguments to use.
49 + * @param int $site_id Target site id.
50 + * @param string $context Context of the event.
51 + * @param string $action Action of the event.
52 + * @param int|null $state action status: null - N/A, 0 - failed, 1 - success.
53 + * @param int $user_id User responsible for the event.
54 + *
55 + * @return bool|WP_Error True if updated, otherwise false|WP_Error
56 + */
57 + public function log( $connector, $message, $args, $site_id, $context, $action, $state = null, $user_id = null ) { //phpcs:ignore -- NOSONAR - compatible.
42 58
59 + if ( is_null( $user_id ) ) {
60 + $user_id = get_current_user_id();
61 + }
43 62
44 - /**
45 - * Log handler.
46 - *
47 - * @param Connector $connector Connector responsible for logging the event.
48 - * @param string $message sprintf-ready error message string.
49 - * @param array $args sprintf (and extra) arguments to use.
50 - * @param int $site_id Target site id.
51 - * @param string $context Context of the event.
52 - * @param string $action Action of the event.
53 - * @param int|null $state action status: null - N/A, 0 - failed, 1 - success.
54 - * @param int $user_id User responsible for the event.
55 - *
56 - * @return bool|WP_Error True if updated, otherwise false|WP_Error
57 - */
58 - public function log( $connector, $message, $args, $site_id, $context, $action, $state = null, $user_id = null ) {
63 + if ( is_null( $site_id ) ) {
64 + $site_id = 0;
65 + }
59 66
60 - if ( is_null( $user_id ) ) {
61 - $user_id = get_current_user_id();
62 - }
67 + $disable_cron_log = apply_filters( 'mainwp_module_log_disable_cron_log', false, $connector, $message, $args, $site_id, $context, $action, $user_id, $state );
63 68
64 - if ( is_null( $site_id ) ) {
65 - $site_id = 0;
66 - }
69 + if ( $disable_cron_log && defined( 'DOING_CRON' ) && DOING_CRON ) {
70 + return false; // disable log cron tasks.
71 + }
67 72
68 - $cron_tracking = apply_filters( 'mainwp_module_log_cron_tracking', true, $connector, $message, $args, $site_id, $context, $action, $user_id, $state );
73 + $cron_tracking = apply_filters( 'mainwp_module_log_cron_tracking', true, $connector, $message, $args, $site_id, $context, $action, $user_id, $state );
69 74
70 - $author = new Log_Author( $user_id );
75 + $author = new Log_Author( $user_id );
71 76
72 - $agent = $author->get_current_agent();
77 + $agent = $author->get_current_agent();
73 78
74 - // WP Cron tracking requires opt-in and WP Cron to be enabled.
75 - if ( ! $cron_tracking && 'wp_cron' === $agent ) {
76 - return false;
77 - }
79 + // WP Cron tracking requires opt-in and WP Cron to be enabled.
80 + if ( ! $cron_tracking && 'wp_cron' === $agent ) {
81 + return false;
82 + }
78 83
79 - $user = new \WP_User( $user_id );
84 + $user = new \WP_User( $user_id );
85 + $user_login = ! empty( $user->user_login ) ? (string) $user->user_login : '';
80 86
81 - $user_meta = array(
82 - 'user_login' => (string) ! empty( $user->user_login ) ? $user->user_login : '',
83 - 'agent' => (string) $agent,
84 - );
87 + $user_meta = array(
88 + 'user_login' => $user_login,
89 + 'agent' => (string) $agent,
90 + );
85 91
86 - if ( 'wp_cli' === $agent && function_exists( 'posix_getuid' ) ) {
87 - $uid = posix_getuid();
88 - $user_info = posix_getpwuid( $uid );
92 + $system_user = '';
93 + if ( 'wp_cli' === $agent ) {
94 + $system_user = 'wp_cli';
95 + if ( is_callable( 'posix_getuid' ) && is_callable( 'posix_getpwuid' ) ) {
96 + $uid = posix_getuid();
97 + $user_info = posix_getpwuid( $uid );
89 98
90 - $user_meta['system_user_id'] = (int) $uid;
91 - $user_meta['system_user_name'] = (string) $user_info['name'];
92 - }
99 + $user_meta['system_user_id'] = (int) $uid;
100 + $user_meta['system_user_name'] = (string) $user_info['name'];
93 101
94 - $dura = isset( $args['duration'] ) ? floatval( $args['duration'] ) : $this->manager->executor->get_exec_time();
102 + if ( ! empty( $user_meta['system_user_name'] ) ) {
103 + $system_user = $user_meta['system_user_name'];
104 + }
105 + }
106 + } elseif ( 'wp_cron' === $agent ) {
107 + $system_user = 'wp_cron';
108 + } elseif ( 'wp_rest_api' === $agent ) {
109 + $system_user = 'wp_rest_api';
110 + }
95 111
96 - if ( isset( $args['duration'] ) ) {
97 - unset( $args['duration'] );
98 - }
112 + $dura = isset( $args['duration'] ) ? floatval( $args['duration'] ) : MainWP_Execution_Helper::get_run_time();
99 113
100 - $dura_bulk = 1;
101 - if ( isset( $args['duration_bulk'] ) ) {
102 - $dura_bulk = intval( $args['duration_bulk'] );
103 - unset( $args['duration_bulk'] );
104 - }
114 + if ( isset( $args['duration'] ) ) {
115 + unset( $args['duration'] );
116 + }
105 117
106 - if ( empty( $dura_bulk ) ) {
107 - $dura_bulk = 1;
108 - }
118 + $dura_bulk = 1;
119 + if ( isset( $args['duration_bulk'] ) ) {
120 + $dura_bulk = intval( $args['duration_bulk'] );
121 + unset( $args['duration_bulk'] );
122 + }
109 123
110 - $dura = $dura / $dura_bulk;
124 + if ( empty( $dura_bulk ) ) {
125 + $dura_bulk = 1;
126 + }
111 127
112 - // Prevent any meta with null values from being logged.
113 - $logs_meta = array_filter(
114 - $args,
115 - function ( $e ) {
116 - return ! is_null( $e );
117 - }
118 - );
128 + $dura = $dura / $dura_bulk;
119 129
120 - // Add user meta to Log meta.
121 - $logs_meta['user_meta'] = $user_meta;
130 + $created = microtime( true );
122 131
123 - $recordarr = array(
124 - 'site_id' => (int) $site_id,
125 - 'user_id' => (int) $user_id,
126 - 'item' => (string) vsprintf( $message, $args ),
127 - 'connector' => (string) $connector,
128 - 'context' => (string) $context,
129 - 'action' => (string) $action,
130 - 'duration' => $dura,
131 - 'created' => time(),
132 - 'state' => $state,
133 - 'meta' => (array) $logs_meta,
134 - );
132 + if ( ! empty( $args['created'] ) ) {
133 + $created = (float) $args['created'];
134 + unset( $args['created'] );
135 + }
135 136
136 - if ( 0 === $recordarr['site_id'] ) {
137 - unset( $recordarr['site_id'] );
138 - }
137 + $created = Log_Manager::normalize_to_microseconds( $created ); // Store timestamps (including microseconds) as a BIGINT.
139 138
140 - if ( null === $recordarr['state'] || '' === $recordarr['state'] ) {
141 - unset( $recordarr['state'] );
142 - }
139 + // Prevent any meta with null values from being logged.
140 + $logs_meta = array_filter(
141 + $args,
142 + function ( $e ) {
143 + return ! is_null( $e );
144 + }
145 + );
143 146
144 - $result = $this->manager->db->insert( $recordarr );
147 + if ( empty( $logs_meta['user_login'] ) ) {
148 + if ( ! empty( $user_meta['user_login'] ) ) {
149 + $logs_meta['user_login'] = $user_meta['user_login'];
150 + } elseif ( ! empty( $system_user ) ) {
151 + $logs_meta['user_login'] = $system_user;
152 + }
153 + }
145 154
146 - // This is helpful in development environments.
147 - // error_log( $this->debug_backtrace( $recordarr ) ); //phpcs:ignore -- development.
155 + // Add user meta to Log meta.
156 + $logs_meta['user_meta_json'] = wp_json_encode( $user_meta );
148 157
149 - return $result;
150 - }
158 + $recordarr = array(
159 + 'site_id' => (int) $site_id,
160 + 'user_id' => (int) $user_id,
161 + 'user_login' => (string) $user_login,
162 + 'item' => (string) vsprintf( $message, $args ),
163 + 'connector' => (string) $connector,
164 + 'context' => (string) $context,
165 + 'action' => (string) $action,
166 + 'duration' => $dura,
167 + 'created' => $created,
168 + 'state' => $state,
169 + 'meta' => (array) $logs_meta,
170 + );
151 171
152 - /**
153 - * Helper function to send a full backtrace of calls to the PHP error log for debugging.
154 - *
155 - * @param array $recordarr Record argument array.
156 - *
157 - * @return string $output MainWP Pro Reports backtrace.
158 - */
159 - public function debug_backtrace( $recordarr ) {
160 - // Record details.
161 - $message = isset( $recordarr['item'] ) ? $recordarr['item'] : null;
162 - $author = isset( $recordarr['author'] ) ? $recordarr['author'] : null;
163 - $connector = isset( $recordarr['connector'] ) ? $recordarr['connector'] : null;
164 - $context = isset( $recordarr['context'] ) ? $recordarr['context'] : null;
165 - $action = isset( $recordarr['action'] ) ? $recordarr['action'] : null;
172 + if ( 0 === $recordarr['site_id'] ) {
173 + unset( $recordarr['site_id'] );
174 + }
166 175
167 - // Log meta.
168 - $logs_meta = isset( $recordarr['meta'] ) ? $recordarr['meta'] : null;
176 + if ( null === $recordarr['state'] || '' === $recordarr['state'] ) {
177 + unset( $recordarr['state'] );
178 + }
179 + // This is helpful in development environments.
180 + // error_log( $this->debug_backtrace( $recordarr ) ); //phpcs:ignore -- development.
181 + return $this->log_record( $recordarr );
182 + }
169 183
170 - unset( $logs_meta['user_meta'] );
184 + /**
185 + * Log record.
186 + *
187 + * @param array $recordarr sprintf (and extra) arguments to use.
188 + *
189 + * @return bool|WP_Error True if updated, otherwise false|WP_Error
190 + */
191 + public function log_record( $recordarr ) { //phpcs:ignore -- NOSONAR - compatible.
192 + return $this->manager->db->insert( $recordarr );
193 + }
171 194
172 - if ( $logs_meta ) {
173 - array_walk(
174 - $logs_meta,
175 - function ( &$value, $key ) {
176 - $value = sprintf( '%s: %s', $key, ( '' === $value ) ? 'null' : $value );
177 - }
178 - );
179 - $logs_meta = implode( ', ', $logs_meta );
180 - }
195 + /**
196 + * Helper function to send a full backtrace of calls to the PHP error log for debugging.
197 + *
198 + * @param array $recordarr Record argument array.
199 + *
200 + * @return string $output MainWP Pro Reports backtrace.
201 + */
202 + public function debug_backtrace( $recordarr ) {
203 + // Record details.
204 + $message = isset( $recordarr['item'] ) ? $recordarr['item'] : null;
205 + $author = isset( $recordarr['author'] ) ? $recordarr['author'] : null;
206 + $connector = isset( $recordarr['connector'] ) ? $recordarr['connector'] : null;
207 + $context = isset( $recordarr['context'] ) ? $recordarr['context'] : null;
208 + $action = isset( $recordarr['action'] ) ? $recordarr['action'] : null;
181 209
182 - // User meta.
183 - $user_meta = isset( $recordarr['meta']['user_meta'] ) ? $recordarr['meta']['user_meta'] : null;
210 + // Log meta.
211 + $logs_meta = isset( $recordarr['meta'] ) ? $recordarr['meta'] : null;
184 212
185 - if ( $user_meta ) {
186 - array_walk(
187 - $user_meta,
188 - function ( &$value, $key ) {
189 - $value = sprintf( '%s: %s', $key, ( '' === $value ) ? 'null' : $value );
190 - }
191 - );
213 + unset( $logs_meta['user_meta'] );
192 214
193 - $user_meta = implode( ', ', $user_meta );
194 - }
215 + if ( $logs_meta ) {
216 + array_walk(
217 + $logs_meta,
218 + function ( &$value, $key ) {
219 + $value = sprintf( '%s: %s', $key, ( '' === $value ) ? 'null' : $value );
220 + }
221 + );
222 + $logs_meta = implode( ', ', $logs_meta );
223 + }
195 224
196 - // Debug backtrace.
197 - ob_start();
225 + // User meta.
226 + $user_meta = isset( $recordarr['meta']['user_meta'] ) ? $recordarr['meta']['user_meta'] : null;
198 227
199 - // @codingStandardsIgnoreStart
200 - debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // Option to ignore args requires PHP 5.3.6
201 - // @codingStandardsIgnoreEnd
228 + if ( $user_meta ) {
229 + array_walk(
230 + $user_meta,
231 + function ( &$value, $key ) {
232 + $value = sprintf( '%s: %s', $key, ( '' === $value ) ? 'null' : $value );
233 + }
234 + );
202 235
203 - $backtrace = ob_get_clean();
204 - $backtrace = array_values( array_filter( explode( "\n", $backtrace ) ) );
236 + $user_meta = implode( ', ', $user_meta );
237 + }
205 238
206 - $output = sprintf(
207 - "Pro Reports Debug Backtrace\n\n Summary | %s\n Author | %s\n Connector | %s\n Context | %s\n Action | %s\nReports Meta | %s\nAuthor Meta | %s\n\n%s\n",
208 - $message,
209 - $author,
210 - $connector,
211 - $context,
212 - $action,
213 - $logs_meta,
214 - $user_meta,
215 - implode( "\n", $backtrace )
216 - );
239 + // Debug backtrace.
240 + ob_start();
217 241
218 - return $output;
219 - }
242 + // @codingStandardsIgnoreStart
243 + debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // Option to ignore args requires PHP 5.3.6
244 + // @codingStandardsIgnoreEnd
245 +
246 + $backtrace = ob_get_clean();
247 + $backtrace = array_values( array_filter( explode( "\n", $backtrace ) ) );
248 +
249 + return sprintf(
250 + "Pro Reports Debug Backtrace\n\n Summary | %s\n Author | %s\n Connector | %s\n Context | %s\n Action | %s\nReports Meta | %s\nAuthor Meta | %s\n\n%s\n",
251 + $message,
252 + $author,
253 + $connector,
254 + $context,
255 + $action,
256 + $logs_meta,
257 + $user_meta,
258 + implode( "\n", $backtrace )
259 + );
260 + }
220 261 }