PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.1.3
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.1.3
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-db.php

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

343 lines 9.2 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_DB;
13
14 // Exit if accessed directly.
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 /**
20 * Class Log_DB
21 *
22 * @package MainWP\Dashboard
23 */
24 class Log_DB extends MainWP_DB {
25
26 /**
27 * Holds the driver instance
28 *
29 * @var Log_DB_Driver
30 */
31 public $driver;
32
33 /**
34 * Number of records in last request
35 *
36 * @var int
37 */
38 protected $found_records_count = 0;
39
40
41 /**
42 * Hold logs sites options.
43 *
44 * @var int
45 */
46 protected $logs_wp_options;
47
48 /**
49 * Constructor.
50 *
51 * Run each time the class is called.
52 *
53 * @param array $driver db driver.
54 */
55 public function __construct( $driver ) {
56 parent::__construct();
57 $this->driver = $driver;
58 }
59
60 /**
61 * Insert a record
62 *
63 * @param array $record New record.
64 *
65 * @return int
66 */
67 public function insert( $record ) {
68 if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
69 return false;
70 }
71
72 /**
73 * Filter allows modification of record information
74 *
75 * @param array $record
76 *
77 * @return array
78 */
79 $record = apply_filters( 'mainwp_module_log_record_array', $record );
80
81 /**
82 * Hook mainwp_module_log_enable_insert_log_type.
83 *
84 * @since 5.5.
85 */
86 $enable_log_type = apply_filters( 'mainwp_module_log_enable_insert_log_type', true, $record );
87
88 if ( ! $enable_log_type ) {
89 return false;
90 }
91
92 $data = $this->sanitize_record( $record );
93
94 if ( empty( $data ) ) {
95 return false;
96 }
97
98 $record_id = $this->driver->insert_record( $data );
99
100 if ( ! $record_id ) {
101 /**
102 * Fires on a record insertion error
103 *
104 * @param array $record
105 * @param mixed $result
106 */
107 do_action( 'mainwp_module_log_record_insert_error', $record, false );
108
109 return false;
110 }
111
112 /**
113 * Fires after a record has been inserted
114 *
115 * @param int $record_id
116 * @param array $record
117 */
118 do_action( 'mainwp_module_log_record_inserted', $record_id, $record );
119
120 return absint( $record_id );
121 }
122
123 /**
124 * Ensure the record matches our schema.
125 *
126 * @param array $record Record to store.
127 *
128 * @return array
129 */
130 protected function sanitize_record( $record ) {
131 if ( ! is_array( $record ) ) {
132 return array();
133 }
134
135 $record_defaults = array(
136 'site_id' => null,
137 'user_id' => null,
138 'user_login' => null,
139 'created' => null,
140 'log_type_id' => null,
141 'item' => null,
142 'connector' => null,
143 'context' => null,
144 'action' => null,
145 'state' => null,
146 'duration' => null,
147 'meta' => array(),
148 );
149
150 // Records can have only these fields.
151 $record = array_intersect_key( $record, $record_defaults );
152
153 // Sanitize all record values.
154 return array_map(
155 function ( $value ) {
156 if ( ! is_array( $value ) ) {
157 return wp_strip_all_tags( $value );
158 }
159
160 return $value;
161 },
162 $record
163 );
164 }
165
166 /**
167 * Get logs records
168 *
169 * @param array $args Arguments to filter result by.
170 *
171 * @return array Log Records
172 */
173 public function get_records( $args ) {
174 $defaults = array(
175 // Search param.
176 'search' => null,
177 'search_field' => 'item',
178 'records_per_page' => get_option( 'posts_per_page', 20 ),
179 'paged' => 1,
180 // Order.
181 'order' => 'desc',
182 'orderby' => 'date',
183 );
184
185 $args = wp_parse_args( $args, $defaults );
186
187 /**
188 * Filter allows additional arguments to query $args
189 *
190 * @return array Array of query arguments
191 */
192 $args = apply_filters( 'mainwp_module_log_query_args', $args );
193
194 $result = (array) $this->driver->get_records( $args );
195 $this->found_records_count = isset( $result['count'] ) ? $result['count'] : 0;
196 $this->logs_wp_options = isset( $result['sites_opts'] ) && is_array( $result['sites_opts'] ) ? $result['sites_opts'] : array();
197
198 return empty( $result['items'] ) ? array() : $result['items'];
199 }
200
201 /**
202 * Helper function, backwards compatibility
203 *
204 * @param array $args Argument to filter result by.
205 *
206 * @return array Log Records
207 */
208 public function query( $args ) {
209 return $this->get_records( $args );
210 }
211
212 /**
213 * Return the number of records found in last request
214 *
215 * @return int
216 */
217 public function get_found_records_count() {
218 return $this->found_records_count;
219 }
220
221 /**
222 * Return the number of records found in last request
223 *
224 * @return int
225 */
226 public function get_logs_sites_opts() {
227 return $this->logs_wp_options;
228 }
229
230 /**
231 * Public getter to return table names
232 *
233 * @return array
234 */
235 public function get_table_names() {
236 return $this->driver->get_table_names();
237 }
238
239
240 /**
241 * Create compact logs and erase records from the database.
242 *
243 * @param int $start_time start time to compact.
244 * @param int $end_time end time to compact.
245 *
246 * @return mixed results.
247 */
248 public function create_compact_and_erase_records( $start_time, $end_time ) { //phpcs:ignore -- NOSONAR - complex.
249
250 global $wpdb;
251
252 $where_compact = $wpdb->prepare( ' AND `logs`.`created` >= %d AND `logs`.`created` <= %d ', $start_time, $end_time );
253 $sql = "SELECT `logs`.* FROM {$wpdb->mainwp_tbl_logs} logs WHERE `logs`.`connector` != 'compact' " . $where_compact;
254
255 $logs = MainWP_DB::instance()->query( $sql );
256 $stats_data = array();
257
258 $done = false;
259 while ( $logs && ( $item = MainWP_DB::fetch_object( $logs ) ) ) {
260 $conn = $item->connector;
261 $cont = $item->context;
262 $act = $item->action;
263
264 if ( empty( $conn ) || empty( $cont ) || empty( $act ) ) {
265 continue;
266 }
267
268 $year = (int) gmdate( 'Y', intval( $item->created / 1000000 ) );
269
270 if ( $year < 2020 ) {
271 return;
272 }
273
274 if ( ! isset( $stats_data[ $year ] ) ) {
275 $stats_data[ $year ] = array();
276 }
277
278 if ( ! isset( $stats_data[ $year ][ $conn ] ) ) {
279 $stats_data[ $year ][ $conn ] = array();
280 }
281 if ( ! isset( $stats_data[ $year ][ $conn ][ $cont ] ) ) {
282 $stats_data[ $year ][ $conn ][ $cont ] = array();
283 }
284
285 if ( ! isset( $stats_data[ $year ][ $conn ][ $cont ][ $act ] ) ) {
286 $stats_data[ $year ][ $conn ][ $cont ][ $act ] = array(
287 'count' => 0,
288 'duration' => 0,
289 );
290 }
291 $stats_data[ $year ][ $conn ][ $cont ][ $act ]['count'] += 1;
292 $stats_data[ $year ][ $conn ][ $cont ][ $act ]['duration'] += $item->duration;
293 $done = true;
294 }
295
296 if ( $done ) {
297 foreach ( $stats_data as $year => $data ) {
298 $year_data = array(
299 'data' => $data,
300 );
301 do_action( 'mainwp_compact_action', 'saved', $year, $year_data, $start_time, $end_time );
302 }
303
304 $this->erase_log_records( $start_time, $end_time );
305 }
306 }
307
308
309 /**
310 * Clears logs records from the database.
311 *
312 * @param int $start_time start time.
313 * @param int $end_time start end.
314 *
315 * @return int results number.
316 */
317 private function erase_log_records( $start_time, $end_time ) {
318 global $wpdb;
319
320 $where = $wpdb->prepare( ' AND `logs`.`created` >= %d AND `logs`.`created` <= %d', $start_time, $end_time );
321
322 return $wpdb->query( //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Destructive operation; caching DELETE is inappropriate.
323 "DELETE `logs`, `meta`
324 FROM {$wpdb->mainwp_tbl_logs} AS `logs`
325 LEFT JOIN {$wpdb->mainwp_tbl_logs_meta} AS `meta`
326 ON `meta`.`meta_log_id` = `logs`.`log_id`
327 WHERE `logs`.`connector` != 'compact' " . $where // phpcs:ignore -- escaped.
328 );
329 }
330
331 /**
332 * Metho check if site action log existed.
333 *
334 * @param int $site_id Site Id.
335 * @param string $object_id Object Id.
336 *
337 * @return mixed Results.
338 */
339 public function is_site_action_log_existed( $site_id = false, $object_id = false ) { //phpcs:ignore -- NOSONAR compatible.
340 return false;
341 }
342 }
343