PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.2
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
mainwp / modules / logs / classes / class-log-db-archive.php

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

206 lines 6.8 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 Archive.
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_Archive
21 *
22 * @package MainWP\Dashboard
23 */
24 class Log_DB_Archive extends MainWP_DB {
25
26 /**
27 * Protected static variable to hold the single instance of the class.
28 *
29 * @var mixed Default null
30 */
31 protected static $instance = null;
32
33 /**
34 * Return the single instance of the class.
35 *
36 * @return mixed $instance The single instance of the class.
37 */
38 public static function instance() {
39 if ( is_null( static::$instance ) ) {
40 static::$instance = new self();
41 }
42 return static::$instance;
43 }
44
45
46 /**
47 * Method archive_sites_changes().
48 *
49 * @param int $before_timestamp Archive Network Activity data created before time.
50 * @param int $by_limit By limit.
51 * @param mixed $dismiss Dismiss: false|0|1.
52 *
53 * @return mixed
54 */
55 public function archive_sites_changes( $before_timestamp = 0, $by_limit = 0, $dismiss = false ) {
56 $before_timestamp = 1000000 * $before_timestamp;
57 $where = '';
58 $order_by = '';
59 $batch_limit = 0;
60 if ( ! empty( $before_timestamp ) ) {
61 $where .= ' AND created < ' . (int) $before_timestamp;
62 }
63
64 if ( ! empty( $by_limit ) ) {
65 $order_by .= ' created ASC ';
66 $batch_limit = (int) $by_limit;
67 }
68
69 if ( false !== $dismiss ) {
70 $where .= ' AND dismiss = ' . intval( $dismiss );
71 }
72
73 $this->bulk_archive_logs( $where, $order_by, $batch_limit );
74 }
75
76
77 /**
78 * Bulk archive logs + meta with batching (no transaction).
79 *
80 * @param string $where SQL WHERE condition (MUST be prepared).
81 * @param string $order_by Column and direction for ORDER BY (e.g. "created ASC").
82 * @param int $batch_limit Number of rows per batch.
83 *
84 * @return int Total archived rows.
85 */
86 public function bulk_archive_logs( $where, $order_by, $batch_limit = 1000 ) {
87 global $wpdb;
88
89 $table_logs = $this->table_name( 'wp_logs' );
90 $table_logs_archive = $this->table_name( 'wp_logs_archive' );
91 $table_meta = $this->table_name( 'wp_logs_meta' );
92 $table_meta_archive = $this->table_name( 'wp_logs_meta_archive' );
93
94 $total_archived = 0;
95
96 do {
97 // 1. Get batch IDs.
98 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL fragments are built from integer-cast archive inputs; table name is internal.
99 $ids = $this->wpdb->get_col(
100 "SELECT log_id
101 FROM $table_logs
102 WHERE 1 $where " . ( ! empty( $order_by ) ? " ORDER BY $order_by " : '' ) . // phpcs:ignore -- NOSONAR -no user input
103 ( $batch_limit ? ' LIMIT ' . intval( $batch_limit ) : '' )
104 );
105
106 if ( empty( $ids ) ) {
107 break;
108 }
109
110 $ids_in = implode( ',', array_map( 'intval', $ids ) );
111
112 // 2. Archive logs (prevent duplicates).
113 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $ids_in contains only intval() log IDs selected from the DB; table names are internal.
114 $this->wpdb->query(
115 "INSERT IGNORE INTO $table_logs_archive
116 SELECT l.*, UNIX_TIMESTAMP() AS archived_at
117 FROM $table_logs l
118 WHERE l.log_id IN ($ids_in)"
119 );
120
121 // 3. Archive meta (prevent duplicates).
122 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $ids_in contains only intval() log IDs selected from the DB; table names are internal.
123 $this->wpdb->query(
124 "INSERT IGNORE INTO $table_meta_archive
125 SELECT m.*
126 FROM $table_meta m
127 WHERE m.meta_log_id IN ($ids_in)"
128 );
129
130 // 4. Delete meta first.
131 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $ids_in contains only intval() log IDs selected from the DB; table name is internal.
132 $this->wpdb->query(
133 "DELETE FROM $table_meta
134 WHERE meta_log_id IN ($ids_in)"
135 );
136
137 // 5. Delete logs
138 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $ids_in contains only intval() log IDs selected from the DB; table name is internal.
139 $this->wpdb->query(
140 "DELETE FROM $table_logs
141 WHERE log_id IN ($ids_in)"
142 );
143
144 $total_archived += count( $ids );
145
146 } while ( count( $ids ) === $batch_limit ); // Continue if we hit the batch limit.
147
148 return $total_archived;
149 }
150
151
152 /**
153 * Method archive_log().
154 *
155 * @param array $data Log data to archive.
156 *
157 * @return mixed
158 */
159 public function archive_log( $data ) {
160 if ( empty( $data ) || ! is_array( $data ) || empty( $data['log_id'] ) ) {
161 return false;
162 }
163
164 $log_id = $data['log_id'];
165
166 $log = $this->wpdb->get_row( $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name('wp_logs') . ' WHERE log_id = %d', $log_id ), ARRAY_A ); //phpcs:ignore -- NOSONAR -ok.
167 if ( $log ) {
168 $log['archived_at'] = time();
169 $this->wpdb->insert( $this->table_name( 'wp_logs_archive' ), $log );
170 $log_mt = $this->wpdb->get_results( $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name('wp_logs_meta') . ' WHERE meta_log_id = %d', $log_id ), ARRAY_A ); //phpcs:ignore -- NOSONAR -ok.
171
172 if ( $log_mt ) {
173 foreach ( $log_mt as $mt ) {
174 $this->wpdb->insert( $this->table_name( 'wp_logs_meta_archive' ), $mt );
175 }
176 }
177
178 $this->wpdb->delete(
179 $this->table_name( 'wp_logs' ),
180 array(
181 'log_id' => $log_id,
182 )
183 );
184
185 $this->wpdb->delete(
186 $this->table_name( 'wp_logs_meta' ),
187 array(
188 'meta_log_id' => $log_id,
189 )
190 );
191
192 return $log;
193 }
194 return false;
195 }
196
197 /**
198 * Method truncate_archive_tables().
199 */
200 public function truncate_archive_tables() {
201 $this->wpdb->query( 'TRUNCATE TABLE ' . $this->table_name( 'wp_logs_archive' ) ); //phpcs:ignore -- ok.
202 $this->wpdb->query( 'TRUNCATE TABLE ' . $this->table_name( 'wp_logs_meta_archive' ) ); //phpcs:ignore -- ok.
203 delete_transient( 'mainwp_module_log_transient_db_logs_size' );
204 }
205 }
206