PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.1.3
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.1.3
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.1.3, at pages/page-mainwp-manage-sites-handler.php

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