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

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