PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 5.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v5.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 5.2.2 5.3 All 153 releases
mainwp / class / class-mainwp-db.php

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

2,570 lines 103.0 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 /**
13 * Class MainWP_DB
14 *
15 * @package MainWP\Dashboard
16 *
17 * @uses \MainWP\Dashboard\MainWP_DB_Base
18 */
19 class MainWP_DB extends MainWP_DB_Base { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
20
21 // 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.
22
23 /**
24 * Private static variable to hold the single instance of the class.
25 *
26 * @static
27 *
28 * @var mixed Default null
29 */
30 private static $instance = null;
31
32 /**
33 * Private static variable to hold the single instance.
34 *
35 * @static
36 *
37 * @var mixed Default null
38 */
39 private static $general_options = null;
40
41 /**
42 * Possible options.
43 *
44 * @var array $possible_options
45 */
46 private static $possible_options = array(
47 'plugin_upgrades',
48 'theme_upgrades',
49 'premium_upgrades',
50 'plugins',
51 'themes',
52 'dtsSync',
53 'version',
54 'sync_errors',
55 'ignored_plugins',
56 'wp_upgrades',
57 'site_info',
58 'client',
59 'signature_algo',
60 'verify_method',
61 'pubkey',
62 );
63
64 /**
65 * Create public static instance.
66 *
67 * @static
68 *
69 * @return MainWP_DB
70 */
71 public static function instance() {
72 if ( null === static::$instance ) {
73 static::$instance = new self();
74 }
75
76 static::$instance->test_connection();
77
78 return static::$instance;
79 }
80
81 /**
82 * Get wp_options database table view.
83 *
84 * @param array $fields Extra option fields.
85 * @param bool $default_value Whether or not to get default option fields.
86 *
87 * @return array wp_options view.
88 */
89 public function get_option_view( $fields = array(), $default_value = true ) {
90
91 if ( ! is_array( $fields ) ) {
92 $fields = array();
93 }
94
95 $view = '(SELECT intwp.id AS wpid ';
96
97 if ( empty( $fields ) || $default_value ) {
98 $view .= ',(SELECT recent_comments.value FROM ' . $this->table_name( 'wp_options' ) . ' recent_comments WHERE recent_comments.wpid = intwp.id AND recent_comments.name = "recent_comments" LIMIT 1) AS recent_comments,
99 (SELECT recent_posts.value FROM ' . $this->table_name( 'wp_options' ) . ' recent_posts WHERE recent_posts.wpid = intwp.id AND recent_posts.name = "recent_posts" LIMIT 1) AS recent_posts,
100 (SELECT recent_pages.value FROM ' . $this->table_name( 'wp_options' ) . ' recent_pages WHERE recent_pages.wpid = intwp.id AND recent_pages.name = "recent_pages" LIMIT 1) AS recent_pages,
101 (SELECT phpversion.value FROM ' . $this->table_name( 'wp_options' ) . ' phpversion WHERE phpversion.wpid = intwp.id AND phpversion.name = "phpversion" LIMIT 1) AS phpversion,
102 (SELECT added_timestamp.value FROM ' . $this->table_name( 'wp_options' ) . ' added_timestamp WHERE added_timestamp.wpid = intwp.id AND added_timestamp.name = "added_timestamp" LIMIT 1) AS added_timestamp,
103 (SELECT wp_upgrades.value FROM ' . $this->table_name( 'wp_options' ) . ' wp_upgrades WHERE wp_upgrades.wpid = intwp.id AND wp_upgrades.name = "wp_upgrades" LIMIT 1) AS wp_upgrades ';
104 }
105
106 if ( ! in_array( 'signature_algo', $fields ) ) {
107 $fields[] = 'signature_algo';
108 }
109
110 if ( ! in_array( 'verify_method', $fields ) ) {
111 $fields[] = 'verify_method';
112 }
113
114 if ( ! in_array( 'cust_site_icon_info', $fields, true ) ) {
115 $fields[] = 'cust_site_icon_info';
116 }
117
118 if ( is_array( $fields ) ) {
119 foreach ( $fields as $field ) {
120 if ( empty( $field ) ) {
121 continue;
122 }
123 $view .= ', ';
124 $view .= '(SELECT ' . $this->escape( $field ) . '.value FROM ' . $this->table_name( 'wp_options' ) . ' ' . $this->escape( $field ) . ' WHERE ' . $this->escape( $field ) . '.wpid = intwp.id AND ' . $this->escape( $field ) . '.name = "' . $this->escape( $field ) . '" LIMIT 1) AS ' . $this->escape( $field );
125 }
126 }
127
128 $view .= ' FROM ' . $this->table_name( 'wp' ) . ' intwp)';
129
130 return $view;
131 }
132
133 /**
134 * Method get_select_groups_belong().
135 *
136 * @return string sql.
137 */
138 public function get_select_groups_belong() {
139 return ', ( SELECT GROUP_CONCAT(grbl.name ORDER BY grbl.name SEPARATOR ",")
140 FROM ' . $this->table_name( 'wp_group' ) . ' wpgrbl
141 JOIN ' . $this->table_name( 'group' ) . ' grbl ON grbl.id = wpgrbl.groupid WHERE wpgrbl.wpid = wp.id ) as wpgroups_belong,
142 ( SELECT GROUP_CONCAT(grbl.id ORDER BY grbl.name SEPARATOR ",") FROM ' . $this->table_name( 'wp_group' ) . ' wpgrbl
143 JOIN ' . $this->table_name( 'group' ) . ' grbl ON grbl.id = wpgrbl.groupid WHERE wpgrbl.wpid = wp.id ) as wpgroupids_belong,
144 ( SELECT GROUP_CONCAT(grbl.color ORDER BY grbl.name SEPARATOR ",") FROM ' . $this->table_name( 'wp_group' ) . ' wpgrbl
145 JOIN ' . $this->table_name( 'group' ) . ' grbl ON grbl.id = wpgrbl.groupid WHERE wpgrbl.wpid = wp.id ) as wpgroupcolors_belong ';
146 }
147
148 /**
149 * Get connected child sites.
150 *
151 * @param array $sites_ids Websites ids - option field.
152 *
153 * @return array $connected_sites Array of connected sites.
154 */
155 public function get_connected_websites( $sites_ids = false ) {
156 $where = $this->get_sql_where_allow_access_sites( 'wp' );
157
158 $sql = 'SELECT wp.*,wp_sync.*
159 FROM ' . $this->table_name( 'wp' ) . ' wp
160 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync
161 ON wp.id = wp_sync.wpid
162 WHERE (wp_sync.sync_errors IS NOT NULL) AND (wp_sync.sync_errors = "") ' .
163 $where;
164
165 $websites = $this->wpdb->get_results( $sql );
166 $connected_sites = array();
167 if ( $websites ) {
168 foreach ( $websites as $website ) {
169
170 if ( ! empty( $sites_ids ) && ! in_array( $website->id, $sites_ids ) ) {
171 continue;
172 }
173
174 $connected_sites[] = array(
175 'id' => $website->id,
176 'name' => $website->name,
177 'url' => $website->url,
178 );
179 }
180 }
181 return $connected_sites;
182 }
183
184 /**
185 * Get disconnected child sites.
186 *
187 * @param array $sites_ids Websites ids - option field.
188 *
189 * @return array $disc_sites Array of disonnected sites.
190 */
191 public function get_disconnected_websites( $sites_ids = false ) {
192 $where = $this->get_sql_where_allow_access_sites( 'wp' );
193
194 $sql = 'SELECT wp.*,wp_sync.*
195 FROM ' . $this->table_name( 'wp' ) . ' wp
196 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync
197 ON wp.id = wp_sync.wpid
198 WHERE (wp_sync.sync_errors IS NOT NULL) AND (wp_sync.sync_errors <> "") ' .
199 $where;
200
201 $websites = $this->wpdb->get_results( $sql );
202 $disc_sites = array();
203 if ( $websites ) {
204 foreach ( $websites as $website ) {
205
206 if ( ! empty( $sites_ids ) && ! in_array( $website->id, $sites_ids ) ) {
207 continue;
208 }
209
210 $disc_sites[] = array(
211 'id' => $website->id,
212 'name' => $website->name,
213 'url' => $website->url,
214 );
215 }
216 }
217 return $disc_sites;
218 }
219
220 /**
221 * Get child site count.
222 *
223 * @param null $userId Current user ID.
224 * @param bool $all_access Check if user has access to all sites.
225 *
226 * @return int Child site count.
227 *
228 * @uses \MainWP\Dashboard\MainWP_System::is_multi_user()
229 */
230 public function get_websites_count( $userId = null, $all_access = false ) {
231 static $total_sites;
232 if ( null !== $total_sites ) { // NOSONAR -- static value.
233 return $total_sites;
234 }
235 if ( ( null === $userId ) && MainWP_System::instance()->is_multi_user() ) {
236
237 /**
238 * Current user global.
239 *
240 * @global string
241 */
242 global $current_user;
243
244 $userId = $current_user->ID;
245 }
246 $where = ( null === $userId ? '' : ' wp.userid = ' . $userId );
247 if ( ! $all_access ) {
248 $where .= $this->get_sql_where_allow_access_sites( 'wp' );
249 }
250 $qry = 'SELECT COUNT(wp.id) FROM ' . $this->table_name( 'wp' ) . ' wp WHERE 1 ' . $where;
251
252 $total = $this->wpdb->get_var( $qry );
253 $total_sites = $total;// NOSONAR -- static value.
254 return $total;
255 }
256
257
258 /**
259 * Get child sites stats count.
260 *
261 * @param array $params Params.
262 */
263 public function get_websites_stats_count( $params = array() ) {
264 if ( ! is_array( $params ) ) {
265 $params = array();
266 }
267
268 if ( isset( $params['all_access'] ) ) {
269 $all_access = ! empty( $params['all_access'] ) ? true : false;
270 } else {
271 $all_access = true;
272 }
273
274 $where = '';
275 if ( ! $all_access ) {
276 $where .= $this->get_sql_where_allow_access_sites( 'wp' );
277 }
278
279 $select_stats = ' ( SELECT COUNT(wp.id) as count_all ';
280 if ( ! empty( $params['count_disconnected'] ) ) {
281 $select_stats .= ',( SELECT COUNT(wp_disconnected.id) FROM ' . $this->table_name( 'wp' ) . ' wp_disconnected LEFT JOIN ' . $this->table_name( 'wp_sync' ) . ' as wp_sync ';
282 $select_stats .= ' ON wp_disconnected.id = wp_sync.wpid WHERE wp_sync.sync_errors != "" ) as count_disconnected ';
283 }
284 if ( ! empty( $params['count_suspended'] ) ) {
285 $select_stats .= ',( SELECT COUNT(wp_suspended.id) FROM ' . $this->table_name( 'wp' ) . ' wp_suspended WHERE wp_suspended.suspended = 1 ) as count_suspended ';
286 }
287 $qry = 'SELECT * FROM ' . $select_stats;
288 $qry .= ' FROM ' . $this->table_name( 'wp' ) . ' wp ' . $where . ' ) as wp_stats ';
289
290 return $this->wpdb->get_row( $qry, ARRAY_A ); //phpcs:ignore -- ok.
291 }
292
293 /**
294 * Get Child site wp_options database table.
295 *
296 * @param array $website Child Site array.
297 * @param mixed $option Child Site wp_options table name.
298 * @param mixed $default_value default value.
299 *
300 * @return string|null Database query result (as string), or null on failure.
301 */
302 public function get_website_option( $website, $option, $default_value = null ) {
303
304 if ( is_array( $website ) ) {
305 if ( isset( $website[ $option ] ) ) {
306 return $website[ $option ];
307 }
308 $site_id = $website['id'];
309 } elseif ( is_object( $website ) ) {
310 if ( property_exists( $website, $option ) ) {
311 return $website->{$option};
312 }
313 $site_id = $website->id;
314 } elseif ( is_numeric( $website ) ) { // to support $site_id = 0, for global options.
315 $site_id = $website;
316 } else {
317 return false;
318 }
319
320 $var = $this->wpdb->get_var( $this->wpdb->prepare( 'SELECT value FROM ' . $this->table_name( 'wp_options' ) . ' WHERE wpid = %d AND name = "' . $this->escape( $option ) . '"', $site_id ) );
321
322 if ( null === $var && null !== $default_value ) {
323 $var = $default_value;
324 }
325 return $var;
326 }
327
328 /**
329 * Get child site options.
330 *
331 * @param array $website Child site.
332 * @param mixed $options Child site options name.
333 *
334 * @return string|null Database query result (as string), or null on failure.
335 */
336 public function get_website_options_array( &$website, $options ) { // phpcs:ignore -- NOSONAR - complex.
337
338 if ( ! is_array( $options ) || empty( $options ) ) {
339 return array();
340 }
341
342 if ( is_array( $website ) ) {
343 $site_id = $website['id'];
344 } elseif ( is_object( $website ) ) {
345 $site_id = $website->id;
346 } elseif ( is_numeric( $website ) ) { // to support $site_id = 0 for global options.
347 $site_id = $website;
348 } else {
349 return array();
350 }
351
352 $arr_options = array();
353 $get_options = array();
354
355 foreach ( $options as $option ) {
356 if ( is_array( $website ) ) {
357 if ( isset( $website[ $option ] ) ) {
358 $arr_options[ $option ] = $website[ $option ];
359 } else {
360 $get_options[] = $option;
361 }
362 } elseif ( is_object( $website ) ) {
363 if ( property_exists( $website, $option ) ) {
364 $arr_options[ $option ] = $website->{$option};
365 } else {
366 $get_options[] = $option;
367 }
368 } else {
369 $get_options[] = $option;
370 }
371 }
372
373 if ( empty( $get_options ) ) {
374 return $arr_options; // all options.
375 }
376
377 $options_name = implode( "','", $get_options );
378 $options_name = "'" . $options_name . "'";
379
380 $options_db = $this->wpdb->get_results( $this->wpdb->prepare( 'SELECT name, value FROM ' . $this->table_name( 'wp_options' ) . ' WHERE wpid = %d AND name IN (' . $options_name . ')', $site_id ) );
381
382 $fill_options = array(
383 'primary_lasttime_backup',
384 );
385
386 foreach ( (array) $options_db as $o ) {
387 $arr_options[ $o->name ] = $o->value;
388 if ( in_array( $o->name, $fill_options ) ) {
389 if ( is_array( $website ) ) {
390 if ( ! isset( $website[ $o->name ] ) ) {
391 $website[ $o->name ] = $o->value;
392 }
393 } elseif ( is_object( $website ) ) {
394 if ( ! property_exists( $website, $o->name ) ) {
395 $website->{$o->name} = $o->value;
396 }
397 }
398 }
399 }
400 return $arr_options;
401 }
402
403 /**
404 * Update child site options.
405 *
406 * @param object $website Child site object.
407 * @param mixed $option Option to update.
408 * @param mixed $value Value to update with.
409 */
410 public function update_website_option( $website, $option, $value ) {
411 $rslt = $this->wpdb->get_results( $this->wpdb->prepare( 'SELECT name FROM ' . $this->table_name( 'wp_options' ) . ' WHERE wpid = %d AND name = "' . $this->escape( $option ) . '"', $website->id ) );
412 if ( empty( $rslt ) ) {
413 $this->wpdb->insert(
414 $this->table_name( 'wp_options' ),
415 array(
416 'wpid' => $website->id,
417 'name' => $option,
418 'value' => $value,
419 )
420 );
421 } else {
422 $this->wpdb->update(
423 $this->table_name( 'wp_options' ),
424 array( 'value' => $value ),
425 array(
426 'wpid' => $website->id,
427 'name' => $option,
428 )
429 );
430 }
431 }
432
433
434 /**
435 * Get general Child site option.
436 *
437 * @param mixed $option Child Site option name.
438 *
439 * @return string|null Database query result (as string), or null on failure.
440 */
441 private function get_general_website_option( $option ) {
442
443 if ( null !== static::$general_options ) {
444 if ( isset( static::$general_options[ $option ] ) ) {
445 return static::$general_options[ $option ];
446 }
447 } else {
448 static::$general_options[] = array();
449 }
450
451 $val = $this->wpdb->get_var( $this->wpdb->prepare( 'SELECT value FROM ' . $this->table_name( 'wp_options' ) . ' WHERE wpid = %d AND name = "' . $this->escape( $option ) . '"', 0 ) );
452
453 static::$general_options[ $option ] = $val;
454 return $val;
455 }
456
457 /**
458 * Get child site options.
459 *
460 * @param mixed $options Child site options name.
461 *
462 * @return string|null Database query result (as string), or null on failure.
463 */
464 public function get_general_options_array( $options ) {
465
466 if ( ! is_array( $options ) || empty( $options ) ) {
467 return array();
468 }
469
470 $return_options = array();
471 if ( null !== static::$general_options ) {
472 foreach ( static::$general_options as $opt => $val ) {
473 if ( in_array( $opt, $options ) ) {
474 $return_options[ $opt ] = $val;
475 }
476 }
477 } else {
478 static::$general_options[] = array();
479 }
480
481 $diff_options = array();
482 foreach ( $options as $opt ) {
483 if ( ! isset( $return_options[ $opt ] ) ) {
484 $diff_options[] = $opt;
485 }
486 }
487
488 $options_name = implode( "','", $diff_options );
489 $options_name = "'" . $options_name . "'";
490
491 $options_db = $this->wpdb->get_results( $this->wpdb->prepare( 'SELECT name, value FROM ' . $this->table_name( 'wp_options' ) . ' WHERE wpid = %d AND name IN (' . $options_name . ')', 0 ) );
492
493 foreach ( (array) $options_db as $o ) {
494 $return_options[ $o->name ] = $o->value;
495 static::$general_options[ $o->name ] = $o->value;
496 }
497 return $return_options;
498 }
499
500 /**
501 * Update general site options.
502 *
503 * @param mixed $option Option to update.
504 * @param mixed $value Value to update with.
505 * @param string $type_value Type values: single|array.
506 */
507 public function update_general_option( $option, $value, $type_value = 'single' ) {
508
509 if ( 'array' === $type_value ) {
510 if ( empty( $value ) ) {
511 $value = array();
512 } elseif ( ! is_array( $value ) ) {
513 return false;
514 }
515 $value = wp_json_encode( $value );
516 }
517
518 if ( null === static::$general_options ) {
519 static::$general_options[] = array();
520 }
521 static::$general_options[ $option ] = $value;
522
523 $rslt = $this->wpdb->get_results( $this->wpdb->prepare( 'SELECT name FROM ' . $this->table_name( 'wp_options' ) . ' WHERE wpid = %d AND name = "' . $this->escape( $option ) . '"', 0 ) );
524
525 if ( empty( $rslt ) ) {
526 $this->wpdb->insert(
527 $this->table_name( 'wp_options' ),
528 array(
529 'wpid' => 0,
530 'name' => $option,
531 'value' => $value,
532 )
533 );
534 } else {
535 $this->wpdb->update(
536 $this->table_name( 'wp_options' ),
537 array( 'value' => $value ),
538 array(
539 'wpid' => 0,
540 'name' => $option,
541 )
542 );
543 }
544 return true;
545 }
546
547 /**
548 * Get general Child site option.
549 *
550 * @param mixed $opt Child Site option name.
551 * @param string $type_value Type values: single|array.
552 *
553 * @return string|null Database query result (as string), or null on failure.
554 */
555 public function get_general_option( $opt, $type_value = 'single' ) {
556 if ( 'single' === $type_value ) {
557 return $this->get_general_website_option( $opt );
558 } elseif ( 'array' === $type_value ) {
559 $json_value = $this->get_general_website_option( $opt );
560 if ( empty( $json_value ) ) {
561 return array();
562 }
563 return json_decode( $json_value, true );
564 }
565 return false;
566 }
567
568 /**
569 * Get child sites by user ID.
570 *
571 * @param int $userid User ID.
572 * @param bool $selectgroups Selected groups.
573 * @param null $search_site Site search field value.
574 * @param string $orderBy Order list by. Default: URL.
575 *
576 * @return array|object|null Database query results or null on failer.
577 */
578 public function get_websites_by_user_id( $userid, $selectgroups = false, $search_site = null, $orderBy = 'wp.url' ) {
579 return $this->get_results_result( $this->get_sql_websites_by_user_id( $userid, $selectgroups, $search_site, $orderBy ) );
580 }
581
582 /**
583 * Get child sites.
584 *
585 * @return string SQL string.
586 */
587 public function get_sql_websites() {
588 $where = $this->get_sql_where_allow_access_sites( 'wp' );
589
590 return 'SELECT wp.*,wp_sync.*,wp_optionview.*
591 FROM ' . $this->table_name( 'wp' ) . ' wp
592 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
593 JOIN ' . $this->get_option_view() . ' wp_optionview ON wp.id = wp_optionview.wpid
594 WHERE 1 ' . $where;
595 }
596
597 /**
598 * Get child sites to run the status check process.
599 *
600 * @param int $last_check Time of the last check.
601 * @param int $count Number of websites.
602 *
603 * @return string SQL string.
604 */
605 public function get_sql_websites_to_check_status( $last_check, $count = 20 ) {
606 $where = $this->get_sql_where_allow_access_sites( 'wp' );
607 return 'SELECT wp.*
608 FROM ' . $this->table_name( 'wp' ) . ' wp
609 WHERE wp.disable_status_check <> 1 AND ( wp.status_check_interval = 0 AND wp.offline_checks_last < ' . intval( $last_check ) . ' )' .
610 $where . '
611 LIMIT ' . intval( $count );
612 }
613
614
615 /**
616 * Get child sites to run the status individual check process.
617 *
618 * @param int $count Number of websites.
619 *
620 * @return string SQL string.
621 */
622 public function get_sql_websites_to_check_individual_status( $count = 20 ) {
623 $where = $this->get_sql_where_allow_access_sites( 'wp' );
624 return 'SELECT wp.*
625 FROM ' . $this->table_name( 'wp' ) . ' wp
626 WHERE wp.disable_status_check <> 1 AND ( wp.status_check_interval <> 0 AND ( wp.offline_checks_last + wp.status_check_interval * 60 < UNIX_TIMESTAMP() ) )' .
627 $where . '
628 LIMIT ' . intval( $count );
629 }
630
631 /**
632 * Get child sites by user id via SQL.
633 *
634 * @param int $userid Given user ID.
635 * @param bool $selectgroups Selected groups. Default: false.
636 * @param null $search_site Site search field value. Default: null.
637 * @param string $orderBy Order list by. Default: URL.
638 * @param bool $offset Query offset. Default: false.
639 * @param bool $rowcount Row count. Default: falese.
640 *
641 * @return object|null Return database query or null on failure.
642 *
643 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
644 */
645 public function get_sql_websites_by_user_id( $userid, $selectgroups = false, $search_site = null, $orderBy = 'wp.url', $offset = false, $rowcount = false ) {
646 if ( MainWP_Utility::ctype_digit( $userid ) ) {
647 $where = '';
648 if ( null !== $search_site ) {
649 $search_site = trim( $search_site );
650 $where = ' AND (wp.name LIKE "%' . $search_site . '%" OR wp.url LIKE "%' . $search_site . '%") ';
651 }
652
653 $where .= $this->get_sql_where_allow_access_sites( 'wp' );
654
655 if ( $selectgroups ) {
656 $qry = 'SELECT wp.*,wp_sync.*,wp_optionview.*, GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ",") as wpgroups, GROUP_CONCAT(gr.id ORDER BY gr.name SEPARATOR ",") as wpgroupids, GROUP_CONCAT(gr.color ORDER BY gr.name SEPARATOR ",") as wpgroups_colors
657 FROM ' . $this->table_name( 'wp' ) . ' wp
658 LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid
659 LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id
660 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
661 JOIN ' . $this->get_option_view() . ' wp_optionview ON wp.id = wp_optionview.wpid
662 WHERE wp.userid = ' . $userid . "
663 $where
664 GROUP BY wp.id, wp_sync.sync_id
665 ORDER BY " . $orderBy;
666 } else {
667 $qry = 'SELECT wp.*,wp_sync.*,wp_optionview.*
668 FROM ' . $this->table_name( 'wp' ) . ' wp
669 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
670 JOIN ' . $this->get_option_view() . ' wp_optionview ON wp.id = wp_optionview.wpid
671 WHERE wp.userid = ' . $userid . "
672 $where
673 ORDER BY " . $orderBy;
674 }
675
676 if ( ( false !== $offset ) && ( false !== $rowcount ) ) {
677 $qry .= ' LIMIT ' . $offset . ', ' . $rowcount;
678 } elseif ( false !== $rowcount ) {
679 $qry .= ' LIMIT ' . $rowcount;
680 }
681
682 return $qry;
683 }
684
685 return null;
686 }
687
688 /**
689 * Get SQL to get child sites for current user.
690 *
691 * @param bool $selectgroups Selected groups. Default: false.
692 * @param null $search_site Site search field value. Default: null.
693 * @param string $orderBy Order list by. Default: URL.
694 * @param bool $offset Query offset. Default: false.
695 * @param bool $rowcount Row count. Default: false.
696 * @param null $extraWhere Extra WHERE. Default: null.
697 * @param bool $for_manager For role manager. Default: false.
698 * @param mixed $extra_view Extra view. Default favi_icon.
699 * @param string $is_staging yes|no Is child site a staging site.
700 * @param array $params other params.
701 *
702 * @return object|null Database query results or null on failure.
703 *
704 * @uses \MainWP\Dashboard\MainWP_System::is_multi_user()
705 */
706 public function get_sql_websites_for_current_user( // phpcs:ignore -- NOSONAR - complex.
707 $selectgroups = false,
708 $search_site = null,
709 $orderBy = 'wp.url',
710 $offset = false,
711 $rowcount = false,
712 $extraWhere = null,
713 $for_manager = false,
714 $extra_view = array( 'favi_icon' ),
715 $is_staging = 'no',
716 $params = array()
717 ) {
718
719 $where = '';
720 if ( MainWP_System::instance()->is_multi_user() ) {
721
722 /**
723 * Current user global.
724 *
725 * @global string
726 */
727 global $current_user;
728
729 $where .= ' AND wp.userid = ' . $current_user->ID . ' ';
730 }
731
732 if ( null !== $search_site ) {
733 $search_site = trim( $search_site );
734 $where .= ' AND (wp.name LIKE "%' . $search_site . '%" OR wp.url LIKE "%' . $search_site . '%") ';
735 }
736
737 if ( null !== $extraWhere ) {
738 $where .= ' AND ' . $extraWhere;
739 }
740
741 if ( ! $for_manager ) {
742 $where .= $this->get_sql_where_allow_access_sites( 'wp', $is_staging );
743 }
744
745 $connected_sql = '';
746
747 if ( is_array( $params ) && isset( $params['connected'] ) && 'yes' === $params['connected'] ) {
748 $connected_sql = ' AND wp_sync.sync_errors = "" ';
749 } elseif ( is_array( $params ) && isset( $params['connected'] ) && 'no' === $params['connected'] ) {
750 $connected_sql = ' AND wp_sync.sync_errors <> "" ';
751 }
752
753 if ( 'wp.url' === $orderBy ) {
754 $orderBy = "replace(replace(replace(replace(replace(wp.url, 'https://www.',''), 'http://www.',''), 'https://', ''), 'http://', ''), 'www.', '')";
755 }
756
757 // wpgroups to fix issue for mysql 8.0, as groups will generate error syntax.
758 if ( $selectgroups ) {
759 $qry = 'SELECT wp.*,wp_sync.*,wp_optionview.*, GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ",") as wpgroups, GROUP_CONCAT(gr.id ORDER BY gr.name SEPARATOR ",") as wpgroupids, GROUP_CONCAT(gr.color ORDER BY gr.name SEPARATOR ",") as wpgroups_colors,
760 wpclient.name as client_name
761 FROM ' . $this->table_name( 'wp' ) . ' wp
762 LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid
763 LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id
764 LEFT JOIN ' . $this->table_name( 'wp_clients' ) . ' wpclient ON wp.client_id = wpclient.client_id
765 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
766 JOIN ' . $this->get_option_view( $extra_view ) . ' wp_optionview ON wp.id = wp_optionview.wpid
767 WHERE 1 ' . $where . $connected_sql . '
768 GROUP BY wp.id, wp_sync.sync_id
769 ORDER BY ' . $orderBy;
770 } else {
771 $qry = 'SELECT wp.*,wp_sync.*,wp_optionview.*, wpclient.name as client_name
772 FROM ' . $this->table_name( 'wp' ) . ' wp
773 LEFT JOIN ' . $this->table_name( 'wp_clients' ) . ' wpclient ON wp.client_id = wpclient.client_id
774 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
775 JOIN ' . $this->get_option_view( $extra_view ) . ' wp_optionview ON wp.id = wp_optionview.wpid
776 WHERE 1 ' . $where . $connected_sql . '
777 GROUP BY wp.id, wp_sync.sync_id
778 ORDER BY ' . $orderBy;
779 }
780
781 if ( ( false !== $offset ) && ( false !== $rowcount ) ) {
782 $qry .= ' LIMIT ' . $offset . ', ' . $rowcount;
783 } elseif ( false !== $rowcount ) {
784 $qry .= ' LIMIT ' . $rowcount;
785 }
786
787 return $qry;
788 }
789
790 /**
791 * Get SQL to get wp child sites for current user.
792 *
793 * @since 4.3
794 *
795 * @param array $params params .
796 *
797 * @return object|null Database query results or null on failure.
798 */
799 public function get_sql_wp_for_current_user( $params = array() ) { // phpcs:ignore -- NOSONAR - complex.
800 if ( ! is_array( $params ) ) {
801 $params = array();
802 }
803
804 $selectgroups = ! empty( $params['select_groups'] ) ? true : false;
805 $search_site = isset( $params['search_site'] ) && ! empty( $params['search_site'] ) ? $params['search_site'] : null;
806 $orderBy = isset( $params['order_by'] ) && ! empty( $params['order_by'] ) ? $params['order_by'] : 'wp.url';
807 $offset = isset( $params['offset'] ) ? $params['offset'] : false;
808 $rowcount = isset( $params['row_count'] ) ? $params['row_count'] : false;
809 $for_manager = isset( $params['for_manager'] ) ? $params['for_manager'] : false;
810 $extraWhere = isset( $params['extra_where'] ) && ! empty( $params['extra_where'] ) ? $params['extra_where'] : null;
811 $extra_view = isset( $params['extra_view'] ) && is_array( $params['extra_view'] ) && ! empty( $params['extra_view'] ) ? $params['extra_view'] : array( 'favi_icon' );
812 $extra_join = isset( $params['extra_join'] ) ? $params['extra_join'] : '';
813
814 $extra_select_wp_fields = isset( $params['extra_select_wp_fields'] ) && is_array( $params['extra_select_wp_fields'] ) && ! empty( $params['extra_select_wp_fields'] ) ? $params['extra_select_wp_fields'] : array();
815 $extra_select_sql_fields = isset( $params['extra_select_sql_fields'] ) && ! empty( $params['extra_select_sql_fields'] ) ? $params['extra_select_sql_fields'] : '';
816
817 $is_staging = isset( $params['is_staging'] ) && 'yes' === $params['is_staging'] ? 'yes' : 'no';
818 $count_only = isset( $params['count_only'] ) && $params['count_only'] ? true : false;
819
820 $where = '';
821
822 if ( null !== $search_site ) {
823 $search_site = trim( $search_site );
824 $where .= ' AND (wp.name LIKE "%' . $this->escape( $search_site ) . '%" OR wp.url LIKE "%' . $this->escape( $search_site ) . '%") ';
825 }
826
827 if ( null !== $extraWhere ) {
828 $where .= ' AND ' . $extraWhere;
829 }
830
831 if ( ! $for_manager ) {
832 $where .= $this->get_sql_where_allow_access_sites( 'wp', $is_staging );
833 }
834
835 if ( 'wp.url' === $orderBy ) {
836 $orderBy = "replace(replace(replace(replace(replace(wp.url, 'https://www.',''), 'http://www.',''), 'https://', ''), 'http://', ''), 'www.', '')";
837 }
838
839 $select_wp_fields = $this->get_sql_select_wp_valid_fields( $extra_select_wp_fields );
840
841 if ( ! empty( $extra_select_sql_fields ) ) {
842 $extra_select_sql_fields = ',' . $extra_select_sql_fields;
843 }
844
845 // wpgroups to fix issue for mysql 8.0, as groups will generate error syntax.
846 if ( $selectgroups ) {
847 if ( $count_only ) {
848 $select = ' COUNT(DISTINCT(wp.id)) ';
849 } else {
850 $select = $select_wp_fields . '
851 ' . $extra_select_sql_fields . '
852 ,wp_sync.sync_errors,wp_optionview.*, GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ",") as wpgroups, GROUP_CONCAT(gr.id ORDER BY gr.name SEPARATOR ",") as wpgroupids, GROUP_CONCAT(gr.color ORDER BY gr.name SEPARATOR ",") as wpgroups_colors, wpclient.name as client_name ';
853 }
854 $qry = 'SELECT ' . $select . '
855 FROM ' . $this->table_name( 'wp' ) . ' wp
856 LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid
857 LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id
858 LEFT JOIN ' . $this->table_name( 'wp_clients' ) . ' wpclient ON wp.client_id = wpclient.client_id
859 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
860 JOIN ' . $this->get_option_view( $extra_view ) . ' wp_optionview ON wp.id = wp_optionview.wpid ' .
861 $extra_join . '
862 WHERE 1 ' . $where;
863 if ( ! $count_only ) {
864 $qry .= ' GROUP BY wp.id, wp_sync.sync_id';
865 }
866 $qry .= ' ORDER BY ' . $orderBy;
867 } else {
868 if ( $count_only ) {
869 $select = ' COUNT(DISTINCT(wp.id)) ';
870 } else {
871 $select = $select_wp_fields . '
872 ' . $extra_select_sql_fields . '
873 ,wp_sync.sync_errors,wp_optionview.*, wpclient.name as client_name ';
874 }
875 $qry = 'SELECT ' . $select . '
876 FROM ' . $this->table_name( 'wp' ) . ' wp
877 LEFT JOIN ' . $this->table_name( 'wp_clients' ) . ' wpclient ON wp.client_id = wpclient.client_id
878 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
879 JOIN ' . $this->get_option_view( $extra_view ) . ' wp_optionview ON wp.id = wp_optionview.wpid ' .
880 $extra_join . '
881 WHERE 1 ' . $where;
882 if ( ! $count_only ) {
883 $qry .= ' GROUP BY wp.id, wp_sync.sync_id';
884 }
885 $qry .= ' ORDER BY ' . $orderBy;
886 }
887
888 if ( ! $count_only ) {
889 if ( ( false !== $offset ) && ( false !== $rowcount ) ) {
890 $qry .= ' LIMIT ' . intval( $offset ) . ', ' . intval( $rowcount );
891 } elseif ( false !== $rowcount ) {
892 $qry .= ' LIMIT ' . intval( $rowcount );
893 }
894 }
895 return $qry;
896 }
897 /**
898 * Get SQL select websites fields.
899 *
900 * @since 4.3
901 *
902 * @param array $other_fields extra select wp fields .
903 *
904 * @return string sql string.
905 */
906 public function get_sql_select_wp_valid_fields( $other_fields = array() ) {
907
908 $allow_other_fields = array(
909 'offline_checks_last',
910 'offline_check_result',
911 'http_response_code',
912 'disable_status_check',
913 'disable_health_check',
914 'status_check_interval',
915 'health_threshold',
916 'note',
917 'statsUpdate',
918 'directories',
919 'plugin_upgrades',
920 'theme_upgrades',
921 'translation_upgrades',
922 'premium_upgrades',
923 'securityIssues',
924 'themes',
925 'ignored_themes',
926 'plugins',
927 'ignored_plugins',
928 'users',
929 'categories',
930 'pluginDir',
931 'automatic_update',
932 'backup_before_upgrade',
933 'mainwpdir',
934 'is_ignoreCoreUpdates',
935 'is_ignorePluginUpdates',
936 'is_ignoreThemeUpdates',
937 'verify_certificate',
938 'force_use_ipv4',
939 'ssl_version',
940 'http_user',
941 'http_pass',
942 'wpe',
943 'is_staging',
944 'client_id',
945 );
946
947 $default_fields = array( 'id', 'url', 'name', 'adminname', 'verify_certificate', 'ssl_version', 'http_user', 'http_pass', 'suspended' );
948
949 $select = ' ';
950
951 foreach ( $default_fields as $field ) {
952 $select .= 'wp.' . $this->escape( $field ) . ',';
953 }
954 foreach ( $other_fields as $field ) {
955 if ( ! in_array( $field, $allow_other_fields ) ) {
956 continue;
957 }
958 if ( in_array( $field, $default_fields ) ) {
959 continue;
960 }
961 $select .= 'wp.' . $this->escape( $field ) . ',';
962 }
963 $select = rtrim( $select, ',' );
964 return $select;
965 }
966
967 /**
968 * Get child sites for current user.
969 *
970 * @param array $params to get sites. Default: array().
971 *
972 * @return array Results or null on failure.
973 *
974 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
975 */
976 public function get_websites_for_current_user( $params = array() ) { // phpcs:ignore -- NOSONAR - complex.
977 if ( ! is_array( $params ) ) {
978 $params = array();
979 }
980
981 $selectgroups = isset( $params['selectgroups'] ) ? $params['selectgroups'] : false;
982 $search_site = isset( $params['search_site'] ) ? $params['search_site'] : null;
983 $orderBy = isset( $params['order_by'] ) ? $params['order_by'] : 'wp.url';
984 $offset = isset( $params['offset'] ) ? $params['offset'] : false;
985 $rowcount = isset( $params['rowcount'] ) ? $params['rowcount'] : false;
986 $extraWhere = isset( $params['where'] ) ? $params['where'] : null;
987 $extra_view = isset( $params['extra_view'] ) && is_array( $params['extra_view'] ) ? $params['extra_view'] : array( 'favi_icon' );
988 $is_staging = isset( $params['is_staging'] ) ? $params['is_staging'] : 'no';
989 $full_data = isset( $params['full_data'] ) && $params['full_data'] && ( 'no' !== $params['full_data'] ) ? true : false;
990 $select_data = isset( $params['select_data'] ) && is_array( $params['select_data'] ) ? $params['select_data'] : false;
991 $format = isset( $params['format'] ) ? $params['format'] : '';
992 $clients = isset( $params['client'] ) ? $params['client'] : '';
993
994 $for_manager = false;
995
996 $urlsWhere = '';
997
998 if ( isset( $params['urls'] ) && ! empty( $params['urls'] ) ) {
999 $urls = explode( ';', $params['urls'] );
1000 foreach ( $urls as $url ) {
1001 $url = str_replace( array( 'https://www.', 'http://www.', 'https://', 'http://', 'www.' ), array( '', '', '', '', '' ), $url );
1002 if ( '/' !== substr( $url, - 1 ) ) {
1003 $url .= '/';
1004 }
1005 $urlsWhere .= '"' . $this->escape( $url ) . '", ';
1006 }
1007 $urlsWhere = rtrim( $urlsWhere, ', ' );
1008 }
1009
1010 if ( ! empty( $urlsWhere ) ) {
1011 $urlsWhere = " ( replace(replace(replace(replace(replace(wp.url, 'https://www.',''), 'http://www.',''), 'https://', ''), 'http://', ''), 'www.', '') IN ( " . $urlsWhere . ') ) ';
1012
1013 if ( empty( $extraWhere ) ) {
1014 $extraWhere = $urlsWhere;
1015 } else {
1016 $extraWhere = $extraWhere . ' AND ' . $urlsWhere;
1017 }
1018 }
1019
1020 $clientWhere = '';
1021 if ( ! empty( $clients ) ) {
1022 $clients = explode( ';', $clients );
1023 foreach ( $clients as $client ) {
1024 if ( is_numeric( $client ) ) {
1025 $clientWhere .= intval( $client ) . ', ';
1026 }
1027 }
1028 $clientWhere = rtrim( $clientWhere, ', ' );
1029 }
1030
1031 if ( ! empty( $clientWhere ) ) {
1032 $clientWhere = ' ( wp.client_id IN ( ' . $clientWhere . ') ) ';
1033 if ( empty( $extraWhere ) ) {
1034 $extraWhere = $clientWhere;
1035 } else {
1036 $extraWhere = $extraWhere . ' AND ' . $clientWhere;
1037 }
1038 }
1039
1040 $data = array( 'id', 'url', 'name', 'client_id' );
1041
1042 if ( $full_data ) {
1043 $data = array(
1044 'id',
1045 'url',
1046 'name',
1047 'offline_checks_last',
1048 'offline_check_result',
1049 'http_response_code',
1050 'disable_status_check',
1051 'disable_health_check',
1052 'status_check_interval',
1053 'health_threshold',
1054 'note',
1055 'plugin_upgrades',
1056 'theme_upgrades',
1057 'translation_upgrades',
1058 'securityIssues',
1059 'themes',
1060 'plugins',
1061 'automatic_update',
1062 'sync_errors',
1063 'dtsAutomaticSync',
1064 'dtsAutomaticSyncStart',
1065 'dtsSync',
1066 'dtsSyncStart',
1067 'last_post_gmt',
1068 'health_value',
1069 'phpversion',
1070 'wp_upgrades',
1071 'security_stats',
1072 'client_id',
1073 'adminname',
1074 'privkey',
1075 'http_user',
1076 'http_pass',
1077 'ssl_version',
1078 'signature_algo',
1079 'verify_method',
1080 'verify_certificate',
1081 );
1082
1083 if ( ! in_array( 'security_stats', $extra_view ) ) {
1084 $extra_view[] = 'security_stats';
1085 }
1086 }
1087
1088 if ( ! empty( $select_data ) && is_array( $select_data ) ) {
1089 $data = $select_data;
1090 }
1091
1092 if ( $selectgroups ) {
1093 $data[] = 'wpgroups';
1094 }
1095
1096 $dbwebsites = array();
1097 $websites = $this->query( $this->get_sql_websites_for_current_user( $selectgroups, $search_site, $orderBy, $offset, $rowcount, $extraWhere, $for_manager, $extra_view, $is_staging ) );
1098 while ( $websites && ( $website = static::fetch_object( $websites ) ) ) {
1099 $obj_data = MainWP_Utility::map_site( $website, $data );
1100
1101 if ( $full_data ) {
1102 $sum_upgrades = 0;
1103 if ( '' !== $obj_data->plugin_upgrades ) {
1104 $plugin_upgrades = json_decode( $obj_data->plugin_upgrades, true );
1105 if ( is_array( $plugin_upgrades ) ) {
1106 $sum_upgrades += count( $plugin_upgrades );
1107 }
1108 }
1109
1110 if ( '' !== $obj_data->theme_upgrades ) {
1111 $theme_upgrades = json_decode( $obj_data->theme_upgrades, true );
1112 if ( is_array( $theme_upgrades ) ) {
1113 $sum_upgrades += count( $theme_upgrades );
1114 }
1115 }
1116
1117 if ( '' !== $obj_data->wp_upgrades ) {
1118 $wp_upgrades = json_decode( $obj_data->wp_upgrades, true );
1119 if ( is_array( $wp_upgrades ) ) {
1120 $sum_upgrades += count( $wp_upgrades );
1121 }
1122 }
1123 $obj_data->sum_of_upgrades = $sum_upgrades;
1124 }
1125
1126 if ( 'array' === $format ) {
1127 $dbwebsites[] = $obj_data;
1128 } else {
1129 $dbwebsites[ $website->id ] = $obj_data;
1130 }
1131 }
1132 static::free_result( $websites );
1133 return $dbwebsites;
1134 }
1135
1136 /**
1137 * Get the child sites the current user has searched for.
1138 *
1139 * @param array $params Query parameters.
1140 *
1141 * @return boolean|null $qry Database query results or null on failure.
1142 *
1143 * @uses \MainWP\Dashboard\MainWP_System::is_multi_user()
1144 */
1145 public function get_sql_search_websites_for_current_user( $params ) { // phpcs:ignore -- NOSONAR - complex.
1146
1147 if ( ! is_array( $params ) ) {
1148 $params = array();
1149 }
1150
1151 $selectgroups = isset( $params['selectgroups'] ) && $params['selectgroups'] ? true : false;
1152 $search_site = isset( $params['search'] ) ? $this->escape( trim( $params['search'] ) ) : null;
1153 $orderBy = isset( $params['orderby'] ) ? $params['orderby'] : 'wp.url';
1154 $offset = isset( $params['offset'] ) ? intval( $params['offset'] ) : false;
1155 $rowcount = isset( $params['rowcount'] ) ? intval( $params['rowcount'] ) : false;
1156 $extraWhere = isset( $params['extra_where'] ) ? $params['extra_where'] : null;
1157 $for_manager = isset( $params['for_manager'] ) && $params['for_manager'] ? true : false;
1158 $extra_view = isset( $params['extra_view'] ) ? $params['extra_view'] : array( 'favi_icon' );
1159 $is_staging = isset( $params['is_staging'] ) && 'yes' === $params['is_staging'] ? 'yes' : 'no';
1160 $is_count = isset( $params['count_only'] ) && $params['count_only'] ? true : false;
1161 $group_ids = isset( $params['group_id'] ) && ! empty( $params['group_id'] ) ? $params['group_id'] : array();
1162 $client_ids = isset( $params['client_id'] ) && ! empty( $params['client_id'] ) ? $params['client_id'] : array();
1163 $is_not = isset( $params['isnot'] ) && ! empty( $params['isnot'] ) ? true : false;
1164 $selected_sites = isset( $params['selected_sites'] ) ? $params['selected_sites'] : array();
1165
1166 if ( ! is_array( $group_ids ) ) {
1167 $group_ids = array();
1168 }
1169
1170 // valid group ids.
1171 $group_ids = array_filter(
1172 $group_ids,
1173 function ( $e ) {
1174 if ( 'nogroups' === $e ) {
1175 return true;
1176 }
1177 return ( is_numeric( $e ) && 0 < $e ) ? true : false;
1178 }
1179 );
1180
1181 if ( ! is_array( $client_ids ) ) {
1182 $client_ids = array();
1183 }
1184
1185 // valid group ids.
1186 $client_ids = array_filter(
1187 $client_ids,
1188 function ( $e ) {
1189 if ( 'noclients' === $e ) {
1190 return true;
1191 }
1192 return is_numeric( $e ) && ! empty( $e ) ? true : false; // to valid client ids.
1193 }
1194 );
1195
1196 if ( $selectgroups ) {
1197 $staging_group = get_option( 'mainwp_stagingsites_group_id' );
1198 if ( $staging_group && in_array( $staging_group, $group_ids ) ) {
1199 if ( empty( $group_ids ) ) {
1200 $is_staging = 'yes';
1201 } else {
1202 $is_staging = 'nocheckstaging';
1203 }
1204 }
1205 }
1206
1207 if ( ! is_array( $selected_sites ) ) {
1208 $selected_sites = array();
1209 }
1210 $selected_sites = MainWP_Utility::array_numeric_filter( $selected_sites );
1211
1212 $where = '';
1213 if ( MainWP_System::instance()->is_multi_user() ) {
1214
1215 /**
1216 * Current user global.
1217 *
1218 * @global string
1219 */
1220 global $current_user;
1221
1222 $where .= ' AND wp.userid = ' . $current_user->ID . ' ';
1223 }
1224
1225 if ( ! empty( $selected_sites ) ) {
1226 $where .= ' AND wp.id IN (' . implode( ',', $selected_sites ) . ') ';
1227 }
1228
1229 // for searching.
1230 if ( null !== $search_site && '' !== $search_site ) {
1231 $where .= ' AND (wp.name LIKE "%' . $search_site . '%" OR wp.url LIKE "%' . $search_site . '%") ';
1232 }
1233
1234 if ( null !== $extraWhere ) {
1235 $where .= ' AND ' . $extraWhere;
1236 }
1237
1238 if ( ! $for_manager ) {
1239 $where .= $this->get_sql_where_allow_access_sites( 'wp', $is_staging );
1240 }
1241
1242 if ( $is_count ) {
1243 $orderBy = '';
1244 } elseif ( 'wp.url' === $orderBy ) {
1245 $orderBy = "replace(replace(replace(replace(replace(wp.url, 'https://www.',''), 'http://www.',''), 'https://', ''), 'http://', ''), 'www.', '')";
1246 }
1247
1248 if ( ! empty( $orderBy ) ) {
1249 $orderBy = ' ORDER BY ' . $orderBy;
1250 }
1251
1252 $join_group = '';
1253 $where_group = '';
1254
1255 if ( in_array( 'nogroups', $group_ids ) ) {
1256 $join_group = ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid ';
1257 $group_ids = array_filter(
1258 $group_ids,
1259 function ( $e ) {
1260 return 'nogroups' !== $e;
1261 }
1262 );
1263 if ( ! empty( $group_ids ) ) {
1264 $groups = implode( ',', $group_ids );
1265 if ( $is_not ) {
1266 $where_group = ' AND wpgroup.groupid IS NOT NULL AND wpgroup.groupid NOT IN (' . $groups . ') ';
1267 // to fix.
1268 $sub_select_is_not = ' SELECT wp.id FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid WHERE wpgroup.groupid IN (' . $groups . ') ';
1269 $where_group .= ' AND wp.id NOT IN ( ' . $sub_select_is_not . ' ) ';
1270 } else {
1271 $where_group = ' AND ( wpgroup.groupid IS NULL OR wpgroup.groupid IN (' . $groups . ') ) ';
1272 }
1273 } elseif ( $is_not ) {
1274 $where_group = ' AND wpgroup.groupid IS NOT NULL ';
1275 } else {
1276 $where_group = ' AND wpgroup.groupid IS NULL ';
1277 }
1278 } elseif ( $group_ids ) {
1279 $groups = implode( ',', $group_ids );
1280 if ( $is_not ) {
1281 $join_group = ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid ';
1282 $where_group = ' AND ( wpgroup.groupid NOT IN (' . $groups . ') OR wpgroup.groupid IS NULL ) ';
1283 // to fix.
1284 $sub_select_is_not = ' SELECT wp.id FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid WHERE wpgroup.groupid IN (' . $groups . ') ';
1285 $where_group .= ' AND wp.id NOT IN ( ' . $sub_select_is_not . ' ) ';
1286 } else {
1287 $join_group = ' JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid ';
1288 $where_group = ' AND wpgroup.groupid IN (' . $groups . ') ';
1289 }
1290 }
1291
1292 $select_groups_belong = '';
1293
1294 if ( ! $is_count && $group_ids ) {
1295 $select_groups_belong = $this->get_select_groups_belong();
1296 }
1297
1298 $join_client = '';
1299 $where_client = '';
1300
1301 if ( in_array( 'noclients', $client_ids ) ) {
1302 $join_client = ' LEFT JOIN ' . $this->table_name( 'wp_clients' ) . ' wpclient ON wp.client_id = wpclient.client_id ';
1303 $client_ids = array_filter(
1304 $client_ids,
1305 function ( $e ) {
1306 return 'noclients' !== $e;
1307 }
1308 );
1309 if ( ! empty( $client_ids ) ) {
1310 $clients = implode( ',', $client_ids );
1311 if ( $is_not ) {
1312 $where_client = ' AND wpclient.client_id IS NOT NULL AND wp.client_id NOT IN (' . $clients . ') ';
1313 } else {
1314 $where_client = ' AND wpclient.client_id IN (' . $clients . ') ';
1315 }
1316 } elseif ( $is_not ) {
1317 $where_client = ' AND wpclient.client_id IS NOT NULL ';
1318 } else {
1319 $where_client = ' AND wpclient.client_id IS NULL ';
1320 }
1321 } elseif ( $client_ids && ! empty( $client_ids ) ) {
1322 $clients = implode( ',', $client_ids );
1323 if ( $is_not ) {
1324 $join_client = ' LEFT JOIN ' . $this->table_name( 'wp_clients' ) . ' wpclient ON wp.client_id = wpclient.client_id ';
1325 $where_client = ' AND ( wpclient.client_id NOT IN (' . $clients . ') OR wpclient.client_id IS NULL ) ';
1326 } else {
1327 $join_client = ' JOIN ' . $this->table_name( 'wp_clients' ) . ' wpclient ON wp.client_id = wpclient.client_id ';
1328 $where_client = ' AND wpclient.client_id IN (' . $clients . ') ';
1329 }
1330 }
1331
1332 if ( '' === $join_client ) {
1333 $join_client = ' LEFT JOIN ' . $this->table_name( 'wp_clients' ) . ' wpclient ON wp.client_id = wpclient.client_id ';
1334 }
1335 // wpgroups to fix issue for mysql 8.0, as groups will generate error syntax.
1336 if ( $selectgroups ) {
1337
1338 if ( empty( $join_group ) ) {
1339 $join_group = ' LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid ';
1340 }
1341
1342 $qry = 'SELECT wp.*,wp_sync.*,wp_optionview.*, GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ",") as wpgroups, GROUP_CONCAT(gr.id ORDER BY gr.name SEPARATOR ",") as wpgroupids, GROUP_CONCAT(gr.color ORDER BY gr.name SEPARATOR ",") as wpgroups_colors, wpclient.name as client_name ' .
1343 $select_groups_belong . ' FROM ' . $this->table_name( 'wp' ) . ' wp ' .
1344 $join_client . ' ' .
1345 $join_group . '
1346 LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgroup.groupid = gr.id
1347
1348 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
1349 JOIN ' . $this->get_option_view( $extra_view ) . ' wp_optionview ON wp.id = wp_optionview.wpid
1350 WHERE 1 ' . $where . $where_group . $where_client . '
1351 GROUP BY wp.id, wp_sync.sync_id ' .
1352 $orderBy;
1353 } else {
1354 $qry = 'SELECT wp.*,wp_sync.*,wp_optionview.*, wpclient.name as client_name ' .
1355 $select_groups_belong . ' FROM ' . $this->table_name( 'wp' ) . ' wp ' .
1356 $join_group . ' ' .
1357 $join_client . '
1358 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
1359 JOIN ' . $this->get_option_view( $extra_view ) . ' wp_optionview ON wp.id = wp_optionview.wpid
1360 WHERE 1 ' . $where . $where_group . $where_client . '
1361 GROUP BY wp.id, wp_sync.sync_id ' .
1362 $orderBy;
1363 }
1364
1365 if ( ( false !== $offset ) && ( false !== $rowcount ) ) {
1366 $qry .= ' LIMIT ' . $offset . ', ' . $rowcount;
1367 } elseif ( false !== $rowcount ) {
1368 $qry .= ' LIMIT ' . $rowcount;
1369 }
1370 //phpcs:ignore
1371 // error_log( $qry ); // NOSONAR - for dev.
1372 return $qry;
1373 }
1374
1375 /**
1376 * Get child sites where allowed access via SQL.
1377 *
1378 * @param string $site_table_alias Child site table alias.
1379 * @param string $is_staging yes|no Is child site a staging site.
1380 *
1381 * @return boolean|null $_where Database query results or null on failure.
1382 */
1383 public function get_sql_where_allow_access_sites( $site_table_alias = '', $is_staging = 'no' ) { // phpcs:ignore -- NOSONAR - complex.
1384
1385 if ( empty( $site_table_alias ) ) {
1386 $site_table_alias = $this->table_name( 'wp' );
1387 }
1388
1389 // check to filter the staging sites.
1390 $where_staging = ' AND ' . $site_table_alias . '.is_staging = 0 ';
1391 if ( 'no' === $is_staging ) {
1392 $where_staging = ' AND ' . $site_table_alias . '.is_staging = 0 ';
1393 } elseif ( 'yes' === $is_staging ) {
1394 $where_staging = ' AND ' . $site_table_alias . '.is_staging = 1 ';
1395 } elseif ( 'nocheckstaging' === $is_staging ) {
1396 $where_staging = '';
1397 }
1398 // end staging filter.
1399
1400 $_where = $where_staging;
1401 // To fix bug run from cron job.
1402 if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
1403 return $_where;
1404 }
1405
1406 // To fix bug run from wp cli.
1407 if ( defined( 'WP_CLI' ) && WP_CLI ) {
1408 return $_where;
1409 }
1410
1411 // Run from Rest Api.
1412 if ( defined( 'MAINWP_REST_API_DOING' ) && MAINWP_REST_API_DOING ) {
1413 return $_where;
1414 }
1415
1416 /**
1417 * Filter: mainwp_currentuserallowedaccesssites
1418 *
1419 * Filters allowed sites for the current user.
1420 *
1421 * @since Unknown
1422 */
1423 $allowed_sites = apply_filters( 'mainwp_currentuserallowedaccesssites', 'all' );
1424
1425 if ( 'all' === $allowed_sites ) {
1426 return $_where;
1427 }
1428
1429 if ( is_array( $allowed_sites ) && ! empty( $allowed_sites ) ) {
1430 // valid group ids.
1431 $allowed_sites = array_filter(
1432 $allowed_sites,
1433 function ( $e ) {
1434 return is_numeric( $e ) ? true : false;
1435 }
1436 );
1437 $_where .= ' AND ' . $site_table_alias . '.id IN (' . implode( ',', $allowed_sites ) . ') ';
1438 } else {
1439 $_where .= ' AND 0 ';
1440 }
1441
1442 return $_where;
1443 }
1444
1445 /**
1446 * Get groupd where allowed access via SQL.
1447 *
1448 * @param string $group_table_alias Child site table alias.
1449 * @param string $with_staging yes|no Is child site a staging site.
1450 *
1451 * @return boolean|null $_where Database query results or null on failer.
1452 */
1453 public function get_sql_where_allow_groups( $group_table_alias = '', $with_staging = 'no' ) { // phpcs:ignore -- NOSONAR - complex.
1454
1455 if ( empty( $group_table_alias ) ) {
1456 $group_table_alias = $this->table_name( 'group' );
1457 }
1458
1459 // check to filter the staging group.
1460 $where_staging_group = '';
1461 $staging_group = get_option( 'mainwp_stagingsites_group_id' );
1462 if ( $staging_group ) {
1463 $where_staging_group = ' AND ' . $group_table_alias . '.id <> ' . $staging_group . ' ';
1464 if ( 'yes' === $with_staging ) {
1465 $where_staging_group = '';
1466 }
1467 }
1468
1469 // end staging filter.
1470 $_where = $where_staging_group;
1471
1472 // To fix bug run from cron job.
1473 if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
1474 return $_where;
1475 }
1476
1477 // Run from wp cli.
1478 if ( defined( 'WP_CLI' ) && WP_CLI ) {
1479 return $_where;
1480 }
1481
1482 // Run from Rest Api.
1483 if ( defined( 'MAINWP_REST_API_DOING' ) && MAINWP_REST_API_DOING ) {
1484 return $_where;
1485 }
1486
1487 /**
1488 * Filter: mainwp_currentuserallowedaccessgroups
1489 *
1490 * Filters allowed groups for the current user.
1491 *
1492 * @since Unknown
1493 */
1494 $allowed_groups = apply_filters( 'mainwp_currentuserallowedaccessgroups', 'all' );
1495
1496 if ( 'all' === $allowed_groups ) {
1497 return $_where;
1498 }
1499
1500 if ( is_array( $allowed_groups ) && ! empty( $allowed_groups ) ) {
1501
1502 // valid group ids.
1503 $allowed_groups = array_filter(
1504 $allowed_groups,
1505 function ( $e ) {
1506 return is_numeric( $e ) ? true : false;
1507 }
1508 );
1509
1510 return ' AND ' . $group_table_alias . '.id IN (' . implode( ',', $allowed_groups ) . ') ' . $_where;
1511 } else {
1512 return ' AND 0 ';
1513 }
1514 }
1515
1516 /**
1517 * Get child site by id.
1518 *
1519 * @param int $id Child site ID.
1520 * @param array $selectGroups Select groups.
1521 * @param array $extra_view Get extra option fields.
1522 *
1523 * @return object|null Database query results or null on failure.
1524 */
1525 public function get_website_by_id( $id, $selectGroups = false, $extra_view = array() ) {
1526 return $this->get_row_result( $this->get_sql_website_by_id( $id, $selectGroups, $extra_view ) );
1527 }
1528
1529 /**
1530 * Get child site by id via SQL.
1531 *
1532 * @param int $id Child site ID.
1533 * @param bool $selectGroups Selected groups.
1534 * @param mixed $extra_view Extra view value.
1535 *
1536 * @return object|null Database query result or null on failure.
1537 *
1538 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
1539 */
1540 public function get_sql_website_by_id( $id, $selectGroups = false, $extra_view = array() ) {
1541
1542 if ( ! is_array( $extra_view ) || empty( $extra_view ) ) {
1543 $extra_view = array( 'favi_icon', 'site_info' );
1544 }
1545
1546 if ( MainWP_Utility::ctype_digit( $id ) ) {
1547 $where = $this->get_sql_where_allow_access_sites( 'wp', 'nocheckstaging' );
1548 if ( $selectGroups ) {
1549 return 'SELECT wp.*,wp_sync.*,wp_optionview.*, GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ",") as wpgroups, GROUP_CONCAT(gr.id ORDER BY gr.name SEPARATOR ",") as wpgroupids, GROUP_CONCAT(gr.color ORDER BY gr.name SEPARATOR ",") as wpgroups_colors
1550 FROM ' . $this->table_name( 'wp' ) . ' wp
1551 LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid
1552 LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id
1553 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
1554 JOIN ' . $this->get_option_view( $extra_view ) . ' wp_optionview ON wp.id = wp_optionview.wpid
1555 WHERE wp.id = ' . $id . $where . '
1556 GROUP BY wp.id, wp_sync.sync_id';
1557 }
1558
1559 return 'SELECT wp.*,wp_sync.*,wp_optionview.*
1560 FROM ' . $this->table_name( 'wp' ) . ' wp
1561 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
1562 JOIN ' . $this->get_option_view( $extra_view ) . ' wp_optionview ON wp.id = wp_optionview.wpid
1563 WHERE id = ' . $id . $where;
1564 }
1565
1566 return null;
1567 }
1568
1569 /**
1570 * Method get_websites_by_ids()
1571 *
1572 * Get child sites by child site IDs.
1573 *
1574 * @param array $ids Child site IDs.
1575 * @param int $userId User ID.
1576 *
1577 * @return object|null Database query result or null on failure.
1578 *
1579 * @uses \MainWP\Dashboard\MainWP_System::is_multi_user()
1580 */
1581 public function get_websites_by_ids( $ids, $userId = null ) {
1582 if ( ( null === $userId ) && MainWP_System::instance()->is_multi_user() ) {
1583
1584 /**
1585 * Current user global.
1586 *
1587 * @global string
1588 */
1589 global $current_user;
1590
1591 $userId = $current_user->ID;
1592 }
1593
1594 // valid group ids.
1595 $ids = array_filter(
1596 $ids,
1597 function ( $e ) {
1598 return ( is_numeric( $e ) && 0 < $e ) ? true : false;
1599 }
1600 );
1601
1602 $where = $this->get_sql_where_allow_access_sites();
1603
1604 return $this->wpdb->get_results( 'SELECT * FROM ' . $this->table_name( 'wp' ) . ' WHERE id IN (' . implode( ',', $ids ) . ')' . ( null !== $userId ? ' AND userid = ' . intval( $userId ) : '' ) . $where, OBJECT );
1605 }
1606
1607 /**
1608 * Get child sites by groups IDs.
1609 *
1610 * @param array $ids Groups IDs.
1611 * @param int $userId User ID.
1612 *
1613 * @return object|null Database query result or null on failure.
1614 *
1615 * @uses \MainWP\Dashboard\MainWP_System::is_multi_user()
1616 */
1617 public function get_websites_by_group_ids( $ids, $userId = null ) {
1618 if ( empty( $ids ) ) {
1619 return array();
1620 }
1621 if ( ( null === $userId ) && MainWP_System::instance()->is_multi_user() ) {
1622
1623 /**
1624 * Current user global.
1625 *
1626 * @global string
1627 */
1628 global $current_user;
1629
1630 $userId = $current_user->ID;
1631 }
1632
1633 // valid group ids.
1634 $group_ids = array_filter(
1635 $ids,
1636 function ( $e ) {
1637 return is_numeric( $e ) ? true : false;
1638 }
1639 );
1640
1641 return $this->wpdb->get_results( 'SELECT * FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid WHERE wpgroup.groupid IN (' . implode( ',', $group_ids ) . ') ' . ( null !== $userId ? ' AND wp.userid = ' . intval( $userId ) : '' ), OBJECT );
1642 }
1643
1644 /**
1645 * Get child sites by group ID.
1646 *
1647 * @param int $id Group ID.
1648 *
1649 * @return object|null Database query result or null on failure.
1650 */
1651 public function get_websites_by_group_id( $id ) {
1652 return $this->get_results_result( $this->get_sql_websites_by_group_id( $id ) );
1653 }
1654
1655 /**
1656 * Get child sites by group id via SQL.
1657 *
1658 * @param int $id Group ID.
1659 * @param bool $selectgroups Selected groups. Default: false.
1660 * @param string $orderBy Order list by. Default: URL.
1661 * @param bool $offset Query offset. Default: false.
1662 * @param bool $rowcount Row count. Default: falese.
1663 * @param null $where SQL WHERE value.
1664 * @param null $search_site Site search field value. Default: null.
1665 * @param array $others Others params.
1666 *
1667 * @return object|null Return database query or null on failure.
1668 *
1669 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
1670 */
1671 public function get_sql_websites_by_group_id( // phpcs:ignore -- NOSONAR - complex.
1672 $id,
1673 $selectgroups = false,
1674 $orderBy = 'wp.url',
1675 $offset = false,
1676 $rowcount = false,
1677 $where = null,
1678 $search_site = null,
1679 $others = array()
1680 ) {
1681
1682 $is_staging = 'no';
1683 if ( $selectgroups ) {
1684 $staging_group = get_option( 'mainwp_stagingsites_group_id' );
1685 if ( $staging_group && $id === $staging_group ) {
1686 $is_staging = 'yes';
1687 }
1688 }
1689
1690 $where_search = '';
1691 if ( ! empty( $search_site ) ) {
1692 $search_site = trim( $search_site );
1693 $where_search .= ' AND (wp.name LIKE "%' . $this->escape( $search_site ) . '%" OR wp.url LIKE "%' . $this->escape( $search_site ) . '%") ';
1694 }
1695
1696 $extra_view = is_array( $others ) && isset( $others['extra_view'] ) && is_array( $others['extra_view'] ) && ! empty( $others['extra_view'] ) ? $others['extra_view'] : array( 'site_info' );
1697
1698 if ( MainWP_Utility::ctype_digit( $id ) ) {
1699 $where_allowed = $this->get_sql_where_allow_access_sites( 'wp', $is_staging );
1700 if ( $selectgroups ) {
1701 $qry = 'SELECT wp.*,wp_sync.*,wp_optionview.*, GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ",") as wpgroups, GROUP_CONCAT(gr.id ORDER BY gr.name SEPARATOR ",") as wpgroupids, GROUP_CONCAT(gr.color ORDER BY gr.name SEPARATOR ",") as wpgroups_colors
1702 FROM ' . $this->table_name( 'wp' ) . ' wp
1703 JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid
1704 LEFT JOIN ' . $this->table_name( 'wp_group' ) . ' wpgr ON wp.id = wpgr.wpid
1705 LEFT JOIN ' . $this->table_name( 'group' ) . ' gr ON wpgr.groupid = gr.id
1706 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
1707 JOIN ' . $this->get_option_view( $extra_view, true ) . ' wp_optionview ON wp.id = wp_optionview.wpid
1708 WHERE wpgroup.groupid = ' . $id . ' ' .
1709 ( empty( $where ) ? '' : ' AND ' . $where ) . $where_allowed . $where_search . '
1710 GROUP BY wp.id, wp_sync.sync_id
1711 ORDER BY ' . $orderBy;
1712 } else {
1713 $qry = 'SELECT wp.*,wp_optionview.*, wp_sync.* FROM ' . $this->table_name( 'wp' ) . ' wp
1714 JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid
1715 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
1716 JOIN ' . $this->get_option_view( $extra_view, false ) . ' wp_optionview ON wp.id = wp_optionview.wpid
1717 WHERE wpgroup.groupid = ' . $id . ' ' . $where_allowed . $where_search .
1718 ( empty( $where ) ? '' : ' AND ' . $where ) . ' ORDER BY ' . $orderBy;
1719 }
1720 if ( ( false !== $offset ) && ( false !== $rowcount ) ) {
1721 $qry .= ' LIMIT ' . $offset . ', ' . $rowcount;
1722 } elseif ( false !== $rowcount ) {
1723 $qry .= ' LIMIT ' . $rowcount;
1724 }
1725
1726 return $qry;
1727 }
1728
1729 return null;
1730 }
1731
1732 /**
1733 * Get child sites by group name.
1734 *
1735 * @param int $userid Current user ID.
1736 * @param string $groupname Group name.
1737 *
1738 * @return object|null Database query result or null on failure.
1739 */
1740 public function get_websites_by_group_name( $userid, $groupname ) {
1741 return $this->get_results_result( $this->get_sql_websites_by_group_name( $groupname, $userid ) );
1742 }
1743
1744 /**
1745 * Get child sites by group name.
1746 *
1747 * @param string $groupname Group name.
1748 * @param int $userid Current user ID.
1749 *
1750 * @return object|null Database query result or null on failure.
1751 *
1752 * @uses \MainWP\Dashboard\MainWP_System::is_multi_user()
1753 */
1754 public function get_sql_websites_by_group_name( $groupname, $userid = null ) {
1755 if ( ( null === $userid ) && MainWP_System::instance()->is_multi_user() ) {
1756
1757 /**
1758 * Current user global.
1759 *
1760 * @global string
1761 */
1762 global $current_user;
1763
1764 $userid = $current_user->ID;
1765 }
1766
1767 $sql = 'SELECT wp.*,wp_sync.*,wp_optionview.* FROM ' . $this->table_name( 'wp' ) . ' wp
1768 INNER JOIN ' . $this->table_name( 'wp_group' ) . ' wpgroup ON wp.id = wpgroup.wpid
1769 JOIN ' . $this->table_name( 'group' ) . ' g ON wpgroup.groupid = g.id
1770 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
1771 JOIN ' . $this->get_option_view() . ' wp_optionview ON wp.id = wp_optionview.wpid
1772 WHERE g.name="' . $this->escape( $groupname ) . '"';
1773 if ( null !== $userid ) {
1774 $sql .= ' AND g.userid = "' . intval( $userid ) . '"';
1775 }
1776
1777 return $sql;
1778 }
1779
1780 /**
1781 * Get child site IP address.
1782 *
1783 * @param int $wpid Child site ID.
1784 *
1785 * @return string|null Child site IP address or null on failure.
1786 */
1787 public function get_wp_ip( $wpid ) {
1788 return $this->wpdb->get_var( $this->wpdb->prepare( 'SELECT ip FROM ' . $this->table_name( 'request_log' ) . ' WHERE wpid = %d', $wpid ) );
1789 }
1790
1791 /**
1792 * Add website to the MainWP Dashboard.
1793 *
1794 * @param int $userid Current user ID.
1795 * @param string $name Child site name.
1796 * @param string $url Child site URL.
1797 * @param string $admin Child site administrator username.
1798 * @param string $pubkey OpenSSL public key.
1799 * @param string $privkey OpenSSL private key.
1800 * @param array $params Other params.
1801 *
1802 * @return int|false Child site ID or false on failure.
1803 *
1804 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
1805 */
1806 public function add_website( // phpcs:ignore -- NOSONAR - complex.
1807 $userid,
1808 $name,
1809 $url,
1810 $admin,
1811 $pubkey,
1812 $privkey,
1813 $params = array()
1814 ) {
1815
1816 if ( ! is_array( $params ) ) {
1817 $params = array();
1818 }
1819
1820 $groupids = isset( $params['groupids'] ) ? $params['groupids'] : array();
1821 $groupnames = isset( $params['groupnames'] ) ? $params['groupnames'] : array();
1822 $verifyCertificate = isset( $params['verifyCertificate'] ) ? (int) $params['verifyCertificate'] : 1;
1823 $uniqueId = isset( $params['uniqueId'] ) ? $params['uniqueId'] : '';
1824 $http_user = isset( $params['http_user'] ) ? $params['http_user'] : null;
1825 $http_pass = isset( $params['http_pass'] ) ? $params['http_pass'] : null;
1826 $sslVersion = isset( $params['sslVersion'] ) ? $params['sslVersion'] : 0;
1827 $wpe = isset( $params['wpe'] ) ? $params['wpe'] : 0;
1828 $isStaging = isset( $params['isStaging'] ) ? $params['isStaging'] : 0;
1829
1830 if ( MainWP_Utility::ctype_digit( $userid ) ) {
1831 if ( '/' !== substr( $url, - 1 ) ) {
1832 $url .= '/';
1833 }
1834 $values = array(
1835 'userid' => $userid,
1836 'adminname' => $this->escape( $admin ),
1837 'name' => $this->escape( wp_strip_all_tags( $name ) ),
1838 'url' => $this->escape( $url ),
1839 'pubkey' => $this->escape( $pubkey ),
1840 'privkey' => $this->escape( $privkey ),
1841 'siteurl' => '',
1842 'ga_id' => '',
1843 'gas_id' => 0,
1844 'offline_checks_last' => 0,
1845 'offline_check_result' => 0,
1846 'note' => '',
1847 'statsUpdate' => 0,
1848 'directories' => '',
1849 'plugin_upgrades' => '',
1850 'theme_upgrades' => '',
1851 'translation_upgrades' => '',
1852 'securityIssues' => '',
1853 'themes' => '',
1854 'ignored_themes' => '',
1855 'plugins' => '',
1856 'ignored_plugins' => '',
1857 'users' => '',
1858 'categories' => '',
1859 'pluginDir' => '',
1860 'automatic_update' => 0,
1861 'backup_before_upgrade' => 2,
1862 'verify_certificate' => intval( $verifyCertificate ),
1863 'ssl_version' => $sslVersion,
1864 'uniqueId' => $uniqueId,
1865 'mainwpdir' => 0,
1866 'http_user' => $http_user,
1867 'http_pass' => $http_pass,
1868 'wpe' => $wpe,
1869 'is_staging' => $isStaging,
1870 );
1871
1872 $syncValues = array(
1873 'dtsSync' => 0,
1874 'dtsSyncStart' => 0,
1875 'dtsAutomaticSync' => 0,
1876 'dtsAutomaticSyncStart' => 0,
1877 'totalsize' => 0,
1878 'extauth' => '',
1879 'sync_errors' => '',
1880 );
1881 if ( $this->wpdb->insert( $this->table_name( 'wp' ), $values ) ) {
1882 $websiteid = $this->wpdb->insert_id;
1883 $syncValues['wpid'] = $websiteid;
1884 $this->wpdb->insert( $this->table_name( 'wp_sync' ), $syncValues );
1885 $this->wpdb->insert(
1886 $this->table_name( 'wp_settings_backup' ),
1887 array(
1888 'wpid' => $websiteid,
1889 'archiveFormat' => 'global',
1890 )
1891 );
1892
1893 foreach ( $groupnames as $groupname ) {
1894 if ( $this->wpdb->insert(
1895 $this->table_name( 'group' ),
1896 array(
1897 'userid' => $userid,
1898 'name' => $this->escape( htmlspecialchars( $groupname ) ),
1899 )
1900 )
1901 ) {
1902 $groupids[] = $this->wpdb->insert_id;
1903 }
1904 }
1905 // add groupids.
1906 foreach ( $groupids as $groupid ) {
1907 $this->wpdb->insert(
1908 $this->table_name( 'wp_group' ),
1909 array(
1910 'wpid' => $websiteid,
1911 'groupid' => $groupid,
1912 )
1913 );
1914 }
1915
1916 return $websiteid;
1917 }
1918 }
1919
1920 return false;
1921 }
1922
1923 /**
1924 * Remove child site from the MainWP Dashboard.
1925 *
1926 * @param int $websiteid Child site ID.
1927 *
1928 * @return int|boolean Return child site ID that was removed or false on failure.
1929 *
1930 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
1931 */
1932 public function remove_website( $websiteid ) {
1933 if ( MainWP_Utility::ctype_digit( $websiteid ) ) {
1934 $nr = $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp' ) . ' WHERE id=%d', $websiteid ) );
1935 $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_group' ) . ' WHERE wpid=%d', $websiteid ) );
1936 $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_sync' ) . ' WHERE wpid=%d', $websiteid ) );
1937 $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_options' ) . ' WHERE wpid=%d', $websiteid ) );
1938 $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_status' ) . ' WHERE wpid=%d', $websiteid ) );
1939
1940 return $nr;
1941 }
1942
1943 return false;
1944 }
1945
1946 /**
1947 * Update child site db values.
1948 *
1949 * @param int $websiteid Child site ID.
1950 * @param array $fields Database fields to update.
1951 *
1952 * @return int|boolean The number of rows updated, or false on error.
1953 */
1954 public function update_website_values( $websiteid, $fields ) {
1955 if ( ! empty( $fields ) ) {
1956 return $this->wpdb->update( $this->table_name( 'wp' ), $fields, array( 'id' => $websiteid ) );
1957 }
1958
1959 return false;
1960 }
1961
1962 /**
1963 * Update child site sync values.
1964 *
1965 * @param int $websiteid Child site ID.
1966 * @param array $fields Database fields to update.
1967 *
1968 * @return int|boolean The number of rows updated, or false on error.
1969 */
1970 public function update_website_sync_values( $websiteid, $fields ) {
1971 if ( ! empty( $fields ) ) {
1972 return $this->wpdb->update( $this->table_name( 'wp_sync' ), $fields, array( 'wpid' => $websiteid ) );
1973 }
1974
1975 return false;
1976 }
1977
1978 /**
1979 * Update child site.
1980 *
1981 * @param int $websiteid Website ID.
1982 * @param string $url Child site URL.
1983 * @param int $userid Current user ID.
1984 * @param string $name Child site name.
1985 * @param string $siteadmin Child site administrator username.
1986 * @param array $groupids Group IDs.
1987 * @param array $groupnames Group Names.
1988 * @param string $pluginDir Plugin directory.
1989 * @param mixed $maximumFileDescriptorsOverride Overwrite the Maximum File Descriptors option.
1990 * @param mixed $maximumFileDescriptorsAuto Auto set the Maximum File Descriptors option.
1991 * @param mixed $maximumFileDescriptors Set the Maximum File Descriptors option.
1992 * @param int $verifyCertificate Whether or not to verify SSL Certificate.
1993 * @param mixed $archiveFormat Backup archive formate.
1994 * @param string $uniqueId Unique security ID.
1995 * @param string $http_user HTTP Basic Authentication username.
1996 * @param string $http_pass HTTP Basic Authentication password.
1997 * @param int $sslVersion SSL Version.
1998 * @param int $disableChecking Wether or not disable sites status checking.
1999 * @param int $checkInterval Status checking interval.
2000 * @param bool $disableHealthChecking Disable Site health threshold.
2001 * @param int $healthThreshold Site health threshold.
2002 * @param int $wpe Is it WP Engine hosted site.
2003 *
2004 * @return boolean ture on success or false on failure.
2005 *
2006 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
2007 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
2008 */
2009 public function update_website( // phpcs:ignore -- NOSONAR - complex.
2010 $websiteid,
2011 $url,
2012 $userid,
2013 $name,
2014 $siteadmin,
2015 $groupids,
2016 $groupnames,
2017 $pluginDir,
2018 $maximumFileDescriptorsOverride,
2019 $maximumFileDescriptorsAuto,
2020 $maximumFileDescriptors,
2021 $verifyCertificate = 1,
2022 $archiveFormat = 'global',
2023 $uniqueId = '',
2024 $http_user = null,
2025 $http_pass = null,
2026 $sslVersion = 0,
2027 $disableChecking = 1,
2028 $checkInterval = 1440,
2029 $disableHealthChecking = 1,
2030 $healthThreshold = 80,
2031 $wpe = 0
2032 ) {
2033
2034 if ( MainWP_Utility::ctype_digit( $websiteid ) && MainWP_Utility::ctype_digit( $userid ) ) {
2035 $website = $this->get_website_by_id( $websiteid );
2036 if ( MainWP_System_Utility::can_edit_website( $website ) ) {
2037 // update admin.
2038 $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp' ) . ' SET url="' . $this->escape( $url ) . '", name="' . $this->escape( wp_strip_all_tags( $name ) ) . '", adminname="' . $this->escape( $siteadmin ) . '",pluginDir="' . $this->escape( $pluginDir ) . '", verify_certificate="' . intval( $verifyCertificate ) . '", ssl_version="' . intval( $sslVersion ) . '", wpe="' . intval( $wpe ) . '", uniqueId="' . $this->escape( $uniqueId ) . '", http_user="' . $this->escape( $http_user ) . '", http_pass="' . $this->escape( $http_pass ) . '", disable_status_check="' . $this->escape( $disableChecking ) . '", status_check_interval="' . $this->escape( $checkInterval ) . '", disable_health_check="' . $this->escape( $disableHealthChecking ) . '", health_threshold="' . $this->escape( $healthThreshold ) . '" WHERE id=%d', $websiteid ) );
2039 $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp_settings_backup' ) . ' SET archiveFormat = "' . $this->escape( $archiveFormat ) . '" WHERE wpid=%d', $websiteid ) );
2040
2041 if ( get_option( 'mainwp_enableLegacyBackupFeature' ) ) {
2042 $this->wpdb->query( $this->wpdb->prepare( 'UPDATE ' . $this->table_name( 'wp' ) . ' SET maximumFileDescriptorsOverride = ' . ( $maximumFileDescriptorsOverride ? 1 : 0 ) . ',maximumFileDescriptorsAuto= ' . ( $maximumFileDescriptorsAuto ? 1 : 0 ) . ',maximumFileDescriptors = ' . $maximumFileDescriptors . ' WHERE id=%d', $websiteid ) );
2043 }
2044
2045 // remove groups.
2046 $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'wp_group' ) . ' WHERE wpid=%d', $websiteid ) );
2047 // Remove GA stats.
2048 $showErrors = $this->wpdb->hide_errors();
2049
2050 /**
2051 * Action: mainwp_ga_delete_site
2052 *
2053 * Fires upon site removal process in order to delete Google Analytics data.
2054 *
2055 * @param int $websiteid Child site ID.
2056 *
2057 * @since Unknown
2058 */
2059 do_action( 'mainwp_ga_delete_site', $websiteid );
2060
2061 if ( $showErrors ) {
2062 $this->wpdb->show_errors();
2063 }
2064 // add groups with groupnames.
2065 foreach ( $groupnames as $groupname ) {
2066 if ( $this->wpdb->insert(
2067 $this->table_name( 'group' ),
2068 array(
2069 'userid' => $userid,
2070 'name' => $this->escape( $groupname ),
2071 )
2072 )
2073 ) {
2074 $groupids[] = $this->wpdb->insert_id;
2075 }
2076 }
2077 // add groupids.
2078 foreach ( $groupids as $groupid ) {
2079 $this->wpdb->insert(
2080 $this->table_name( 'wp_group' ),
2081 array(
2082 'wpid' => $websiteid,
2083 'groupid' => $groupid,
2084 )
2085 );
2086 }
2087
2088 return true;
2089 }
2090 }
2091
2092 return false;
2093 }
2094
2095 /**
2096 * Get websites check updates count.
2097 *
2098 * @param int $lasttime_start Lasttime start automatic update.
2099 *
2100 * @return int Child sites update count.
2101 */
2102 public function get_websites_check_updates_count( $lasttime_start ) {
2103 $where = $this->get_sql_where_allow_access_sites( 'wp' );
2104
2105 return $this->wpdb->get_var( '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 < ' . intval( $lasttime_start ) . ')' . $where );
2106 }
2107
2108 /**
2109 * Get child site count where date & time Session sync is smaller then start.
2110 *
2111 * @param int $lasttime_start Last time start automatic.
2112 *
2113 * @return int Returned child site count.
2114 */
2115 public function get_websites_count_where_dts_automatic_sync_smaller_then_start( $lasttime_start ) {
2116 $where = $this->get_sql_where_allow_access_sites( 'wp' );
2117
2118 return $this->wpdb->get_var( '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.dtsAutomaticSync < wp_sync.dtsAutomaticSyncStart AND wp_sync.dtsAutomaticSyncStart > ' . intval( $lasttime_start ) . ') OR (wp_sync.dtsAutomaticSyncStart = 0)) ' . $where );
2119 }
2120
2121 /**
2122 * Get child site last automatic sync date & time.
2123 *
2124 * @return string Date and time of last automatic sync.
2125 */
2126 public function get_websites_last_automatic_sync() {
2127 return $this->wpdb->get_var( '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' );
2128 }
2129
2130 /**
2131 * Get child sites check updates.
2132 *
2133 * @param int $limit Query limit.
2134 * @param int $lasttime_start Lasttime start automatic update.
2135 *
2136 * @return object|null Database query result or null on failure.
2137 */
2138 public function get_websites_check_updates( $limit, $lasttime_start ) {
2139 $where = $this->get_sql_where_allow_access_sites( 'wp' );
2140
2141 return $this->wpdb->get_results( 'SELECT wp.*,wp_sync.*,wp_optionview.* FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid JOIN ' . $this->get_option_view() . ' wp_optionview ON wp.id = wp_optionview.wpid WHERE ( wp_sync.dtsAutomaticSync = 0 OR wp_sync.dtsAutomaticSyncStart = 0 OR wp_sync.dtsAutomaticSyncStart < ' . intval( $lasttime_start ) . ' ) ' . $where . ' ORDER BY wp_sync.dtsAutomaticSyncStart ASC LIMIT ' . $limit, OBJECT );
2142 }
2143
2144 /**
2145 * Get website update stats via SQL.
2146 *
2147 * @return object|null Database query result of null on failure.
2148 */
2149 public function get_websites_stats_update_sql() {
2150 $where = $this->get_sql_where_allow_access_sites( 'wp' );
2151 return 'SELECT wp.*,wp_sync.sync_errors FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid WHERE (wp.statsUpdate = 0 OR ' . time() . ' - wp.statsUpdate >= ' . ( 60 * 60 * 24 ) . ')' . $where . ' ORDER BY wp.statsUpdate ASC';
2152 }
2153
2154 /**
2155 * Update child site statistics.
2156 *
2157 * Update whether or not a child site has been updated.
2158 *
2159 * @param mixed $websiteid Child site ID.
2160 * @param mixed $statsUpdated Child site Update status.
2161 *
2162 * @return (int|boolean) Number of rows effected in update or false on failure.
2163 */
2164 public function update_website_stats( $websiteid, $statsUpdated ) {
2165 return $this->wpdb->update(
2166 $this->table_name( 'wp' ),
2167 array( 'statsUpdate' => $statsUpdated ),
2168 array( 'id' => $websiteid )
2169 );
2170 }
2171
2172 /**
2173 * Get child site by url.
2174 *
2175 * @param string $url Child site URL.
2176 *
2177 * @return object|null Database query result or null on failure.
2178 */
2179 public function get_websites_by_url( $url ) {
2180 if ( '/' !== substr( $url, - 1 ) ) {
2181 $url .= '/';
2182 }
2183 $results = $this->wpdb->get_results( $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid WHERE wp.url = %s ', $this->escape( $url ) ), OBJECT );
2184 if ( $results ) {
2185 return $results;
2186 }
2187
2188 if ( stristr( $url, '/www.' ) ) {
2189 // remove www if it's there!
2190 $url = str_replace( '/www.', '/', $url );
2191 } else {
2192 // add www if it's not there!
2193 $url = str_replace( 'https://', 'https://www.', $url );
2194 $url = str_replace( 'http://', 'http://www.', $url );
2195 }
2196
2197 $results = $this->wpdb->get_results( $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid WHERE wp.url = %s ', $this->escape( $url ) ), OBJECT );
2198 if ( $results ) {
2199 return $results;
2200 }
2201
2202 $url = str_replace( array( 'https://www.', 'http://www.', 'https://', 'http://', 'www.' ), array( '', '', '', '', '' ), $url );
2203
2204 return $this->wpdb->get_results( $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'wp' ) . ' wp JOIN ' . $this->table_name( 'wp_sync' ) . " wp_sync ON wp.id = wp_sync.wpid WHERE replace(replace(replace(replace(replace(wp.url, 'https://www.',''), 'http://www.',''), 'https://', ''), 'http://', ''), 'www.', '') = %s ", $this->escape( $url ) ), OBJECT );
2205 }
2206
2207 /**
2208 * Get websites offline status.
2209 *
2210 * @return array Child site monitoring status.
2211 */
2212 public function get_websites_offline_status_to_send_notice() {
2213 $where = $this->get_sql_where_allow_access_sites( 'wp' );
2214 $extra_view = array( 'monitoring_notification_emails', 'settings_notification_emails' );
2215
2216 return $this->wpdb->get_results(
2217 'SELECT wp.*,wp_sync.*,wp_optionview.* FROM ' . $this->table_name( 'wp' ) . ' wp
2218 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
2219 JOIN ' . $this->get_option_view( $extra_view ) . ' wp_optionview ON wp.id = wp_optionview.wpid
2220 WHERE wp.disable_status_check <> 1 AND wp.offline_check_result <> 1 AND wp.offline_check_result <> 0 AND wp.http_code_noticed = 0' . // http_code_noticed = 0: not noticed yet.
2221 $where,
2222 OBJECT
2223 );
2224 }
2225
2226 /**
2227 * Method get_websites_to_notice_health_threshold()
2228 *
2229 * Get websites to notice site health.
2230 *
2231 * @param int $globalThreshold Global site health threshold.
2232 */
2233 public function get_websites_to_notice_health_threshold( $globalThreshold ) {
2234
2235 $where = $this->get_sql_where_allow_access_sites( 'wp' );
2236 $extra_view = array( 'monitoring_notification_emails', 'settings_notification_emails' );
2237
2238 if ( 80 >= $globalThreshold ) { // actual is 80.
2239 // should-be-improved site health.
2240 $where_global_threshold = '( wp.health_threshold = 0 AND wp_sync.health_value < 80 )';
2241 } else {
2242 // good site health.
2243 $where_global_threshold = '( wp.health_threshold = 0 AND wp_sync.health_value >= 80 )';
2244 }
2245
2246 $where_site_threshold = ' ( wp.health_threshold = 80 AND wp_sync.health_value < 80 ) '; // should-be-improved site health.
2247 $where_site_threshold .= ' OR ( wp.health_threshold = 100 AND wp_sync.health_value >= 80 ) '; // good site health.
2248
2249 return $this->wpdb->get_results(
2250 'SELECT wp.*,wp_sync.*,wp_optionview.* FROM ' . $this->table_name( 'wp' ) . ' wp
2251 JOIN ' . $this->table_name( 'wp_sync' ) . ' wp_sync ON wp.id = wp_sync.wpid
2252 JOIN ' . $this->get_option_view( $extra_view ) . ' wp_optionview ON wp.id = wp_optionview.wpid
2253 WHERE wp.disable_health_check <> 1 AND wp.offline_check_result = 1 AND ( ' . $where_global_threshold . ' OR' . $where_site_threshold . ' ) AND wp_sync.health_site_noticed = 0 ' .
2254 $where,
2255 OBJECT
2256 );
2257 }
2258
2259 /**
2260 * Get websites offline status.
2261 *
2262 * @return array Sites with offline status.
2263 */
2264 public function get_websites_offline_check_status() {
2265 $where = $this->get_sql_where_allow_access_sites( 'wp' );
2266 $extra_view = array( 'settings_notification_emails' );
2267
2268 return $this->wpdb->get_results(
2269 'SELECT wp.*,wp_optionview.* FROM ' . $this->table_name( 'wp' ) . ' wp
2270 JOIN ' . $this->get_option_view( $extra_view ) . ' wp_optionview ON wp.id = wp_optionview.wpid
2271 WHERE wp.disable_status_check <> 1 AND wp.offline_check_result = -1' . // offline checked status.
2272 $where,
2273 OBJECT
2274 );
2275 }
2276
2277 /**
2278 * Get DB Sites.
2279 *
2280 * @since 4.6
2281 *
2282 * @param mixed $params params.
2283 *
2284 * @return array $dbwebsites.
2285 */
2286 public static function get_db_sites( $params = array() ) { // phpcs:ignore -- NOSONAR - complex.
2287
2288 $dbwebsites = array();
2289
2290 $data_fields = MainWP_System_Utility::get_default_map_site_fields();
2291 $data_fields[] = 'verify_certificate';
2292 $data_fields[] = 'client_id';
2293
2294 $fields = isset( $params['fields'] ) && is_array( $params['fields'] ) ? $params['fields'] : array();
2295 $sites = isset( $params['sites'] ) && is_array( $params['sites'] ) ? $params['sites'] : array();
2296 $groups = isset( $params['groups'] ) && is_array( $params['groups'] ) ? $params['groups'] : array();
2297 $clients = isset( $params['clients'] ) && is_array( $params['clients'] ) ? $params['clients'] : array();
2298
2299 if ( is_array( $fields ) ) {
2300 foreach ( $fields as $field_indx => $field_name ) {
2301
2302 $get_field = $field_name;
2303 if ( is_numeric( $get_field ) || is_bool( $get_field ) ) { // to compatible fix.
2304 $get_field = $field_indx;
2305 }
2306
2307 if ( in_array( $get_field, static::$possible_options ) && ! in_array( $get_field, $data_fields ) ) {
2308 $data_fields[] = $get_field;
2309 }
2310 }
2311 }
2312
2313 if ( ! empty( $sites ) ) {
2314 foreach ( $sites as $v ) {
2315 if ( MainWP_Utility::ctype_digit( $v ) ) {
2316 $website = static::instance()->get_website_by_id( $v );
2317 if ( empty( $website ) ) {
2318 continue;
2319 }
2320 $dbwebsites[ $website->id ] = MainWP_Utility::map_site( $website, $data_fields );
2321 }
2322 }
2323 }
2324
2325 if ( ! empty( $groups ) ) {
2326 foreach ( $groups as $v ) {
2327 if ( MainWP_Utility::ctype_digit( $v ) ) {
2328 $websites = static::instance()->query( static::instance()->get_sql_websites_by_group_id( $v ) );
2329 while ( $websites && ( $website = static::fetch_object( $websites ) ) ) {
2330 $dbwebsites[ $website->id ] = MainWP_Utility::map_site( $website, $data_fields );
2331 }
2332 static::free_result( $websites );
2333 }
2334 }
2335 }
2336
2337 $params = array(
2338 'full_data' => true,
2339 );
2340 $client_sites = MainWP_DB_Client::instance()->get_websites_by_client_ids( $clients, $params );
2341 if ( $client_sites ) {
2342 foreach ( $client_sites as $website ) {
2343 $dbwebsites[ $website->id ] = MainWP_Utility::map_site( $website, $data_fields );
2344 }
2345 }
2346 return $dbwebsites;
2347 }
2348
2349 /**
2350 * Get Sites.
2351 *
2352 * @param int $websiteid The id of the child site you wish to retrieve.
2353 * @param bool $for_manager Check Team Control.
2354 * @param array $others Array of others.
2355 *
2356 * @return array $output Array of content to output.
2357 *
2358 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
2359 * @uses \MainWP\Dashboard\MainWP_Utility::get_nice_url()
2360 */
2361 public function get_sites( $websiteid = null, $for_manager = false, $others = array() ) { // phpcs:ignore -- NOSONAR - not quite complex function.
2362
2363 if ( ! is_array( $others ) ) {
2364 $others = array();
2365 }
2366
2367 $search_site = null;
2368 $orderBy = 'wp.url';
2369 $offset = false;
2370 $rowcount = false;
2371 $extraWhere = null;
2372
2373 if ( isset( $websiteid ) && ( null !== $websiteid ) ) {
2374 $website = static::instance()->get_website_by_id( $websiteid );
2375
2376 if ( ! MainWP_System_Utility::can_edit_website( $website ) ) {
2377 return false;
2378 }
2379
2380 if ( ! mainwp_current_user_have_right( 'site', $websiteid ) ) {
2381 return false;
2382 }
2383
2384 return array(
2385 array(
2386 'id' => $websiteid,
2387 'url' => MainWP_Utility::get_nice_url( $website->url, true ),
2388 'name' => $website->name,
2389 'totalsize' => $website->totalsize,
2390 'sync_errors' => $website->sync_errors,
2391 ),
2392 );
2393 } else {
2394 if ( isset( $others['orderby'] ) ) {
2395 if ( 'site' === $others['orderby'] ) {
2396 $orderBy = 'wp.name ' . ( 'asc' === $others['order'] ? 'asc' : 'desc' );
2397 } elseif ( 'url' === $others['orderby'] ) {
2398 $orderBy = 'wp.url ' . ( 'asc' === $others['order'] ? 'asc' : 'desc' );
2399 }
2400 }
2401 if ( isset( $others['search'] ) ) {
2402 $search_site = trim( $others['search'] );
2403 }
2404
2405 if ( is_array( $others ) && isset( $others['plugins_slug'] ) ) {
2406 $slugs = explode( ',', $others['plugins_slug'] );
2407 $extraWhere = '';
2408 foreach ( $slugs as $slug ) {
2409 $slug = wp_json_encode( $slug );
2410 $slug = trim( $slug, '"' );
2411 $slug = str_replace( '\\', '.', $slug );
2412 $extraWhere .= ' wp.plugins REGEXP "' . $slug . '" OR';
2413 }
2414 $extraWhere = trim( rtrim( $extraWhere, 'OR' ) );
2415
2416 if ( '' === $extraWhere ) {
2417 $extraWhere = null;
2418 } else {
2419 $extraWhere = '(' . $extraWhere . ')';
2420 }
2421 }
2422 }
2423
2424 $totalRecords = '';
2425
2426 if ( isset( $others['per_page'] ) && ! empty( $others['per_page'] ) ) {
2427 $sql = static::instance()->get_sql_websites_for_current_user( false, $search_site, $orderBy, false, false, $extraWhere, $for_manager );
2428 $websites_total = static::instance()->query( $sql );
2429 $totalRecords = ( $websites_total ? static::num_rows( $websites_total ) : 0 );
2430
2431 if ( $websites_total ) {
2432 static::free_result( $websites_total );
2433 }
2434
2435 $rowcount = absint( $others['per_page'] );
2436 $pagenum = isset( $others['paged'] ) ? absint( $others['paged'] ) : 0;
2437 if ( $pagenum > $totalRecords ) {
2438 $pagenum = $totalRecords;
2439 }
2440 $pagenum = max( 1, $pagenum );
2441 $offset = ( $pagenum - 1 ) * $rowcount;
2442
2443 }
2444
2445 $sql = static::instance()->get_sql_websites_for_current_user( false, $search_site, $orderBy, $offset, $rowcount, $extraWhere, $for_manager );
2446 $websites = static::instance()->query( $sql );
2447
2448 $output = array();
2449 while ( $websites && ( $website = static::fetch_object( $websites ) ) ) {
2450 $re = array(
2451 'id' => $website->id,
2452 'url' => MainWP_Utility::get_nice_url( $website->url, true ),
2453 'name' => $website->name,
2454 'totalsize' => $website->totalsize,
2455 'sync_errors' => $website->sync_errors,
2456 'client_id' => $website->client_id,
2457 );
2458
2459 if ( 0 < $totalRecords ) {
2460 $re['totalRecords'] = $totalRecords;
2461 $totalRecords = 0;
2462 }
2463
2464 $output[] = $re;
2465 }
2466 static::free_result( $websites );
2467
2468 return $output;
2469 }
2470
2471 /**
2472 * Method get_lookup_items().
2473 *
2474 * Get bulk lookup items to reduce number of db queries.
2475 *
2476 * @param string $item_name lookup item name.
2477 * @param int $item_id lookup item id.
2478 * @param string $obj_name loockup object name.
2479 *
2480 * @return mixed Result
2481 */
2482 public function get_lookup_items( $item_name, $item_id, $obj_name ) {
2483 return $this->wpdb->get_results( $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'lookup_item_objects' ) . ' WHERE item_name=%s AND item_id = %d AND object_name = %s', $item_name, $item_id, $obj_name ) ); //phpcs:ignore -- ok.
2484 }
2485
2486 /**
2487 * Method insert_lookup_item().
2488 *
2489 * Insert lookup item, need checks existed before to prevent double values.
2490 *
2491 * @param string $item_name item name.
2492 * @param int $item_id item id.
2493 * @param string $obj_name object name.
2494 * @param int $obj_id object id.
2495 *
2496 * @return mixed Result
2497 */
2498 public function insert_lookup_item( $item_name, $item_id, $obj_name, $obj_id ) {
2499 if ( empty( $item_name ) || empty( $item_id ) || empty( $obj_name ) || empty( $obj_id ) ) {
2500 return false;
2501 }
2502 $data = array(
2503 'item_name' => 'cost',
2504 'item_id' => $item_id,
2505 'object_name' => $obj_name,
2506 'object_id' => $obj_id,
2507 );
2508 $this->wpdb->insert( $this->table_name( 'lookup_item_objects' ), $data );
2509 return $this->wpdb->insert_id; // must return lookup id.
2510 }
2511
2512 /**
2513 * Method delete_lookup_items().
2514 *
2515 * Delete bulk lookup items by lookup ids or object names with item id and item name, to reduce number of db queries.
2516 *
2517 * @param string $by Delete by.
2518 * @param array $params params.
2519 *
2520 * @return mixed Result
2521 */
2522 public function delete_lookup_items( $by = 'lookup_id', $params = array() ) { // phpcs:ignore -- NOSONAR - complex.
2523 if ( ! is_array( $params ) ) {
2524 return false;
2525 }
2526
2527 $lookup_ids = isset( $params['lookup_ids'] ) ? $params['lookup_ids'] : null;
2528 $item_id = isset( $params['item_id'] ) ? $params['item_id'] : null;
2529 $object_id = isset( $params['object_id'] ) ? $params['object_id'] : null;
2530 $item_name = isset( $params['item_name'] ) ? $params['item_name'] : null;
2531 $obj_names = isset( $params['object_names'] ) ? $params['object_names'] : null;
2532
2533 if ( 'object_name' === $by ) {
2534 if ( empty( $item_id ) || empty( $item_name ) ) {
2535 return false;
2536 }
2537
2538 $obj_names = $this->escape_array( $obj_names );
2539 if ( ! empty( $obj_names ) ) {
2540 $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'lookup_item_objects' ) . ' WHERE item_name = %s AND item_id = %d AND object_name IN ("' . implode( '","', $obj_names ) . '") ', $item_name, $item_id ) ); //phpcs:ignore -- ok.
2541 return true;
2542 }
2543 } elseif ( 'object_id' === $by ) {
2544 if ( empty( $object_id ) || empty( $item_name ) || empty( $obj_names ) ) {
2545 return false;
2546 }
2547
2548 $obj_names = $this->escape_array( $obj_names );
2549 if ( ! empty( $obj_names ) ) {
2550 $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $this->table_name( 'lookup_item_objects' ) . ' WHERE item_name = %s AND object_id = %d AND object_name IN ("' . implode( '","', $obj_names ) . '") ', $item_name, $object_id ) ); //phpcs:ignore -- ok.
2551 return true;
2552 }
2553 } elseif ( 'lookup_id' === $by ) {
2554 if ( empty( $lookup_ids ) ) {
2555 return false;
2556 }
2557 if ( is_numeric( $lookup_ids ) ) {
2558 $lookup_ids = array( $lookup_ids );
2559 } elseif ( is_array( $lookup_ids ) ) {
2560 $lookup_ids = MainWP_Utility::array_numeric_filter( $lookup_ids );
2561 } else {
2562 return false;
2563 }
2564 $this->wpdb->query( 'DELETE FROM ' . $this->table_name( 'lookup_item_objects' ) . ' WHERE lookup_id IN (' . implode( ',', $lookup_ids ) . ') ' ); //phpcs:ignore -- ok.
2565 return true;
2566 }
2567 return false;
2568 }
2569 }
2570