PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.1.8
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.1.8
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / modules / logs / classes / class-log.php

class-log.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.1.8, at modules/logs/classes/class-log.php

262 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Database Logs.
4 *
5 * This file handles all interactions with the Client DB.
6 *
7 * @package MainWP/Dashboard
8 */
9
10 namespace MainWP\Dashboard\Module\Log;
11
12 use MainWP\Dashboard\MainWP_Execution_Helper;
13
14 // Exit if accessed directly.
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 /**
20 * Class Logs
21 */
22 class Log {
23
24 /**
25 * Log_Manager
26 *
27 * @var manager Hold Log_Manager class
28 * */
29 public $manager;
30
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 }
41
42
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.
58
59 if ( is_null( $user_id ) ) {
60 $user_id = get_current_user_id();
61 }
62
63 if ( is_null( $site_id ) ) {
64 $site_id = 0;
65 }
66
67 $disable_cron_log = apply_filters( 'mainwp_module_log_disable_cron_log', false, $connector, $message, $args, $site_id, $context, $action, $user_id, $state );
68
69 if ( $disable_cron_log && defined( 'DOING_CRON' ) && DOING_CRON ) {
70 return false; // disable log cron tasks.
71 }
72
73 $cron_tracking = apply_filters( 'mainwp_module_log_cron_tracking', true, $connector, $message, $args, $site_id, $context, $action, $user_id, $state );
74
75 $author = new Log_Author( $user_id );
76
77 $agent = $author->get_current_agent();
78
79 // WP Cron tracking requires opt-in and WP Cron to be enabled.
80 if ( ! $cron_tracking && 'wp_cron' === $agent ) {
81 return false;
82 }
83
84 $user = new \WP_User( $user_id );
85 $user_login = ! empty( $user->user_login ) ? (string) $user->user_login : '';
86
87 $user_meta = array(
88 'user_login' => $user_login,
89 'agent' => (string) $agent,
90 );
91
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 );
98
99 $user_meta['system_user_id'] = (int) $uid;
100 $user_meta['system_user_name'] = (string) $user_info['name'];
101
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 }
111
112 $dura = isset( $args['duration'] ) ? floatval( $args['duration'] ) : MainWP_Execution_Helper::get_run_time();
113
114 if ( isset( $args['duration'] ) ) {
115 unset( $args['duration'] );
116 }
117
118 $dura_bulk = 1;
119 if ( isset( $args['duration_bulk'] ) ) {
120 $dura_bulk = intval( $args['duration_bulk'] );
121 unset( $args['duration_bulk'] );
122 }
123
124 if ( empty( $dura_bulk ) ) {
125 $dura_bulk = 1;
126 }
127
128 $dura = $dura / $dura_bulk;
129
130 $created = microtime( true );
131
132 if ( ! empty( $args['created'] ) ) {
133 $created = (float) $args['created'];
134 unset( $args['created'] );
135 }
136
137 $created = Log_Manager::normalize_to_microseconds( $created ); // Store timestamps (including microseconds) as a BIGINT.
138
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 );
146
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 }
154
155 // Add user meta to Log meta.
156 $logs_meta['user_meta_json'] = wp_json_encode( $user_meta );
157
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 );
171
172 if ( 0 === $recordarr['site_id'] ) {
173 unset( $recordarr['site_id'] );
174 }
175
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 }
183
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 }
194
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;
209
210 // Log meta.
211 $logs_meta = isset( $recordarr['meta'] ) ? $recordarr['meta'] : null;
212
213 unset( $logs_meta['user_meta'] );
214
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 }
224
225 // User meta.
226 $user_meta = isset( $recordarr['meta']['user_meta'] ) ? $recordarr['meta']['user_meta'] : null;
227
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 );
235
236 $user_meta = implode( ', ', $user_meta );
237 }
238
239 // Debug backtrace.
240 ob_start();
241
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 }
261 }
262