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.php

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

2,617 lines 142.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Manage Sites Page.
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
17 *
18 * @package MainWP\Dashboard
19 */
20 class MainWP_Manage_Sites { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
21
22 /**
23 * The single instance of the class
24 *
25 * @var mixed Default null
26 */
27 protected static $instance = null;
28
29 /**
30 * Private static variable to hold the total sites.
31 *
32 * @var mixed Default null
33 */
34 private static $total_sites = null;
35
36 /**
37 * Get instance.
38 *
39 * @return static::singlton
40 */
41 public static function get_instance() {
42 if ( null === static::$instance ) {
43 static::$instance = new self();
44 }
45 return static::$instance;
46 }
47
48 /**
49 * MainWP_Setup_Wizard constructor.
50 *
51 * Run each time the class is called.
52 */
53 public function __construct() {
54 $this->get_total_sites();
55 }
56
57 /**
58 * Get instance.
59 *
60 * @return static::singlton
61 */
62 public static function get_total_sites() {
63 if ( null === static::$total_sites ) {
64 static::$total_sites = MainWP_DB::instance()->get_websites_count();
65 }
66 return static::$total_sites;
67 }
68
69 /**
70 * Get Class Name
71 *
72 * @return string __CLASS__
73 */
74 public static function get_class_name() {
75 return __CLASS__;
76 }
77
78 /**
79 * Sub pages
80 *
81 * @static
82 * @var array $subPages Sub pages.
83 */
84 public static $subPages;
85
86 /**
87 * Current page.
88 *
89 * @static
90 * @var string $page Current page.
91 */
92 public static $page;
93
94 /**
95 * Widgets to enable.
96 *
97 * @static
98 * @var array $enable_widgets Widgets to enable.
99 */
100 private static $enable_widgets = array(
101 'overview' => true,
102 'recent_posts' => true,
103 'recent_pages' => true,
104 'security_issues' => true,
105 'manage_backups' => true,
106 'plugins' => true,
107 'themes' => true,
108 'notes' => true,
109 'site_note' => true,
110 'client_info' => true,
111 'non_mainwp_changes' => true,
112 'uptime_monitoring_info' => true,
113 'uptime_monitoring_response_time' => true,
114 );
115
116 /**
117 * Magage Sites table
118 *
119 * @var $sitesTable Magage Sites table.
120 */
121 public static $sitesTable;
122
123 /**
124 * Method init()
125 *
126 * Initiate Manage Sites.
127 *
128 * @uses \MainWP\Dashboard\MainWP_Security_Issues::get_class_name()
129 */
130 public static function init() {
131 /**
132 * This hook allows you to render the Sites page header via the 'mainwp-pageheader-sites' action.
133 *
134 * @link http://codex.mainwp.com/#mainwp-pageheader-sites
135 *
136 * This hook is normally used in the same context of 'mainwp-getsubpages-sites'
137 * @link http://codex.mainwp.com/#mainwp-getsubpages-sites
138 *
139 * @see \MainWP_Manage_Sites::render_header
140 */
141 add_action( 'mainwp-pageheader-sites', array( static::get_class_name(), 'render_header' ) ); // @deprecated Use 'mainwp_pageheader_sites' instead.
142 add_action( 'mainwp_pageheader_sites', array( static::get_class_name(), 'render_header' ) );
143
144 /**
145 * This hook allows you to render the Sites page footer via the 'mainwp-pagefooter-sites' action.
146 *
147 * @link http://codex.mainwp.com/#mainwp-pagefooter-sites
148 *
149 * This hook is normally used in the same context of 'mainwp-getsubpages-sites'
150 * @link http://codex.mainwp.com/#mainwp-getsubpages-sites
151 *
152 * @see \MainWP_Manage_Sites::render_footer
153 */
154 add_action( 'mainwp-pagefooter-sites', array( static::get_class_name(), 'render_footer' ) ); // @deprecated Use 'mainwp_pagefooter_sites' instead.
155 add_action( 'mainwp_pagefooter_sites', array( static::get_class_name(), 'render_footer' ) );
156
157 add_action( 'mainwp_securityissues_sites', array( MainWP_Security_Issues::get_class_name(), 'render' ) );
158 add_action( 'mainwp_manage_sites_edit', array( static::get_class_name(), 'on_edit_site' ) );
159
160 // Hook the Help Sidebar content.
161 add_action( 'mainwp_help_sidebar_content', array( static::get_class_name(), 'mainwp_help_content' ) );
162 MainWP_Post_Handler::instance()->add_action( 'mainwp_managesites_add_edit_site_upload_site_icon', array( static::class, 'ajax_upload_icon' ) );
163 }
164
165 /**
166 * Method on_screen_layout_columns()
167 *
168 * Columns to display.
169 *
170 * @param mixed $columns Columns to display.
171 * @param mixed $screen Current page.
172 *
173 * @return array $columns
174 */
175 public static function on_screen_layout_columns( $columns, $screen ) {
176 if ( $screen === static::$page ) {
177 $columns[ static::$page ] = 3;
178 }
179
180 return $columns;
181 }
182
183 /**
184 * Initiate menu.
185 *
186 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::init_menu()
187 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::init_left_menu()
188 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
189 * @uses \MainWP\Dashboard\MainWP_Site_Open::get_class_name()
190 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
191 */
192 public static function init_menu() { // phpcs:ignore -- NOSONAR - complex.
193 static::$page = MainWP_Manage_Sites_View::init_menu();
194 add_action( 'load-' . static::$page, array( static::get_class_name(), 'on_load_page' ) );
195
196 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
197 if ( isset( $_REQUEST['dashboard'] ) ) {
198 // phpcs:enable
199 /**
200 * Current user global.
201 *
202 * @global string
203 */
204 global $current_user;
205
206 delete_user_option( $current_user->ID, 'screen_layout_toplevel_page_managesites' );
207 add_filter( 'screen_layout_columns', array( static::get_class_name(), 'on_screen_layout_columns' ), 10, 2 );
208
209 $val = get_user_option( 'screen_layout_' . static::$page );
210 if ( ! MainWP_Utility::ctype_digit( $val ) ) {
211 global $current_user;
212 update_user_option( $current_user->ID, 'screen_layout_' . static::$page, 2, true );
213 }
214 }
215 add_submenu_page(
216 'mainwp_tab',
217 __( 'Sites', 'mainwp' ),
218 '<div class="mainwp-hidden">' . esc_html__( 'Sites', 'mainwp' ) . '</div>',
219 'read',
220 'SiteOpen',
221 array(
222 MainWP_Site_Open::get_class_name(),
223 'render',
224 )
225 );
226 add_submenu_page(
227 'mainwp_tab',
228 __( 'Sites', 'mainwp' ),
229 '<div class="mainwp-hidden">' . esc_html__( 'Sites', 'mainwp' ) . '</div>',
230 'read',
231 'SiteRestore',
232 array(
233 MainWP_Site_Open::get_class_name(),
234 'render_restore',
235 )
236 );
237
238 /**
239 * Sites Subpages
240 *
241 * Filters subpages for the Sites page.
242 *
243 * @since Unknown
244 */
245 $sub_pages = array();
246 $sub_pages = apply_filters_deprecated( 'mainwp-getsubpages-sites', array( $sub_pages ), '4.0.7.2', 'mainwp_getsubpages_sites' ); // @deprecated Use 'mainwp_getsubpages_sites' instead. NOSONAR - not IP.
247 static::$subPages = apply_filters( 'mainwp_getsubpages_sites', $sub_pages );
248
249 if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
250 foreach ( static::$subPages as $subPage ) {
251 if ( ! empty( $subPage['no_submenu_page'] ) ) {
252 continue;
253 }
254 if ( ! isset( $subPage['slug'] ) && ! isset( $subPage['title'] ) ) {
255 continue;
256 }
257 if ( MainWP_Menu::is_disable_menu_item( 2, 'ManageSites' . $subPage['slug'] ) ) {
258 continue;
259 }
260 $_page = add_submenu_page( 'mainwp_tab', $subPage['title'], '<div class="mainwp-hidden">' . $subPage['title'] . '</div>', 'read', 'ManageSites' . $subPage['slug'], $subPage['callback'] );
261 add_action( 'load-' . $_page, array( static::get_class_name(), 'on_load_subpages' ), 9 );
262 if ( isset( $subPage['on_load_callback'] ) && ! empty( $subPage['on_load_callback'] ) ) {
263 add_action( 'load-' . $_page, $subPage['on_load_callback'] );
264 }
265 }
266 }
267
268 MainWP_Manage_Sites_View::init_left_menu( static::$subPages );
269 }
270
271 /**
272 * Initiate sub page menu.
273 *
274 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::init_subpages_menu()
275 */
276 public static function init_subpages_menu() {
277 MainWP_Manage_Sites_View::init_subpages_menu( static::$subPages );
278 }
279
280 /**
281 * Method on_load_page()
282 *
283 * Run on page load.
284 *
285 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_List_Table
286 * @uses \MainWP\Dashboard\MainWP_System::enqueue_postbox_scripts()
287 */
288 public static function on_load_page() {
289
290 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
291 if ( isset( $_REQUEST['dashboard'] ) ) {
292 static::on_load_page_dashboard();
293 return;
294 }
295
296 MainWP_System::enqueue_postbox_scripts();
297
298 if ( isset( $_REQUEST['do'] ) ) {
299 if ( 'new' === $_REQUEST['do'] || 'bulknew' === $_REQUEST['do'] ) {
300 return;
301 }
302 } elseif ( isset( $_GET['id'] ) || isset( $_GET['scanid'] ) || isset( $_GET['backupid'] ) || isset( $_GET['updateid'] ) || isset( $_GET['monitor_wpid'] ) || isset( $_GET['emailsettingsid'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,ized
303 return;
304 }
305 // phpcs:enable
306
307 $sitesViewMode = MainWP_Utility::get_siteview_mode();
308
309 add_filter( 'mainwp_header_actions_right', array( static::get_class_name(), 'screen_options' ), 10, 2 );
310 if ( 'grid' !== $sitesViewMode ) {
311 static::load_sites_table();
312 } else {
313 MainWP_Manage_Screenshots::get_instance(); // to init hooks.
314 }
315 }
316
317
318 /**
319 * Method load_sites_table()
320 *
321 * Load sites table.
322 */
323 public static function load_sites_table() {
324 if ( empty( static::$sitesTable ) ) {
325 static::$sitesTable = new MainWP_Manage_Sites_List_Table();
326 }
327 }
328
329
330 /**
331 * Method on_load_sunpages()
332 *
333 * Run on subpage load.
334 *
335 * @uses \MainWP\Dashboard\MainWP_System_Utility::set_current_wpid()
336 */
337 public static function on_load_subpages() {
338 if ( ! empty( $_GET['id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,ized
339 MainWP_System_Utility::set_current_wpid( intval( $_GET['id'] ) ); // phpcs:ignore WordPress.Security.NonceVerification,ized
340 }
341 }
342
343 /**
344 * Method render_header()
345 *
346 * Render page header.
347 *
348 * @param string $shownPage Current page slug.
349 *
350 * @uses \MainWP\Dashboard\MainWP_Deprecated_Hooks::maybe_handle_deprecated_hook()
351 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::render_header()
352 */
353 public static function render_header( $shownPage = '' ) {
354 MainWP_Deprecated_Hooks::maybe_handle_deprecated_hook();
355 MainWP_Manage_Sites_View::render_header( $shownPage, static::$subPages );
356 }
357
358 /**
359 * Method render_footer()
360 *
361 * Render page footer.
362 */
363 public static function render_footer() {
364 MainWP_Manage_Sites_View::render_footer();
365 }
366
367 /**
368 * Method screen_options()
369 *
370 * Create Page Settings button.
371 *
372 * @param mixed $input Page Settings button HTML.
373 *
374 * @return mixed Page Settings button.
375 */
376 public static function screen_options( $input ) {
377 return $input .
378 '<a class="ui button basic icon" onclick="mainwp_manage_sites_screen_options(); return false;" data-inverted="" data-position="bottom right" href="#" target="_blank" data-tooltip="' . esc_html__( 'Page Settings', 'mainwp' ) . '">
379 <i class="cog icon"></i>
380 </a>';
381 }
382
383 /**
384 * Method render_screen_options()
385 *
386 * Render Page Settings Modal.
387 */
388 public static function render_screen_options() { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
389
390 $columns = static::$sitesTable->get_columns();
391
392 if ( isset( $columns['cb'] ) ) {
393 unset( $columns['cb'] );
394 }
395
396 if ( isset( $columns['status'] ) ) {
397 $columns['status'] = esc_html__( 'Status', 'mainwp' );
398 }
399
400 if ( isset( $columns['favicon'] ) ) {
401 $columns['favicon'] = esc_html__( 'Favicon', 'mainwp' );
402 }
403
404 $list_items = array(
405 'login' => esc_html__( 'Jump to WP Admin', 'mainwp' ),
406 'update' => esc_html__( 'Updates', 'mainwp' ),
407 'wpcore_update' => esc_html__( 'WP updates', 'mainwp' ),
408 'plugin_update' => esc_html__( 'Plugin updates', 'mainwp' ),
409 'theme_update' => esc_html__( 'Theme updates', 'mainwp' ),
410 'site-cost-tracker' => esc_html__( 'Cost Tracker', 'mainwp' ),
411 'note' => esc_html__( 'Notes', 'mainwp' ),
412 'site_preview' => esc_html__( 'Site preview', 'mainwp' ),
413 'time-tracker-tasks' => esc_html__( 'Time Tracker tasks', 'mainwp' ),
414 'lighthouse_desktop_score' => esc_html__( 'Lighthouse desktop score', 'mainwp' ),
415 'lighthouse_mobile_score' => esc_html__( 'Lighthouse mobile score', 'mainwp' ),
416 );
417
418 foreach ( $list_items as $idx => $title ) {
419 if ( isset( $columns[ $idx ] ) ) {
420 $columns[ $idx ] = $title;
421 }
422 }
423
424 $sites_per_page = get_option( 'mainwp_default_sites_per_page', 25 );
425
426 if ( isset( $columns['site_actions'] ) && empty( $columns['site_actions'] ) ) {
427 $columns['site_actions'] = esc_html__( 'Actions', 'mainwp' );
428 }
429
430 $show_cols = get_user_option( 'mainwp_settings_show_manage_sites_columns' );
431 if ( false === $show_cols ) { // to backwards.
432 $show_cols = array();
433 foreach ( $columns as $name => $title ) {
434 if ( in_array( $name, array( 'status', 'favicon', 'site_combo', 'client_name', 'update', 'wpcore_version', 'security', 'index', 'backup', 'site_actions' ) ) ) {
435 $show_cols[ $name ] = 1;
436 } else {
437 $show_cols[ $name ] = 0;
438 }
439 }
440 $user = wp_get_current_user();
441 if ( $user ) {
442 update_user_option( $user->ID, 'mainwp_settings_show_manage_sites_columns', $show_cols, true );
443 }
444 }
445
446 if ( ! is_array( $show_cols ) ) {
447 $show_cols = array();
448 }
449
450 $siteViewMode = MainWP_Utility::get_siteview_mode();
451 ?>
452 <div class="ui modal" id="mainwp-manage-sites-screen-options-modal">
453 <i class="close icon"></i>
454 <div class="header"><?php esc_html_e( 'Page Settings', 'mainwp' ); ?></div>
455 <div class="scrolling content ui form">
456 <form method="POST" action="" id="manage-sites-screen-options-form" name="manage_sites_screen_options_form">
457 <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
458 <input type="hidden" name="wp_nonce" value="<?php echo esc_attr( wp_create_nonce( 'ManageSitesScrOptions' ) ); ?>" />
459 <div class="ui grid field">
460 <label class="top aligned six wide column" tabindex="0"><?php esc_html_e( 'Sites view mode', 'mainwp' ); ?></label>
461 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Sites view mode.', 'mainwp' ); ?>" data-inverted="" data-position="left center">
462 <div class="ui info message">
463 <div><strong><?php echo esc_html__( 'Sites view mode is an experimental feature.', 'mainwp' ); ?></strong></div>
464 <div><?php echo esc_html__( 'In the Grid mode, sites options are limited in comparison to the Table mode.', 'mainwp' ); ?></div>
465 <div><?php echo esc_html__( 'Grid mode queries WordPress.com servers to capture a screenshot of your site the same way comments show you a preview of URLs.', 'mainwp' ); ?></div>
466 </div>
467 <select name="mainwp_sitesviewmode" id="mainwp_sitesviewmode" class="ui dropdown">
468 <option value="table" <?php echo 'table' === $siteViewMode ? 'selected' : ''; ?>><?php esc_html_e( 'Table', 'mainwp' ); ?></option>
469 <option value="grid" <?php echo 'grid' === $siteViewMode ? 'selected' : ''; ?>><?php esc_html_e( 'Grid', 'mainwp' ); ?></option>
470 </select>
471 </div>
472 </div>
473 <div class="ui grid field">
474 <label class="six wide column"><?php esc_html_e( 'Default items per page value', 'mainwp' ); ?></label>
475 <div class="ten wide column">
476 <div class="ui info message">
477 <ul>
478 <li><?php esc_html_e( 'Based on your Dashboard server default large numbers can severely impact page load times.', 'mainwp' ); ?></li>
479 <li><?php esc_html_e( 'Do not add commas for thousands (ex 1000).', 'mainwp' ); ?></li>
480 <li><?php esc_html_e( '-1 to default to All of your Child Sites.', 'mainwp' ); ?></li>
481 </ul>
482 </div>
483 <input type="text" name="mainwp_default_sites_per_page" id="mainwp_default_sites_per_page" saved-value="<?php echo intval( $sites_per_page ); ?>" value="<?php echo intval( $sites_per_page ); ?>"/>
484 </div>
485 </div>
486 <div class="ui grid field">
487 <label class="six wide column"><?php esc_html_e( 'Show columns', 'mainwp' ); ?></label>
488 <div class="ten wide column">
489 <ul class="mainwp_hide_wpmenu_checkboxes">
490 <?php
491 foreach ( $columns as $name => $title ) {
492 if ( empty( $title ) ) {
493 continue;
494 }
495 ?>
496 <li>
497 <div class="ui checkbox <?php echo ( 'site_preview' === $name ) ? 'site_preview not-auto-init' : ''; ?>">
498 <input type="checkbox"
499 <?php
500 $show_col = ! isset( $show_cols[ $name ] ) || ( 1 === (int) $show_cols[ $name ] );
501
502 if ( 'added_datetime' === $name && ! isset( $show_cols[ $name ] ) ) {
503 $show_col = false; // default is hidden.
504 }
505
506 if ( $show_col ) {
507 echo 'checked="checked"';
508 }
509
510 ?>
511 id="mainwp_show_column_<?php echo esc_attr( $name ); ?>" name="mainwp_show_column_<?php echo esc_attr( $name ); ?>" value="<?php echo esc_attr( $name ); ?>">
512 <label for="mainwp_show_column_<?php echo esc_attr( $name ); ?>" ><?php echo $title; // phpcs:ignore WordPress.Security.EscapeOutput ?></label>
513 <input type="hidden" value="<?php echo esc_attr( $name ); ?>" name="show_columns_name[]" />
514 </div>
515 </li>
516 <?php
517 }
518 ?>
519 </ul>
520 </div>
521 </div>
522 <div class="ui grid field">
523 <label class="six wide column middle aligned"><?php esc_html_e( 'Optimize for shared hosting or big networks', 'mainwp' ); ?></label>
524 <div class="ten wide column ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'If enabled, your MainWP Dashboard will cache updates for faster loading.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
525 <input type="checkbox" name="mainwp_optimize" id="mainwp_optimize" <?php echo 1 === (int) get_option( 'mainwp_optimize', 1 ) ? 'checked="true"' : ''; ?> /><label><?php esc_html_e( 'Default: Disabled', 'mainwp' ); ?></label>
526 </div>
527 </div>
528 <div class="ui grid field">
529 <label class="six wide column middle aligned"><?php esc_html_e( 'Export child sites to CSV file', 'mainwp' ); ?></label>
530 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Click this button to export all connected sites to a CSV file.', 'mainwp' ); ?>" data-inverted="" data-position="top left"><a href="admin.php?page=MainWPTools&doExportSites=yes&_wpnonce=<?php echo esc_html( wp_create_nonce( 'export_sites' ) ); ?>" class="ui button green basic"><?php esc_html_e( 'Export Child Sites', 'mainwp' ); ?></a></div>
531 </div>
532 <div class="ui grid field">
533 <label class="six wide column middle aligned"><?php esc_html_e( 'Disconnect all child sites', 'mainwp' ); ?></label>
534 <div class="ten wide column" id="mainwp-disconnect-sites-tool" data-tooltip="<?php esc_attr_e( 'This will function will break the connection and leave the MainWP Child plugin active.', 'mainwp' ); ?>" data-variation="inverted" data-position="top left">
535 <a href="admin.php?page=MainWPTools&disconnectSites=yes&_wpnonce=<?php echo esc_html( wp_create_nonce( 'disconnect_sites' ) ); ?>" onclick="mainwp_tool_disconnect_sites(); return false;" class="ui button green basic"><?php esc_html_e( 'Disconnect Websites.', 'mainwp' ); ?></a>
536 </div>
537 </div>
538 <div class="ui hidden divider"></div>
539 <div class="ui hidden divider"></div>
540 </div>
541 <div class="actions">
542 <div class="ui two columns grid">
543 <div class="left aligned column">
544 <span data-tooltip="<?php esc_attr_e( 'Resets the page to its original layout and reinstates relocated columns.', 'mainwp' ); ?>" data-inverted="" data-position="top center"><input type="button" class="ui button" name="reset" id="reset-managersites-settings" value="<?php esc_attr_e( 'Reset Page', 'mainwp' ); ?>" /></span>
545 </div>
546 <div class="ui right aligned column">
547 <input type="submit" class="ui green button" name="btnSubmit" id="submit-managersites-settings" value="<?php esc_attr_e( 'Save Settings', 'mainwp' ); ?>" />
548 </div>
549 </div>
550 </div>
551 <input type="hidden" name="reset_managersites_columns_order" value="0">
552 </form>
553 </div>
554 <div class="ui small modal" id="mainwp-manage-sites-site-preview-screen-options-modal">
555 <div class="header"><?php esc_html_e( 'Page Settings', 'mainwp' ); ?></div>
556 <div class="scrolling content ui form">
557 <span><?php esc_html_e( 'Would you like to turn on home screen previews? This function queries WordPress.com servers to capture a screenshot of your site the same way comments shows you preview of URLs.', 'mainwp' ); ?>
558 </div>
559 <div class="actions">
560 <div class="ui ok button"><?php esc_html_e( 'Yes', 'mainwp' ); ?></div>
561 <div class="ui cancel button"><?php esc_html_e( 'No', 'mainwp' ); ?></div>
562 </div>
563 </div>
564 <script type="text/javascript">
565 jQuery( document ).ready( function () {
566 jQuery( '.ui.checkbox.not-auto-init.site_preview' ).checkbox( {
567 onChecked : function() {
568 let $chk = jQuery( this );
569 jQuery( '#mainwp-manage-sites-site-preview-screen-options-modal' ).modal( {
570 allowMultiple: true, // multiple modals.
571 width: 100,
572 onDeny: function () {
573 $chk.prop('checked', false);
574 }
575 } ).modal( 'show' );
576 }
577 } );
578 jQuery('#reset-managersites-settings').on( 'click', function () {
579 mainwp_confirm(__( 'Are you sure?' ), function(){
580 jQuery('#mainwp_sitesviewmode').dropdown( 'set selected', 'table' );
581 jQuery('input[name=mainwp_default_sites_per_page]').val(25);
582 jQuery('.mainwp_hide_wpmenu_checkboxes input[id^="mainwp_show_column_"]').prop( 'checked', false );
583 //default columns.
584 let cols = ['status', 'favicon', 'site_combo','client_name', 'update', 'wpcore_version', 'security', 'index', 'site_actions'];
585 jQuery.each( cols, function ( index, value ) {
586 jQuery('.mainwp_hide_wpmenu_checkboxes input[id="mainwp_show_column_' + value + '"]').prop( 'checked', true );
587 } );
588 jQuery('input[name=reset_managersites_columns_order]').attr('value',1);
589 jQuery('#submit-managersites-settings').click();
590 }, false, false, true );
591 return false;
592 });
593 } );
594 </script>
595 <?php
596 }
597
598 /**
599 * Method ajax_optimize_display_rows()
600 *
601 * Display table rows, optimize for shared hosting or big networks.
602 *
603 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_List_Table
604 */
605 public static function ajax_optimize_display_rows() {
606 static::load_sites_table();
607 static::$sitesTable->prepare_items( true );
608 $output = static::$sitesTable->ajax_get_datatable_rows();
609 static::$sitesTable->clear_items();
610
611 MainWP_Logger::instance()->log_execution_time( 'ajax_optimize_display_rows()' );
612
613 wp_send_json( $output );
614 }
615
616 /**
617 * Method render_new_site()
618 *
619 * Render add new site page.
620 *
621 * @return string Add new site html.
622 *
623 * @uses \MainWP\Dashboard\MainWP_DB_Common::get_groups_for_current_user()
624 * @uses \MainWP\Dashboard\MainWP_DB::query()
625 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_for_current_user()
626 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::render_sync_exts_settings()
627 */
628 public static function render_new_site() {
629
630 $showpage = 'AddNew';
631 $title_page = esc_html__( 'Add a New Site', 'mainwp' );
632 static::render_header( $showpage );
633 $has_import_data = ! empty( $_POST['mainwp_managesites_import'] );
634
635 if ( ! \mainwp_current_user_can( 'dashboard', 'add_sites' ) ) {
636 \mainwp_do_not_have_permissions( esc_html__( 'add sites', 'mainwp' ) );
637 return;
638 } elseif ( $has_import_data && check_admin_referer( 'mainwp-admin-nonce' ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
639 static::render_import_sites_modal( 'admin.php?page=managesites&do=new', $title_page );
640 } else {
641 $groups = MainWP_DB_Common::instance()->get_groups_for_current_user();
642 if ( ! is_array( $groups ) ) {
643 $groups = array();
644 }
645 ?>
646 <div id="mainwp-add-new-site">
647 <form method="POST" class="ui form" action="" enctype="multipart/form-data" id="mainwp_managesites_add_form">
648 <?php
649 MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' );
650 self::render_new_site_navigation();
651
652 $active = 'single-site';
653
654 if ( isset( $_GET['menu_active'] ) ) {
655 $active = sanitize_text_field( wp_unslash( $_GET['menu_active'] ) ); // phpcs:ignore -- NOSONAR - ok. 'single-site';
656 }
657
658 ?>
659 <div class="ui bottom attached tab padded segment <?php echo esc_attr( 'single-site' === $active ? 'active' : '' ); ?>" data-tab="single-site">
660 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-add-site-info-message' ) ) : ?>
661 <div class="ui info message">
662 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-add-site-info-message"></i>
663 <div><?php /* translators: 1: Opening link tag, 2: Closing link tag with icon */ printf( esc_html__( 'Use the provided form to connect your websites to your MainWP Dashboard. For additional help, please check this %1$shelp documentation%2$s.', 'mainwp' ), '<a href="https://docs.mainwp.com/getting-started/get-started-with-mainwp" target="_blank">', '</a> <i class="external alternate icon"></i>' ); // NOSONAR - noopener - open safe. ?></div>
664 <div><?php /* translators: 1: Opening link tag, 2: Closing link tag with icon */ printf( esc_html__( 'If you are experiencing issues with adding a website to your MainWP Dashboard, use the %1$sTest Connection%2$s feature to ensure that your MainWP Dashboard can communicate with your website.', 'mainwp' ), '<a href="https://docs.mainwp.com/getting-started/get-started-with-mainwp#test-connection" target="_blank">', '</a> <i class="external alternate icon"></i>' ); // NOSONAR - noopener - open safe. ?></div>
665 <div><?php /* translators: 1: Opening link tag, 2: Closing link tag */ printf( esc_html__( 'If you still can not connect the site, see the list of %1$spotential issues%2$s.', 'mainwp' ), '<a href="https://docs.mainwp.com/troubleshooting/potential-issues" target="_blank">', '</a>' ); // NOSONAR - noopener - open safe. ?></div>
666 </div>
667 <?php endif; ?>
668
669 <div id="mainwp-message-zone" style="display: none;" class="ui message"></div>
670
671 <div id="mainwp_managesites_add_errors" style="display: none" class="ui red message"></div>
672 <div id="mainwp_managesites_add_message" style="display: none" class="ui green message"></div>
673
674 <div class="ui info message" id="mainwp_message_verify_installed_child" style="display:none">
675 <?php esc_html_e( 'MainWP requires the MainWP Child plugin to be installed and activated on the WordPress site that you want to connect to your MainWP Dashboard. ', 'mainwp' ); ?>
676 <?php esc_html_e( 'To install the MainWP Child plugin, please follow these steps:', 'mainwp' ); ?>
677 <ol>
678 <li><?php /* translators: 1: Opening em tag, 2: Closing em tag */ printf( esc_html__( 'Login to the WordPress site you want to connect %1$s(open it in a new browser tab)%2$s', 'mainwp' ), '<em>', '</em>' ); ?></li>
679 <li><?php /* translators: 1: Opening strong tag, 2: Closing strong tag */ printf( esc_html__( 'Go to the %1$sWP > Plugins%2$s page', 'mainwp' ), '<strong>', '</strong>' ); ?></li>
680 <li><?php /* translators: 1: Opening strong tag, 2: Closing strong tag */ printf( esc_html__( 'Click %1$sAdd New%2$s to install a new plugin', 'mainwp' ), '<strong>', '</strong>' ); ?></li>
681 <li><?php /* translators: 1: Opening strong tag, 2: Closing strong tag */ printf( esc_html__( 'In the %1$sSearch Field%2$s, enter "MainWP Child" and once the plugin shows, click the Install button', 'mainwp' ), '<strong>', '</strong>' ); ?></li>
682 <li><?php /* translators: 1: Opening strong tag, 2: Closing strong tag */ printf( esc_html__( '%1$sActivate%2$s the plugin', 'mainwp' ), '<strong>', '</strong>' ); ?></li>
683 </ol>
684 </div>
685 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-add-site-trust-message' ) ) : ?>
686 <div class="ui message">
687 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-add-site-trust-message"></i>
688 <?php /* translators: %1$s: Lock emoji element */ printf( esc_html__( '%1$s Your credentials are never sent to MainWP.com. Communication occurs only between your Dashboard and your sites.', 'mainwp' ), '<em data-emoji=":lock:" class="small"></em>' ); ?>
689 </div>
690 <?php endif; ?>
691 <h2 class="ui dividing header">
692 <?php echo esc_html__( 'Verify Connection', 'mainwp' ); ?>
693 <div class="sub header"><?php echo esc_html__( 'Connect your site to your MainWP Dashboard for centralized management.', 'mainwp' ); ?></div>
694 </h2>
695 <?php static::render_new_site_add_new_site( $groups ); // NOSONAR - render html form. ?>
696 </div>
697
698 <div class="ui bottom attached tab padded segment <?php echo esc_attr( 'multiple-site' === $active ? 'active' : '' ); ?>" data-tab="multiple-site">
699 <?php static::render_new_site_add_multi_new_site(); // NOSONAR - render html form. ?>
700 </div>
701 <?php
702 do_action( 'mainwp_add_site_tabs_content' );
703 ?>
704 </form>
705 </div>
706
707 <div class="ui modal" id="mainwp-test-connection-modal">
708 <i class="close icon"></i>
709 <div class="header"><?php esc_html_e( 'Connection Test', 'mainwp' ); ?></div>
710 <div class="content">
711 <div class="ui active dimmer">
712 <div class="ui double text loader"><?php esc_html_e( 'Testing...', 'mainwp' ); ?></div>
713 </div>
714 <div id="mainwp-test-connection-result" class="ui segment" style="display:none">
715 <h2 class="ui center aligned icon header">
716 <i class=" icon"></i>
717 <div class="content">
718 <span></span>
719 <div class="sub header"></div>
720 </div>
721 </h2>
722 </div>
723 </div>
724 <div class="actions">
725 </div>
726 </div>
727
728 <script type="text/javascript">
729 jQuery( document ).ready( function () {
730 jQuery('#mainwp-add-sites-tabular-menu .item').tab();
731 jQuery(document).ready(function () {
732 // Parse query parameter
733 const urlParams = new URLSearchParams(window.location.search);
734 const tabName = urlParams.get('data-tab');
735
736 if (tabName) {
737 // Activate tab by name
738 jQuery('.menu .item').tab('change tab', tabName);
739 }
740 });
741 jQuery( '#mainwp_managesites_add_addgroups' ).dropdown( {
742 allowAdditions: true
743 } );
744 jQuery( '#mainwp_manage_add_edit_site_icon_select' ).dropdown( {
745 onChange: function( val ) {
746 jQuery( '#mainwp_managesites_add_site_select_icon_hidden' ).val(val);
747 }
748 } );
749
750 jQuery(document).on('click', '.mainwp-managesites-add-site-icon-customable', function () {
751 let iconObj = jQuery(this);
752 jQuery('#mainwp_delete_image_field').hide();
753 jQuery('#mainwp-upload-custom-icon-modal').modal('setting', 'closable', false).modal('show');
754 jQuery('#update_custom_icon_btn').removeAttr('disabled');
755 jQuery('#update_custom_icon_btn').attr('uploading-icon', 'site');
756 jQuery('#mainwp_delete_image_field').find('#mainwp_delete_image_chk').attr('iconItemId', iconObj.attr('iconItemId') ); // @see used by mainwp_upload_custom_types_icon().
757 jQuery('#mainwp_delete_image_field').find('#mainwp_delete_image_chk').attr('iconFileSlug', iconObj.attr('iconFileSlug') ); // @see used by mainwp_upload_custom_types_icon().
758
759 if (iconObj.attr('icon-src') != '') {
760 jQuery('#mainwp_delete_image_field').find('.ui.image').attr('src', iconObj.attr('icon-src'));
761 jQuery('#mainwp_delete_image_field').show();
762 }
763
764 jQuery(document).on('click', '#update_custom_icon_btn', function () {
765 let deleteIcon = jQuery('#mainwp_delete_image_chk').is(':checked');
766 let iconItemId = iconObj.attr('iconItemId');
767 let iconFileSlug = iconObj.attr('iconFileSlug'); // to support delete file when iconItemId = 0.
768 // upload/delete icon action.
769 mainwp_upload_custom_types_icon(iconObj, 'mainwp_managesites_add_edit_site_upload_site_icon', iconItemId, iconFileSlug, deleteIcon, function(response){
770 if (jQuery('#mainwp_managesites_add_site_uploaded_icon_hidden').length > 0) {
771 if (typeof response.iconfile !== undefined) {
772 jQuery('#mainwp_managesites_add_site_uploaded_icon_hidden').val(response.iconfile);
773 } else {
774 jQuery('#mainwp_managesites_add_site_uploaded_icon_hidden').val('');
775 }
776 }
777 let deleteIcon = jQuery('#mainwp_delete_image_chk').is(':checked'); // to delete.
778 if(deleteIcon){
779 jQuery('#mainw_managesites_add_edit_site_upload_custom_icon').hide();
780 } else if (jQuery('#mainw_managesites_add_edit_site_upload_custom_icon').length > 0) {
781 if (typeof response.iconfile !== undefined) {
782 let icon_img = typeof response.iconimg !== undefined ? response.iconimg : '';
783 let icon_src = typeof response.iconsrc !== undefined ? response.iconsrc : '';
784 iconObj.attr('icon-src', icon_src);
785 iconObj.attr('iconFileSlug', response.iconfile); // to support delete file when iconItemId = 0.
786 iconObj.attr('del-icon-nonce', response.iconnonce);
787 jQuery('#mainwp_delete_image_field').find('.ui.image').attr('src', icon_src);
788 jQuery('#mainw_managesites_add_edit_site_upload_custom_icon').html(icon_img).show();
789 }
790 }
791 setTimeout(function () {
792 jQuery('#mainwp-upload-custom-icon-modal').modal('hide')
793 }, 1000);
794 });
795 return false;
796 });
797 });
798
799 } );
800 </script>
801 <?php
802 }
803 static::render_footer( $showpage );
804 MainWP_UI::render_modal_upload_icon();
805 }
806
807 /**
808 * Renders the Add New Site page navigation.
809 *
810 * Highlights the specified navigation item as active.
811 *
812 * @param bool $item_link Optional. Whether to render navigation items as links. Default false.
813 *
814 * @return void
815 */
816 private static function render_new_site_navigation( $item_link = false ) {
817
818 $active = isset( $_GET['menu_active'] ) ? sanitize_text_field( wp_unslash( $_GET['menu_active'] ) ) : 'single-site'; // phpcs:ignore -- NOSONAR - ok.
819
820 ?>
821 <div class="ui labeled icon inverted menu mainwp-sub-submenu" id="mainwp-add-sites-tabular-menu">
822 <a class="item <?php echo esc_attr( 'single-site' === $active ? 'active' : '' ); ?>>" data-tab="single-site" <?php echo $item_link ? 'href="admin.php?page=managesites&do=new&menu_active=single-site"' : ''; ?> >
823 <i class="wordpress icon"></i><?php //phpcs:ignore -- WP icon. ?>
824 <?php esc_html_e( 'Single Site', 'mainwp' ); ?>
825 </a>
826 <a class="item <?php echo esc_attr( 'multiple-site' === $active ? 'active' : '' ); ?>" data-tab="multiple-site" <?php echo $item_link ? 'href="admin.php?page=managesites&do=new&menu_active=multiple-site"' : ''; ?>>
827 <div class="icons" style="margin:0.5rem auto">
828 <i class="icon wordpress"></i><?php //phpcs:ignore -- WP icon. ?>
829 <i class="icon wordpress"></i><?php //phpcs:ignore -- WP icon. ?>
830 </div>
831 <?php esc_html_e( 'Multiple Sites', 'mainwp' ); ?>
832 </a>
833 <a class="item <?php echo esc_attr( 'import-sites' === $active ? 'active' : '' ); ?>" href="admin.php?page=managesites&do=bulknew&menu_active=import-sites">
834 <i class="file upload icon"></i>
835 <?php esc_html_e( 'Import Sites', 'mainwp' ); ?>
836 </a>
837 <?php
838 do_action( 'mainwp_add_site_top_navigation', $active, $item_link );
839 ?>
840 </div>
841 <?php
842 }
843
844 /**
845 * Method render_new_site_add_new_site()
846 *
847 * Render page managesites add new site.
848 *
849 * @uses MainWP_UI::get_default_icons()
850 * @uses MainWP_DB_Client::instance()->get_wp_client_by()
851 * @uses MainWP_Manage_Sites_View::render_sync_exts_settings()
852 *
853 * @param array $groups manage sites add groups.
854 */
855 public static function render_new_site_add_new_site( $groups ) {
856 ?>
857 <div class="ui grid field">
858 <label class="six wide column middle aligned"><?php esc_html_e( 'Site URL', 'mainwp' ); ?></label>
859 <div class="ui six wide column" data-tooltip="<?php esc_attr_e( 'Enter your website URL.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
860 <div class="ui left action input">
861 <select class="ui compact selection dropdown" id="mainwp_managesites_add_wpurl_protocol" name="mainwp_managesites_add_wpurl_protocol">
862 <option value="http"><?php echo esc_html( 'http://' ); ?></option>
863 <option selected="" value="https"><?php echo esc_html( 'https://' ); ?></option>
864 </select>
865 <input type="text" id="mainwp_managesites_add_wpurl" name="mainwp_managesites_add_wpurl" value="" autofocus />
866 </div>
867 </div>
868 <div class="ui four wide middle aligned column">
869 <input type="button" name="mainwp_managesites_edit_test" id="mainwp_managesites_test" class="ui button basic green" value="<?php esc_attr_e( 'Test Connection', 'mainwp' ); ?>"/>
870 </div>
871 </div>
872 <div class="ui grid field">
873 <label class="six wide column middle aligned"><?php esc_html_e( 'Confirm the MainWP Child plugin is active on this site', 'mainwp' ); ?></label>
874 <div class="six wide column ui toggle checkbox">
875 <input type="checkbox" name="mainwp_managesites_verify_installed_child" id="mainwp_managesites_verify_installed_child" />
876 <label><?php esc_attr_e( 'This confirms the required plugin is installed before proceeding.', 'mainwp' ); ?></label>
877 </div>
878 </div>
879
880 <div id="mainwp-add-site-hidden-form" style="display:none">
881 <h2 class="ui dividing header">
882 <?php esc_html_e( 'Configure Settings', 'mainwp' ); ?>
883 <div class="sub header">
884 <?php esc_html_e( 'Enter site connection details', 'mainwp' ); ?>
885 </div>
886 </h2>
887 <div class="ui grid field">
888 <label class="six wide column middle aligned"><?php esc_html_e( 'Administrator username', 'mainwp' ); ?></label>
889 <div class="ui six wide column" data-tooltip="<?php esc_attr_e( 'Enter the website Administrator username.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
890 <div class="ui left labeled input">
891 <input type="text" id="mainwp_managesites_add_wpadmin" name="mainwp_managesites_add_wpadmin" value="" />
892 </div>
893 </div>
894 </div>
895 <div class="ui hidden divider"></div>
896 <div class="ui grid field">
897 <label class="six wide column top aligned"><?php esc_html_e( 'Connection authentication method(s)', 'mainwp' ); ?></label>
898 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Select which connection authentication processes you are using.', 'mainwp' ); ?>" data-inverted="" data-position="left center">
899 <div class="ui toggle checked checkbox not-auto-init" id="addsite-adminpwd" style="margin-right:2em;">
900 <input type="checkbox" id="mainwp-administrator-password-checkbox-field" checked=""><label><?php esc_html_e( 'Administrator password', 'mainwp' ); ?></label>
901 </div>
902 <div class="ui toggle checkbox not-auto-init" id="addsite-uniqueid">
903 <input type="checkbox" id="mainwp-unique-security-id-checkbox-field"><label><?php esc_html_e( 'Unique Security ID', 'mainwp' ); ?></label>
904 </div>
905
906 <div class="ui fluid accordion" id="mainwp-connection-authentication-accordion" style="margin-top:1em">
907 <div class="title">
908 <i class="dropdown icon"></i>
909 <?php esc_html_e( 'Connection authentication methods explained', 'mainwp' ); ?>
910 </div>
911 <div class="content">
912 <span class="ui text"><?php esc_html_e( 'Choose options based on how the MainWP Child plugin is configured on your WordPress site.', 'mainwp' ); ?></span>
913
914 <h4 class="ui small header"><?php esc_html_e( 'Default Setup (most users)', 'mainwp' ); ?></h4>
915 <div class="item"><?php esc_html_e( 'Use Administrator Password only — this is the standard configuration.', 'mainwp' ); ?></div>
916
917 <h4 class="ui small header"><?php esc_html_e( 'Advanced Setup', 'mainwp' ); ?></h4>
918 <div class="item"><?php esc_html_e( 'If authentication was disabled in the Child plugin, turn both toggles off.', 'mainwp' ); ?></div>
919
920 <h4 class="ui small header"><?php esc_html_e( 'Toggle Summary', 'mainwp' ); ?></h4>
921 <div class="ui bulleted small list">
922 <div class="item"><?php esc_html_e( 'Password On → Displays the Password field.', 'mainwp' ); ?></div>
923 <div class="item"><?php esc_html_e( 'Security Key On → Displays the Security Key field.', 'mainwp' ); ?></div>
924 <div class="item"><?php esc_html_e( 'Both On → Displays both fields.', 'mainwp' ); ?></div>
925 <div class="item"><?php esc_html_e( 'Both Off → Hides both fields.', 'mainwp' ); ?></div>
926 </div>
927 <span class="ui text"><strong><?php esc_html_e( 'Your settings must match the Child plugin configuration. If unsure, use the default.', 'mainwp' ); ?></strong></span>
928 </div>
929 </div>
930 </div>
931 </div>
932 <div id="mainwp-administrator-password-field">
933 <input type="password" id="fake-disable-autofill" style="display:none;" name="fake-disable-autofill" />
934 <div class="ui grid field">
935 <label class="six wide column top aligned"><?php esc_html_e( 'Administrator password', 'mainwp' ); ?></label>
936 <div class="ui six wide column" data-tooltip="<?php esc_attr_e( 'Enter the website Administrator password.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
937 <div class="ui left labeled input">
938 <input type="password" id="mainwp_managesites_add_admin_pwd" name="mainwp_managesites_add_admin_pwd" autocomplete="one-time-code" autocorrect="off" autocapitalize="none" spellcheck="false" value="" />
939 </div>
940 <div class="ui hidden fitted divider"></div>
941 <span class="ui small text"><?php esc_html_e( 'Your password is never stored by your Dashboard and never sent to MainWP.com. Once this initial connection is complete, your MainWP Dashboard generates a secure Public and Private key pair (2048 bits) using OpenSSL, allowing future connections without needing your password again. For added security, you can even change this admin password once connected, just be sure not to delete the admin account, as this would disrupt the connection.', 'mainwp' ); ?></span>
942 </div>
943 </div>
944 </div>
945 <div id="mainwp-unique-security-id-field" style="display:none">
946 <div class="ui grid field">
947 <label class="six wide column middle aligned"><?php esc_html_e( 'Unique security ID', 'mainwp' ); ?></label>
948 <div class="ui six wide column" data-tooltip="<?php esc_attr_e( 'If in use, enter the website Unique ID.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
949 <div class="ui left labeled input">
950 <input type="text" id="mainwp_managesites_add_uniqueId" name="mainwp_managesites_add_uniqueId" value="" />
951 </div>
952 </div>
953 </div>
954 </div>
955 <div class="ui hidden divider"></div>
956 <div class="ui grid field">
957 <label class="six wide column middle aligned"><?php esc_html_e( 'Site title', 'mainwp' ); ?></label>
958 <div class="ui six wide column" data-tooltip="<?php esc_attr_e( 'Enter the website title.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
959 <div class="ui left labeled input">
960 <input type="text" id="mainwp_managesites_add_wpname" name="mainwp_managesites_add_wpname" value="" />
961 </div>
962 </div>
963 </div>
964 <div class="ui grid field">
965 <div class="six wide column middle aligned">
966 <a href="#" id="mainwp-add-site-advanced-options-toggle"><i class="eye slash outline icon"></i> <?php esc_html_e( 'Show Optional Settings', 'mainwp' ); ?></a>
967 </div>
968 <div class="six wide column middle aligned">
969 </div>
970 </div>
971
972 <div id="mainwp-add-site-advanced-options" class="ui secondary segment" style="display:none" >
973
974 <h2 class="ui dividing header">
975 <?php esc_html_e( 'Site Details', 'mainwp' ); ?>
976 <div class="sub header">
977 <?php esc_html_e( 'Optional fields to help identify and organize your site.', 'mainwp' ); ?>
978 </div>
979 </h2>
980
981 <div class="ui grid field">
982 <label class="six wide column middle aligned">
983 <?php esc_html_e( 'Upload site icon (Optional)', 'mainwp' ); ?>
984 </label>
985 <input type="hidden" name="mainwp_managesites_add_site_uploaded_icon_hidden" id="mainwp_managesites_add_site_uploaded_icon_hidden" value="">
986
987 <div class="three wide middle aligned column">
988 <span class="ui circular bordered image">
989 <div style="display:inline-block;" id="mainw_managesites_add_edit_site_upload_custom_icon"></div>
990 </span>
991 <div class="ui basic button mainwp-managesites-add-site-icon-customable" iconItemId="" iconFileSlug="" icon-src="" del-icon-nonce="">
992 <i class="image icon"></i> <?php esc_html_e( 'Upload Image', 'mainwp' ); ?>
993 </div>
994 </div>
995 </div>
996
997 <?php
998 $default_icons = MainWP_UI::get_default_icons();
999 $selected_default_icon = 'wordpress'; //phpcs:ignore -- WP icon.
1000 $selected_site_color = '#34424D';
1001 ?>
1002
1003 <div class="ui grid field">
1004 <label class="six wide column middle aligned">
1005 <?php esc_html_e( 'Select icon (Optional)', 'mainwp' ); ?>
1006 </label>
1007 <input type="hidden" name="mainwp_managesites_add_site_select_icon_hidden" id="mainwp_managesites_add_site_select_icon_hidden" value="">
1008 <div class="six wide column" data-tooltip="<?php esc_attr_e( 'Select an icon if not using original site icon.', 'mainwp' ); ?>" data-inverted="" data-position="left center">
1009 <div class="ui left action input mainwp-dropdown-color-picker-field">
1010 <div class="ui five column selection search dropdown not-auto-init" id="mainwp_manage_add_edit_site_icon_select">
1011 <div class="text">
1012 <span style="color:<?php echo esc_attr( $selected_site_color ); ?>" ><?php echo ! empty( $selected_default_icon ) ? '<i class="' . esc_attr( $selected_default_icon ) . ' icon"></i>' : ''; ?></span>
1013 </div>
1014 <i class="dropdown icon"></i>
1015 <div class="menu">
1016 <?php foreach ( $default_icons as $icon ) : ?>
1017 <?php echo '<div class="item" style="color:' . esc_attr( $selected_site_color ) . '" data-value="' . esc_attr( $icon ) . '"><i class="' . esc_attr( $icon ) . ' icon"></i></div>'; ?>
1018 <?php endforeach; ?>
1019 </div>
1020 </div>
1021 <input type="color" data-tooltip="Color will update on save" data-position="top center" data-inverted="" name="mainwp_managesites_add_site_color" class="mainwp-color-picker-input" id="mainwp_managesites_add_site_color" value="<?php echo esc_attr( $selected_site_color ); ?>" />
1022 </div>
1023 </div>
1024 <div class="one wide column"></div>
1025 </div>
1026 <div class="ui grid field">
1027 <label class="six wide column middle aligned">
1028 <?php esc_html_e( 'Tags (optional)', 'mainwp' ); ?>
1029 </label>
1030 <div class="ten wide column">
1031 <div class="ui multiple search selection dropdown" init-value="" id="mainwp_managesites_add_addgroups">
1032 <i class="dropdown icon"></i>
1033 <div class="default text"></div>
1034 <div class="menu">
1035 <?php foreach ( $groups as $group ) { ?>
1036 <div class="item" data-value="<?php echo intval( $group->id ); ?>"><?php echo esc_html( stripslashes( $group->name ) ); ?></div>
1037 <?php } ?>
1038 </div>
1039 </div>
1040 </div>
1041 </div>
1042 <?php
1043 if ( \mainwp_current_user_can( 'dashboard', 'manage_clients' ) ) {
1044 $clients = MainWP_DB_Client::instance()->get_wp_client_by( 'all' );
1045 ?>
1046 <div class="ui grid field">
1047 <label class="six wide column middle aligned"><?php esc_html_e( 'Client (optional)', 'mainwp' ); ?></label>
1048 <div class="ten wide column">
1049 <div class="ui search selection dropdown" init-value="" id="mainwp_managesites_add_client_id">
1050 <i class="dropdown icon"></i>
1051 <div class="default text"></div>
1052 <div class="menu">
1053 <div class="item" data-value="0"><?php esc_attr_e( 'Select client', 'mainwp' ); ?></div>
1054 <?php foreach ( $clients as $client ) { ?>
1055 <div class="item" data-value="<?php echo intval( $client->client_id ); ?>"><?php echo esc_html( $client->name ); ?></div>
1056 <?php } ?>
1057 </div>
1058 </div>
1059 </div>
1060 </div>
1061 <?php } ?>
1062
1063 <!-- fake fields are a workaround for chrome autofill getting the wrong fields. -->
1064 <input style="display:none" type="text" name="fakeusernameremembered"/>
1065 <input style="display:none" type="password" name="fakepasswordremembered"/>
1066
1067 <h2 class="ui dividing header">
1068 <?php esc_html_e( 'Advanced Settings', 'mainwp' ); ?>
1069 <div class="sub header">
1070 <?php esc_html_e( 'Extra options for special cases, modify only if needed.', 'mainwp' ); ?>
1071 </div>
1072 </h2>
1073
1074 <div class="ui grid field settings-field-indicator-wrapper">
1075 <label class="six wide column middle aligned"><?php esc_html_e( 'Verify SSL certificate (optional)', 'mainwp' ); ?></label>
1076 <div class="six wide column ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'Disabling this is only necessary if your site\'s SSL certificate is broken or self-signed. For security, keep it enabled unless you experience connection issues.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1077 <input type="checkbox" name="mainwp_managesites_verify_certificate" id="mainwp_managesites_verify_certificate" checked="true" />
1078 </div>
1079 </div>
1080
1081 <div class="ui grid field">
1082 <label class="six wide column middle aligned"><?php esc_html_e( 'SSL version (optional)', 'mainwp' ); ?></label>
1083 <div class="ui six wide column" data-tooltip="<?php esc_attr_e( 'This setting is only needed in rare cases where the default Auto-Detect option fails, usually on outdated servers with old SSL protocols. If unsure, keep it set to Auto-Detect for best compatibility.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1084 <select class="ui dropdown" id="mainwp_managesites_add_ssl_version" name="mainwp_managesites_add_ssl_version">
1085 <option value="0"><?php esc_html_e( 'Auto detect', 'mainwp' ); ?></option>
1086 <option value="6"><?php esc_html_e( 'TLS v1.2', 'mainwp' ); ?></option>
1087 <option value="1"><?php esc_html_e( 'TLS v1.x', 'mainwp' ); ?></option>
1088 <option value="2"><?php esc_html_e( 'SSL v2', 'mainwp' ); ?></option>
1089 <option value="3"><?php esc_html_e( 'SSL v3', 'mainwp' ); ?></option>
1090 <option value="4"><?php esc_html_e( 'TLS v1.0', 'mainwp' ); ?></option>
1091 <option value="5"><?php esc_html_e( 'TLS v1.1', 'mainwp' ); ?></option>
1092 </select>
1093 </div>
1094 </div>
1095
1096 <div class="ui grid field">
1097 <label class="six wide column middle aligned"><?php esc_html_e( 'HTTP username (optional)', 'mainwp' ); ?></label>
1098 <div class="ui six wide column" data-tooltip="<?php esc_attr_e( 'If the child site is HTTP Basic Auth protected, enter the HTTP username here.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1099 <div class="ui left labeled input">
1100 <input type="text" id="mainwp_managesites_add_http_user" name="mainwp_managesites_add_http_user" value="" autocomplete="off" />
1101 </div>
1102 </div>
1103 </div>
1104
1105 <div class="ui grid field">
1106 <label class="six wide column middle aligned"><?php esc_html_e( 'HTTP password (optional)', 'mainwp' ); ?></label>
1107 <div class="ui six wide column" data-tooltip="<?php esc_attr_e( 'If the child site is HTTP Basic Auth protected, enter the HTTP password here.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1108 <div class="ui left labeled input">
1109 <input type="password" id="mainwp_managesites_add_http_pass" name="mainwp_managesites_add_http_pass" value="" autocomplete="new-password" />
1110 </div>
1111 </div>
1112 </div>
1113
1114 <?php MainWP_Manage_Sites_View::render_sync_exts_settings(); ?>
1115 </div>
1116
1117 <?php
1118 do_action_deprecated( 'mainwp-manage-sites-edit', array( false ), '4.0.7.2', 'mainwp_manage_sites_edit' ); // @deprecated Use 'mainwp_manage_sites_edit' instead. NOSONAR - not IP.
1119
1120 /**
1121 * Edit site
1122 *
1123 * Fires on the Edit child site page and allows user to hook in new site options.
1124 *
1125 * @param bool false
1126 */
1127 do_action( 'mainwp_manage_sites_edit', false );
1128 ?>
1129
1130 <div class="ui divider"></div>
1131 <input type="button" name="mainwp_managesites_add" id="mainwp_managesites_add" class="ui button green big" value="<?php esc_attr_e( 'Add Site', 'mainwp' ); ?>" />
1132 <div class="ui hidden clearing divider"></div>
1133 </div>
1134 <?php
1135 static::render_add_site_scripts();
1136 }
1137
1138 /**
1139 * Render add site scripts.
1140 *
1141 * @return void
1142 */
1143 public static function render_add_site_scripts() {
1144 ?>
1145 <script type="text/javascript">
1146 jQuery( document ).ready( function () {
1147 let adminwpTip = jQuery('#mainwp-connection-authentication-accordion').accordion({
1148 onChange:function(){
1149 mainwp_ui_state_save( 'adminpwd_tip_showhide', jQuery(this).hasClass('active') ? 1 : 0 );
1150 }
1151 });
1152
1153 mainwp_ui_state_init('adminpwd_tip_showhide', function(state){
1154 if( '1' === state ){
1155 adminwpTip.accordion('open', 0);
1156 } else {
1157 adminwpTip.accordion('close', 0);
1158 }
1159 });
1160
1161 let chkbx1 = jQuery('#addsite-adminpwd').checkbox({
1162 onChange:function(){
1163 mainwp_ui_state_save( 'addsite-adminpwd', jQuery(this).is(':checked') ? 2 : 0 );
1164 if(jQuery(this).is(':checked')){
1165 jQuery('#mainwp-administrator-password-field').fadeIn(500);
1166 } else {
1167 jQuery('#mainwp-administrator-password-field').fadeOut(500);
1168 }
1169 }
1170 });
1171
1172 let chkbx2 = jQuery('#addsite-uniqueid').checkbox({
1173 onChange:function(){
1174 mainwp_ui_state_save( 'addsite-uniqueid', jQuery(this).is(':checked') ? 2 : 0 );
1175 if(jQuery(this).is(':checked')){
1176 jQuery('#mainwp-unique-security-id-field').fadeIn(500);
1177 } else {
1178 jQuery('#mainwp-unique-security-id-field').fadeOut(500);
1179 }
1180 }
1181 });
1182
1183 mainwp_ui_state_init('addsite-adminpwd', function(state){
1184 if( '1' === state || '0' === state ){
1185 chkbx1.checkbox('set unchecked');
1186 jQuery('#mainwp-administrator-password-field').fadeOut(500);
1187 } else {
1188 chkbx1.checkbox('set checked');
1189 jQuery('#mainwp-administrator-password-field').fadeIn(500);
1190 }
1191 });
1192
1193
1194 mainwp_ui_state_init('addsite-uniqueid', function(state){
1195 if( '1' === state || '0' === state ){
1196 chkbx2.checkbox('set unchecked');
1197 jQuery('#mainwp-unique-security-id-field').fadeOut(500);
1198 } else {
1199 chkbx2.checkbox('set checked');
1200 jQuery('#mainwp-unique-security-id-field').fadeIn(500);
1201 }
1202 });
1203 });
1204 </script>
1205 <?php
1206 }
1207
1208 /**
1209 * Method render_new_site_add_multi_new_site()
1210 *
1211 * Render page managesites add multi new site.
1212 *
1213 * @uses static::mainwp_managesites_form_import_sites()
1214 */
1215 public static function render_new_site_add_multi_new_site() {
1216 ?>
1217 <h2 class="ui dividing header">
1218 <?php echo esc_html__( 'Connect Multiple Sites', 'mainwp' ); ?>
1219 <div class="sub header"><?php echo esc_html__( 'Connect multiple sites to your MainWP Dashboard for centralized management.', 'mainwp' ); ?></div>
1220 </h2>
1221 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-add-multiple-sites-info-message' ) ) : ?>
1222 <div class="ui blue message">
1223 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-add-multiple-sites-info-message"></i>
1224 <?php static::mainwp_managesites_information_import_sites(); ?>
1225 </div>
1226 <?php endif; ?>
1227
1228 <div id="mainwp-add-multi-new-site-message-zone" style="display: none;" class="ui message"></div>
1229
1230 <?php static::mainwp_managesites_form_import_sites(); // NOSONAR - render html form. ?>
1231
1232 <div class="ui divider"></div>
1233 <input type="button" name="mainwp_managesites_add" id="mainwp_managesites_add_multi_site" class="ui big green button" value="<?php esc_html_e( 'Add Sites', 'mainwp' ); ?>"/>
1234 <div class="ui hidden divider"></div>
1235 <?php
1236 }
1237
1238 /**
1239 * Method ajax_upload_icon()
1240 */
1241 public static function ajax_upload_icon() { //phpcs:ignore -- NOSONAR - complex.
1242 MainWP_Post_Handler::instance()->secure_request( 'mainwp_managesites_add_edit_site_upload_site_icon' );
1243
1244 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1245 $iconfile_slug = isset( $_POST['iconFileSlug'] ) ? sanitize_text_field( wp_unslash( $_POST['iconFileSlug'] ) ) : '';
1246 $delete = isset( $_POST['delete'] ) ? intval( $_POST['delete'] ) : 0;
1247 $site_id = isset( $_POST['iconItemId'] ) ? intval( $_POST['iconItemId'] ) : 0;
1248 $delnonce = isset( $_POST['delnonce'] ) ? sanitize_key( $_POST['delnonce'] ) : '';
1249
1250 if ( $delete ) {
1251 if ( ! MainWP_System_Utility::is_valid_custom_nonce( 'site', $iconfile_slug, $delnonce ) ) {
1252 die( 'Invalid nonce!' );
1253 }
1254 if ( $site_id ) {
1255 $website = MainWP_DB::instance()->get_website_by_id( $site_id );
1256 if ( $website && ! empty( $website->cust_site_icon_info ) ) {
1257 $uploaded_site_icon = static::get_instance()->get_cust_site_icon( $website->cust_site_icon_info, 'uploaded' );
1258 if ( ! empty( $uploaded_site_icon ) ) {
1259 $tmp = explode( ';', $website->cust_site_icon_info );
1260 $new_info = 'uploaded:;' . $tmp[1] . ';' . $tmp[2];
1261 MainWP_DB::instance()->update_website_option( $website, 'cust_site_icon_info', $new_info ); // to delete uploaded icon.
1262 MainWP_Utility::instance()->delete_uploaded_icon_file( 'site-icons', $uploaded_site_icon );
1263 }
1264 }
1265 } elseif ( ! empty( $iconfile_slug ) ) {
1266 MainWP_Utility::instance()->delete_uploaded_icon_file( 'site-icons', $iconfile_slug );
1267 }
1268 wp_die( wp_json_encode( array( 'result' => 'success' ) ) );
1269 }
1270
1271 $output = isset( $_FILES['mainwp_upload_icon_uploader'] ) ? MainWP_System_Utility::handle_upload_image( 'site-icons', $_FILES['mainwp_upload_icon_uploader'] ) : null;
1272 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1273
1274 $uploaded_icon = 'NOTCHANGE';
1275 if ( is_array( $output ) && isset( $output['filename'] ) && ! empty( $output['filename'] ) ) {
1276 $uploaded_icon = $output['filename'];
1277 }
1278
1279 if ( 'NOTCHANGE' !== $uploaded_icon ) {
1280 $dirs = MainWP_System_Utility::get_mainwp_dir( 'site-icons', true );
1281 $icon_url = $dirs[1] . $uploaded_icon;
1282 wp_die(
1283 wp_json_encode(
1284 array(
1285 'result' => 'success',
1286 'iconfile' => esc_html( $uploaded_icon ),
1287 'iconsrc' => esc_html( $icon_url ),
1288 'iconimg' => '<img class="ui circular image" src="' . esc_attr( $icon_url ) . '" style="width:32px;height:auto;display:inline-block;" alt="Custom icon">',
1289 'iconnonce' => MainWP_System_Utility::get_custom_nonce( 'site', esc_html( $uploaded_icon ) ),
1290 )
1291 )
1292 );
1293 } else {
1294 $result = array(
1295 'result' => 'failed',
1296 );
1297 $error = MainWP_Post_Handler::get_upload_icon_error( $output );
1298 if ( ! empty( $error ) ) {
1299 $result['error'] = esc_html( $error );
1300 }
1301 wp_die( wp_json_encode( $result ) );
1302 }
1303 }
1304
1305 /**
1306 * Method get_site_icon_display()
1307 *
1308 * Get site icon.
1309 *
1310 * @param string $icon_data icon data.
1311 * @param string $favi_url favico url.
1312 */
1313 public function get_site_icon_display( $icon_data, $favi_url ) {
1314 $output = '';
1315 // 1 priority.
1316 if ( ! empty( $icon_data ) ) {
1317 $uploaded = $this->get_cust_site_icon( $icon_data, 'uploaded' );
1318 if ( ! empty( $uploaded ) ) {
1319 $output = $this->get_cust_site_icon( $icon_data, 'display' );
1320 }
1321 }
1322
1323 // 2 priority.
1324 if ( empty( $output ) && ! empty( $favi_url ) ) {
1325 $output = '<img src="' . esc_attr( $favi_url ) . '" style="width:28px;height:28px;" class="ui circular image" alt="Site icon"/>';
1326 }
1327
1328 // 3 priority.
1329 $selected = $this->get_cust_site_icon( $icon_data, 'selected' );
1330 if ( empty( $output ) && ! empty( $selected ) ) {
1331 $output = $this->get_cust_site_icon( $icon_data, 'display_selected' );
1332 }
1333
1334 if ( empty( $output ) ) {
1335 $output = '<i class="icon big wordpress" style="width:28px;height:28px;"></i> '; // phpcs:ignore -- WP icon.
1336 }
1337
1338 // last default.
1339 return $output;
1340 }
1341
1342 /**
1343 * Method get_cust_site_icon()
1344 *
1345 * Get site icon.
1346 *
1347 * @param string $icon_data icon data.
1348 * @param string $type Type: uploaded|selected|color|display.
1349 */
1350 public function get_cust_site_icon( $icon_data, $type = 'display' ) { //phpcs:ignore -- NOSONAR - complex.
1351
1352 if ( empty( $icon_data ) ) {
1353 return '';
1354 }
1355 $data = explode( ';', $icon_data );
1356
1357 $uploaded = ! empty( $data[0] ) ? str_replace( 'uploaded:', '', $data[0] ) : '';
1358 $selected = ! empty( $data[1] ) ? str_replace( 'selected:', '', $data[1] ) : '';
1359 $color = ! empty( $data[2] ) ? str_replace( 'color:', '', $data[2] ) : '';
1360
1361 if ( empty( $color ) ) {
1362 $color = '#34424D';
1363 }
1364
1365 if ( 'display_selected' === $type ) {
1366 if ( empty( $selected ) ) {
1367 $selected = 'wordpress'; // phpcs:ignore -- WP icon.
1368 }
1369 return '<span style="color:' . esc_attr( $color ) . '" ><i class="' . esc_attr( $selected ) . ' big icon"></i></span>';
1370 }
1371
1372 $output = '';
1373 if ( 'uploaded' === $type ) {
1374 $output = $uploaded;
1375 } elseif ( 'selected' === $type ) {
1376 $output = $selected;
1377 } elseif ( 'color' === $type ) {
1378 $output = $color;
1379 } elseif ( 'display' === $type || 'display_edit' === $type ) {
1380 $style = 'width:28px;height:auto;display:inline-block;';
1381 $default_cls = 'mainw_site_custom_icon_display';
1382 $icon = '';
1383 if ( ! empty( $uploaded ) ) {
1384 $dirs = MainWP_System_Utility::get_mainwp_dir( 'site-icons', true );
1385 $icon_base = $dirs[1];
1386 $scr = $icon_base . $uploaded;
1387 $icon_wrapper_attr = ' class="' . esc_attr( $default_cls ) . ' ui circular image " ';
1388 if ( 'display_edit' === $type ) {
1389 $icon_wrapper_attr = ' id="mainw_managesites_add_edit_site_upload_custom_icon" class="' . esc_attr( $default_cls ) . ' ui circular image" ';
1390 }
1391 $icon = '<div style="display:inline-block;" ' . $icon_wrapper_attr . '><img style="' . $style . '" src="' . esc_attr( $scr ) . '" alt="Site icon"/></div>';
1392 }
1393 $output = $icon;
1394 }
1395 return $output;
1396 }
1397
1398
1399 /**
1400 * Method render_bulk_new_site()
1401 *
1402 * Render Import Sites - bulk new site modal.
1403 *
1404 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::render_import_sites()
1405 * @uses \MainWP_Utility::show_mainwp_message()
1406 */
1407 public static function render_bulk_new_site() {
1408 $title_page = esc_html__( 'Import Sites', 'mainwp' );
1409 $showpage = 'BulkAddNew';
1410 static::render_header( $showpage );
1411 $has_file_upload = isset( $_FILES['mainwp_managesites_file_bulkupload'] ) && isset( $_FILES['mainwp_managesites_file_bulkupload']['error'] ) && UPLOAD_ERR_OK === $_FILES['mainwp_managesites_file_bulkupload']['error'];
1412 $has_import_data = ! empty( $_POST['mainwp_managesites_import'] );
1413
1414 if ( ! \mainwp_current_user_can( 'dashboard', 'add_sites' ) ) {
1415 \mainwp_do_not_have_permissions( esc_html__( 'add sites', 'mainwp' ) );
1416 return;
1417 } elseif ( ( $has_file_upload || $has_import_data ) && check_admin_referer( 'mainwp-admin-nonce' ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
1418 static::render_import_sites_modal( 'admin.php?page=managesites&do=bulknew', $title_page );
1419 } else {
1420 self::render_new_site_navigation( true );
1421
1422 $active = 'import-sites';
1423
1424 if ( isset( $_GET['menu_active'] ) ) {
1425 $active = sanitize_text_field( wp_unslash( $_GET['menu_active'] ) ); // phpcs:ignore -- NOSONAR - ok. 'single-site';
1426 }
1427
1428 ?>
1429 <div id="mainwp-import-sites" class="ui padded segment <?php echo esc_attr( 'import-sites' === $active ? 'active' : '' ); ?>">
1430 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-import-new-sites-info-message' ) ) : ?>
1431 <div class="ui message">
1432 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-import-new-sites-info-message"></i>
1433 <?php /* translators: 1: Bulb emoji element, 2: Opening link tag, 3: Closing link tag */ printf( esc_html__( '%1$s Tip: If you\'re importing 10 or fewer sites, we recommend using the %2$sAdd Multiple Sites%3$s screen instead , it\'s faster and doesn\'t require a CSV file.', 'mainwp' ), '<em data-emoji=":bulb:" class="small"></em>', '<a href="admin.php?page=managesites&do=new&data-tab=multiple-site">', '</a>' ); ?>
1434 </div>
1435 <?php endif; ?>
1436 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-import-sites-info-message' ) ) : ?>
1437 <div class="ui info message">
1438 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-import-sites-info-message"></i>
1439 <?php /* translators: 1: Opening link tag, 2: Closing link tag with icon */ printf( esc_html__( 'You can download the sample CSV file to see how to format the import file properly. For additional help, please check this %1$shelp documentation%2$s.', 'mainwp' ), '<a href="https://docs.mainwp.com/sites/management/manage-child-sites?search=Test+Connection#import-sites-csv-import" target="_blank">', '</a> <i class="external alternate icon"></i>' ); // NOSONAR - noopener - open safe. ?>
1440 </div>
1441 <?php endif; ?>
1442 <form method="POST" action="" enctype="multipart/form-data" id="mainwp_managesites_bulkadd_form" class="ui form">
1443 <div id="mainwp-message-zone" class="ui message" style="display:none"></div>
1444 <h2 class="ui dividing header">
1445 <?php echo esc_html( $title_page ); ?>
1446 <div class="sub header"><?php esc_html_e( 'Import multiple websites to your MainWP Dashboard.', 'mainwp' ); ?></div>
1447 </h2>
1448 <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
1449 <div class="ui grid field">
1450 <label class="three wide column middle aligned" for="mainwp_managesites_file_bulkupload"><?php esc_html_e( 'Upload CSV', 'mainwp' ); ?> (<a href="<?php echo esc_url( MAINWP_PLUGIN_URL . 'assets/csv/sample.csv' ); ?>"><?php esc_html_e( 'Download Sample', 'mainwp' ); ?></a>)</label>
1451 <div class="nine wide column">
1452 <div class="ui file input">
1453 <input type="file" name="mainwp_managesites_file_bulkupload" id="mainwp_managesites_file_bulkupload" accept="text/comma-separated-values"/>
1454 </div>
1455 </div>
1456 <div class="ui toggle checkbox four wide column middle aligned">
1457 <input type="checkbox" name="mainwp_managesites_chk_header_first" checked="checked" id="mainwp_managesites_chk_header_first" value="1"/>
1458 <label for="mainwp_managesites_chk_header_first"><?php esc_html_e( 'CSV file contains a header', 'mainwp' ); ?></label>
1459 </div>
1460 </div>
1461 <div class="ui divider"></div>
1462 <input type="button" name="mainwp_managesites_add" id="mainwp_managesites_bulkadd" class="ui big green button" value="<?php echo esc_attr( $title_page ); ?>"/>
1463 </form>
1464 </div>
1465 <?php
1466 }
1467 static::render_footer( $showpage );
1468 }
1469
1470 /**
1471 * Method on_load_page_dashboard()
1472 *
1473 * Add individual meta boxes.
1474 *
1475 * @uses \MainWP\Dashboard\MainWP_System_Handler::apply_filters()
1476 * @uses \MainWP\Dashboard\MainWP_UI::add_widget_box()
1477 * @uses \MainWP\Dashboard\MainWP_Notes::get_class_name()
1478 * @uses \MainWP\Dashboard\MainWP_Recent_Pages::get_class_name()
1479 * @uses \MainWP\Dashboard\MainWP_Recent_Posts::get_class_name()
1480 * @uses \MainWP\Dashboard\MainWP_Security_Issues_Widget::get_class_name()
1481 * @uses \MainWP\Dashboard\MainWP_Site_Info::get_class_name()
1482 * @uses \MainWP\Dashboard\MainWP_Updates_Overview::get_class_name()
1483 * @uses \MainWP\Dashboard\MainWP_Widget_Plugins::get_class_name()
1484 * @uses \MainWP\Dashboard\MainWP_Widget_Themes::get_class_name()
1485 */
1486 public static function on_load_page_dashboard() { // phpcs:ignore -- NOSONAR - current complexity is required to achieve desired results. Pull request solutions are welcome.
1487 wp_enqueue_script( 'common' );
1488 wp_enqueue_script( 'wp-lists' );
1489 wp_enqueue_script( 'postbox' );
1490 wp_enqueue_script( 'dashboard' );
1491 wp_enqueue_script( 'widgets' );
1492
1493 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1494 $dashboard_siteid = isset( $_GET['dashboard'] ) ? intval( $_GET['dashboard'] ) : null;
1495 // phpcs:enable
1496
1497 /**
1498 * Get getmetaboxes
1499 *
1500 * Adds metaboxes (widgets) to the Operations page.
1501 *
1502 * @since Unknown
1503 */
1504 $extMetaBoxs = MainWP_System_Handler::instance()->apply_filters( 'mainwp-getmetaboxes', array() ); // @deprecated Use 'mainwp_getmetaboxes' instead.
1505 $extMetaBoxs = apply_filters( 'mainwp_getmetaboxes', $extMetaBoxs, $dashboard_siteid ); // hooks load widgets for individual overview page and for manage sites's subpage.
1506
1507 foreach ( $extMetaBoxs as $box ) {
1508 // to compatible.
1509 if ( isset( $box['custom'] ) && $box['custom'] && isset( $box['plugin'] ) ) {
1510 continue;
1511 }
1512
1513 if ( isset( $box['plugin'] ) ) {
1514 $name = basename( $box['plugin'], '.php' );
1515 static::$enable_widgets[ $name ] = true;
1516 } elseif ( isset( $box['widget_id'] ) ) {
1517 static::$enable_widgets[ $box['widget_id'] ] = true;
1518 }
1519 }
1520
1521 $values = static::$enable_widgets;
1522
1523 /**
1524 * Unset unwanted Widgets
1525 *
1526 * Contains the list of enabled widgets and allows user to unset unwanted widgets.
1527 *
1528 * @param array $values Array containing enabled widgets.
1529 * @param int $dashboard_siteid Child site (Overview) ID.
1530 *
1531 * @since 4.0
1532 */
1533 $values = apply_filters( 'mainwp_overview_enabled_widgets', $values, $dashboard_siteid );
1534 static::$enable_widgets = array_merge( static::$enable_widgets, $values );
1535
1536 // Load the Updates Overview widget.
1537 if ( static::$enable_widgets['overview'] ) {
1538 MainWP_UI::add_widget_box( 'overview', array( MainWP_Updates_Overview::get_class_name(), 'render' ), static::$page, array( 1, 1, 12, 19 ) );
1539 }
1540
1541 // Load the Uptime monitoring widget.
1542 if ( MainWP_Uptime_Monitoring_Edit::is_enable_global_monitoring() && \mainwp_current_user_can( 'dashboard', 'manage_uptime_monitoring' ) && static::$enable_widgets['uptime_monitoring_response_time'] ) {
1543 MainWP_UI::add_widget_box( 'uptime_monitoring_response_time', array( MainWP_Uptime_Monitoring_Site_Widget::instance(), 'render_response_times_widget' ), static::$page, array( -1, -1, 12, 43 ) );
1544 }
1545
1546 // Load the Themes widget.
1547 if ( static::$enable_widgets['themes'] ) {
1548 MainWP_UI::add_widget_box( 'themes', array( MainWP_Widget_Themes::get_class_name(), 'render' ), static::$page, array( -1, -1, 6, 30 ) );
1549 }
1550
1551 // Load the Pluins widget.
1552 if ( static::$enable_widgets['plugins'] ) {
1553 MainWP_UI::add_widget_box( 'plugins', array( MainWP_Widget_Plugins::get_class_name(), 'render' ), static::$page, array( -1, -1, 6, 30 ) );
1554 }
1555
1556 // Load the Non-MainWP Changes widget.
1557 if ( static::$enable_widgets['non_mainwp_changes'] ) {
1558 MainWP_UI::add_widget_box( 'non_mainwp_changes', array( MainWP_Site_Actions::get_class_name(), 'render' ), static::$page, array( -1, -1, 6, 30 ) );
1559 }
1560
1561 // Load the Client widget.
1562 if ( static::$enable_widgets['client_info'] && \mainwp_current_user_can( 'dashboard', 'manage_clients' ) ) {
1563 MainWP_UI::add_widget_box( 'client_info', array( MainWP_Client_Info::get_class_name(), 'render' ), static::$page, array( -1, -1, 3, 30 ) );
1564 }
1565
1566 // Load the Notes widget.
1567 if ( static::$enable_widgets['notes'] ) {
1568 MainWP_UI::add_widget_box( 'notes', array( MainWP_Notes::get_class_name(), 'render' ), static::$page, array( -1, -1, 3, 30 ) );
1569 }
1570
1571 // Load the Site Info widget.
1572 MainWP_UI::add_widget_box( 'child_site_info', array( MainWP_Site_Info::get_class_name(), 'render' ), static::$page, array( -1, -1, 4, 30 ) );
1573
1574 // Load the Recent Pages widget.
1575 if ( \mainwp_current_user_can( 'dashboard', 'manage_pages' ) && static::$enable_widgets['recent_pages'] ) {
1576 MainWP_UI::add_widget_box( 'recent_pages', array( MainWP_Recent_Pages::get_class_name(), 'render' ), static::$page, array( -1, -1, 4, 30 ) );
1577 }
1578
1579 // Load the Recent Posts widget.
1580 if ( \mainwp_current_user_can( 'dashboard', 'manage_posts' ) && static::$enable_widgets['recent_posts'] ) {
1581 MainWP_UI::add_widget_box( 'recent_posts', array( MainWP_Recent_Posts::get_class_name(), 'render' ), static::$page, array( -1, -1, 4, 30 ) );
1582 }
1583
1584 $i = 0;
1585 foreach ( $extMetaBoxs as $metaBox ) {
1586 $enabled = true;
1587 if ( isset( $metaBox['plugin'] ) ) {
1588 $name = basename( $metaBox['plugin'], '.php' );
1589 if ( isset( static::$enable_widgets[ $name ] ) && ! static::$enable_widgets[ $name ] ) {
1590 $enabled = false;
1591 }
1592 }
1593
1594 $id = isset( $metaBox['id'] ) ? $metaBox['id'] : $i++;
1595 $id = 'advanced-' . $id;
1596
1597 if ( $enabled ) {
1598 $layout = array( -1, -1, 6, 30 );
1599 if ( isset( $metaBox['id'] ) && ( 'google-widget' === $metaBox['id'] || 'matomo' === $metaBox['id'] ) ) {
1600 $layout = array( -1, -1, 6, 30 );
1601 }
1602 $layout = ! empty( $metaBox['layout'] ) && is_array( $metaBox['layout'] ) ? $metaBox['layout'] : $layout;
1603 MainWP_UI::add_widget_box( $id, $metaBox['callback'], static::$page, $layout );
1604 }
1605 }
1606 }
1607
1608 /**
1609 * Method render_updates()
1610 *
1611 * Render updates.
1612 *
1613 * @param mixed $website Child Site.
1614 *
1615 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_Update_View::render_updates()
1616 * @uses \MainWP\Dashboard\MainWP_System_Utility::set_current_wpid()
1617 */
1618 public static function render_updates( $website ) {
1619 MainWP_System_Utility::set_current_wpid( $website->id );
1620 static::render_header( 'ManageSitesUpdates' );
1621 MainWP_Manage_Sites_Update_View::render_updates( $website );
1622 static::render_footer( 'ManageSitesUpdates' );
1623 }
1624
1625 /**
1626 * Method render_email_settings()
1627 *
1628 * Render email settings.
1629 *
1630 * @param mixed $website Child Site.
1631 * @param bool $updated updated settings.
1632 * @param bool $updated_templ updated template file.
1633 * @param bool $editing_temp editing template file.
1634 *
1635 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
1636 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::render_site_edit_email_settings()
1637 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_notification_types()
1638 * @uses \MainWP\Dashboard\MainWP_System_Utility::set_current_wpid()
1639 */
1640 public static function render_email_settings( $website, $updated = false, $updated_templ = false, $editing_temp = false ) {
1641 $website = MainWP_DB::instance()->get_website_by_id( $website->id, false, array( 'monitoring_notification_emails', 'settings_notification_emails' ) ); // reload.
1642
1643 MainWP_System_Utility::set_current_wpid( $website->id );
1644
1645 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1646 $edit = false;
1647 $email_type = isset( $_GET['edit-email'] ) ? sanitize_text_field( wp_unslash( $_GET['edit-email'] ) ) : false;
1648
1649 if ( ! empty( $email_type ) ) {
1650 $notification_emails = MainWP_Notification_Settings::get_notification_types();
1651 if ( isset( $notification_emails[ $email_type ] ) ) {
1652 $edit = true;
1653 }
1654 }
1655 // phpcs:enable
1656
1657 if ( $editing_temp ) {
1658 static::render_header( 'ManageSitesEdit' );
1659 }
1660 if ( $edit ) {
1661 MainWP_Manage_Sites_View::render_site_edit_email_settings( $website, $email_type, $updated_templ );
1662 } else {
1663 MainWP_Manage_Sites_View::render_edit_site_email_settings( $website, $updated );
1664 }
1665 if ( $editing_temp ) {
1666 static::render_footer( 'ManageSitesEdit' );
1667 }
1668 }
1669
1670 /**
1671 * Method render_dashboard()
1672 *
1673 * Render Manage Sites Dashboard.
1674 *
1675 * @param mixed $website Child Site.
1676 *
1677 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::render_dashboard()
1678 * @uses \MainWP\Dashboard\MainWP_System_Utility::set_current_wpid()
1679 */
1680 public static function render_dashboard( $website ) {
1681 MainWP_System_Utility::set_current_wpid( $website->id );
1682 static::render_header( 'ManageSitesDashboard' );
1683 MainWP_Manage_Sites_View::render_dashboard( $website );
1684 static::render_footer( 'ManageSitesDashboard' );
1685 }
1686
1687 /**
1688 * Method render_backup_site()
1689 *
1690 * Render Manage Sites Backups.
1691 *
1692 * @param mixed $website Child Site.
1693 *
1694 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_Backup_View::render_backup_site()
1695 * @uses \MainWP\Dashboard\MainWP_System_Utility::set_current_wpid()
1696 */
1697 public static function render_backup_site( $website ) {
1698 MainWP_System_Utility::set_current_wpid( $website->id );
1699 static::render_header( 'ManageSitesBackups' );
1700 MainWP_Manage_Sites_Backup_View::render_backup_site( $website );
1701 static::render_footer( 'ManageSitesBackups' );
1702 }
1703
1704 /**
1705 * Method render_scan_site()
1706 *
1707 * Render Site Hardening.
1708 *
1709 * @param mixed $website Child Site.
1710 *
1711 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::render_scan_site()
1712 * @uses \MainWP\Dashboard\MainWP_System_Utility::set_current_wpid()
1713 */
1714 public static function render_scan_site( $website ) {
1715 MainWP_System_Utility::set_current_wpid( $website->id );
1716 static::render_header( 'SecurityScan' );
1717 MainWP_Manage_Sites_View::render_scan_site( $website );
1718 static::render_footer( 'SecurityScan' );
1719 }
1720
1721 /**
1722 * Method render_monitor_site()
1723 *
1724 * @param mixed $website Child Site.
1725 */
1726 public static function render_monitor_site( $website ) {
1727 MainWP_System_Utility::set_current_wpid( $website->id );
1728 static::render_header( 'ManageSitesMonitor' );
1729 MainWP_Uptime_Monitoring_Edit::instance()->render_monitor_settings( $website->id, true );
1730 static::render_footer( 'ManageSitesMonitor' );
1731 }
1732
1733
1734 /**
1735 * Method show_backups()
1736 *
1737 * Render Backups.
1738 *
1739 * @param mixed $website Child Site.
1740 *
1741 * @uses \MainWP\Dashboard\MainWP_Backup_Handler::is_sql_file()
1742 * @uses \MainWP\Dashboard\MainWP_Backup_Handler::is_archive()
1743 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_Backup_View::show_backups()
1744 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_specific_dir()
1745 */
1746 public static function show_backups( &$website ) { //phpcs:ignore -- NOSONAR - complex.
1747 $dir = MainWP_System_Utility::get_mainwp_specific_dir( $website->id );
1748
1749 MainWP_System_Utility::touch( $dir . 'index.php' );
1750
1751 $dbBackups = array();
1752 $fullBackups = array();
1753 if ( file_exists( $dir ) ) {
1754 $dh = opendir( $dir );
1755 if ( $dh ) {
1756 while ( false !== ( $file = readdir( $dh ) ) ) {
1757 if ( '.' !== $file && '..' !== $file ) {
1758 $theFile = $dir . $file;
1759 if ( MainWP_Backup_Handler::is_sql_file( $file ) ) {
1760 $dbBackups[ filemtime( $theFile ) . $file ] = $theFile;
1761 } elseif ( MainWP_Backup_Handler::is_archive( $file ) ) {
1762 $fullBackups[ filemtime( $theFile ) . $file ] = $theFile;
1763 }
1764 }
1765 }
1766 closedir( $dh );
1767 }
1768 }
1769 krsort( $dbBackups );
1770 krsort( $fullBackups );
1771
1772 MainWP_Manage_Sites_Backup_View::show_backups( $website, $fullBackups, $dbBackups );
1773 }
1774
1775 /**
1776 * Method render_all_sites()
1777 *
1778 * Render manage sites content.
1779 *
1780 * @uses \MainWP\Dashboard\MainWP_UI::render_modal_edit_notes()
1781 */
1782 public static function render_all_sites() {
1783
1784 static::load_sites_table();// to fix loading.
1785
1786 $optimize_for_sites_table = apply_filters( 'mainwp_manage_sites_optimize_loading', 1, 'manage-sites' ); // use ajax to load sites table .
1787
1788 if ( ! $optimize_for_sites_table ) {
1789 static::$sitesTable->prepare_items( false );
1790 }
1791
1792 static::render_header( '' );
1793
1794 ?>
1795 <div id="mainwp-manage-sites-content" class="ui padded segment">
1796 <div id="mainwp-message-zone" class="ui message" style="display: none;"></div>
1797 <form method="post" class="mainwp-table-container">
1798 <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
1799 <?php
1800 static::$sitesTable->display( $optimize_for_sites_table );
1801 static::$sitesTable->clear_items();
1802 ?>
1803 </form>
1804 </div>
1805 <?php MainWP_UI::render_modal_edit_notes(); ?>
1806 <div class="ui modal" id="managesites-backup-box" tabindex="0">
1807 <div class="header"><?php esc_html_e( 'Full backup required', 'mainwp' ); ?></div>
1808 <div class="content mainwp-modal-content"></div>
1809 <div class="actions mainwp-modal-actions">
1810 <input id="managesites-backup-all" type="button" name="Backup All" value="<?php esc_attr_e( 'Backup all', 'mainwp' ); ?>" class="button-primary"/>
1811 <a id="managesites-backup-now" href="#" target="_blank" style="display: none" class="button-primary button"><?php esc_html_e( 'Backup Now', 'mainwp' ); ?></a>&nbsp;
1812 <input id="managesites-backup-ignore" type="button" name="Ignore" value="<?php esc_attr_e( 'Ignore', 'mainwp' ); ?>" class="button"/>
1813 </div>
1814 </div>
1815 <?php
1816 static::render_screen_options();
1817 static::render_footer( '' );
1818 }
1819
1820 /**
1821 * Method render_manage_sites()
1822 *
1823 * Render Manage Sites Page.
1824 *
1825 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
1826 * @uses \MainWP\Dashboard\MainWP_Notification_Template::handle_template_file_action()
1827 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
1828 */
1829 public static function render_manage_sites() { // phpcs:ignore -- NOSONAR - complex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
1830
1831 /**
1832 * Current user global.
1833 *
1834 * @global string
1835 */
1836 global $current_user;
1837
1838 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1839 if ( isset( $_REQUEST['do'] ) ) {
1840 if ( 'new' === $_REQUEST['do'] ) {
1841 static::render_new_site();
1842 } elseif ( 'bulknew' === $_REQUEST['do'] ) {
1843 static::render_bulk_new_site();
1844 }
1845
1846 return;
1847 }
1848
1849 if ( get_option( 'mainwp_enableLegacyBackupFeature' ) && ! empty( $_GET['backupid'] ) ) {
1850 $websiteid = ! empty( $_GET['backupid'] ) ? intval( $_GET['backupid'] ) : false;
1851 $backupwebsite = MainWP_DB::instance()->get_website_by_id( $websiteid );
1852 if ( MainWP_System_Utility::can_edit_website( $backupwebsite ) ) {
1853 static::render_backup_site( $backupwebsite );
1854 return;
1855 }
1856 }
1857
1858 if ( isset( $_GET['scanid'] ) ) {
1859 $websiteid = intval( $_GET['scanid'] );
1860
1861 $scanwebsite = MainWP_DB::instance()->get_website_by_id( $websiteid );
1862 if ( MainWP_System_Utility::can_edit_website( $scanwebsite ) ) {
1863 static::render_scan_site( $scanwebsite );
1864
1865 return;
1866 }
1867 }
1868
1869 if ( isset( $_GET['dashboard'] ) ) {
1870 $websiteid = intval( $_GET['dashboard'] );
1871
1872 $dashboardWebsite = MainWP_DB::instance()->get_website_by_id_params( $websiteid, array( 'view_fields' => array( 'child_monitor_data' ) ) );
1873 if ( MainWP_System_Utility::can_edit_website( $dashboardWebsite ) ) {
1874 static::render_dashboard( $dashboardWebsite );
1875
1876 return;
1877 }
1878 }
1879
1880 if ( isset( $_GET['updateid'] ) ) {
1881 $websiteid = intval( $_GET['updateid'] );
1882 $updatesWebsite = MainWP_DB::instance()->get_website_by_id( $websiteid );
1883 if ( MainWP_System_Utility::can_edit_website( $updatesWebsite ) ) {
1884 static::render_updates( $updatesWebsite );
1885 return;
1886 }
1887 }
1888
1889 if ( ( isset( $_GET['action'] ) && 'add_submonitor' === $_GET['action'] ) || ! empty( $_GET['sub_monitor_id'] ) ) {
1890 $websiteid = intval( $_GET['monitor_wpid'] );
1891 $website = MainWP_DB::instance()->get_website_by_id( $websiteid );
1892 // Show modal.
1893 static::render_monitor_site( $website );
1894 return;
1895 }
1896
1897 if ( ! empty( $_GET['emailsettingsid'] ) ) {
1898 $websiteid = intval( $_GET['emailsettingsid'] );
1899 $website = MainWP_DB::instance()->get_website_by_id( $websiteid, false, array( 'settings_notification_emails' ) );
1900 $updated = false;
1901 $updated_templ = false;
1902 if ( MainWP_System_Utility::can_edit_website( $website ) ) {
1903 $updated = static::update_site_emails_settings_handle( $website );
1904 $updated_templ = MainWP_Notification_Template::instance()->handle_template_file_action();
1905 }
1906 if ( ! empty( $_GET['edit-email'] ) ) {
1907 // Edit email settings show in separated page in site settings.
1908 static::render_email_settings( $website, $updated, $updated_templ, true );
1909 return;
1910 }
1911 }
1912
1913 if ( isset( $_GET['id'] ) ) {
1914 $websiteid = intval( $_GET['id'] );
1915 $website = MainWP_DB::instance()->get_website_by_id( $websiteid );
1916 if ( MainWP_System_Utility::can_edit_website( $website ) ) {
1917 // Edit website.
1918 $updated = static::update_site_handle( $website );
1919 static::render_edit_site( $websiteid, $updated );
1920 return;
1921 }
1922 }
1923 // phpcs:enable
1924
1925 $sitesViewMode = MainWP_Utility::get_siteview_mode();
1926 if ( 'grid' === $sitesViewMode ) {
1927 MainWP_Manage_Screenshots::render_all_sites();
1928 } else {
1929 static::render_all_sites();
1930 }
1931 MainWP_Logger::instance()->log_execution_time( 'render_manage_sites()' );
1932 }
1933
1934
1935 /**
1936 * Method update_site_emails_settings_handle()
1937 *
1938 * Handle site email settings update.
1939 *
1940 * @param mixed $website Child Site object.
1941 *
1942 * @return bool $updated Updated.
1943 *
1944 * @uses \MainWP\Dashboard\MainWP_DB::get_website_option()
1945 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_notification_types()
1946 * @uses \MainWP\Dashboard\MainWP_Utility::valid_input_emails()
1947 */
1948 private static function update_site_emails_settings_handle( $website ) { // phpcs:ignore -- NOSONAR - complex.
1949 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1950 $updated = false;
1951 if ( isset( $_POST['submit'] ) && isset( $_GET['emailsettingsid'] ) && isset( $_POST['wp_nonce'] ) && wp_verify_nonce( sanitize_key( $_POST['wp_nonce'] ), 'UpdateWebsiteEmailSettings' . sanitize_text_field( wp_unslash( $_GET['emailsettingsid'] ) ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification,ized
1952 $settings_emails = MainWP_DB::instance()->get_website_option( $website, 'settings_notification_emails', '' );
1953 $settings_emails = ! empty( $settings_emails ) ? json_decode( $settings_emails, true ) : $settings_emails;
1954 if ( ! is_array( $settings_emails ) ) {
1955 $settings_emails = array();
1956 }
1957
1958 $notification_emails = MainWP_Notification_Settings::get_notification_types();
1959 $type = isset( $_POST['mainwp_managesites_setting_emails_type'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_setting_emails_type'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,ized
1960 $edit_settingEmails = isset( $_POST['mainwp_managesites_edit_settingEmails'][ $type ] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['mainwp_managesites_edit_settingEmails'][ $type ] ) ) : array(); // phpcs:ignore WordPress.Security.NonceVerification,ized
1961
1962 if ( isset( $notification_emails[ $type ] ) && ! empty( $edit_settingEmails ) ) {
1963 $update_settings = $edit_settingEmails;
1964 $update_settings['recipients'] = MainWP_Utility::valid_input_emails( $edit_settingEmails['recipients'] );
1965 $update_settings['disable'] = isset( $edit_settingEmails['disable'] ) ? 0 : 1; // isset 'on' means enable (0), not isset mean disabled (1).
1966
1967 /**
1968 * Action: mainwp_before_save_email_settings
1969 *
1970 * Fires before save email settings.
1971 *
1972 * @since 4.1
1973 */
1974 do_action( 'mainwp_before_save_email_settings', $type, $update_settings, $website );
1975
1976 $settings_emails[ $type ] = $update_settings;
1977 MainWP_DB::instance()->update_website_option( $website, 'settings_notification_emails', wp_json_encode( $settings_emails ) );
1978 $updated = true;
1979
1980 /**
1981 * Action: mainwp_after_save_email_settings
1982 *
1983 * Fires after save email settings.
1984 *
1985 * @since 4.1
1986 */
1987 do_action( 'mainwp_after_save_email_settings', $settings_emails );
1988
1989 }
1990 }
1991 // phpcs:enable
1992 return $updated;
1993 }
1994
1995 /**
1996 * Method update_site_handle()
1997 *
1998 * Handle site update.
1999 *
2000 * @param mixed $website Child Site object.
2001 *
2002 * @return bool $updated Updated.
2003 *
2004 * @uses \MainWP\Dashboard\MainWP_DB::update_website()
2005 * @uses \MainWP\Dashboard\MainWP_DB::update_website_values()
2006 * @uses \MainWP\Dashboard\MainWP_DB::update_website_option()
2007 * @uses \MainWP\Dashboard\MainWP_Utility::remove_http_prefix()
2008 * @uses \MainWP\Dashboard\MainWP_Utility::valid_input_emails()
2009 */
2010 private static function update_site_handle( $website ) { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
2011
2012 /**
2013 * Current user global.
2014 *
2015 * @global string
2016 */
2017 global $current_user;
2018
2019 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2020 $updated = false;
2021 if ( isset( $_POST['submit'] ) && isset( $_POST['wp_nonce'] ) && isset( $_REQUEST['id'] ) && isset( $_POST['mainwp_managesites_edit_siteadmin'] ) && ( '' !== $_POST['mainwp_managesites_edit_siteadmin'] ) && wp_verify_nonce( sanitize_key( $_POST['wp_nonce'] ), 'UpdateWebsite' . sanitize_key( $_REQUEST['id'] ) ) && \mainwp_current_user_can( 'dashboard', 'edit_sites' ) ) {
2022 // update site.
2023 $groupids = array();
2024 $groupnames = array();
2025 if ( isset( $_POST['mainwp_managesites_edit_addgroups'] ) && ! empty( $_POST['mainwp_managesites_edit_addgroups'] ) ) {
2026 $groupids = explode( ',', sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_addgroups'] ) ) );
2027 }
2028
2029 // to fix update staging site.
2030 if ( $website->is_staging ) {
2031 $stag_gid = get_option( 'mainwp_stagingsites_group_id' );
2032 if ( $stag_gid && ! in_array( $stag_gid, $groupids, true ) ) {
2033 $groupids[] = $stag_gid;
2034 }
2035 }
2036
2037 $newPluginDir = '';
2038
2039 $maximumFileDescriptorsOverride = isset( $_POST['mainwp_options_maximumFileDescriptorsOverride'] );
2040 $maximumFileDescriptorsAuto = isset( $_POST['mainwp_maximumFileDescriptorsAuto'] );
2041 $maximumFileDescriptors = isset( $_POST['mainwp_options_maximumFileDescriptors'] ) ? intval( $_POST['mainwp_options_maximumFileDescriptors'] ) : 150;
2042
2043 $archiveFormat = isset( $_POST['mainwp_archiveFormat'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_archiveFormat'] ) ) : 'global';
2044
2045 $http_user = isset( $_POST['mainwp_managesites_edit_http_user'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_http_user'] ) ) : '';
2046 $http_pass = isset( $_POST['mainwp_managesites_edit_http_pass'] ) ? wp_unslash( $_POST['mainwp_managesites_edit_http_pass'] ) : '';
2047 // MWP-1548: the Edit Site form renders a sentinel for the
2048 // password input when a value is already stored. If the
2049 // admin submitted the form without changing the field, we
2050 // see the sentinel back -- treat it as "no change" and pass
2051 // through the stored value (envelope or legacy plaintext).
2052 // update_website() runs encrypt_credential() which is
2053 // idempotent on envelopes, so this round-trips cleanly.
2054 if ( MainWP_Credential_Render::is_sentinel( $http_pass ) ) {
2055 $http_pass = isset( $website->http_pass ) ? $website->http_pass : '';
2056 }
2057 $url = ( isset( $_POST['mainwp_managesites_edit_wpurl_with_www'] ) && ( 'www' === sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_wpurl_with_www'] ) ) ) ? 'www.' : '' ) . MainWP_Utility::remove_http_www_prefix( $website->url, true );
2058 $url = ( isset( $_POST['mainwp_managesites_edit_siteurl_protocol'] ) && ( 'https' === sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_siteurl_protocol'] ) ) ) ? 'https' : 'http' ) . '://' . MainWP_Utility::remove_http_prefix( $url, true );
2059 $backup_method = isset( $_POST['mainwp_primaryBackup'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_primaryBackup'] ) ) : 'global';
2060
2061 $disableHealthChecking = isset( $_POST['mainwp_managesites_edit_disableSiteHealthMonitoring'] ) ? 0 : 1;
2062 $healthThreshold = isset( $_POST['mainwp_managesites_edit_healthThreshold'] ) ? intval( $_POST['mainwp_managesites_edit_healthThreshold'] ) : 0; // 0 use global settings.
2063
2064 $site_name = isset( $_POST['mainwp_managesites_edit_sitename'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_sitename'] ) ) : '';
2065 $site_admin = isset( $_POST['mainwp_managesites_edit_siteadmin'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_siteadmin'] ) ) : '';
2066 $verifycertificate = isset( $_POST['mainwp_managesites_edit_verifycertificate'] ) ? intval( $_POST['mainwp_managesites_edit_verifycertificate'] ) : 2;
2067 $uniqueId = isset( $_POST['mainwp_managesites_edit_uniqueId'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_uniqueId'] ) ) : '';
2068 $ssl_version = isset( $_POST['mainwp_managesites_edit_ssl_version'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_ssl_version'] ) ) : '';
2069
2070 MainWP_DB::instance()->update_website( $website->id, $url, $current_user->ID, $site_name, $site_admin, $groupids, $groupnames, $newPluginDir, $maximumFileDescriptorsOverride, $maximumFileDescriptorsAuto, $maximumFileDescriptors, $verifycertificate, $archiveFormat, $uniqueId, $http_user, $http_pass, $ssl_version, $disableHealthChecking, $healthThreshold, $backup_method );
2071
2072 $url_locked = isset( $_POST['mainwp_managesites_edit_url_lock'] ) ? 1 : 0;
2073 MainWP_Site_Url_Corrector::set_lock( $website, $url_locked );
2074 if ( ! $url_locked && $url !== $website->url ) {
2075 // Auto-set the lock only when the user actually CHANGED the URL to
2076 // something diverging from the child-reported address; saving
2077 // unrelated fields must not lock a mismatched site.
2078 MainWP_Site_Url_Corrector::after_user_set_url( $website, $url );
2079 }
2080
2081 if ( \mainwp_current_user_can( 'dashboard', 'manage_clients' ) ) {
2082 $new_client_id = isset( $_POST['mainwp_managesites_edit_client_id'] ) ? intval( $_POST['mainwp_managesites_edit_client_id'] ) : 0;
2083 if ( $website->client_id !== $new_client_id ) {
2084 $update = array(
2085 'client_id' => $new_client_id,
2086 );
2087 MainWP_DB::instance()->update_website_values( $website->id, $update );
2088 }
2089 }
2090
2091 /**
2092 * Update site
2093 *
2094 * Fires after updating a website settings.
2095 *
2096 * @param int $website->id Child site ID.
2097 *
2098 * @since 3.4
2099 */
2100 do_action( 'mainwp_update_site', $website->id );
2101
2102 $backup_before_upgrade = isset( $_POST['mainwp_backup_before_upgrade'] ) ? intval( $_POST['mainwp_backup_before_upgrade'] ) : 2;
2103 if ( 2 < $backup_before_upgrade ) {
2104 $backup_before_upgrade = 2;
2105 }
2106
2107 $forceuseipv4 = isset( $_POST['mainwp_managesites_edit_forceuseipv4'] ) ? intval( $_POST['mainwp_managesites_edit_forceuseipv4'] ) : 0;
2108 if ( 2 < $forceuseipv4 ) {
2109 $forceuseipv4 = 0;
2110 }
2111
2112 $old_suspended = (int) $website->suspended;
2113 $suspended = isset( $_POST['mainwp_suspended_site'] ) ? 1 : 0;
2114 $newValues = array(
2115 'automatic_update' => ( ! isset( $_POST['mainwp_automaticDailyUpdate'] ) ? 0 : 1 ),
2116 'backup_before_upgrade' => $backup_before_upgrade,
2117 'force_use_ipv4' => $forceuseipv4,
2118 'loadFilesBeforeZip' => isset( $_POST['mainwp_options_loadFilesBeforeZip'] ) ? 1 : 0,
2119 'suspended' => $suspended,
2120 );
2121
2122 if ( \mainwp_current_user_can( 'dashboard', 'ignore_unignore_updates' ) ) {
2123 $newValues['is_ignoreCoreUpdates'] = ! empty( $_POST['mainwp_is_ignoreCoreUpdates'] ) ? 1 : 0;
2124 $newValues['is_ignorePluginUpdates'] = ! empty( $_POST['mainwp_is_ignorePluginUpdates'] ) ? 1 : 0;
2125 $newValues['is_ignoreThemeUpdates'] = ! empty( $_POST['mainwp_is_ignoreThemeUpdates'] ) ? 1 : 0;
2126 MainWP_DB::instance()->update_website_option( $website, 'ignored_trans_updates', ! empty( $_POST['mainwp_is_ignore_trans_updates'] ) ? 1 : 0 );
2127 }
2128
2129 MainWP_DB::instance()->update_website_values( $website->id, $newValues );
2130
2131 $monitoring_emails = isset( $_POST['mainwp_managesites_edit_monitoringNotificationEmails'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_monitoringNotificationEmails'] ) ) : '';
2132 $monitoring_emails = MainWP_Utility::valid_input_emails( $monitoring_emails );
2133 MainWP_DB::instance()->update_website_option( $website, 'monitoring_notification_emails', trim( $monitoring_emails ) );
2134
2135 $added = isset( $_POST['mainwp_managesites_edit_dt_added'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_dt_added'] ) ) : '';
2136 if ( ! empty( $added ) ) {
2137 $added = strtotime( $added );
2138 }
2139 MainWP_DB::instance()->update_website_option( $website, 'added_timestamp', $added );
2140
2141 $new_alg = isset( $_POST['mainwp_managesites_edit_openssl_alg'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_openssl_alg'] ) ) : '';
2142 MainWP_DB::instance()->update_website_option( $website, 'signature_algo', $new_alg );
2143
2144 $use_lib = isset( $_POST['mainwp_managesites_edit_verify_connection_method'] ) ? intval( $_POST['mainwp_managesites_edit_verify_connection_method'] ) : 0;
2145 MainWP_DB::instance()->update_website_option( $website, 'verify_method', $use_lib );
2146
2147 $uploaded_site_icon = isset( $_POST['mainwp_managesites_edit_site_uploaded_icon_hidden'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_site_uploaded_icon_hidden'] ) ) : '';
2148 $selected_site_icon = isset( $_POST['mainwp_managesites_edit_site_selected_icon_hidden'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_managesites_edit_site_selected_icon_hidden'] ) ) : '';
2149 $cust_icon_color = isset( $_POST['mainwp_managesites_edit_site_color'] ) ? sanitize_hex_color( wp_unslash( $_POST['mainwp_managesites_edit_site_color'] ) ) : '';
2150 $icon_info = 'uploaded:' . $uploaded_site_icon . ';selected:' . $selected_site_icon . ';color:' . $cust_icon_color;
2151 MainWP_DB::instance()->update_website_option( $website, 'cust_site_icon_info', $icon_info );
2152
2153 if ( ! empty( $website->cust_site_icon_info ) ) {
2154 $current_uploaded = static::get_instance()->get_cust_site_icon( $website->cust_site_icon_info, 'uploaded' );
2155 if ( ! empty( $current_uploaded ) && $current_uploaded !== $uploaded_site_icon ) {
2156 MainWP_Utility::instance()->delete_uploaded_icon_file( 'site-icons', $current_uploaded ); // delete old icon.
2157 }
2158 }
2159
2160 /**
2161 * Update site
2162 *
2163 * Fires after updating a website settings.
2164 *
2165 * @param int $website Child site Ọbject.
2166 *
2167 * @since 3.4
2168 */
2169 do_action( 'mainwp_site_updated', $website, $_POST );
2170
2171 if ( $old_suspended !== $suspended ) { // changed suspended.
2172 /**
2173 * Site suspended changed.
2174 *
2175 * Fires after suspended a website changed.
2176 *
2177 * @param int $website->id Child site ID.
2178 *
2179 * @since 4.5.1.1
2180 */
2181 do_action( 'mainwp_site_suspended', $website, $suspended );
2182 }
2183 MainWP_Manage_Sites_List_Table::invalidate_manage_sites_cache();
2184 $updated = true;
2185 }
2186 // phpcs:enable
2187 return $updated;
2188 }
2189
2190 /**
2191 * Method render_edit_site()
2192 *
2193 * Render edit site.
2194 *
2195 * @param mixed $websiteid Child Site ID.
2196 * @param mixed $updated Updated.
2197 *
2198 * @uses \MainWP\Dashboard\MainWP_Manage_Sites_View::render_edit_site()
2199 * @uses \MainWP\Dashboard\MainWP_System_Utility::set_current_wpid()
2200 */
2201 public static function render_edit_site( $websiteid, $updated ) {
2202 if ( $websiteid ) {
2203 MainWP_System_Utility::set_current_wpid( $websiteid );
2204 }
2205 static::render_header( 'ManageSitesEdit' );
2206 MainWP_Manage_Sites_View::render_edit_site( $websiteid, $updated );
2207 static::render_footer( 'ManageSitesEdit' );
2208 }
2209
2210 /**
2211 * Method on_edit_site()
2212 *
2213 * Render on edit.
2214 *
2215 * @param object $website The website object.
2216 */
2217 public static function on_edit_site( $website ) {
2218 if ( isset( $_POST['submit'] ) && isset( $_REQUEST['id'] ) && isset( $_POST['wp_nonce'] ) && isset( $_POST['mainwp_managesites_edit_siteadmin'] ) && ( '' !== $_POST['mainwp_managesites_edit_siteadmin'] ) && wp_verify_nonce( sanitize_key( $_POST['wp_nonce'] ), 'UpdateWebsite' . sanitize_key( $_REQUEST['id'] ) ) && isset( $_POST['mainwp_managesites_edit_uniqueId'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,ized
2219 ?>
2220 <script type="text/javascript">
2221 jQuery( document ).ready( function () {
2222 mainwp_managesites_update_childsite_value( <?php echo esc_attr( $website->id ); ?>, '<?php echo esc_js( $website->uniqueId ); ?>' );
2223 } );
2224 </script>
2225 <?php
2226 }
2227 }
2228
2229 /**
2230 * Method mainwp_help_content()
2231 *
2232 * Creates the MainWP Help Documentation List for the help component in the sidebar.
2233 */
2234 public static function mainwp_help_content() {
2235 // @NO_SONAR_START@ start block.
2236 if ( isset( $_GET['page'] ) && 'managesites' === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification,ized
2237 if ( isset( $_GET['do'] ) && 'new' === $_GET['do'] ) { // phpcs:ignore WordPress.Security.NonceVerification,ized
2238 ?>
2239 <p><?php esc_html_e( 'If you need help connecting your websites, please review following help documents', 'mainwp' ); ?></p>
2240 <div class="ui list">
2241 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/getting-started/get-started-with-mainwp#install-mainwp-dashboard" target="_blank">Set up the MainWP Plugin</a></div> <?php // NOSONAR - noopener - open safe. ?>
2242 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/getting-started/get-started-with-mainwp#install-mainwp-child" target="_blank">Install MainWP Child</a></div> <?php // NOSONAR - noopener - open safe. ?>
2243 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/getting-started/get-started-with-mainwp#add-a-site-to-your-dashboard" target="_blank">Add a Site to your Dashboard</a></div> <?php // NOSONAR - noopener - open safe. ?>
2244 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/manage-child-sites?search=Test+Connection#import-sites-csv-import" target="_blank">Import Sites</a></div> <?php // NOSONAR - noopener - open safe. ?>
2245 </div>
2246 <?php
2247 } elseif ( isset( $_GET['do'] ) && 'bulknew' === $_GET['do'] ) { // phpcs:ignore WordPress.Security.NonceVerification,ized
2248 ?>
2249 <p><?php esc_html_e( 'If you need help connecting your websites, please review following help documents', 'mainwp' ); ?></p>
2250 <div class="ui list">
2251 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/getting-started/get-started-with-mainwp#install-mainwp-dashboard" target="_blank">Set up the MainWP Plugin</a></div> <?php // NOSONAR - noopener - open safe. ?>
2252 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/getting-started/get-started-with-mainwp#install-mainwp-child" target="_blank">Install MainWP Child</a></div> <?php // NOSONAR - noopener - open safe. ?>
2253 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/getting-started/get-started-with-mainwp#add-a-site-to-your-dashboard" target="_blank">Add a Site to your Dashboard</a></div> <?php // NOSONAR - noopener - open safe. ?>
2254 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/manage-child-sites?search=Test+Connection#import-sites-csv-import" target="_blank">Import Sites</a></div> <?php // NOSONAR - noopener - open safe. ?>
2255 </div>
2256 <?php
2257 } else {
2258 ?>
2259 <p><?php esc_html_e( 'If you need help with managing child sites, please review following help documents', 'mainwp' ); ?></p>
2260 <div class="ui list">
2261 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/manage-child-sites" target="_blank">Manage Child Sites</a></div> <?php // NOSONAR - noopener - open safe. ?>
2262 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/manage-child-sites#access-child-site-wp-admin" target="_blank">Access Child Site WP Admin</a></div> <?php // NOSONAR - noopener - open safe. ?>
2263 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/manage-child-sites#synchronize-a-child-site" target="_blank">Synchronize a Child Site</a></div> <?php // NOSONAR - noopener - open safe. ?>
2264 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/manage-child-sites#edit-child-site-settings" target="_blank">Edit a Child Site</a></div> <?php // NOSONAR - noopener - open safe. ?>
2265 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/manage-child-sites#reconnect-a-child-site" target="_blank">Reconnect a Child Site</a></div> <?php // NOSONAR - noopener - open safe. ?>
2266 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/manage-child-sites#delete-a-child-site" target="_blank">Delete a Child Site</a></div> <?php // NOSONAR - noopener - open safe. ?>
2267 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/manage-child-sites#security-issues" target="_blank">Site Hardening</a></div> <?php // NOSONAR - noopener - open safe. ?>
2268 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/manage-child-sites#manage-child-site-tags" target="_blank">Manage Child Site Tags</a></div> <?php // NOSONAR - noopener - open safe. ?>
2269 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/manage-child-sites#manage-child-site-notes" target="_blank">Manage Child Site Notes</a></div> <?php // NOSONAR - noopener - open safe. ?>
2270 </div>
2271 <?php
2272 }
2273 }
2274 // @NO_SONAR_END@ end of block.
2275 }
2276
2277 /**
2278 * Method mainwp_managesites_information_import_sites()
2279 *
2280 * @param bool $is_qsw is qsw.
2281 *
2282 * Display Import site information.
2283 */
2284 public static function mainwp_managesites_information_import_sites( $is_qsw = false ) {
2285 ?>
2286 <?php esc_html_e( 'MainWP requires the MainWP Child plugin to be installed and activated on the WordPress sites that you want to connect to your MainWP Dashboard. ', 'mainwp' ); ?>
2287 <?php esc_html_e( 'To connect multiple sites, please follow these steps:', 'mainwp' ); ?>
2288 <div class="ui hidden divier"></div>
2289 <div class="ui relaxed bulleted list">
2290 <div class="item"><?php esc_html_e( 'Fill in the Site URL field by entering the URL of the website you want to connect.', 'mainwp' ); ?></div>
2291 <div class="item"><?php esc_html_e( 'Enter the username of your Administrator account on the site.', 'mainwp' ); ?></div>
2292 <div class="item"><?php esc_html_e( 'Optionally, enter a custom Site Name, or MainWP will automatically generate a name for it.', 'mainwp' ); ?></div>
2293 <div class="item"><?php esc_html_e( 'Enter the administrator account password. If the requirement is disabled in the MainWP Child plugin settings, leave blank.', 'mainwp' ); ?></div>
2294 <?php if ( $is_qsw ) : ?>
2295 <div class="item"><?php esc_html_e( 'To show additional fields (Tags, Security ID, HTTP Username, HTTP Password, SSL Version, and SSL Verification, click the eye icon at the end of the row.', 'mainwp' ); ?></div>
2296 <?php endif; ?>
2297 <div class="item"><?php esc_html_e( 'If needed, you can tag your sites in the Tag field.', 'mainwp' ); ?></div>
2298 <div class="item"><?php esc_html_e( 'If you have enabled the Unique Security ID in the MainWP Child plugin settings, enter the Security ID in the corresponding field.', 'mainwp' ); ?></div>
2299 <div class="item"><?php esc_html_e( 'If the website you are trying to connect is protected with HTTP Basic Auth, enter the HTTP Username & Password. If not, leave it blank.', 'mainwp' ); ?></div>
2300 <div class="item"><?php esc_html_e( 'Keep the default value of "1" to verify the SSL certificate for your sites, or change it if you prefer not to verify.', 'mainwp' ); ?></div>
2301 <div class="item"><?php esc_html_e( 'Leave the SSL Version as "auto" unless you know the specific version required by the site. The "auto" option typically works for most sites.', 'mainwp' ); ?></div>
2302 <div class="item"><?php esc_html_e( 'Repeat this process for all sites you want to add.', 'mainwp' ); ?></div>
2303 <div class="item"><?php esc_html_e( 'Use the Add New Row button to add additional rows if you need to connect more sites at once.', 'mainwp' ); ?></div>
2304 <?php if ( ! $is_qsw ) : ?>
2305 <div class="item"><?php esc_html_e( 'After filling in all the required information, submit the form to connect the selected sites to your MainWP Dashboard.', 'mainwp' ); ?></div>
2306 <?php else : ?>
2307 <div class="item"><?php esc_html_e( 'After filling in all the required information, confirm that you have the MainWP Child plugin installed and activated and click the Connect Sites button to proceed.', 'mainwp' ); ?></div>
2308 <?php endif; ?>
2309 </div>
2310 <?php if ( ! $is_qsw ) : ?>
2311 <span class="ui small text">* <?php esc_html_e( 'Your password is never stored by your Dashboard and never sent to MainWP.com. Once this initial connection is complete, your MainWP Dashboard generates a secure Public and Private key pair (2048 bits) using OpenSSL, allowing future connections without needing your password again. For added security, you can even change this admin password once connected, just be sure not to delete the admin account, as this would disrupt the connection.', 'mainwp' ); ?></span>
2312 <?php endif; ?>
2313 <?php
2314 }
2315
2316 /**
2317 * Method mainwp_managesites_form_import_sites()
2318 *
2319 * Creates the form import websites.
2320 *
2321 * @uses MainWP_DB::instance()->get_general_option()
2322 * @uses MainWP_DB::instance()->update_general_option()
2323 */
2324 public static function mainwp_managesites_form_import_sites() {
2325 $temp_sites = MainWP_DB::instance()->get_general_option( 'temp_import_sites', 'array' );
2326
2327 // Reset key of temp_sites.
2328 if ( ! empty( $temp_sites ) && is_array( $temp_sites ) ) {
2329 $temp_sites = array_values( $temp_sites );
2330 MainWP_DB::instance()->update_general_option( 'temp_import_sites', $temp_sites, 'array' );
2331 }
2332
2333 // Get total rows import site default 5.
2334 $total_sites = max( 5, count( $temp_sites ) );
2335 $is_page_setup = isset( $_GET['page'] ) && 'mainwp-setup' === $_GET['page'] ? true : false; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2336 $display_none = $is_page_setup ? 'display:none' : '';
2337 ?>
2338 <div>
2339 <div class="ui left aligned middle aligned very compact stackable grid" id="mainwp-managesites-row-import-sites">
2340 <div class="ui row">
2341 <div class="<?php echo $is_page_setup ? 'four' : 'two'; ?> wide column" >
2342 <span class="ui text small"><strong><?php esc_html_e( 'Site URL (required)', 'mainwp' ); ?></strong></span>
2343 </div>
2344 <div class="<?php echo $is_page_setup ? 'four' : 'two'; ?> wide column">
2345 <span class="ui text small"><?php esc_html_e( 'Site Name', 'mainwp' ); ?></span>
2346 </div>
2347 <div class="<?php echo $is_page_setup ? 'four' : 'two'; ?> wide column">
2348 <span class="ui text small"><strong><?php esc_html_e( 'Admin Name (required)', 'mainwp' ); ?></strong></span>
2349 </div>
2350 <div class="<?php echo $is_page_setup ? 'three' : 'two'; ?> wide column">
2351 <span class="ui text small"><strong><?php esc_html_e( 'Admin Password *', 'mainwp' ); ?></strong></span>
2352 </div>
2353 <?php if ( ! $is_page_setup ) : ?>
2354 <div class="one wide column">
2355 <span class="ui text small"><?php esc_html_e( 'Tag', 'mainwp' ); ?></span>
2356 </div>
2357 <div class="one wide column">
2358 <span class="ui text small"><?php esc_html_e( 'Security ID', 'mainwp' ); ?></span>
2359 </div>
2360 <div class="two wide column">
2361 <span class="ui text small"><?php esc_html_e( 'HTTP Username', 'mainwp' ); ?></span>
2362 </div>
2363 <div class="one wide column">
2364 <span class="ui text small"><?php esc_html_e( 'HTTP Password', 'mainwp' ); ?></span>
2365 </div>
2366 <div class="one wide column">
2367 <span class="ui text small"><?php esc_html_e( 'Verify SSL', 'mainwp' ); ?></span>
2368 </div>
2369 <div class="one wide column">
2370 <span class="ui text small"><?php esc_html_e( 'SSL Version', 'mainwp' ); ?></span>
2371 </div>
2372 <div class="one wide column">
2373 <span></span>
2374 </div>
2375 <?php else : ?>
2376 <div class="one wide column"></div>
2377 <?php endif; ?>
2378 </div>
2379 <?php
2380 $fields = self::mainwp_managesites_form_import_sites_fields();
2381 for ( $x = 0; $x < $total_sites; $x++ ) {
2382 $site = ! empty( $temp_sites[ $x ] ) ? $temp_sites[ $x ] : array();
2383 self::mainwp_managesites_form_import_sites_row( $x, $site, $is_page_setup, $display_none, $fields );
2384 }
2385 ?>
2386 <div class="add-row row" id="mainwp-managesites-add-row">
2387 <div class="sixteen wide column"><a href="#" class="ui mini basic button" id="mainwp-managesites-import-row" data-default-row="<?php echo esc_attr( $total_sites ); ?>" data-page-setup="<?php echo esc_attr( $is_page_setup ); ?>"><?php esc_html_e( 'Add New Row', 'mainwp' ); ?></a></div>
2388 </div>
2389 </div>
2390 </div>
2391 <?php
2392 }
2393
2394 /**
2395 * Method mainwp_managesites_form_import_sites_fields();
2396 *
2397 * Array containing fields value
2398 *
2399 * @return array array data
2400 */
2401 public static function mainwp_managesites_form_import_sites_fields() {
2402 $default_class = 'mainwp-managesites-import';
2403 return array(
2404 'fields' => array(
2405 'site_url' => array(
2406 'label' => 'Site URL',
2407 'class' => $default_class . '-site-url',
2408 'id' => $default_class . '-site-url',
2409 ),
2410 'site_name' => array(
2411 'label' => 'Site Name',
2412 'class' => $default_class . '-site-name',
2413 'id' => $default_class . '-site-name',
2414 ),
2415 'admin_name' => array(
2416 'label' => 'Admin Name',
2417 'class' => $default_class . '-admin-name',
2418 'id' => $default_class . '-admin-name',
2419 ),
2420 'admin_password' => array(
2421 'label' => 'Admin Password',
2422 'class' => $default_class . '-admin-password',
2423 'id' => $default_class . '-admin-password',
2424 'type' => 'password',
2425 ),
2426 ),
2427 'optional_fields' => array(
2428 'tag' => array(
2429 'label' => 'Tag',
2430 'class' => $default_class . '-tag',
2431 'id' => $default_class . '-tag-',
2432 ),
2433 'security_id' => array(
2434 'label' => 'Security ID',
2435 'class' => $default_class . '-security-id',
2436 'id' => $default_class . '-security-id',
2437 ),
2438 'http_username' => array(
2439 'label' => 'HTTP Username',
2440 'class' => $default_class . '-http-username',
2441 'id' => $default_class . '-http-usernam',
2442 ),
2443 'http_password' => array(
2444 'label' => 'HTTP Password',
2445 'class' => $default_class . '-http-password',
2446 'id' => $default_class . '-http-password',
2447 ),
2448 'verify_certificate' => array(
2449 'label' => 'Verify Certificate',
2450 'input_type' => 'number',
2451 'default' => 1,
2452 'class' => 'mini ' . $default_class . '-verify-certificate',
2453 'id' => $default_class . '-verify-certificate',
2454 ),
2455 'ssl_version' => array(
2456 'label' => 'SSL Version',
2457 'default' => 'auto',
2458 'class' => 'mini ' . $default_class . '-ssl-version',
2459 'id' => $default_class . '-ssl-version',
2460 ),
2461 ),
2462 );
2463 }
2464 /**
2465 * Method mainwp_managesites_form_import_sites_render_input()
2466 * Html input rendering.
2467 *
2468 * @param int $index row index.
2469 * @param string $key_optional field key.
2470 * @param mixed $field_optional field value.
2471 * @param array $field field data.
2472 * @param array $site site row data.
2473 */
2474 public static function mainwp_managesites_form_import_sites_render_input( $index, $key_optional, $field_optional, $field, $site ) {
2475 $input_optional = isset( $field_optional['default'] ) ? $field_optional['default'] : '';
2476 $value = static::mainwp_managesites_form_import_sites_get_value( $site, $key_optional, $input_optional );
2477 $index_rand = wp_rand( 0, 9999 );
2478 ?>
2479 <div class="ui mini fluid input">
2480 <input type="text" name="mainwp_managesites_import[<?php echo esc_attr( $index ); ?>][<?php echo esc_attr( $key_optional ); ?>]" value="<?php echo esc_attr( $value ); ?>" data-row-index="<?php echo esc_attr( $index ); ?>" <?php echo isset( $field_optional['input_type'] ) && 'number' === $field_optional['input_type'] ? 'oninput="this.value = this.value.replace(/[^0-9]/g, \'\')"' : ''; ?> id="<?php echo esc_attr( $field['id'] . '-' . $index . '-' . $index_rand ); ?>" class="<?php echo esc_attr( $field['class'] ); ?>"/>
2481 </div>
2482 <?php
2483 }
2484
2485 /**
2486 * Method mainwp_managesites_form_import_sites_get_value()
2487 *
2488 * Get the result of input.
2489 *
2490 * @param array $site site row data.
2491 * @param string $key field name.
2492 * @param string $default_value value.
2493 * @return mixed value of input
2494 */
2495 public static function mainwp_managesites_form_import_sites_get_value( $site, $key, $default_value = '' ) {
2496 return isset( $site[ $key ] ) ? esc_attr( $site[ $key ] ) : $default_value;
2497 }
2498
2499 /**
2500 * Method mainwp_managesites_form_import_sites_row()
2501 *
2502 * Creates the form import row websites.
2503 *
2504 * @param int $index row index.
2505 * @param array $site row site data.
2506 * @param bool $is_page_setup is page setup or not found.
2507 * @param string $display_none display none if page setup wizard.
2508 * @param array $fields fields data.
2509 */
2510 public static function mainwp_managesites_form_import_sites_row( $index, $site, $is_page_setup, $display_none, $fields ) { // phpcs:ignore -- NOSONAR - complex.
2511 $general_fields = $fields['fields'];
2512 $optional_fields = $fields['optional_fields'];
2513 $row_class = $is_page_setup ? 'four' : 'two';
2514 ?>
2515 <div class="row mainwp-managesites-import-rows" id="mainwp-managesites-import-row-<?php echo esc_attr( $index ); ?>" data-index="<?php echo esc_attr( $index ); ?>">
2516 <?php
2517 foreach ( $general_fields as $key => $field ) :
2518 if ( 'admin_password' === $key ) {
2519 $row_class = $is_page_setup ? 'three' : 'two';
2520 }
2521 $field_value = self::mainwp_managesites_form_import_sites_get_value( $site, $key, '' );
2522 $field_id = $field['id'] . '-' . $index;
2523 ?>
2524 <div class="<?php echo esc_attr( $row_class ); ?> wide column">
2525 <div class="ui mini fluid input">
2526 <input type="<?php echo isset( $field['type'] ) && 'password' === $field['type'] ? 'password' : 'text'; ?>" name="mainwp_managesites_import[<?php echo esc_attr( $index ); ?>][<?php echo esc_attr( $key ); ?>]" class="<?php echo esc_attr( $field['class'] ); ?>" value="<?php echo esc_attr( $field_value ); ?>" data-row-index="<?php echo esc_attr( $index ); ?>" id="<?php echo esc_attr( $field_id ); ?>"/>
2527 </div>
2528 </div>
2529 <?php endforeach; ?>
2530 <?php if ( ! $is_page_setup ) : ?>
2531 <?php foreach ( $optional_fields as $key_optional => $field_optional ) : ?>
2532 <?php $one_class = array( 'security_id', 'verify_certificate', 'ssl_version', 'tag', 'http_password' ); ?>
2533 <div class="<?php echo in_array( $key_optional, $one_class, true ) ? 'one' : 'two'; ?> wide column">
2534 <?php self::mainwp_managesites_form_import_sites_render_input( $index, $key_optional, $field_optional, $field, $site ); ?>
2535 </div>
2536 <?php endforeach; ?>
2537 <div class="column">
2538 <div class="">
2539 <a class="mainwp-managesites-delete-import-row" href="javascript:void(0)" onclick="mainwp_managesites_import_sites_delete_row(<?php echo esc_attr( $index ); ?>)">
2540 <i class="trash alternate outline icon"></i>
2541 </a>
2542 </div>
2543 </div>
2544 <?php else : ?>
2545 <div class="one wide column">
2546 <div class="ui mini fluid input">
2547 <a class="mainwp-managesites-more-import-row " onclick="mainwp_managesites_import_sites_more_row(<?php echo esc_attr( $index ); ?>)" style="margin-right: 10px !important;" href="javascript:void(0)">
2548 <i class="caret left icon" id="icon-visible-<?php echo esc_attr( $index ); ?>"></i>
2549 <i class="caret down icon" id="icon-hidden-<?php echo esc_attr( $index ); ?>" style="<?php echo esc_attr( $display_none ); ?>"></i>
2550 </a>
2551 <a class="mainwp-managesites-delete-import-row" href="javascript:void(0)" onclick="mainwp_managesites_import_sites_delete_row(<?php echo esc_attr( $index ); ?>)">
2552 <i class="trash alternate outline icon"></i>
2553 </a>
2554 </div>
2555 </div>
2556 <?php foreach ( $optional_fields as $key_optional => $field_optional ) : ?>
2557 <div class="<?php echo ( 'verify_certificate' === $key_optional || 'ssl_version' === $key_optional ) ? 'two' : 'one'; ?> wide column mainwp-managesites-import-column-more-<?php echo esc_attr( $index ); ?>" style="<?php echo esc_attr( $display_none ); ?>">
2558 <div class="">
2559 <span class="ui small text"><?php echo esc_html( $field_optional['label'] ); ?></span>
2560 <?php self::mainwp_managesites_form_import_sites_render_input( $index, $key_optional, $field_optional, $field, $site ); ?>
2561 </div>
2562 </div>
2563 <?php endforeach; ?>
2564 <?php endif; ?>
2565 </div>
2566 <?php
2567 }
2568
2569 /**
2570 * Method render_import_sites_modal()
2571 *
2572 * Render import sites modal.
2573 *
2574 * @uses MainWP_Manage_Sites_View::render_import_sites()
2575 *
2576 * @param string $url location url href.
2577 * @param string|null $title_page modal title.
2578 */
2579 public static function render_import_sites_modal( $url, $title_page = null ) {
2580 ?>
2581 <div class="ui large modal <?php echo ( 'Import Sites' === $title_page ) ? 'mainwp-qsw-import-modal' : ''; ?>" id="mainwp-import-sites-modal" data-page-url="<?php echo esc_url( $url ); ?>" >
2582 <i class="close icon" <?php echo 'Import Sites' === $title_page ? 'style="display:none"' : ''; ?> ></i>
2583 <div class="header"><?php echo esc_html( $title_page ); ?></div>
2584 <div class="scrolling content">
2585 <?php MainWP_Manage_Sites_View::render_import_sites(); ?>
2586 </div>
2587 <div class="actions">
2588 <div class="ui two column grid">
2589 <div class="left aligned middle aligned column">
2590 <input type="button" name="mainwp_managesites_btn_import" id="mainwp_managesites_btn_import" class="ui basic button" value="<?php esc_attr_e( 'Pause', 'mainwp' ); ?>"/>
2591 <?php if ( 'Import Sites' === $title_page ) : ?>
2592 <a class="ui green button" id="mainwp-import-sites-modal-try-again" href="admin.php?page=mainwp-setup&step=connect_first_site" style="display:none"><?php esc_html_e( 'Try Again', 'mainwp' ); ?></a>
2593 <?php endif; ?>
2594 </div>
2595 <div class="right aligned middle aligned column">
2596 <?php if ( 'Import Sites' === $title_page ) : ?>
2597 <a class="ui basic green button" id="mainwp-import-sites-modal-continue" href="<?php echo esc_url( $url ); ?>" style="display:none"><?php esc_html_e( 'Continue', 'mainwp' ); ?></a>
2598 <?php endif; ?>
2599 </div>
2600 </div>
2601
2602 </div>
2603 </div>
2604 <script type="text/javascript">
2605 jQuery( document ).ready( function () {
2606 jQuery( "#mainwp-import-sites-modal" ).modal( {
2607 closable: false,
2608 onHide: function() {
2609 location.href = '<?php echo ! empty( $url ) ? $url : ''; // phpcs:ignore WordPress.Security.EscapeOutput ?>';
2610 }
2611 } ).modal( 'show' );
2612 } );
2613 </script>
2614 <?php
2615 }
2616 }
2617