PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 4.6.0.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v4.6.0.1
6.2.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 All 156 releases
mainwp / pages / page-mainwp-install-bulk.php

page-mainwp-install-bulk.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 4.6.0.1, at pages/page-mainwp-install-bulk.php

677 lines 22.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * This file handles all of the Bulk Installation Methods
4 * for Plugins & Themes.
5 *
6 * @package MainWP/Dashboard
7 */
8
9 namespace MainWP\Dashboard;
10
11 /**
12 * Class MainWP_Install_Bulk
13 *
14 * @used-by MainWP_Plugins::InstallPlugins
15 * @used-by MainWP_Themes::InstallThemes
16 */
17 class MainWP_Install_Bulk {
18
19 /**
20 * Get Class Name
21 *
22 * @return string __CLASS__
23 *
24 * @uses self::init()
25 */
26 public static function get_class_name() {
27 return __CLASS__;
28 }
29
30 /**
31 * Method init()
32 *
33 * Instantiate the main page
34 *
35 * Has to be called in System constructor,
36 * adds handling for the main page.
37 */
38 public static function init() {
39 add_action( 'admin_init', array( self::get_class_name(), 'admin_init' ) );
40 }
41
42 /**
43 * Method admin_init()
44 *
45 * Handles the uploading of a file.
46 *
47 * @uses \MainWP\Dashboard\MainWP_QQ2_File_Uploader
48 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_specific_dir()
49 */
50 public static function admin_init() {
51 if ( isset( $_REQUEST['mainwp_do'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
52 if ( isset( $_REQUEST['qq_nonce'] ) && 'MainWP_Install_Bulk-uploadfile' === $_REQUEST['mainwp_do'] ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
53 do_action( 'mainwp_secure_request', 'qq_nonce', 'qq_nonce' );
54 $allowedExtensions = array( 'zip' ); // Only zip allowed.
55 // max file size in bytes.
56 $sizeLimit = 2 * 1024 * 1024; // 2MB = max allowed.
57
58 $uploader = new MainWP_QQ2_File_Uploader( $allowedExtensions, $sizeLimit );
59 $path = MainWP_System_Utility::get_mainwp_specific_dir( 'bulk' );
60
61 $result = $uploader->handle_upload( $path, true );
62 // to pass data through iframe you will need to encode all html tags.
63 die( htmlspecialchars( wp_json_encode( $result ), ENT_NOQUOTES ) ); // phpcs:ignore WordPress.Security.EscapeOutput
64 }
65 }
66 }
67
68
69 /**
70 * Method render_upload()
71 *
72 * Renders the upload sub part.
73 *
74 * @param string $type Plugin|Theme Type of upload.
75 */
76 public static function render_upload( $type ) {
77 $title = ( 'plugin' === $type ) ? 'Plugins' : 'Themes';
78 $favorites_enabled = is_plugin_active( 'mainwp-favorites-extension/mainwp-favorites-extension.php' );
79 $cls = $favorites_enabled ? 'favorites-extension-enabled ' : '';
80 $cls .= ( 'plugin' === $type ) ? 'qq-upload-plugins' : '';
81 ?>
82 <div class="ui secondary center aligned padded segment">
83 <h2 class="ui icon header">
84 <i class="file archive outline icon"></i>
85 <div class="content">
86 <?php esc_html_e( 'Upload .zip File', 'mainwp' ); ?>
87 <div class="sub header"><?php esc_html_e( 'If you have', 'mainwp' ); ?> <?php echo esc_html( strtolower( $title ) ); ?> <?php esc_html_e( 'in a .zip format, you may install it by uploading it here.', 'mainwp' ); ?></div>
88 </div>
89 </h2>
90 <div class="ui divider"></div>
91 <div id="mainwp-file-uploader" class="<?php echo esc_attr( $cls ); ?>" >
92 <noscript>
93 <div class="ui message red"><?php esc_html_e( 'Please enable JavaScript to use file uploader.', 'mainwp' ); ?></div>
94 </noscript>
95 </div>
96 <script>
97 function createUploader() {
98 var uploader = new qq.FileUploader( {
99 element: document.getElementById( 'mainwp-file-uploader' ),
100 action: location.href,
101 <?php
102 /**
103 * Uploader options
104 *
105 * Adds extra options to the bulk upload process as a support for the Favorites extension.
106 *
107 * @param string $type Determines if plugins or themes are being installed.
108 *
109 * @since Unknown
110 */
111 $extraOptions = apply_filters( 'mainwp_uploadbulk_uploader_options', '', $type );
112 $extraOptions = trim( $extraOptions );
113 $extraOptions = trim( trim( $extraOptions, ',' ) );
114 if ( '' !== $extraOptions ) {
115 echo wp_strip_all_tags( $extraOptions ) . ','; // phpcs:ignore WordPress.Security.EscapeOutput
116 }
117 ?>
118 params: {mainwp_do: 'MainWP_Install_Bulk-uploadfile', qq_nonce: '<?php echo esc_js( wp_create_nonce( 'qq_nonce' ) ); ?>' }
119 } );
120 }
121
122 // in your app create uploader as soon as the DOM is ready.
123 // don't wait for the window to load.
124 createUploader();
125 </script>
126 </div>
127 <?php
128 }
129
130 /**
131 * Method prepare_install()
132 *
133 * Prepare for the installation.
134 *
135 * Grab all the necessary data to make the upload and prepare json response.
136 *
137 * @uses \MainWP\Dashboard\MainWP_DB::query()
138 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
139 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_by_group_id()
140 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
141 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
142 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir()
143 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
144 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
145 */
146 public static function prepare_install() { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated.
147 include_once ABSPATH . '/wp-admin/includes/plugin-install.php';
148 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
149 if ( ! isset( $_POST['url'] ) ) {
150
151 $what = 'theme';
152 if ( isset( $_POST['type'] ) && 'plugin' === $_POST['type'] ) {
153 $what = 'plugin';
154 }
155 $api = MainWP_System_Utility::get_plugin_theme_info(
156 $what,
157 array(
158 'slug' => isset( $_POST['slug'] ) ? wp_unslash( $_POST['slug'] ) : '',
159 'fields' => array( 'sections' => false ),
160 )
161 ); // Save on a bit of bandwidth.
162
163 $url = $api->download_link;
164 $url = apply_filters( 'mainwp_prepare_install_download_url', $url, $_POST );
165 } else {
166 $url = isset( $_POST['url'] ) ? wp_unslash( $_POST['url'] ) : '';
167
168 $mwpDir = MainWP_System_Utility::get_mainwp_dir();
169 $mwpUrl = $mwpDir[1];
170 if ( stristr( $url, $mwpUrl ) ) {
171 $fullFile = $mwpDir[0] . str_replace( $mwpUrl, '', $url );
172 $url = admin_url( '?sig=' . MainWP_System_Utility::get_download_sig( $fullFile ) . '&mwpdl=' . rawurlencode( str_replace( $mwpDir[0], '', $fullFile ) ) );
173 }
174 }
175
176 $output = array();
177 $output['url'] = $url;
178 $output['sites'] = array();
179
180 $data_fields = array(
181 'id',
182 'url',
183 'name',
184 'sync_errors',
185 );
186
187 if ( isset( $_POST['selected_by'] ) && 'site' === $_POST['selected_by'] ) {
188 $selected_sites = isset( $_POST['selected_sites'] ) && is_array( $_POST['selected_sites'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_sites'] ) ) : array();
189 // Get sites.
190 foreach ( $selected_sites as $enc_id ) {
191 $websiteid = $enc_id;
192 if ( MainWP_Utility::ctype_digit( $websiteid ) ) {
193 $website = MainWP_DB::instance()->get_website_by_id( $websiteid );
194 $output['sites'][ $website->id ] = MainWP_Utility::map_site(
195 $website,
196 array(
197 'id',
198 'url',
199 'name',
200 )
201 );
202 }
203 }
204 } elseif ( isset( $_POST['selected_by'] ) && 'client' === $_POST['selected_by'] ) {
205 $selected_clients = isset( $_POST['selected_clients'] ) && is_array( $_POST['selected_clients'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_clients'] ) ) : array();
206 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids(
207 $selected_clients,
208 array(
209 'select_data' => $data_fields,
210 )
211 );
212 // Get sites.
213 if ( $websites ) {
214 foreach ( $websites as $website ) {
215 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
216 continue;
217 }
218 $output['sites'][ $website->id ] = MainWP_Utility::map_site(
219 $website,
220 array(
221 'id',
222 'url',
223 'name',
224 )
225 );
226 }
227 }
228 } else {
229 $selected_groups = ( isset( $_POST['selected_groups'] ) && is_array( $_POST['selected_groups'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_groups'] ) ) : array();
230 // Get sites from group.
231 foreach ( $selected_groups as $enc_id ) {
232 $groupid = $enc_id;
233 if ( MainWP_Utility::ctype_digit( $groupid ) ) {
234 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_id( $groupid ) );
235 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
236 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
237 continue;
238 }
239 $output['sites'][ $website->id ] = MainWP_Utility::map_site(
240 $website,
241 array(
242 'id',
243 'url',
244 'name',
245 )
246 );
247 }
248 MainWP_DB::free_result( $websites );
249 }
250 }
251 }
252 // phpcs:enable
253 mainwp_send_json_output( $output );
254 }
255
256
257 /**
258 * Method addition_post_data()
259 *
260 * Grab Post addition data.
261 *
262 * @param array $post_data Data for post.
263 *
264 * @return mixed $post_data Bulk post addition data.
265 */
266 public static function addition_post_data( &$post_data = array() ) {
267
268 /**
269 * Clean and Lock extension options
270 *
271 * Adds additional options related to Clean and Lock options in order to avoid conflicts when HTTP Basic auth is set.
272 *
273 * @since Unknown
274 */
275 $clear_and_lock_opts = apply_filters( 'mainwp_clear_and_lock_options', array() );
276 if ( isset( $post_data['url'] ) && false !== strpos( $post_data['url'], 'mwpdl' ) && false !== strpos( $post_data['url'], 'sig' ) ) {
277 if ( is_array( $clear_and_lock_opts ) && isset( $clear_and_lock_opts['wpadmin_user'] ) && ! empty( $clear_and_lock_opts['wpadmin_user'] ) && isset( $clear_and_lock_opts['wpadmin_passwd'] ) && ! empty( $clear_and_lock_opts['wpadmin_passwd'] ) ) {
278 $post_data['wpadmin_user'] = $clear_and_lock_opts['wpadmin_user'];
279 $post_data['wpadmin_passwd'] = $clear_and_lock_opts['wpadmin_passwd'];
280 }
281 }
282 return $post_data;
283 }
284
285 /**
286 * Perform Install.
287 *
288 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
289 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
290 * @uses \MainWP\Dashboard\MainWP_Utility::end_session()
291 */
292 public static function perform_install() {
293 MainWP_Utility::end_session();
294
295 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
296 // Fetch info.
297 $type = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '';
298 $post_data = array(
299 'type' => $type,
300 );
301 if ( isset( $_POST['activatePlugin'] ) && 'true' === $_POST['activatePlugin'] ) {
302 $post_data['activatePlugin'] = 'yes';
303 }
304 if ( isset( $_POST['overwrite'] ) && 'true' === $_POST['overwrite'] ) {
305 $post_data['overwrite'] = true;
306 }
307
308 /**
309 * Addition Post Data.
310 *
311 * @param $post_data The post data.
312 * @deprecated From.
313 * @since 3.5.6.
314 */
315 self::addition_post_data( $post_data );
316
317 $site_id = isset( $_POST['siteId'] ) ? intval( $_POST['siteId'] ) : 0;
318 $website = MainWP_DB::instance()->get_website_by_id( $site_id );
319
320 // to support demo data.
321 if ( MainWP_Demo_Handle::get_instance()->is_demo_website( $website ) ) {
322 return MainWP_Demo_Handle::get_instance()->handle_action_demo( $website, 'perform_install' );
323 }
324
325 $websites = array( $website );
326
327 /**
328 * Perform insatallation additional data
329 *
330 * Adds support for additional data such as HTTP User and HTTP Password.
331 *
332 * @param array $post_data Array containg the post data.
333 *
334 * @since Unknown
335 */
336 $post_data = apply_filters( 'mainwp_perform_install_data', $post_data );
337
338 $post_data['url'] = isset( $_POST['url'] ) ? wp_json_encode( wp_unslash( $_POST['url'] ) ) : '';
339
340 $output = new \stdClass();
341 $output->ok = array();
342 $output->errors = array();
343 $output->results = array();
344 $output->other_data = array();
345
346 // phpcs:enable
347 /**
348 * Action: mainwp_before_plugin_theme_install
349 *
350 * Fires before plugin/theme install.
351 *
352 * @since 4.1
353 */
354 do_action( 'mainwp_before_plugin_theme_install', $post_data, $websites );
355
356 MainWP_Connect::fetch_urls_authed(
357 $websites,
358 'installplugintheme',
359 $post_data,
360 array(
361 self::get_class_name(),
362 'install_plugin_theme_handler',
363 ),
364 $output,
365 null,
366 array( 'upgrade' => true )
367 );
368
369 $output_obj = $output;
370
371 mainwp_get_actions_handler_instance()->do_action_mainwp_install_actions( $websites, 'install', $output_obj, $type, $post_data );
372
373 /**
374 * Action: mainwp_after_plugin_theme_install
375 *
376 * Fires after plugin/theme install.
377 *
378 * @since 4.1
379 */
380 do_action( 'mainwp_after_plugin_theme_install', $output, $post_data, $websites );
381
382 wp_send_json( $output );
383 }
384
385 /**
386 * Method prepare_upload()
387 *
388 * Prepare the upload.
389 *
390 * @uses \MainWP\Dashboard\MainWP_DB::query()
391 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
392 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
393 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
394 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_download_url()
395 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
396 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
397 */
398 public static function prepare_upload() { // phpcs:ignore -- comlex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
399 include_once ABSPATH . '/wp-admin/includes/plugin-install.php';
400
401 $output = array();
402 $output['sites'] = array();
403
404 $data_fields = array(
405 'id',
406 'url',
407 'name',
408 'sync_errors',
409 );
410 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
411 if ( isset( $_POST['selected_by'] ) && 'site' === $_POST['selected_by'] ) {
412 $selected_sites = isset( $_POST['selected_sites'] ) && is_array( $_POST['selected_sites'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_sites'] ) ) : array();
413 // Get sites.
414 foreach ( $selected_sites as $enc_id ) {
415 $websiteid = $enc_id;
416 if ( MainWP_Utility::ctype_digit( $websiteid ) ) {
417 $website = MainWP_DB::instance()->get_website_by_id( $websiteid );
418 $output['sites'][ $website->id ] = MainWP_Utility::map_site(
419 $website,
420 array(
421 'id',
422 'url',
423 'name',
424 )
425 );
426 }
427 }
428 } elseif ( isset( $_POST['selected_by'] ) && 'client' === $_POST['selected_by'] ) {
429 $selected_clients = isset( $_POST['selected_clients'] ) && is_array( $_POST['selected_clients'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_clients'] ) ) : array();
430 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids(
431 $selected_clients,
432 array(
433 'select_data' => $data_fields,
434 )
435 );
436 // Get sites.
437 if ( $websites ) {
438 foreach ( $websites as $website ) {
439 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
440 continue;
441 }
442 $output['sites'][ $website->id ] = MainWP_Utility::map_site(
443 $website,
444 array(
445 'id',
446 'url',
447 'name',
448 )
449 );
450 }
451 }
452 } else {
453 $selected_groups = ( isset( $_POST['selected_groups'] ) && is_array( $_POST['selected_groups'] ) ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['selected_groups'] ) ) : array();
454 // Get sites from group.
455 foreach ( $selected_groups as $enc_id ) {
456 $groupid = $enc_id;
457 if ( MainWP_Utility::ctype_digit( $groupid ) ) {
458 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_id( $groupid ) );
459 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
460 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
461 continue;
462 }
463 $output['sites'][ $website->id ] = MainWP_Utility::map_site(
464 $website,
465 array(
466 'id',
467 'url',
468 'name',
469 )
470 );
471 }
472 MainWP_DB::free_result( $websites );
473 }
474 }
475 }
476
477 $output['urls'] = array();
478 $files = isset( $_POST['files'] ) && is_array( $_POST['files'] ) ? wp_unslash( $_POST['files'] ) : array();
479 foreach ( $files as $file ) {
480 $output['urls'][] = MainWP_System_Utility::get_download_url( 'bulk', $file );
481 }
482 $output['urls'] = implode( '||', $output['urls'] );
483 // phpcs:enable
484
485 /**
486 * Prepare upload
487 *
488 * Prepares upload URLs for the bulk install process.
489 *
490 * @since Unknown
491 */
492 $output['urls'] = apply_filters( 'mainwp_installbulk_prepareupload', $output['urls'] );
493
494 wp_send_json( $output );
495 }
496
497 /**
498 * Method perform_upload()
499 *
500 * Perform the upload.
501 *
502 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
503 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
504 * @uses \MainWP\Dashboard\MainWP_Utility::end_session()
505 */
506 public static function perform_upload() {
507 MainWP_Utility::end_session();
508 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
509 $type = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '';
510 // Fetch info.
511 $post_data = array(
512 'type' => $type,
513 );
514 if ( isset( $_POST['activatePlugin'] ) && 'true' === $_POST['activatePlugin'] ) {
515 $post_data['activatePlugin'] = 'yes';
516 }
517 if ( isset( $_POST['overwrite'] ) && 'true' === $_POST['overwrite'] ) {
518 $post_data['overwrite'] = true;
519 }
520
521 // deprecated from 3.5.6.
522 self::addition_post_data( $post_data );
523
524 /** This filter is documented in pages/page-mainwp-install-bulk.php */
525 $post_data = apply_filters( 'mainwp_perform_install_data', $post_data );
526
527 $urls = isset( $_POST['urls'] ) ? esc_url_raw( wp_unslash( $_POST['urls'] ) ) : '';
528 $post_data['url'] = wp_json_encode( explode( '||', $urls ) );
529 $site_id = isset( $_POST['siteId'] ) ? intval( $_POST['siteId'] ) : 0;
530 $website = MainWP_DB::instance()->get_website_by_id( $site_id );
531
532 // phpcs:enable
533
534 // to support demo data.
535 if ( MainWP_Demo_Handle::get_instance()->is_demo_website( $website ) ) {
536 return MainWP_Demo_Handle::get_instance()->handle_action_demo( $website, 'perform_upload' );
537 }
538
539 $output = new \stdClass();
540 $output->ok = array();
541 $output->errors = array();
542 $output->results = array();
543 $output->other_data = array();
544 $websites = array( $website );
545
546 /**
547 * Action: mainwp_before_plugin_theme_install
548 *
549 * Fires before plugin/theme install.
550 *
551 * @since 4.1
552 */
553 do_action( 'mainwp_before_plugin_theme_install', $post_data, $websites );
554
555 MainWP_Connect::fetch_urls_authed(
556 $websites,
557 'installplugintheme',
558 $post_data,
559 array(
560 self::get_class_name(),
561 'install_plugin_theme_handler',
562 ),
563 $output,
564 null,
565 array( 'upgrade' => true )
566 );
567 $output_obj = $output;
568 mainwp_get_actions_handler_instance()->do_action_mainwp_install_actions( $websites, 'install', $output_obj, $type, $post_data, true );
569
570 /**
571 * Action: mainwp_after_plugin_theme_install
572 *
573 * Fires after plugin/theme install.
574 *
575 * @since 4.1
576 */
577 do_action( 'mainwp_after_plugin_theme_install', $output, $post_data, $websites );
578
579 wp_send_json( $output );
580 }
581
582 /**
583 * Clean the upload
584 *
585 * Do file structure maintenance and tmp file removals.
586 *
587 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system()
588 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_specific_dir()
589 */
590 public static function clean_upload() {
591 $hasWPFileSystem = MainWP_System_Utility::get_wp_file_system();
592
593 /**
594 * WordPress files system object.
595 *
596 * @global object
597 */
598 global $wp_filesystem;
599
600 $path = MainWP_System_Utility::get_mainwp_specific_dir( 'bulk' );
601 if ( $wp_filesystem->exists( $path ) ) {
602 $dh = opendir( $path );
603 if ( $dh ) {
604 while ( false !== ( $file = readdir( $dh ) ) ) {
605 if ( '.' !== $file && '..' !== $file ) {
606 $wp_filesystem->delete( $path . $file );
607 }
608 }
609 closedir( $dh );
610 }
611 }
612
613 die( wp_json_encode( array( 'ok' => true ) ) );
614 }
615
616 /**
617 * Plugin & Theme upload handler.
618 *
619 * @param mixed $data Processing data.
620 * @param object $website The website object.
621 * @param mixed $output Function output.
622 * @param mixed $post_data Post data.
623 *
624 * @return mixed $output->ok[ $website->id ] = array( $website->name )|Error,
625 * Already installed,
626 * Undefined error! Please reinstall the MainWP Child plugin on the child site,
627 * Error while installing.
628 *
629 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_child_response()
630 */
631 public static function install_plugin_theme_handler( $data, $website, &$output, $post_data = array() ) {
632 if ( MainWP_Demo_Handle::get_instance()->is_demo_website( $website ) ) {
633 return;
634 }
635 if ( preg_match( '/<mainwp>(.*)<\/mainwp>/', $data, $results ) > 0 ) {
636
637 $result = $results[1];
638 // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
639 $information = MainWP_System_Utility::get_child_response( base64_decode( $result ) );
640 if ( is_array( $information ) ) {
641 if ( isset( $information['other_data']['install_items'] ) ) {
642 $output->other_data[ $website->id ] = $information['other_data']; // content: install_items themes/plugins.
643 }
644 }
645
646 if ( isset( $information['installation'] ) && 'SUCCESS' === $information['installation'] ) {
647 $output->ok[ $website->id ] = array( $website->name );
648 $output->results[ $website->id ] = isset( $information['install_results'] ) ? $information['install_results'] : array();
649 } elseif ( isset( $information['error'] ) ) {
650 $error = esc_html( $information['error'] );
651 if ( isset( $information['error_code'] ) && 'folder_exists' === $information['error_code'] ) {
652 $error = esc_html__( 'Already installed', 'mainwp' );
653 }
654
655 if ( 'not found' === strtolower( $error ) ) {
656 if ( is_array( $post_data ) && isset( $post_data['type'] ) ) {
657 if ( 'plugin' === $post_data['type'] ) {
658 $error = esc_html__( 'Plugin file not found. Make sure security plugins or server-side security rules are not blocking requests from your child sites.', 'mainwp' );
659 } elseif ( 'theme' === $post_data['type'] ) {
660 $error = esc_html__( 'Theme file not found. Make sure security plugins or server-side security rules are not blocking requests from your child sites.', 'mainwp' );
661 }
662 }
663 }
664
665 $output->errors[ $website->id ] = array( $website->name, $error );
666 } else {
667 $output->errors[ $website->id ] = array(
668 $website->name,
669 __( 'Undefined error! Please reinstall the MainWP Child plugin on the child site', 'mainwp' ),
670 );
671 }
672 } else {
673 $output->errors[ $website->id ] = array( $website->name, 'Error while installing' );
674 }
675 }
676 }
677