PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.1
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
← All changes | class/class-mainwp-db-base.php +403 -335 5.0.3.1 → 6.2.1 View file →
@@ -8,384 +8,452 @@
8 8 */
9 9
10 10 namespace MainWP\Dashboard;
11 11
12 +// Exit if accessed directly.
13 +if ( ! defined( 'ABSPATH' ) ) {
14 + exit;
15 +}
16 +
12 17 /**
13 18 * Class MainWP_DB_Base
14 19 *
15 20 * @package MainWP\Dashboard
16 21 */
17 -class MainWP_DB_Base {
22 +class MainWP_DB_Base { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
18 23
19 - // phpcs:disable WordPress.DB.RestrictedFunctions, WordPress.DB.PreparedSQL.NotPrepared -- unprepared SQL ok, accessing the database directly to custom database functions.
24 + // phpcs:disable WordPress.DB.RestrictedFunctions, WordPress.DB.PreparedSQL.NotPrepared -- unprepared SQL ok, accessing the database directly to custom database functions.
20 25
21 - /**
22 - * Private static instance.
23 - *
24 - * @static
25 - * @var $instance MainWP_DB_Base.
26 - */
27 - private static $instance = null;
26 + /**
27 + * Private static instance.
28 + *
29 + * @static
30 + * @var $instance MainWP_DB_Base.
31 + */
32 + private static $instance = null;
28 33
29 - /**
30 - * Table prefix.
31 - *
32 - * @var string $table_prefix
33 - */
34 - protected $table_prefix;
34 + /**
35 + * Table prefix.
36 + *
37 + * @var string $table_prefix
38 + */
39 + protected $table_prefix;
35 40
36 - /**
37 - * WordPress Database.
38 - *
39 - * @var mixed $wpdb WordPress Database.
40 - */
41 - protected $wpdb;
41 + /**
42 + * WordPress Database.
43 + *
44 + * @var mixed $wpdb WordPress Database.
45 + */
46 + protected $wpdb;
42 47
43 - /**
44 - * MainWP_DB_Base constructor.
45 - *
46 - * Run each time the class is called.
47 - */
48 - public function __construct() {
48 + /**
49 + * MainWP_DB_Base constructor.
50 + *
51 + * Run each time the class is called.
52 + */
53 + public function __construct() {
49 54
50 - self::$instance = $this;
55 + self::$instance = $this;
51 56
52 - /**
53 - * WordPress Database.
54 - *
55 - * @var mixed $wpdb Global WordPress Database.
56 - */
57 - global $wpdb;
57 + /**
58 + * WordPress Database.
59 + *
60 + * @var mixed $wpdb Global WordPress Database.
61 + */
62 + global $wpdb;
58 63
59 - $this->wpdb = &$wpdb;
60 - $this->table_prefix = $wpdb->prefix . 'mainwp_';
61 - }
64 + $this->wpdb = &$wpdb;
65 + $this->table_prefix = $wpdb->prefix . 'mainwp_';
66 + }
62 67
63 - /**
64 - * Method test_connection()
65 - *
66 - * Test db connection.
67 - *
68 - * @uses \MainWP\Dashboard\MainWP_Logger::info()
69 - */
70 - protected function test_connection() {
71 - if ( ! self::ping( $this->wpdb->dbh ) ) {
72 - MainWP_Logger::instance()->info( esc_html__( 'Trying to reconnect WordPress database connection...', 'mainwp' ) );
73 - $this->wpdb->db_connect();
74 - }
75 - }
68 + /**
69 + * Method test_connection()
70 + *
71 + * Test db connection.
72 + *
73 + * @uses \MainWP\Dashboard\MainWP_Logger::info()
74 + */
75 + protected function test_connection() {
76 + if ( ! static::ping( $this->wpdb->dbh ) ) {
77 + MainWP_Logger::instance()->info( esc_html__( 'Trying to reconnect WordPress database connection...', 'mainwp' ) );
78 + $this->wpdb->db_connect();
79 + }
80 + }
76 81
77 - /**
78 - * Method table_name()
79 - *
80 - * Create entire table name.
81 - *
82 - * @param mixed $suffix Table suffix.
83 - * @param null $tablePrefix Table prefix.
84 - *
85 - * @return string Table name.
86 - */
87 - protected function table_name( $suffix, $tablePrefix = null ) {
88 - return ( null === $tablePrefix ? $this->table_prefix : $tablePrefix ) . $suffix;
89 - }
82 + /**
83 + * Method table_name()
84 + *
85 + * Create entire table name.
86 + *
87 + * @param mixed $suffix Table suffix.
88 + * @param null $tablePrefix Table prefix.
89 + *
90 + * @return string Table name.
91 + */
92 + protected function table_name( $suffix, $tablePrefix = null ) {
93 + return ( null === $tablePrefix ? $this->table_prefix : $tablePrefix ) . $suffix;
94 + }
90 95
91 96
92 - /**
93 - * Method get_table_name()
94 - *
95 - * Create entire table name.
96 - *
97 - * @param mixed $suffix Table suffix.
98 - *
99 - * @return string Table name.
100 - */
101 - public function get_table_name( $suffix ) {
102 - return $this->table_name( $suffix );
103 - }
97 + /**
98 + * Method get_table_name()
99 + *
100 + * Create entire table name.
101 + *
102 + * @param mixed $suffix Table suffix.
103 + *
104 + * @return string Table name.
105 + */
106 + public function get_table_name( $suffix ) {
107 + return $this->table_name( $suffix );
108 + }
104 109
105 - /**
106 - * Method get_my_sql_version()
107 - *
108 - * Get MySQL Version.
109 - *
110 - * @return mixed MySQL vresion.
111 - */
112 - public function get_my_sql_version() {
113 - return $this->wpdb->get_var( 'SHOW VARIABLES LIKE "version"', 1 );
114 - }
110 + /**
111 + * Method get_wpdb_instance()
112 + *
113 + * @return object wpdb.
114 + */
115 + public function get_wpdb_instance() {
116 + return $this->wpdb;
117 + }
115 118
116 - /**
117 - * Method get_row_result()
118 - *
119 - * Get row result.
120 - *
121 - * @param mixed $sql SQL Query.
122 - *
123 - * @return mixed null|Row
124 - */
125 - public function get_row_result( $sql ) {
126 - if ( null === $sql ) {
127 - return null;
128 - }
119 + /**
120 + * Method get_my_sql_version()
121 + *
122 + * Get MySQL Version.
123 + *
124 + * @return mixed MySQL vresion.
125 + */
126 + public function get_my_sql_version() {
127 + return $this->wpdb->get_var( 'SHOW VARIABLES LIKE "version"', 1 );
128 + }
129 129
130 - return $this->wpdb->get_row( $sql, OBJECT );
131 - }
130 + /**
131 + * Method get_var_field()
132 + *
133 + * Execute a SQL query and return a single variable.
134 + * This is a low-level wrapper for WPDB that expects SQL to be safely pre-constructed by callers.
135 + * Callers must ensure all dynamic values are either validated primitives or safely escaped.
136 + * See usage in get_sql_*() methods which construct safe SQL using whitelisted operations.
137 + *
138 + * @param string $sql Safe SQL query string. Must be pre-constructed safely by caller.
139 + *
140 + * @return mixed Database query result or null.
141 + */
142 + public function get_var_field( $sql ) {
143 + if ( null === $sql ) {
144 + return null;
145 + }
146 + // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql is safe by contract; callers construct via get_sql_*() methods with validated/escaped values. All call sites verified in mainwp-db.php.
147 + return $this->wpdb->get_var( $sql );
148 + }
132 149
133 - /**
134 - * Method get_results_result()
135 - *
136 - * Get Results of result.
137 - *
138 - * @param mixed $sql SQL query.
139 - *
140 - * @return mixed null|get_results()
141 - */
142 - public function get_results_result( $sql ) {
143 - if ( null === $sql ) {
144 - return null;
145 - }
150 + /**
151 + * Method get_row_result()
152 + *
153 + * Execute a SQL query and return a single row result.
154 + * This is a low-level wrapper for WPDB that expects SQL to be safely pre-constructed by callers.
155 + * Callers must ensure all dynamic values are either validated primitives or safely escaped.
156 + * See usage in get_sql_*() methods which construct safe SQL using whitelisted operations.
157 + *
158 + * @param mixed $sql Safe SQL query string. Must be pre-constructed safely by caller.
159 + * @param int $obj Return type: OBJECT or ARRAY_A (defaults to OBJECT).
160 + *
161 + * @return mixed Single row result or null.
162 + */
163 + public function get_row_result( $sql, $obj = OBJECT ) {
164 + if ( null === $sql ) {
165 + return null;
166 + }
146 167
147 - return $this->wpdb->get_results( $sql, OBJECT_K );
148 - }
168 + if ( ! in_array( $obj, array( OBJECT, ARRAY_A ) ) ) {
169 + $obj = OBJECT;
170 + }
149 171
150 - /**
151 - * Method query()
152 - *
153 - * SQL Query.
154 - *
155 - * @param mixed $sql SQL Query.
156 - *
157 - * @return mixed false|$result.
158 - */
159 - public function query( $sql ) {
160 - if ( null === $sql ) {
161 - return false;
162 - }
172 + // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql is safe by contract; callers construct via get_sql_*() methods with validated/escaped values. All call sites verified in mainwp-db.php.
173 + return $this->wpdb->get_row( $sql, $obj );
174 + }
163 175
164 - $result = self::m_query( $sql, $this->wpdb->dbh );
176 + /**
177 + * Method get_results_result()
178 + *
179 + * Execute a SQL query and return multiple results indexed by primary key.
180 + * This is a low-level wrapper for WPDB that expects SQL to be safely pre-constructed by callers.
181 + * Callers must ensure all dynamic values are either validated primitives or safely escaped.
182 + * See usage in get_sql_*() methods which construct safe SQL using whitelisted operations.
183 + *
184 + * @param mixed $sql Safe SQL query string. Must be pre-constructed safely by caller.
185 + *
186 + * @return mixed Array of results indexed by primary key, or null.
187 + */
188 + public function get_results_result( $sql ) {
189 + if ( null === $sql ) {
190 + return null;
191 + }
165 192
166 - if ( ! $result || ( empty( self::num_rows( $result ) ) ) ) {
167 - return false;
168 - }
193 + // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $sql is safe by contract; callers construct via get_sql_*() methods with validated/escaped values. All call sites verified in mainwp-db.php.
194 + return $this->wpdb->get_results( $sql, OBJECT_K );
195 + }
169 196
170 - return $result;
171 - }
197 + /**
198 + * Method query()
199 + *
200 + * SQL Query.
201 + *
202 + * @param mixed $sql SQL Query.
203 + *
204 + * @return mixed false|$result.
205 + */
206 + public function query( $sql ) {
207 + if ( null === $sql ) {
208 + return false;
209 + }
172 210
173 - /**
174 - * Method escape_array()
175 - *
176 - * Escape SQL Data.
177 - *
178 - * @param mixed $data_arr Data array to escape.
179 - *
180 - * @return mixed Escapped SQL Data.
181 - */
182 - public function escape_array( $data_arr ) {
183 - if ( ! is_array( $data_arr ) || empty( $data_arr ) ) {
184 - return false;
185 - }
186 - $tmp_arr = array();
187 - foreach ( $data_arr as $dt ) {
188 - $tmp_arr[] = $this->escape( $dt );
189 - }
190 - return $tmp_arr;
191 - }
211 + $result = static::m_query( $sql, $this->wpdb->dbh ); // NOSONAR - required.
192 212
193 - /**
194 - * Method escape()
195 - *
196 - * Escape SQL Data.
197 - *
198 - * @param mixed $data Data to escape.
199 - *
200 - * @return mixed Escapped SQL Data.
201 - */
202 - public function escape( $data ) {
203 - if ( function_exists( 'esc_sql' ) ) {
204 - return esc_sql( $data );
205 - } else {
206 - return $this->wpdb->escape( $data );
207 - }
208 - }
213 + if ( ! $result || ( empty( self::num_rows( $result ) ) ) ) { // NOSONAR - required.
214 + return false;
215 + }
209 216
210 - /**
211 - * Method use_mysqli()
212 - *
213 - * Use MySQLi, Support old & new versions of WordPress (3.9+).
214 - *
215 - * @return boolean|self false|$instance Instance of \mysqli
216 - */
217 - public static function use_mysqli() {
218 - if ( ! function_exists( '\mysqli_connect' ) ) {
219 - return false;
220 - }
221 - return ( self::$instance->wpdb->dbh instanceof \mysqli );
222 - }
217 + return $result;
218 + }
223 219
224 - /**
225 - * Method ping()
226 - *
227 - * Ping MySQLi.
228 - *
229 - * @param mixed $link Query link.
230 - *
231 - * @return mixed \mysqli_ping
232 - */
233 - public static function ping( $link ) {
234 - if ( self::use_mysqli() ) {
235 - return \mysqli_ping( $link );
236 - } else {
237 - return \mysql_ping( $link );
238 - }
239 - }
240 220
241 - /**
242 - * Method m_query()
243 - *
244 - * MySQLi m_query.
245 - *
246 - * @param mixed $query Query params.
247 - * @param mixed $link Query link.
248 - *
249 - * @return mixed \mysqli_query
250 - */
251 - public static function m_query( $query, $link ) {
252 - if ( self::use_mysqli() ) {
253 - return \mysqli_query( $link, $query );
254 - } else {
255 - return \mysql_query( $query, $link );
256 - }
257 - }
221 + /**
222 + * Method get_last_query()
223 + *
224 + * @return string Get last query.
225 + */
226 + public function get_last_query() {
227 + return $this->wpdb->last_query;
228 + }
258 229
259 - /**
260 - * Method fetch_object()
261 - *
262 - * Fetch object.
263 - *
264 - * @param mixed $result Query result.
265 - *
266 - * @return boolean|mixed false|\mysqli_fetch_object
267 - */
268 - public static function fetch_object( $result ) {
269 - if ( is_bool( $result ) ) {
270 - return $result;
271 - }
272 230
273 - if ( self::use_mysqli() ) {
274 - return \mysqli_fetch_object( $result );
275 - } else {
276 - return \mysql_fetch_object( $result );
277 - }
278 - }
231 + /**
232 + * Method escape_array()
233 + *
234 + * Escape SQL Data.
235 + *
236 + * @param mixed $data_arr Data array to escape.
237 + *
238 + * @return mixed Escapped SQL Data.
239 + */
240 + public function escape_array( $data_arr ) {
241 + if ( ! is_array( $data_arr ) || empty( $data_arr ) ) {
242 + return false;
243 + }
244 + $tmp_arr = array();
245 + foreach ( $data_arr as $dt ) {
246 + $tmp_arr[] = $this->escape( $dt );
247 + }
248 + return $tmp_arr;
249 + }
279 250
280 - /**
281 - * Method free_result()
282 - *
283 - * MySQLi free result.
284 - *
285 - * @param mixed $result Query result.
286 - *
287 - * @return boolean|mixed false|\mysqli_free_result
288 - */
289 - public static function free_result( $result ) {
290 - if ( is_bool( $result ) ) {
291 - return $result;
292 - }
251 + /**
252 + * Method escape()
253 + *
254 + * Escape SQL Data.
255 + *
256 + * @param mixed $data Data to escape.
257 + *
258 + * @return mixed Escapped SQL Data.
259 + */
260 + public function escape( $data ) {
261 + if ( function_exists( 'esc_sql' ) ) {
262 + return esc_sql( $data );
263 + } else {
264 + return $this->wpdb->escape( $data );
265 + }
266 + }
293 267
294 - if ( self::use_mysqli() ) {
295 - return \mysqli_free_result( $result );
296 - } else {
297 - return \mysql_free_result( $result );
298 - }
299 - }
268 + /**
269 + * Method use_mysqli()
270 + *
271 + * Use MySQLi, Support old & new versions of WordPress (3.9+).
272 + *
273 + * @return boolean|self false|$instance Instance of \mysqli
274 + */
275 + public static function use_mysqli() {
276 + if ( ! function_exists( '\mysqli_connect' ) ) {
277 + return false;
278 + }
279 + return self::$instance->wpdb->dbh instanceof \mysqli; // NOSONAR - required.
280 + }
300 281
301 - /**
302 - * Method data_seek()
303 - *
304 - * MySQLi data seek.
305 - *
306 - * @param mixed $result Query result.
307 - * @param mixed $offset Query offset.
308 - *
309 - * @return boolean|mixed false|\mysqli_data_seek
310 - */
311 - public static function data_seek( $result, $offset ) {
312 - if ( is_bool( $result ) ) {
313 - return $result;
314 - }
282 + /**
283 + * Method ping()
284 + *
285 + * Ping MySQLi.
286 + *
287 + * @param mixed $link Query link.
288 + *
289 + * @return mixed \mysqli_ping
290 + */
291 + public static function ping( $link ) {
292 + if ( self::use_mysqli() ) { // NOSONAR - required.
293 + if ( version_compare( phpversion(), '8.4', '<' ) ) {
294 + return \mysqli_ping( $link );
295 + } else {
296 + try {
297 + self::$instance->wpdb->query( 'DO 1' );
298 + return true;
299 + } catch ( \mysqli_sql_exception $e ) { // NOSONAR - ok.
300 + // error.
301 + return false;
302 + }
303 + }
304 + } else {
305 + return \mysql_ping( $link );
306 + }
307 + }
315 308
316 - if ( self::use_mysqli() ) {
317 - if ( ! ( $result instanceof \mysqli_result ) ) {
318 - return $result;
319 - }
320 - return \mysqli_data_seek( $result, $offset );
321 - } else {
322 - return \mysql_data_seek( $result, $offset );
323 - }
324 - }
309 + /**
310 + * Method m_query()
311 + *
312 + * MySQLi m_query.
313 + *
314 + * @param mixed $query Query params.
315 + * @param mixed $link Query link.
316 + *
317 + * @return mixed \mysqli_query
318 + */
319 + public static function m_query( $query, $link ) {
320 + if ( self::use_mysqli() ) { // NOSONAR - required.
321 + return \mysqli_query( $link, $query );
322 + } else {
323 + return \mysql_query( $query, $link );
324 + }
325 + }
325 326
326 - /**
327 - * Method fetch_array()
328 - *
329 - * MySQLi fetch array.
330 - *
331 - * @param mixed $result Query result.
332 - * @param null $result_type Query result type.
333 - *
334 - * @return boolean|mixed false|\mysqli_fetch_array.
335 - */
336 - public static function fetch_array( $result, $result_type = null ) {
337 - if ( is_bool( $result ) ) {
338 - return $result;
339 - }
327 + /**
328 + * Method fetch_object()
329 + *
330 + * Fetch object.
331 + *
332 + * @param mixed $result Query result.
333 + *
334 + * @return boolean|mixed false|\mysqli_fetch_object
335 + */
336 + public static function fetch_object( $result ) {
337 + if ( is_bool( $result ) ) {
338 + return $result;
339 + }
340 340
341 - if ( self::use_mysqli() ) {
342 - return \mysqli_fetch_array( $result, ( null === $result_type ? MYSQLI_BOTH : $result_type ) );
343 - } else {
344 - return \mysql_fetch_array( $result, ( null === $result_type ? MYSQL_BOTH : $result_type ) );
345 - }
346 - }
341 + if ( self::use_mysqli() ) { // NOSONAR - required.
342 + return \mysqli_fetch_object( $result );
343 + } else {
344 + return \mysql_fetch_object( $result );
345 + }
346 + }
347 347
348 + /**
349 + * Method free_result()
350 + *
351 + * MySQLi free result.
352 + *
353 + * @param mixed $result Query result.
354 + *
355 + * @return boolean|mixed false|\mysqli_free_result
356 + */
357 + public static function free_result( $result ) {
358 + if ( is_bool( $result ) ) {
359 + return $result;
360 + }
348 361
349 - /**
350 - * Method num_rows()
351 - *
352 - * MySQLi number of rows.
353 - *
354 - * @param mixed $result Query result.
355 - *
356 - * @return boolean|mixed false|\mysqli_num_rows.
357 - */
358 - public static function num_rows( $result ) {
359 - if ( ! self::is_result( $result ) ) {
360 - return false;
361 - }
362 + if ( self::use_mysqli() ) { // NOSONAR - required.
363 + \mysqli_free_result( $result );
364 + } else {
365 + \mysql_free_result( $result );
366 + }
367 + }
362 368
363 - if ( self::use_mysqli() ) {
364 - return \mysqli_num_rows( $result );
365 - } else {
366 - return \mysql_num_rows( $result );
367 - }
368 - }
369 + /**
370 + * Method data_seek()
371 + *
372 + * MySQLi data seek.
373 + *
374 + * @param mixed $result Query result.
375 + * @param mixed $offset Query offset.
376 + *
377 + * @return boolean|mixed false|\mysqli_data_seek
378 + */
379 + public static function data_seek( $result, $offset ) {
380 + if ( is_bool( $result ) ) {
381 + return $result;
382 + }
369 383
370 - /**
371 - * Method is_result()
372 - *
373 - * Return instance of \mysqli_result
374 - *
375 - * @param mixed $result Query result.
376 - *
377 - * @return boolean|mixed false|\mysqli_result
378 - */
379 - public static function is_result( $result ) {
380 - if ( is_bool( $result ) ) {
381 - return $result;
382 - }
384 + if ( self::use_mysqli() ) { // NOSONAR - required.
385 + if ( ! ( $result instanceof \mysqli_result ) ) {
386 + return $result;
387 + }
388 + return \mysqli_data_seek( $result, $offset );
389 + } else {
390 + return \mysql_data_seek( $result, $offset );
391 + }
392 + }
383 393
384 - if ( self::use_mysqli() ) {
385 - return ( $result instanceof \mysqli_result );
386 - } else {
387 - return is_resource( $result );
388 - }
389 - }
390 - // phpcs:enable
394 + /**
395 + * Method fetch_array()
396 + *
397 + * MySQLi fetch array.
398 + *
399 + * @param mixed $result Query result.
400 + * @param null $result_type Query result type.
401 + *
402 + * @return boolean|mixed false|\mysqli_fetch_array.
403 + */
404 + public static function fetch_array( $result, $result_type = null ) {
405 + if ( is_bool( $result ) ) {
406 + return $result;
407 + }
408 +
409 + if ( self::use_mysqli() ) { // NOSONAR - required.
410 + return \mysqli_fetch_array( $result, ( null === $result_type ? MYSQLI_BOTH : $result_type ) );
411 + } else {
412 + return \mysql_fetch_array( $result, ( null === $result_type ? MYSQL_BOTH : $result_type ) );
413 + }
414 + }
415 +
416 +
417 + /**
418 + * Method num_rows()
419 + *
420 + * MySQLi number of rows.
421 + *
422 + * @param mixed $result Query result.
423 + *
424 + * @return boolean|mixed false|\mysqli_num_rows.
425 + */
426 + public static function num_rows( $result ) {
427 + if ( ! self::is_result( $result ) ) { // NOSONAR - required.
428 + return false;
429 + }
430 +
431 + if ( self::use_mysqli() ) { // NOSONAR - required.
432 + return \mysqli_num_rows( $result );
433 + } else {
434 + return \mysql_num_rows( $result );
435 + }
436 + }
437 +
438 + /**
439 + * Method is_result()
440 + *
441 + * Return instance of \mysqli_result
442 + *
443 + * @param mixed $result Query result.
444 + *
445 + * @return boolean|mixed false|\mysqli_result
446 + */
447 + public static function is_result( $result ) {
448 + if ( is_bool( $result ) ) {
449 + return $result;
450 + }
451 +
452 + if ( self::use_mysqli() ) { // NOSONAR - required.
453 + return $result instanceof \mysqli_result;
454 + } else {
455 + return is_resource( $result );
456 + }
457 + }
458 + // phpcs:enable
391 459 }