PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.2
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
mainwp / pages / page-mainwp-manage-sites-handler.php

page-mainwp-manage-sites-handler.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.2.2, at pages/page-mainwp-manage-sites-handler.php

535 lines 21.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Manage Sites Handler.
4 *
5 * @package MainWP/Dashboard
6 */
7
8 namespace MainWP\Dashboard;
9
10 // Exit if accessed directly.
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 /**
16 * Class MainWP_Manage_Sites_Handler
17 *
18 * @package MainWP\Dashboard
19 */
20 class MainWP_Manage_Sites_Handler { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
21
22 /**
23 * Get Class Name
24 *
25 * @return string __CLASS__
26 */
27 public static function get_class_name() {
28 return __CLASS__;
29 }
30
31 /**
32 * Method check_site()
33 *
34 * Check to add site.
35 *
36 * @return mixed send json encode data
37 *
38 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
39 * @uses \MainWP\Dashboard\MainWP_Utility::esc_content()
40 */
41 public static function check_site() { // phpcs:ignore -- NOSONAR - complex.
42 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
43 $url = isset( $_POST['url'] ) ? sanitize_text_field( wp_unslash( $_POST['url'] ) ) : '';
44 $url = urldecode( $url );
45
46 $is_valid = static::is_valid_wp_url( $url );
47
48 if ( ! $is_valid ) { // to fix: valid url to check.
49 die( wp_json_encode( array( 'error' => esc_html__( 'Invalid URL! Please enter valid URL to the Site URL field.', 'mainwp' ) ) ) );
50 }
51
52 $website = MainWP_DB::instance()->get_websites_by_url( $url );
53 $ret = array();
54
55 if ( MainWP_System_Utility::can_edit_website( $website ) ) {
56 $ret['response'] = esc_html__( 'ERROR Site is already connected to your MainWP Dashboard.', 'mainwp' );
57 } else {
58 try {
59
60 $cur_id = MainWP_System_Utility::get_current_wpid();
61 if ( empty( $cur_id ) && is_object( $website ) && isset( $website->id ) ) {
62 MainWP_System_Utility::set_current_wpid( $website->id );
63 }
64
65 MainWP_Logger::instance()->log_execution_sync( 'init', '', $website );
66
67 $verify_cert = empty( $_POST['verify_certificate'] ) ? false : intval( $_POST['verify_certificate'] );
68 $ssl_version = empty( $_POST['ssl_version'] ) ? 0 : intval( $_POST['ssl_version'] );
69 $force_use_ipv4 = apply_filters( 'mainwp_manage_sites_force_use_ipv4', null, $url );
70 $http_user = ( isset( $_POST['http_user'] ) ? sanitize_text_field( wp_unslash( $_POST['http_user'] ) ) : '' );
71 $http_pass = ( isset( $_POST['http_pass'] ) ? wp_unslash( $_POST['http_pass'] ) : '' );
72 $admin = ( isset( $_POST['admin'] ) ? sanitize_text_field( wp_unslash( $_POST['admin'] ) ) : '' );
73
74 $output = array();
75
76 $visit_track_id = MainWP_Execution_Helper::execute_call_track( 'start_point', $website );
77
78 $information = MainWP_Connect::fetch_url_not_authed(
79 $url,
80 $admin,
81 'stats',
82 null,
83 false,
84 $verify_cert,
85 $http_user,
86 $http_pass,
87 $ssl_version,
88 array(
89 'force_use_ipv4' => $force_use_ipv4,
90 ),
91 $output
92 ); // Fetch the stats with the given admin name.
93
94 MainWP_Execution_Helper::execute_call_track( 'end_point', $website, $visit_track_id, 'visit site' );
95
96 if ( isset( $information['wpversion'] ) ) {
97 $ret['response'] = 'OK';
98 } elseif ( isset( $information['error'] ) ) {
99 $ret['response'] = 'ERROR ' . MainWP_Utility::esc_content( $information['error'] );
100 } else {
101 $ret['response'] = 'ERROR';
102 $ret['resp_data'] = isset( $output['fetch_data'] ) ? $output['fetch_data'] : '';
103 }
104 } catch ( MainWP_Exception $e ) {
105 $ret['response'] = $e->getMessage();
106 $ret['resp_data'] = $e->get_data();
107 }
108 }
109 $ret['check_me'] = ( isset( $_POST['check_me'] ) ? intval( $_POST['check_me'] ) : null );
110 do_action( 'mainwp_check_site_result', $ret, $_POST );
111 die( wp_json_encode( $ret ) );
112 // phpcs:enable
113 }
114
115 /**
116 * Method is_valid_wp_url().
117 *
118 * @param string $url Site url.
119 *
120 * @return bool Valid or not.
121 */
122 public static function is_valid_wp_url( $url ) {
123
124 if ( empty( $url ) ) {
125 return false;
126 }
127
128 $valid = true;
129
130 $info = wp_parse_url( $url );
131
132 if ( is_array( $info ) && ! empty( $info['port'] ) && ( 21 === intval( $info['port'] ) || 22 === intval( $info['port'] ) ) ) { // port 21, 22.
133 $valid = false;
134 }
135
136 if ( $valid && ( ( 0 !== strpos( $url, 'http://' ) && 0 !== strpos( $url, 'https://' ) ) || false !== strpos( $url, '?=' ) ) ) { // to fix: valid url to check.
137 $valid = false;
138 }
139
140 return $valid;
141 }
142
143
144 /**
145 * Method reconnect_site()
146 *
147 * Try to reconnect to Child Site.
148 *
149 * @throws \MainWP_Exception Error message.
150 *
151 * @uses \MainWP\Dashboard\MainWP_Manage_DB::get_website_by_id()
152 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::m_reconnect_site()
153 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
154 */
155 public static function reconnect_site() { //phpcs:ignore -- NOSONAR - complexity.
156 $siteId = isset( $_POST['siteid'] ) ? intval( $_POST['siteid'] ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Missing
157
158 try {
159 if ( MainWP_Utility::ctype_digit( $siteId ) ) {
160 $website = MainWP_DB::instance()->get_website_by_id( $siteId );
161
162 $params = array();
163 $sync_first = true;
164 if ( is_array( $params ) && ! empty( $_POST['managesites_add_wpadmin'] ) && ! empty( $_POST['managesites_add_adminpwd'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
165 $params['wpadmin'] = isset( $_POST['managesites_add_wpadmin'] ) ? sanitize_text_field( wp_unslash( $_POST['managesites_add_wpadmin'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
166 $params['adminpwd'] = isset( $_POST['managesites_add_adminpwd'] ) ? wp_unslash( $_POST['managesites_add_adminpwd'] ) : ''; //phpcs:ignore -- NOSONAR - requires urlencoded passwd, do not sanitize for specical chars.
167 $sync_first = false; // reconnect use user's passwd so do not sync first.
168 }
169
170 MainWP_Manage_Sites_View::m_reconnect_site( $website, $sync_first, $params );
171 } else {
172 throw new MainWP_Exception( esc_html__( 'Site could not be connected. Please check the Status page and be sure that all system requirments pass.', 'mainwp' ) );
173 }
174 } catch ( \Exception $e ) {
175 $msg = $e->getMessage();
176 $arr_msg = MainWP_Utility::parse_html_error_message( $msg );
177
178 if ( $e instanceof MainWP_Exception ) {
179 $error_code = $e->get_message_error_code();
180 if ( 'reconnect_failed' === $error_code ) {
181 die( $error_code ); // phpcs:ignore WordPress.Security.EscapeOutput
182 }
183 }
184
185 if ( is_array( $arr_msg ) ) {
186 die( 'ERROR ' . wp_json_encode( $arr_msg ) ); // phpcs:ignore WordPress.Security.EscapeOutput
187 }
188 die( 'ERROR ' . $msg ); // phpcs:ignore WordPress.Security.EscapeOutput
189 }
190
191 die( esc_html__( 'Site has been reconnected successfully!', 'mainwp' ) );
192 }
193
194
195 /**
196 * Method add_site()
197 *
198 * Add new Child Site.
199 *
200 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::add_site()
201 */
202 public static function add_site() {
203 $ret = array();
204 $error = '';
205 $message = '';
206 $site_id = 0;
207 $output = array();
208
209 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
210 if ( isset( $_POST['managesites_add_wpurl'] ) && isset( $_POST['managesites_add_wpadmin'] ) ) {
211 // Check if already in DB.
212 $website = MainWP_DB::instance()->get_websites_by_url( sanitize_text_field( wp_unslash( $_POST['managesites_add_wpurl'] ) ) );
213 list( $message, $error, $site_id ) = MainWP_Manage_Sites_View::add_site( $website, $output );
214 }
215
216 $ret['add_me'] = ( isset( $_POST['add_me'] ) ? intval( $_POST['add_me'] ) : null );
217 if ( '' !== $error ) {
218 $ret['response'] = 'ERROR ' . $error;
219 die( wp_json_encode( $ret ) );
220 }
221 $ret['response'] = $message;
222 $ret['siteid'] = $site_id;
223
224 if ( isset( $output['fetch_data'] ) ) {
225 $ret['resp_data'] = $output['fetch_data'];
226 }
227 // phpcs:enable
228
229 if ( 1 === MainWP_DB::instance()->get_websites_count() ) {
230 $ret['redirectUrl'] = esc_url( admin_url( 'admin.php?page=managesites' ) );
231 }
232
233 die( wp_json_encode( $ret ) );
234 }
235
236 /**
237 * Method rest_api_add_site().
238 *
239 * Rest API add website.
240 *
241 * @param array $data fields array.
242 * @param array $output Output array.
243 *
244 * $data fields.
245 * 'url'.
246 * 'name'.
247 * 'admin'.
248 * 'uniqueid'.
249 * 'ssl_verify'.
250 * 'force_use_ipv4'.
251 * 'ssl_version'.
252 * 'http_user'.
253 * 'http_pass'.
254 * 'groupids'.
255 *
256 * @return mixed Results.
257 */
258 public static function rest_api_add_site( $data, &$output = array() ) {
259 $params['url'] = isset( $data['url'] ) ? sanitize_text_field( wp_unslash( $data['url'] ) ) : '';
260 $params['name'] = isset( $data['name'] ) ? sanitize_text_field( wp_unslash( $data['name'] ) ) : '';
261 $params['wpadmin'] = isset( $data['admin'] ) ? sanitize_text_field( wp_unslash( $data['admin'] ) ) : '';
262 $params['adminpwd'] = isset( $data['adminpassword'] ) ? wp_unslash( $data['adminpassword'] ) : '';
263 $params['unique_id'] = isset( $data['uniqueid'] ) ? sanitize_text_field( wp_unslash( $data['uniqueid'] ) ) : '';
264 $params['ssl_verify'] = empty( $data['ssl_verify'] ) ? false : intval( $data['ssl_verify'] );
265 $params['force_use_ipv4'] = ( ! isset( $data['force_use_ipv4'] ) || ( empty( $data['force_use_ipv4'] ) && ( '0' !== $data['force_use_ipv4'] ) ) ? null : intval( $data['force_use_ipv4'] ) );
266 $params['http_user'] = isset( $data['http_user'] ) ? sanitize_text_field( wp_unslash( $data['http_user'] ) ) : '';
267 $params['http_pass'] = isset( $data['http_pass'] ) ? wp_unslash( $data['http_pass'] ) : '';
268 $params['groupids'] = isset( $data['groupids'] ) && ! empty( $data['groupids'] ) ? explode( ',', sanitize_text_field( wp_unslash( $data['groupids'] ) ) ) : array();
269 $website = MainWP_DB::instance()->get_websites_by_url( $params['url'] );
270 list( $message, $error, $site_id ) = MainWP_Manage_Sites_View::add_wp_site( $website, $params, $output );
271
272 if ( '' !== $error ) {
273 return array( 'error' => $error );
274 }
275 return array(
276 'response' => $message,
277 'siteid' => $site_id,
278 );
279 }
280
281 /**
282 * Method apply_plugin_settings()
283 *
284 * Apply plugin settings.
285 */
286 public static function apply_plugin_settings() {
287 $site_id = isset( $_POST['siteId'] ) ? intval( $_POST['siteId'] ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Missing
288 $ext_dir_slug = isset( $_POST['ext_dir_slug'] ) ? sanitize_text_field( wp_unslash( $_POST['ext_dir_slug'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
289 if ( empty( $site_id ) ) {
290 die( wp_json_encode( array( 'error' => esc_html__( 'Invalid site ID. Please try again.', 'mainwp' ) ) ) );
291 }
292
293 /**
294 * Apply plugin settings
295 *
296 * Fires to apply certain plugin settigns automatically while adding a new site.
297 *
298 * @param int $site_id Child site ID.
299 *
300 * @since Unknown
301 */
302 do_action( 'mainwp_applypluginsettings_' . $ext_dir_slug, $site_id );
303 die( wp_json_encode( array( 'error' => esc_html__( 'Undefined error occurred. Please try again.', 'mainwp' ) ) ) );
304 }
305
306 /**
307 * Method save_note()
308 *
309 * Save Child Site Note.
310 *
311 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
312 * @uses \MainWP\Dashboard\MainWP_Utility::esc_content()
313 */
314 public static function save_note() {
315 if ( isset( $_POST['websiteid'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
316 $website = MainWP_DB::instance()->get_website_by_id( intval( $_POST['websiteid'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
317 if ( MainWP_System_Utility::can_edit_website( $website ) ) {
318 $note = isset( $_POST['note'] ) ? wp_unslash( $_POST['note'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
319 $esc_note = MainWP_Utility::esc_content( $note );
320 MainWP_DB_Common::instance()->update_note( $website->id, $esc_note );
321
322 die(
323 wp_json_encode(
324 array(
325 'result' => 'SUCCESS',
326 'esc_note_content' => $esc_note,
327 )
328 )
329 );
330 } else {
331 die( wp_json_encode( array( 'error' => esc_html__( 'Are you sure this is your website?', 'mainwp' ) ) ) );
332 }
333 }
334 die( wp_json_encode( array( 'undefined_error' => true ) ) );
335 }
336
337 /**
338 * Method remove_wp_site()
339 *
340 * Try to remove Child Site.
341 *
342 * @throws MainWP_Extra_Exception Error message.
343 *
344 * @param intt $site_id The Site ID.
345 *
346 * @return mixed result.
347 */
348 public static function remove_wp_site( $site_id ) {
349 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
350 if ( isset( $site_id ) ) {
351 $info = static::remove_website( intval( $site_id ) );
352 $error = is_array( $info ) && isset( $info['error'] ) ? $info['error'] : '';
353 if ( 'NOMAINWP' === $error ) {
354 $error = esc_html__( 'Be sure to deactivate the child plugin on the child site to avoid potential security issues.', 'mainwp' );
355 }
356 if ( '' !== $error ) {
357 throw new MainWP_Extra_Exception( 'mainwp_remove_site_error', $error ); //phpcs:ignore -- ok.
358 } elseif ( is_array( $info ) && isset( $info['deactivated'] ) ) {
359 $result = array( 'result' => 'success' );
360 } elseif ( is_array( $info ) && isset( $info['removed'] ) ) {
361 $result = array( 'result' => 'removed' );
362 } else {
363 throw new MainWP_Extra_Exception( 'mainwp_remove_site_error', esc_html__( 'Undefined error. Please try again.', 'mainwp' ) );
364 }
365 return $result;
366 }
367
368 return false;
369 }
370
371 /**
372 * Method remove_site()
373 *
374 * Try to remove Child Site.
375 */
376 public static function remove_site() {
377 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
378 if ( isset( $_POST['id'] ) ) {
379
380 $result = static::remove_website( intval( $_POST['id'] ) );
381 $error = is_array( $result ) && isset( $result['error'] ) ? $result['error'] : '';
382
383 if ( 'NOMAINWP' === $error ) {
384 $error = esc_html__( 'Be sure to deactivate the child plugin on the child site to avoid potential security issues.', 'mainwp' );
385 }
386
387 $resp = array(
388 'removed_site' => ! empty( $result['removed_site'] ),
389 );
390
391 if ( '' !== $error ) {
392 $resp['error'] = esc_html( $error );
393 } elseif ( is_array( $result ) && isset( $result['deactivated'] ) ) {
394 $resp['result'] = 'SUCCESS';
395 } elseif ( is_array( $result ) && isset( $result['removed'] ) ) {
396 $resp['result'] = 'REMOVED';
397 } else {
398 $resp['undefined_error'] = true;
399 }
400 die( wp_json_encode( $resp ) );
401 }
402 // phpcs:enable
403 die( wp_json_encode( array( 'result' => 'NOSITE' ) ) );
404 }
405
406 /**
407 * Method handle remove_site()
408 *
409 * Try to remove Child Site.
410 *
411 * @param object|int $site object or Child site ID.
412 *
413 * @return mixed|false result
414 * @throws \MainWP_Exception Error message.
415 *
416 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
417 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system()
418 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_icons_dir()
419 */
420 public static function remove_website( $site ) { //phpcs:ignore -- NOSONAR - complex.
421
422 if ( is_numeric( $site ) ) {
423 $website = MainWP_DB::instance()->get_website_by_id( intval( $site ) );
424 } else {
425 $website = $site;
426 }
427
428 $information = array();
429
430 if ( MainWP_System_Utility::can_edit_website( $website ) ) {
431
432 $is_demo_wp = MainWP_Demo_Handle::get_instance()->is_demo_website( $website );
433
434 /**
435 * Deactive child plugin on live site only,
436 * DO NOT deactive child on staging site, it will deactive child plugin of source site.
437 */
438 if ( ! $website->is_staging && ! $is_demo_wp ) {
439 try {
440 $information = MainWP_Connect::fetch_url_authed(
441 $website,
442 'deactivate',
443 );
444 } catch ( MainWP_Exception $e ) {
445 $information['error'] = $e->getMessage();
446 }
447 } else {
448 $information['removed'] = true;
449 }
450
451 // Delete icon file.
452 $favi = MainWP_DB::instance()->get_website_option( $website, 'favi_icon', '' );
453 if ( ! empty( $favi ) && ( false !== strpos( $favi, 'favi-' . $website->id . '-' ) ) ) {
454
455 MainWP_System_Utility::get_wp_file_system();
456
457 /**
458 * WordPress files system object.
459 *
460 * @global object
461 */
462 global $wp_filesystem;
463
464 $dirs = MainWP_System_Utility::get_icons_dir();
465 if ( $wp_filesystem->exists( $dirs[0] . $favi ) ) {
466 $wp_filesystem->delete( $dirs[0] . $favi );
467 }
468 }
469
470 // Remove from DB.
471 $removed = MainWP_DB::instance()->remove_website( $website->id );
472
473 if ( $removed ) {
474 $information['removed_site'] = true;
475 }
476
477 /**
478 * Delete Child Sites
479 *
480 * Fires after a child site has been removed from MainWP Dashboard
481 *
482 * @param object $website Object containing child site data.
483 *
484 * @since 3.4
485 */
486 ! $is_demo_wp && do_action( 'mainwp_delete_site', $website );
487
488 /**
489 * Fires immediately after a new website is deleted.
490 *
491 * @since 4.5.1.1
492 *
493 * @param object $website website data.
494 */
495 ! $is_demo_wp && do_action( 'mainwp_site_deleted', $website );
496
497 }
498
499 return $information ? $information : false;
500 }
501
502 /**
503 * Method update_child_site_value()
504 *
505 * Update Child Site ID.
506 *
507 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
508 */
509 public static function update_child_site_value() {
510 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
511 if ( isset( $_POST['site_id'] ) ) {
512 $website = MainWP_DB::instance()->get_website_by_id( intval( $_POST['site_id'] ) );
513 if ( MainWP_System_Utility::can_edit_website( $website ) ) {
514 $error = '';
515 $uniqueId = isset( $_POST['unique_id'] ) ? sanitize_text_field( wp_unslash( $_POST['unique_id'] ) ) : '';
516 try {
517 $information = MainWP_Connect::fetch_url_authed( $website, 'update_values', array( 'uniqueId' => $uniqueId ) );
518 } catch ( MainWP_Exception $e ) {
519 $error = $e->getMessage();
520 }
521
522 if ( '' !== $error ) {
523 die( wp_json_encode( array( 'error' => $error ) ) );
524 } elseif ( isset( $information['result'] ) && ( 'ok' === $information['result'] ) ) {
525 die( wp_json_encode( array( 'result' => 'SUCCESS' ) ) );
526 } else {
527 die( wp_json_encode( array( 'undefined_error' => true ) ) );
528 }
529 }
530 }
531 // phpcs:enable
532 die( wp_json_encode( array( 'error' => 'NO_SIDE_ID' ) ) );
533 }
534 }
535