PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / trunk
MainWP Dashboard: Self-hosted WordPress Management for Agencies vtrunk
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 trunk, at modules/logs/classes/class-log-db.php

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