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 / class / class-mainwp-auto-updates-db.php

class-mainwp-auto-updates-db.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.2.2, at class/class-mainwp-auto-updates-db.php

304 lines 10.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 Controller
4 *
5 * This file handles all interactions with the DB.
6 *
7 * @package MainWP/Dashboard
8 */
9
10 namespace MainWP\Dashboard;
11
12 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Class MainWP_DB
19 *
20 * @package MainWP\Dashboard
21 *
22 * @uses \MainWP\Dashboard\MainWP_DB
23 */
24 class MainWP_Auto_Updates_DB extends MainWP_DB { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
25
26 // phpcs:disable WordPress.DB.RestrictedFunctions, WordPress.DB.PreparedSQL.NotPrepared, Generic.Metrics.CyclomaticComplexity -- This is the only way to achieve desired results, pull request solutions appreciated.
27
28 /**
29 * Private static variable to hold the single instance of the class.
30 *
31 * @static
32 *
33 * @var mixed Default null
34 */
35 private static $instance = null;
36
37 /**
38 * Create public static instance.
39 *
40 * @static
41 *
42 * @return MainWP_DB
43 */
44 public static function instance() {
45 if ( null === static::$instance ) {
46 static::$instance = new self();
47 }
48
49 static::$instance->test_connection();
50
51 return static::$instance;
52 }
53
54
55 /**
56 * Get child sites check updates.
57 *
58 * @param int $limit Query limit.
59 * @param int $lasttime_start Lasttime start automatic update.
60 * @param bool $connected Requires sites connected.
61 * @param bool $not_suspended Requires sites unsuspended.
62 *
63 * @return object|null Database query result or null on failure.
64 */
65 public function get_websites_check_updates( $limit, $lasttime_start, $connected = false, $not_suspended = false ) {
66 global $wpdb;
67
68 // do not use cache for this function because it is used for automatic updates and it needs to be accurate, and the result is not used in other places, so it will not cause performance issues.
69
70 $where = '';
71 if ( true === $connected ) {
72 $where .= ' wp_sync.sync_errors = "" AND';
73 }
74 if ( true === $not_suspended ) {
75 $where .= ' wp.suspended = 0 AND';
76 }
77
78 $view_selects = '';
79 $view_joins = '';
80
81 $opts_view = $this->get_wp_options_join( array( 'favi_icon' ) );
82
83 if ( is_array( $opts_view ) && ! empty( $opts_view['selects'] ) ) {
84 $view_selects = ',' . $opts_view['selects'];
85 $view_joins = $opts_view['joins'];
86 }
87
88 $sql = $wpdb->prepare(
89 'SELECT wp.*,wp_sync.*' . $view_selects . ' FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid ' . $view_joins . ' WHERE ' . $where . ' ( wp_sync.dtsAutomaticSyncStart = 0 OR wp_sync.dtsAutomaticSyncStart < %d ) GROUP BY wp.id ORDER BY wp_sync.dtsAutomaticSyncStart ASC LIMIT %d',
90 $lasttime_start,
91 $limit
92 );
93
94 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- $sql is prepared by $wpdb->prepare() with parameterized values; direct query required for complex joins.
95 $result = $wpdb->get_results( $sql, OBJECT );
96
97 return $result;
98 }
99
100
101 /**
102 * Get child sites to start updates.
103 *
104 * @param bool $connected Requires sites connected.
105 * @param bool $not_suspended Requires sites unsuspended.
106 *
107 * @return object|null Database query result or null on failure.
108 */
109 public function get_websites_to_start_updates( $connected = false, $not_suspended = false ) {
110
111 $where = '';
112 if ( true === $connected ) {
113 $where .= ' wp_sync.sync_errors = "" AND';
114 }
115 if ( true === $not_suspended ) {
116 $where .= ' wp.suspended = 0 AND';
117 }
118
119 $where = rtrim( $where, 'AND' );
120 $params = array(
121 'view' => 'updates_view',
122 'where' => $where,
123 );
124
125 return MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user_by_params( $params ) );
126 }
127
128
129 /**
130 * Get child sites to continue updates.
131 *
132 * @param int $limit limit sites to continue updates.
133 * @param int $lasttime_start Lasttime start automatic update.
134 * @param bool $connected Requires sites connected.
135 * @param bool $not_suspended Requires sites unsuspended.
136 *
137 * @return object|null Database query result or null on failure.
138 */
139 public function get_websites_to_continue_updates( $limit, $lasttime_start, $connected = false, $not_suspended = false ) {
140
141 if ( empty( $lasttime_start ) ) {
142 return false;
143 }
144
145 $where = ' ( wp_sync.dtsAutomaticSyncStart > 0 AND wp_sync.dtsAutomaticSync < wp_sync.dtsAutomaticSyncStart AND wp_sync.dtsAutomaticSyncStart <= ' . intval( $lasttime_start ) . ' ) AND'; // less than to sure that exactly trigger start updates timestamp.
146 if ( true === $connected ) {
147 $where .= ' wp_sync.sync_errors = "" AND';
148 }
149 if ( true === $not_suspended ) {
150 $where .= ' wp.suspended = 0 AND';
151 }
152
153 $orderby = ' wp_sync.dtsAutomaticSyncStart ASC ';
154
155 $where = rtrim( $where, 'AND' );
156
157 $params = array(
158 'view' => 'updates_view',
159 'where' => $where,
160 'limit' => $limit,
161 'orderby' => $orderby, // to fix.
162 );
163
164 $sql = MainWP_DB::instance()->get_sql_websites_for_current_user_by_params( $params );
165
166 $results = MainWP_DB::instance()->query( $sql );
167
168 $websites = array();
169 while ( $results && $website = static::fetch_object( $results ) ) {
170 $websites[] = $website;
171 }
172
173 if ( $results ) {
174 static::free_result( $results );
175 }
176
177 return $websites;
178 }
179
180
181 /**
182 * Get child sites to start updates.
183 *
184 * @param int $limit limit sites to continue updates.
185 * @param int $lasttime_start Lasttime start automatic update.
186 *
187 * @return object|null Database query result or null on failure.
188 */
189 public function get_websites_to_continue_individual_updates( $limit = 4, $lasttime_start = false ) {
190
191 if ( empty( $lasttime_start ) ) {
192 return false;
193 }
194
195 $where = ' wp_sync.sync_errors = "" AND ';
196 $where .= ' wp.suspended = 0 AND ';
197 $where .= ' owp_batch_individual_queue_time.value >= ' . intval( $lasttime_start ) . ' '; // owp_batch_individual_queue_time left join alias.
198
199 $params = array(
200 'view' => 'updates_view',
201 'where' => $where,
202 'limit' => $limit,
203 'others_fields' => array( 'batch_individual_queue_time' ),
204 );
205
206 $results = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user_by_params( $params ) );
207
208 $websites = array();
209 while ( $results && $website = static::fetch_object( $results ) ) {
210 $websites[] = $website;
211 }
212
213 if ( $results ) {
214 static::free_result( $results );
215 }
216
217 return $websites;
218 }
219
220
221 /**
222 * Get websites check updates count.
223 *
224 * @param int $lasttime_start Lasttime start automatic update.
225 *
226 * @return int Child sites update count.
227 */
228 public function get_websites_check_updates_count( $lasttime_start ) {
229 global $wpdb;
230
231 $cache_identifier = array( 'lasttime_start' => absint( $lasttime_start ) );
232 $cache_key = 'mainwp_auto_updates_count_' . md5( wp_json_encode( $cache_identifier ) ); // NOSONAR - MD5 for cache key only.
233 $cached = wp_cache_get( $cache_key );
234 if ( false !== $cached ) {
235 return $cached;
236 }
237
238 $where = $this->get_sql_where_allow_access_sites( 'wp' );
239
240 $sql = $wpdb->prepare(
241 'SELECT count(wp.id) FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid WHERE ( wp_sync.dtsAutomaticSyncStart = 0 OR wp_sync.dtsAutomaticSyncStart < %d)' . $where,
242 $lasttime_start
243 );
244
245 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery -- $sql is prepared by $wpdb->prepare() with parameterized values; direct query required for complex joins.
246 $result = $wpdb->get_var( $sql );
247 wp_cache_set( $cache_key, $result, '', HOUR_IN_SECONDS );
248
249 return $result;
250 }
251
252 /**
253 * Get child site count where date & time Session sync is smaller then start.
254 *
255 * @param int $lasttime_start Last time start automatic.
256 *
257 * @return int Returned child site count.
258 */
259 public function get_websites_count_where_dts_automatic_sync_smaller_then_start( $lasttime_start ) {
260 global $wpdb;
261
262 $cache_identifier = array( 'lasttime_start' => absint( $lasttime_start ) );
263 $cache_key = 'mainwp_auto_updates_sync_smaller_' . md5( wp_json_encode( $cache_identifier ) ); // NOSONAR - MD5 for cache key only.
264 $cached = wp_cache_get( $cache_key );
265 if ( false !== $cached ) {
266 return $cached;
267 }
268
269 $sql = $wpdb->prepare(
270 'SELECT count(wp.id) FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid WHERE wp.suspended = 0 AND ( ( wp_sync.dtsAutomaticSync < wp_sync.dtsAutomaticSyncStart AND wp_sync.dtsAutomaticSyncStart > %d) OR (wp_sync.dtsAutomaticSyncStart = 0) ) ',
271 $lasttime_start
272 );
273
274 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery -- $sql is prepared by $wpdb->prepare() with parameterized values; direct query required for complex joins.
275 $result = $wpdb->get_var( $sql );
276 wp_cache_set( $cache_key, $result, '', HOUR_IN_SECONDS );
277
278 return $result;
279 }
280
281 /**
282 * Get child site last automatic sync date & time.
283 *
284 * @return string Date and time of last automatic sync.
285 */
286 public function get_websites_last_automatic_sync() {
287 global $wpdb;
288
289 $cache_key = 'mainwp_auto_updates_last_sync';
290 $cached = wp_cache_get( $cache_key );
291 if ( false !== $cached ) {
292 return $cached;
293 }
294
295 $sql = 'SELECT MAX(wp_sync.dtsAutomaticSync) FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid';
296
297 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery -- Table names come from safe $this->table_name() methods only, no user input in this query; direct query required for complex joins.
298 $result = $wpdb->get_var( $sql );
299 wp_cache_set( $cache_key, $result, '', HOUR_IN_SECONDS );
300
301 return $result;
302 }
303 }
304