PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.1.8
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.1.8
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-settings.php

page-mainwp-settings.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.1.8, at pages/page-mainwp-settings.php

2,707 lines 165.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Settings page
4 *
5 * This Class handles building/Managing the
6 * Settings MainWP DashboardPage & all SubPages.
7 *
8 * @package MainWP/Settings
9 */
10
11 namespace MainWP\Dashboard;
12
13 use MainWP\Dashboard\Module\CostTracker\Cost_Tracker_Settings;
14
15 // Exit if accessed directly.
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit;
18 }
19
20 /**
21 * Class MainWP_Settings
22 *
23 * @package MainWP\Dashboard
24 */
25 class MainWP_Settings { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
26
27 // phpcs:disable Generic.Metrics.CyclomaticComplexity -- complexity.
28
29 /**
30 * Protected static variable to hold the single instance of the class.
31 *
32 * @var mixed Default null
33 */
34 protected static $instance = null;
35
36 /**
37 * Public static varable to hold Subpages information.
38 *
39 * @var array $subPages
40 */
41 public static $subPages;
42
43 /**
44 * Get Class Name
45 *
46 * @return __CLASS__
47 */
48 public static function get_class_name() {
49 return __CLASS__;
50 }
51
52 /**
53 * Return the single instance of the class.
54 *
55 * @return mixed $instance The single instance of the class.
56 */
57 public static function get_instance() {
58 if ( is_null( static::$instance ) ) {
59 static::$instance = new self();
60 }
61 return static::$instance;
62 }
63
64 /** Instantiate Hooks for the Settings Page. */
65 public static function init() {
66 /**
67 * This hook allows you to render the Settings page header via the 'mainwp_pageheader_settings' action.
68 *
69 * This hook is normally used in the same context of 'mainwp_getsubpages_settings'
70 *
71 * @see \MainWP_Settings::render_header
72 */
73 add_action( 'mainwp-pageheader-settings', array( static::get_class_name(), 'render_header' ) ); // deprecated, use mainwp_pageheader_settings.
74
75 add_action( 'mainwp_pageheader_settings', array( static::get_class_name(), 'render_header' ) );
76
77 /**
78 * This hook allows you to render the Settings page footer via the 'mainwp-pagefooter-settings' action.
79 *
80 * This hook is normally used in the same context of 'mainwp-getsubpages-settings'
81 *
82 * @see \MainWP_Settings::render_footer
83 */
84 add_action( 'mainwp-pagefooter-settings', array( static::get_class_name(), 'render_footer' ) ); // deprecated, use mainwp_pagefooter_settings.
85
86 add_action( 'mainwp_pagefooter_settings', array( static::get_class_name(), 'render_footer' ) );
87
88 add_action( 'admin_init', array( static::get_class_name(), 'admin_init' ) );
89
90 add_action( 'mainwp_help_sidebar_content', array( static::get_class_name(), 'mainwp_help_content' ) );
91 }
92
93 /** Run the export_sites method that exports the Child Sites .csv file */
94 public static function admin_init() { // phpcs:ignore -- NOSONAR - complex.
95 static::export_sites();
96 if ( isset( $_GET['clearActivationData'] ) && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_GET['_wpnonce'] ), 'clear_activation_data' ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
97 delete_option( 'mainwp_extensions_api_username' );
98 delete_option( 'mainwp_extensions_api_password' );
99 delete_option( 'mainwp_extensions_api_save_login' );
100 delete_option( 'mainwp_extensions_plan_info' );
101 MainWP_Keys_Manager::instance()->update_key_value( 'mainwp_extensions_master_api_key', false );
102
103 $new_extensions = array();
104 $extensions = get_option( 'mainwp_extensions', array() );
105
106 if ( is_array( $extensions ) ) {
107 foreach ( $extensions as $ext ) {
108 if ( isset( $ext['api'] ) && isset( $ext['apiManager'] ) && ! empty( $ext['apiManager'] ) ) {
109 if ( isset( $ext['api_key'] ) ) {
110 $ext['api_key'] = '';
111 }
112 if ( isset( $ext['activation_email'] ) ) {
113 $ext['activation_email'] = '';
114 }
115 if ( isset( $ext['activated_key'] ) ) {
116 $ext['activated_key'] = 'Deactivated';
117 }
118
119 $act_info = MainWP_Api_Manager::instance()->get_activation_info( $ext['api'] );
120 if ( isset( $act_info['api_key'] ) ) {
121 $act_info['api_key'] = '';
122 }
123 if ( isset( $act_info['activation_email'] ) ) {
124 $act_info['activation_email'] = '';
125 }
126 if ( isset( $act_info['activated_key'] ) ) {
127 $act_info['activated_key'] = 'Deactivated';
128 }
129 MainWP_Api_Manager::instance()->set_activation_info( $ext['api'], $act_info );
130 }
131 $new_extensions[] = $ext;
132 }
133 }
134
135 MainWP_Utility::update_option( 'mainwp_extensions', $new_extensions );
136 update_option( 'mainwp_extensions_all_activation_cached', '' );
137 wp_safe_redirect( esc_url( admin_url( 'admin.php?page=MainWPTools' ) ) );
138 die();
139 }
140 }
141
142 /**
143 * Instantiate the Settings Menu.
144 *
145 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
146 */
147 public static function init_menu() {
148 add_submenu_page(
149 'mainwp_tab',
150 __( 'Settings Global options', 'mainwp' ),
151 ' <span id="mainwp-Settings">' . esc_html__( 'Settings', 'mainwp' ) . '</span>',
152 'read',
153 'Settings',
154 array(
155 static::get_class_name(),
156 'render',
157 )
158 );
159
160 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'MainWPTools' ) ) {
161 add_submenu_page(
162 'mainwp_tab',
163 __( 'Tools', 'mainwp' ),
164 ' <div class="mainwp-hidden">' . esc_html__( 'Tools', 'mainwp' ) . '</div>',
165 'read',
166 'MainWPTools',
167 array(
168 static::get_class_name(),
169 'render_mainwp_tools',
170 )
171 );
172 }
173
174 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'CostTrackerSettings' ) ) {
175 add_submenu_page(
176 'mainwp_tab',
177 esc_html__( 'Cost Tracker Settings', 'mainwp' ),
178 '<div class="mainwp-hidden">' . esc_html__( 'Cost Tracker', 'mainwp' ) . '</div>',
179 'read',
180 'CostTrackerSettings',
181 array(
182 Cost_Tracker_Settings::get_instance(),
183 'render_settings_page',
184 )
185 );
186 }
187
188 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'SettingsAdvanced' ) ) {
189 add_submenu_page(
190 'mainwp_tab',
191 __( 'Advanced Options', 'mainwp' ),
192 ' <div class="mainwp-hidden">' . esc_html__( 'Advanced Options', 'mainwp' ) . '</div>',
193 'read',
194 'SettingsAdvanced',
195 array(
196 static::get_class_name(),
197 'render_advanced',
198 )
199 );
200 }
201
202 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'MonitoringSettings' ) ) {
203 add_submenu_page(
204 'mainwp_tab',
205 __( 'Monitoring Options', 'mainwp' ),
206 ' <div class="mainwp-hidden">' . esc_html__( 'Monitoring Options', 'mainwp' ) . '</div>',
207 'read',
208 'MonitoringSettings',
209 array(
210 static::get_class_name(),
211 'render_monitoring',
212 )
213 );
214 }
215
216 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'SettingsEmail' ) ) {
217 add_submenu_page(
218 'mainwp_tab',
219 __( 'Email Settings', 'mainwp' ),
220 ' <div class="mainwp-hidden">' . esc_html__( 'Email Settings', 'mainwp' ) . '</div>',
221 'read',
222 'SettingsEmail',
223 array(
224 static::get_class_name(),
225 'render_email_settings',
226 )
227 );
228 }
229
230 /**
231 * Settings Subpages
232 *
233 * Filters subpages for the Settings page.
234 *
235 * @since Unknown
236 */
237 $sub_pages = apply_filters_deprecated( 'mainwp-getsubpages-settings', array( array() ), '4.0.7.2', 'mainwp_getsubpages_settings' ); // @deprecated Use 'mainwp_getsubpages_settings' instead. NOSONAR - not IP.
238 static::$subPages = apply_filters( 'mainwp_getsubpages_settings', $sub_pages );
239
240 if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
241 foreach ( static::$subPages as $subPage ) {
242 if ( MainWP_Menu::is_disable_menu_item( 3, 'Settings' . $subPage['slug'] ) ) {
243 continue;
244 }
245 add_submenu_page( 'mainwp_tab', $subPage['title'], '<div class="mainwp-hidden">' . $subPage['title'] . '</div>', 'read', 'Settings' . $subPage['slug'], $subPage['callback'] );
246 }
247 }
248 }
249
250 /**
251 * Instantiate Settings SubPages Menu.
252 *
253 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
254 */
255 public static function init_subpages_menu() {
256 ?>
257 <div id="menu-mainwp-Settings" class="mainwp-submenu-wrapper">
258 <div class="wp-submenu sub-open" style="">
259 <div class="mainwp_boxout">
260 <div class="mainwp_boxoutin"></div>
261 <a href="<?php echo esc_url( admin_url( 'admin.php?page=Settings' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'General Settings', 'mainwp' ); ?></a>
262 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'SettingsAdvanced' ) ) { ?>
263 <a href="<?php echo esc_url( admin_url( 'admin.php?page=SettingsAdvanced' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Advanced Settings', 'mainwp' ); ?></a>
264 <?php } ?>
265 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'MonitoringSettings' ) ) { ?>
266 <a href="<?php echo esc_url( admin_url( 'admin.php?page=MonitoringSettings' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Monitoring Settings', 'mainwp' ); ?></a>
267 <?php } ?>
268 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'SettingsEmail' ) ) { ?>
269 <a href="<?php echo esc_url( admin_url( 'admin.php?page=SettingsEmail' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Email Settings', 'mainwp' ); ?></a>
270 <?php } ?>
271 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'CostTrackerSettings' ) ) { ?>
272 <a href="<?php echo esc_url( admin_url( 'admin.php?page=CostTrackerSettings' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Cost Tracker Settings', 'mainwp' ); ?></a>
273 <?php } ?>
274 <?php
275 if ( isset( static::$subPages ) && is_array( static::$subPages ) && ! empty( static::$subPages ) ) {
276 foreach ( static::$subPages as $subPage ) {
277 if ( MainWP_Menu::is_disable_menu_item( 3, 'Settings' . $subPage['slug'] ) ) {
278 continue;
279 }
280 ?>
281 <a href="<?php echo esc_url( admin_url( 'admin.php?page=Settings' . $subPage['slug'] ) ); ?>" class="mainwp-submenu"><?php echo isset( $subPage['before_title'] ) ? $subPage['before_title'] : ''; // phpcs:ignore WordPress.Security.EscapeOutput ?> <?php echo esc_html( $subPage['title'] ); ?></a>
282 <?php
283 }
284 }
285 ?>
286 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'MainWPTools' ) ) { ?>
287 <a href="<?php echo esc_url( admin_url( 'admin.php?page=MainWPTools' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Tools', 'mainwp' ); ?></a>
288 <?php } ?>
289 </div>
290 </div>
291 </div>
292 <?php
293 }
294
295 /**
296 * Instantiate left menu
297 *
298 * Settings Page & SubPage link data.
299 *
300 * @param array $subPages SubPages Array.
301 *
302 * @uses \MainWP\Dashboard\MainWP_Menu::add_left_menu()
303 * @uses \MainWP\Dashboard\MainWP_Menu::init_subpages_left_menu()
304 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
305 */
306 public static function init_left_menu( $subPages = array() ) {
307 MainWP_Menu::add_left_menu(
308 array(
309 'title' => esc_html__( 'Settings', 'mainwp' ),
310 'parent_key' => 'mainwp_tab',
311 'slug' => 'Settings',
312 'href' => 'admin.php?page=Settings',
313 'icon' => '<i class="cog icon"></i>',
314 ),
315 0
316 );
317
318 $init_sub_subleftmenu = array(
319 array(
320 'title' => esc_html__( 'General Settings', 'mainwp' ),
321 'parent_key' => 'Settings',
322 'href' => 'admin.php?page=Settings',
323 'slug' => 'Settings',
324 'right' => '',
325 ),
326 array(
327 'title' => esc_html__( 'Advanced Settings', 'mainwp' ),
328 'parent_key' => 'Settings',
329 'href' => 'admin.php?page=SettingsAdvanced',
330 'slug' => 'SettingsAdvanced',
331 'right' => '',
332 ),
333 array(
334 'title' => esc_html__( 'Monitoring Settings', 'mainwp' ),
335 'parent_key' => 'Settings',
336 'href' => 'admin.php?page=MonitoringSettings',
337 'slug' => 'MonitoringSettings',
338 'right' => '',
339 ),
340 array(
341 'title' => esc_html__( 'Email Settings', 'mainwp' ),
342 'parent_key' => 'Settings',
343 'href' => 'admin.php?page=SettingsEmail',
344 'slug' => 'SettingsEmail',
345 'right' => '',
346 ),
347 array(
348 'title' => esc_html__( 'Tools', 'mainwp' ),
349 'parent_key' => 'Settings',
350 'href' => 'admin.php?page=MainWPTools',
351 'slug' => 'MainWPTools',
352 'right' => '',
353 ),
354 array(
355 'title' => esc_html__( 'Cost Tracker Settings', 'mainwp' ),
356 'parent_key' => 'Settings',
357 'href' => 'admin.php?page=CostTrackerSettings',
358 'slug' => 'CostTrackerSettings',
359 'right' => '',
360 ),
361 );
362
363 MainWP_Menu::init_subpages_left_menu( $subPages, $init_sub_subleftmenu, 'Settings', 'Settings' );
364 foreach ( $init_sub_subleftmenu as $item ) {
365 if ( MainWP_Menu::is_disable_menu_item( 3, $item['slug'] ) ) {
366 continue;
367 }
368
369 MainWP_Menu::add_left_menu( $item, 2 );
370 }
371 }
372
373 /**
374 * Render Page Header.
375 *
376 * @param string $shownPage The page slug shown at this moment.
377 *
378 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
379 * @uses \MainWP\Dashboard\MainWP_UI::render_top_header()
380 * @uses \MainWP\Dashboard\MainWP_UI::render_page_navigation()
381 */
382 public static function render_header( $shownPage = '' ) { // phpcs:ignore -- NOSONAR - complex.
383
384 $params = array(
385 'title' => esc_html__( 'MainWP Settings', 'mainwp' ),
386 );
387
388 MainWP_UI::render_top_header( $params );
389
390 $renderItems = array();
391
392 $renderItems[] = array(
393 'title' => esc_html__( 'General Settings', 'mainwp' ),
394 'href' => 'admin.php?page=Settings',
395 'active' => ( '' === $shownPage ) ? true : false,
396 );
397
398 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'SettingsAdvanced' ) ) {
399 $renderItems[] = array(
400 'title' => esc_html__( 'Advanced Settings', 'mainwp' ),
401 'href' => 'admin.php?page=SettingsAdvanced',
402 'active' => ( 'Advanced' === $shownPage ) ? true : false,
403 );
404 }
405
406 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'MonitoringSettings' ) ) {
407 $renderItems[] = array(
408 'title' => esc_html__( 'Monitoring Settings', 'mainwp' ),
409 'href' => 'admin.php?page=MonitoringSettings',
410 'active' => ( 'Monitoring' === $shownPage ) ? true : false,
411 );
412 }
413
414 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'SettingsEmail' ) ) {
415 $renderItems[] = array(
416 'title' => esc_html__( 'Email Settings', 'mainwp' ),
417 'href' => 'admin.php?page=SettingsEmail',
418 'active' => ( 'Emails' === $shownPage ) ? true : false,
419 );
420 }
421
422 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'CostTrackerSettings' ) ) {
423 $renderItems[] = array(
424 'title' => esc_html__( 'Cost Tracker Settings', 'mainwp' ),
425 'href' => 'admin.php?page=CostTrackerSettings',
426 'active' => ( 'CostTrackerSettings' === $shownPage ) ? true : false,
427 );
428 }
429
430 if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
431 foreach ( static::$subPages as $subPage ) {
432 if ( MainWP_Menu::is_disable_menu_item( 3, 'Settings' . $subPage['slug'] ) ) {
433 continue;
434 }
435 $item = array();
436 $item['title'] = $subPage['title'];
437 $item['href'] = 'admin.php?page=Settings' . $subPage['slug'];
438 $item['active'] = ( $subPage['slug'] === $shownPage ) ? true : false;
439 if ( ! empty( $subPage['before_title'] ) ) {
440 $item['before_title'] = $subPage['before_title'];
441 }
442
443 if ( isset( $subPage['class'] ) ) {
444 $item['class'] = $subPage['class'];
445 }
446 $renderItems[] = $item;
447 }
448 }
449
450 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'MainWPTools' ) ) {
451 $renderItems[] = array(
452 'title' => esc_html__( 'Tools', 'mainwp' ),
453 'href' => 'admin.php?page=MainWPTools',
454 'active' => ( 'MainWPTools' === $shownPage ) ? true : false,
455 );
456 }
457
458 MainWP_UI::render_page_navigation( $renderItems, 'nav_mainwp_settings' );
459 }
460
461 /**
462 * Close the HTML container.
463 */
464 public static function render_footer() {
465 echo '</div>';
466 }
467
468 /**
469 * Method handle_settings_post().
470 *
471 * This class handles the $_POST of Settings Options.
472 *
473 * @uses MainWP_DB::instance()
474 * @uses MainWP_Utility::update_option()
475 *
476 * @return boolean True|False Posts On True.
477 *
478 * @uses \MainWP\Dashboard\MainWP_DB_Common::get_user_extension()
479 * @uses \MainWP\Dashboard\MainWP_DB_Common::update_user_extension()
480 * @uses \MainWP\Dashboard\MainWP_System_Utility::is_admin()
481 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
482 */
483 public static function handle_settings_post() { // phpcs:ignore -- NOSONAR - complex.
484 if ( isset( $_POST['submit'] ) && isset( $_POST['wp_nonce'] ) && wp_verify_nonce( sanitize_key( $_POST['wp_nonce'] ), 'Settings' ) ) {
485 $userExtension = MainWP_DB_Common::instance()->get_user_extension();
486 $userExtension->pluginDir = '';
487
488 MainWP_DB_Common::instance()->update_user_extension( $userExtension );
489 if ( MainWP_System_Utility::is_admin() ) {
490
491 $old_settings = self::get_all_settings_values();
492
493 /**
494 * Action: mainwp_before_save_general_settings
495 *
496 * Fires before general settings save.
497 *
498 * @since 4.1
499 */
500 do_action( 'mainwp_before_save_general_settings', $_POST );
501
502 $val = ( ! isset( $_POST['mainwp_pluginAutomaticDailyUpdate'] ) ? 0 : intval( $_POST['mainwp_pluginAutomaticDailyUpdate'] ) );
503 MainWP_Utility::update_option( 'mainwp_pluginAutomaticDailyUpdate', $val );
504 $val = ( ! isset( $_POST['mainwp_themeAutomaticDailyUpdate'] ) ? 0 : intval( $_POST['mainwp_themeAutomaticDailyUpdate'] ) );
505 MainWP_Utility::update_option( 'mainwp_themeAutomaticDailyUpdate', $val );
506 $val = ( ! isset( $_POST['mainwp_transAutomaticDailyUpdate'] ) ? 0 : intval( $_POST['mainwp_transAutomaticDailyUpdate'] ) );
507 MainWP_Utility::update_option( 'mainwp_transAutomaticDailyUpdate', $val );
508 $val = ( ! isset( $_POST['mainwp_automaticDailyUpdate'] ) ? 0 : intval( $_POST['mainwp_automaticDailyUpdate'] ) );
509 MainWP_Utility::update_option( 'mainwp_automaticDailyUpdate', $val );
510 $val = ( ! isset( $_POST['mainwp_show_language_updates'] ) ? 0 : 1 );
511 MainWP_Utility::update_option( 'mainwp_show_language_updates', $val );
512 $val = ( ! isset( $_POST['mainwp_disable_update_confirmations'] ) ? 0 : intval( $_POST['mainwp_disable_update_confirmations'] ) );
513 MainWP_Utility::update_option( 'mainwp_disable_update_confirmations', $val );
514 $val = ( ! isset( $_POST['mainwp_backup_before_upgrade'] ) ? 0 : 1 );
515 MainWP_Utility::update_option( 'mainwp_backup_before_upgrade', $val );
516 $val = ( ! isset( $_POST['mainwp_backup_before_upgrade_days'] ) ? 7 : intval( $_POST['mainwp_backup_before_upgrade_days'] ) );
517 MainWP_Utility::update_option( 'mainwp_backup_before_upgrade_days', $val );
518
519 if ( is_plugin_active( 'mainwp-comments-extension/mainwp-comments-extension.php' ) ) {
520 MainWP_Utility::update_option( 'mainwp_maximumComments', isset( $_POST['mainwp_maximumComments'] ) ? intval( $_POST['mainwp_maximumComments'] ) : 50 );
521 }
522
523 $current_timeDailyUpdate = get_option( 'mainwp_timeDailyUpdate' );
524 $new_timeDailyUpdate = isset( $_POST['mainwp_timeDailyUpdate'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_timeDailyUpdate'] ) ) : '';
525
526 if ( $current_timeDailyUpdate !== $new_timeDailyUpdate ) {
527 MainWP_Utility::update_option( 'mainwp_timeDailyUpdate', $new_timeDailyUpdate );
528 }
529
530 $old_freq = (int) get_option( 'mainwp_frequencyDailyUpdate', 2 );
531 $new_freq = ( isset( $_POST['mainwp_frequencyDailyUpdate'] ) ? intval( $_POST['mainwp_frequencyDailyUpdate'] ) : 2 );
532 if ( $old_freq !== $new_freq ) {
533 MainWP_Utility::update_option( 'mainwp_frequencyDailyUpdate', $new_freq );
534 MainWP_Logger::instance()->log_update_check( 'New frequency daily :: ' . $new_freq );
535 }
536
537 $curr_frequency_updates = get_option( 'mainwp_frequency_AutoUpdate', 'daily' );
538 $new_frequency_updates = isset( $_POST['mainwp_frequency_AutoUpdate'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_frequency_AutoUpdate'] ) ) : 'daily';
539 if ( $new_frequency_updates !== $curr_frequency_updates ) {
540 MainWP_Utility::update_option( 'mainwp_frequency_AutoUpdate', $new_frequency_updates );
541 }
542
543 $curr_day_updates = (int) get_option( 'mainwp_dayinweek_AutoUpdate', 0 );
544 $new_day_updates = isset( $_POST['mainwp_dayinweek_AutoUpdate'] ) ? intval( wp_unslash( $_POST['mainwp_dayinweek_AutoUpdate'] ) ) : 0;
545 if ( $new_day_updates !== $curr_day_updates ) {
546 MainWP_Utility::update_option( 'mainwp_dayinweek_AutoUpdate', $new_day_updates );
547 }
548
549 $curr_dayinmonth_updates = (int) get_option( 'mainwp_dayinmonth_AutoUpdate', 1 );
550 $new_dayinmonth_updates = isset( $_POST['mainwp_dayinmonth_AutoUpdate'] ) ? intval( wp_unslash( $_POST['mainwp_dayinmonth_AutoUpdate'] ) ) : 1;
551 if ( $new_dayinmonth_updates !== $curr_dayinmonth_updates ) {
552 MainWP_Utility::update_option( 'mainwp_dayinmonth_AutoUpdate', $new_dayinmonth_updates );
553 }
554
555 $curr_time_updates = get_option( 'mainwp_time_AutoUpdate', '00:00' );
556 $new_time_updates = isset( $_POST['mainwp_time_AutoUpdate'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_time_AutoUpdate'] ) ) : '00:00';
557 if ( $new_time_updates !== $curr_time_updates ) {
558 MainWP_Utility::update_option( 'mainwp_time_AutoUpdate', $new_time_updates );
559 }
560
561 MainWP_Cron_Jobs_Auto_Updates::set_next_auto_updates_time();
562
563 $new_delay = ( isset( $_POST['mainwp_delay_autoupdate'] ) ? intval( $_POST['mainwp_delay_autoupdate'] ) : 1 );
564 MainWP_Utility::update_option( 'mainwp_delay_autoupdate', $new_delay );
565
566 $val = ( isset( $_POST['mainwp_sidebarPosition'] ) ? intval( $_POST['mainwp_sidebarPosition'] ) : 1 );
567 $user = wp_get_current_user();
568 if ( $user ) {
569 update_user_option( $user->ID, 'mainwp_sidebarPosition', $val, true );
570 }
571
572 MainWP_Utility::update_option( 'mainwp_numberdays_Outdate_Plugin_Theme', ! empty( $_POST['mainwp_numberdays_Outdate_Plugin_Theme'] ) ? intval( $_POST['mainwp_numberdays_Outdate_Plugin_Theme'] ) : 365 );
573
574 $actions_notification_enable = ( isset( $_POST['mainwp_site_actions_notification_enable'] ) ? 1 : 0 );
575 MainWP_Utility::update_option( 'mainwp_site_actions_notification_enable', $actions_notification_enable );
576
577 //phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
578 // Handle custom date/time formats.
579 if ( ! empty( $_POST['date_format'] ) && isset( $_POST['date_format_custom'] )
580 && '\c\u\s\t\o\m' === wp_unslash( $_POST['date_format'] )
581 ) {
582 $_POST['date_format'] = wp_unslash( $_POST['date_format_custom'] );
583 }
584
585 if ( ! empty( $_POST['time_format'] ) && isset( $_POST['time_format_custom'] )
586 && '\c\u\s\t\o\m' === wp_unslash( $_POST['time_format'] )
587 ) {
588 $_POST['time_format'] = wp_unslash( $_POST['time_format_custom'] );
589 }
590
591 if ( isset( $_POST['timezone_string'] ) ) {
592 // Map UTC+- timezones to gmt_offsets and set timezone_string to empty.
593 if ( ! empty( $_POST['timezone_string'] ) && preg_match( '/^UTC[+-]/', wp_unslash( $_POST['timezone_string'] ) ) ) {
594 $_POST['gmt_offset'] = wp_unslash( $_POST['timezone_string'] );
595 $_POST['gmt_offset'] = preg_replace( '/UTC\+?/', '', wp_unslash( $_POST['gmt_offset'] ) ); //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
596 $_POST['timezone_string'] = '';
597 }
598
599 $options = array(
600 'gmt_offset',
601 'date_format',
602 'time_format',
603 'timezone_string',
604 );
605
606 foreach ( $options as $option ) {
607 $value = null;
608 if ( isset( $_POST[ $option ] ) ) {
609 $value = wp_unslash( $_POST[ $option ] );
610 if ( ! is_array( $value ) ) {
611 $value = trim( $value );
612 }
613 }
614 update_option( $option, $value );
615 }
616 }
617 //phpcs:enable
618
619 MainWP_Utility::update_option( 'mainwp_use_favicon', 1 );
620 /**
621 * Action: mainwp_after_save_general_settings
622 *
623 * Fires after save general settings.
624 *
625 * @since 4.1
626 */
627 do_action( 'mainwp_after_save_general_settings', $_POST );
628
629 $new_settings = self::get_all_settings_values();
630
631 /**
632 * Action: mainwp_after_save_settings
633 *
634 * Fires after save settings.
635 *
636 * @since 6.0
637 *
638 * @param array $new_settings The new settings.
639 * @param array $old_settings The old settings.
640 */
641 do_action( 'mainwp_after_save_settings', $new_settings, $old_settings );
642
643 }
644
645 return true;
646 }
647
648 return false;
649 }
650
651 /**
652 * Method get_all_settings_values().
653 *
654 * @param mixed $keys_only True if get Keys only.
655 *
656 * @return array All Settings Fields.
657 */
658 public static function get_all_settings_values( $keys_only = false ) {
659 $keys = array(
660 'mainwp_hide_update_everything',
661 'mainwp_pluginAutomaticDailyUpdate',
662 'mainwp_themeAutomaticDailyUpdate',
663 'mainwp_transAutomaticDailyUpdate',
664 'mainwp_automaticDailyUpdate',
665 'mainwp_show_language_updates',
666 'mainwp_disable_update_confirmations',
667 'mainwp_backup_before_upgrade',
668 'mainwp_backup_before_upgrade_days',
669 'mainwp_maximumComments',
670 'mainwp_automatic_update_next_run_timestamp',
671 'mainwp_delay_autoupdate',
672 'mainwp_numberdays_Outdate_Plugin_Theme',
673 'mainwp_check_http_response',
674 'mainwp_check_http_response_method',
675 'mainwp_site_actions_notification_enable',
676 'mainwp_use_favicon',
677 'mainwp_backupsOnServer',
678 'mainwp_maximumFileDescriptors',
679 'mainwp_maximumFileDescriptorsAuto',
680 'mainwp_backupOnExternalSources',
681 'mainwp_archiveFormat',
682 'mainwp_notificationOnBackupFail',
683 'mainwp_notificationOnBackupStart',
684 'mainwp_chunkedBackupTasks',
685 'mainwp_primaryBackup',
686 'mainwp_enableLegacyBackupFeature',
687 'mainwp_global_uptime_monitoring_settings',
688 'mainwp_disableSitesHealthMonitoring',
689 'mainwp_sitehealthThreshold',
690 'mainwp_maximumRequests',
691 'mainwp_minimumDelay',
692 'mainwp_maximumIPRequests',
693 'mainwp_minimumIPDelay',
694 'mainwp_maximumSyncRequests',
695 'mainwp_maximumInstallUpdateRequests',
696 'mainwp_sslVerifyCertificate',
697 'mainwp_connect_signature_algo',
698 'mainwp_verify_connection_method',
699 'mainwp_forceUseIPv4',
700 'mainwp_wp_cron',
701 'mainwp_warm_cache_pages_ttl',
702 'mainwp_optimize',
703 'mainwp_maximum_uptime_monitoring_requests',
704 'mainwp_chunksitesnumber',
705 'mainwp_chunksleepinterval',
706 'mainwp_settings_sync_data',
707 'mainwp_module_log_settings',
708 'mainwp_module_log_settings_logs_selection_data',
709 'mainwp_uptimecheck_running',
710 'mainwp_uptimecheck_auto_main_counter_lasttime_started',
711 'mainwp_enable_guided_tours',
712 'mainwp_enable_guided_chatbase',
713 'mainwp_enable_guided_video',
714 'mainwp_enable_cloudways_api',
715 'mainwp_enable_gridpane_api',
716 'mainwp_enable_vultr_api',
717 'mainwp_enable_linode_api',
718 'mainwp_enable_digitalocean_api',
719 'mainwp_enable_cpanel_api',
720 'mainwp_enable_plesk_api',
721 'mainwp_enable_kinsta_api',
722 );
723
724 if ( $keys_only ) {
725 return $keys;
726 }
727
728 $values = array();
729 foreach ( $keys as $key ) {
730 $values[ $key ] = get_option( $key );
731 }
732 return $values;
733 }
734
735 /**
736 * Render the MainWP Settings Page.
737 *
738 * @uses \MainWP\Dashboard\MainWP_Monitoring_View
739 * @uses \MainWP\Dashboard\MainWP_Manage_Backups::render_settings()
740 * @uses \MainWP\Dashboard\MainWP_Utility::get_http_codes()
741 */
742 public static function render() { //phpcs:ignore -- NOSONAR - complex method.
743 if ( ! \mainwp_current_user_can( 'dashboard', 'manage_dashboard_settings' ) ) {
744 \mainwp_do_not_have_permissions( esc_html__( 'manage dashboard settings', 'mainwp' ) );
745 return;
746 }
747
748 static::render_header( '' );
749 ?>
750 <div id="mainwp-general-settings" class="ui padded segment">
751
752 <?php if ( isset( $_GET['message'] ) && 'saved' === $_GET['message'] ) : // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized ?>
753 <div class="ui green message"><i class="close icon"></i><?php esc_html_e( 'Settings have been saved successfully!', 'mainwp' ); ?></div>
754 <?php endif; ?>
755 <div class="ui form">
756 <form method="POST" action="admin.php?page=Settings" id="mainwp-settings-page-form">
757 <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
758 <input type="hidden" name="wp_nonce" value="<?php echo esc_attr( wp_create_nonce( 'Settings' ) ); ?>" />
759 <?php
760 /**
761 * Action: mainwp_settings_form_top
762 *
763 * Fires at the top of settings form.
764 *
765 * @since 4.1
766 */
767 do_action( 'mainwp_settings_form_top' );
768 ?>
769 <h3 class="ui dividing header">
770 <?php MainWP_Settings_Indicator::render_indicator( 'header', 'settings-field-indicator-general' ); ?>
771 <?php esc_html_e( 'General Settings', 'mainwp' ); ?></h3>
772 <?php
773 $timeDailyUpdate = get_option( 'mainwp_timeDailyUpdate' );
774 $frequencyDailyUpdate = (int) get_option( 'mainwp_frequencyDailyUpdate', 2 );
775 $run_timestamp = MainWP_System_Cron_Jobs::get_timestamp_from_hh_mm( $timeDailyUpdate );
776 $delay_autoupdate = (int) get_option( 'mainwp_delay_autoupdate', 1 );
777
778 ?>
779 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-general">
780 <label class="six wide column middle aligned">
781 <?php
782 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_timeDailyUpdate', $timeDailyUpdate );
783 esc_html_e( 'Daily sync time', 'mainwp' );
784 ?>
785 </label>
786 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Choose a specific time to initiate the first daily synchronization process.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
787 <div class="time-selector">
788 <div class="ui input left icon">
789 <i class="clock icon"></i>
790 <input type="text" class="settings-field-value-change-handler" current-utc-datetime="<?php echo esc_attr( gmdate( 'Y-m-d H:i:s' ) ); ?>" sync-time-local-datetime="<?php echo esc_attr( gmdate( 'Y-m-d H:i:s', $run_timestamp ) ); ?>" local-datetime="<?php echo esc_attr( gmdate( 'Y-m-d H:i:s', MainWP_Utility::get_timestamp() ) ); // phpcs:ignore -- to get local time. ?>" name="mainwp_timeDailyUpdate" id="mainwp_timeDailyUpdate" value="<?php echo esc_attr( $timeDailyUpdate ); ?>" />
791 </div>
792 </div>
793 </div>
794 </div>
795 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-general" default-indi-value="2">
796 <label class="six wide column middle aligned">
797 <?php
798 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_frequencyDailyUpdate', $frequencyDailyUpdate );
799 esc_html_e( 'Frequency of auto sync', 'mainwp' );
800 ?>
801 </label>
802 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Set the frequency for automatic synchronization throughout the day.', 'mainwp' ); ?>" data-inverted="" data-position="top left" >
803 <select name="mainwp_frequencyDailyUpdate" id="mainwp_frequencyDailyUpdate" class="ui dropdown settings-field-value-change-handler">
804 <option value="1" <?php echo 1 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Once per day', 'mainwp' ); ?></option>
805 <option value="2" <?php echo 2 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Twice per day', 'mainwp' ); ?></option>
806 <option value="3" <?php echo 3 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Three times per day', 'mainwp' ); ?></option>
807 <option value="4" <?php echo 4 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Four times per day', 'mainwp' ); ?></option>
808 <option value="5" <?php echo 5 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Five times per day', 'mainwp' ); ?></option>
809 <option value="6" <?php echo 6 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Six times per day', 'mainwp' ); ?></option>
810 <option value="7" <?php echo 7 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Seven times per day', 'mainwp' ); ?></option>
811 <option value="8" <?php echo 8 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Eight times per day', 'mainwp' ); ?></option>
812 <option value="9" <?php echo 9 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Nine times per day', 'mainwp' ); ?></option>
813 <option value="10" <?php echo 10 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Ten times per day', 'mainwp' ); ?></option>
814 <option value="11" <?php echo 11 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Eleven times per day', 'mainwp' ); ?></option>
815 <option value="12" <?php echo 12 === $frequencyDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Twelve times per day', 'mainwp' ); ?></option>
816 </select>
817 </div>
818 </div>
819 <script type="text/javascript">
820 jQuery( document ).ready( function() {
821 jQuery( '.time-selector' ).calendar( {
822 type: 'time',
823 ampm: false,
824 formatter: {
825 time: 'H:mm',
826 cellTime: 'H:mm'
827 }
828 } );
829 } );
830 </script>
831
832 <?php
833
834 static::render_timezone_settings();
835 static::render_datetime_settings();
836
837 $sidebarPosition = get_user_option( 'mainwp_sidebarPosition' );
838 if ( false === $sidebarPosition ) {
839 $sidebarPosition = 1;
840 }
841
842 ?>
843 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-general" default-indi-value="1">
844 <label class="six wide column middle aligned">
845 <?php
846 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_sidebarPosition', (int) $sidebarPosition );
847 esc_html_e( 'Sidebar position', 'mainwp' );
848 ?>
849 </label>
850 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Select if you want to show sidebar with option on left or right.', 'mainwp' ); ?>" data-inverted="" data-position="bottom left">
851 <select name="mainwp_sidebarPosition" id="mainwp_sidebarPosition" class="ui dropdown settings-field-value-change-handler">
852 <option value="1" <?php echo 1 === (int) $sidebarPosition ? 'selected' : ''; ?>><?php esc_html_e( 'Right (default)', 'mainwp' ); ?></option>
853 <option value="0" <?php echo 0 === (int) $sidebarPosition ? 'selected' : ''; ?>><?php esc_html_e( 'Left', 'mainwp' ); ?></option>
854 </select>
855 </div>
856 </div>
857 <?php MainWP_UI::render_screen_options(); ?>
858
859 <h3 class="ui dividing header">
860 <?php MainWP_Settings_Indicator::render_indicator( 'header', 'settings-field-indicator-updates' ); ?>
861 <?php esc_html_e( 'Updates Settings', 'mainwp' ); ?></h3>
862 <?php
863 $snAutomaticDailyUpdate = (int) get_option( 'mainwp_automaticDailyUpdate', 0 );
864 $snPluginAutomaticDailyUpdate = (int) get_option( 'mainwp_pluginAutomaticDailyUpdate', 0 );
865 $snThemeAutomaticDailyUpdate = (int) get_option( 'mainwp_themeAutomaticDailyUpdate', 0 );
866 $snTransAutomaticUpdate = (int) get_option( 'mainwp_transAutomaticDailyUpdate', 0 );
867
868 $backup_before_upgrade = get_option( 'mainwp_backup_before_upgrade' );
869 $mainwp_backup_before_upgrade_days = get_option( 'mainwp_backup_before_upgrade_days' );
870 if ( empty( $mainwp_backup_before_upgrade_days ) || ! ctype_digit( $mainwp_backup_before_upgrade_days ) ) {
871 $mainwp_backup_before_upgrade_days = 7;
872 }
873 $mainwp_show_language_updates = get_option( 'mainwp_show_language_updates', 1 );
874 $enableLegacyBackupFeature = get_option( 'mainwp_enableLegacyBackupFeature' );
875 $primaryBackup = get_option( 'mainwp_primaryBackup' );
876 $disableUpdateConfirmations = (int) get_option( 'mainwp_disable_update_confirmations', 0 );
877 ?>
878 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-updates">
879 <label class="six wide column middle aligned">
880 <?php
881 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_pluginAutomaticDailyUpdate', $snPluginAutomaticDailyUpdate );
882 esc_html_e( 'Plugin advanced automatic updates', 'mainwp' );
883 ?>
884 </label>
885 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Enable or disable automatic plugin updates. If enabled, MainWP will update only plugins that you have marked as Trusted.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
886 <select name="mainwp_pluginAutomaticDailyUpdate" id="mainwp_pluginAutomaticDailyUpdate" class="ui dropdown settings-field-value-change-handler">
887 <option value="1" <?php echo 1 === $snPluginAutomaticDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Install Trusted Updates', 'mainwp' ); ?></option>
888 <option value="0" <?php echo 0 === $snPluginAutomaticDailyUpdate || 2 === $snPluginAutomaticDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Disabled', 'mainwp' ); ?></option>
889 </select>
890 </div>
891 </div>
892 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-updates">
893 <label class="six wide column middle aligned">
894 <?php
895 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_themeAutomaticDailyUpdate', $snThemeAutomaticDailyUpdate );
896 esc_html_e( 'Theme advanced automatic updates', 'mainwp' );
897 ?>
898 </label>
899 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Enable or disable automatic theme updates. If enabled, MainWP will update only themes that you have marked as Trusted.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
900 <select name="mainwp_themeAutomaticDailyUpdate" id="mainwp_themeAutomaticDailyUpdate" class="ui dropdown settings-field-value-change-handler">
901 <option value="1" <?php echo 1 === $snThemeAutomaticDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Install Trusted Updates', 'mainwp' ); ?></option>
902 <option value="0" <?php echo 0 === $snThemeAutomaticDailyUpdate || 2 === $snThemeAutomaticDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Disabled', 'mainwp' ); ?></option>
903 </select>
904 </div>
905 </div>
906 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-updates">
907 <label class="six wide column middle aligned">
908 <?php
909 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_stransAutomaticUpdate', $snTransAutomaticUpdate );
910 esc_html_e( 'Translation advanced automatic updates', 'mainwp' );
911 ?>
912 </label>
913 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Enable or disable automatic Translation updates.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
914 <select name="mainwp_transAutomaticDailyUpdate" id="mainwp_transAutomaticDailyUpdate" class="ui dropdown settings-field-value-change-handler">
915 <option value="1" <?php echo 1 === $snTransAutomaticUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Install Trusted Updates', 'mainwp' ); ?></option>
916 <option value="0" <?php echo 0 === $snTransAutomaticUpdate || 2 === (int) $snTransAutomaticUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Disabled', 'mainwp' ); ?></option>
917 </select>
918 </div>
919 </div>
920 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-updates">
921 <label class="six wide column middle aligned">
922 <?php
923 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_automaticDailyUpdate', $snAutomaticDailyUpdate );
924 esc_html_e( 'WP Core advanced automatic updates', 'mainwp' );
925 ?>
926 </label>
927 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Enable or disable automatic WordPress core updates.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
928 <select name="mainwp_automaticDailyUpdate" id="mainwp_automaticDailyUpdate" class="ui dropdown settings-field-value-change-handler">
929 <option value="1" <?php echo 1 === $snAutomaticDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Install Trusted Updates', 'mainwp' ); ?></option>
930 <option value="0" <?php echo 0 === $snAutomaticDailyUpdate || 2 === (int) $snAutomaticDailyUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Disabled', 'mainwp' ); ?></option>
931 </select>
932 </div>
933 </div>
934 <?php static::render_auto_updates_settings(); ?>
935 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-updates" default-indi-value="1">
936 <label class="six wide column middle aligned">
937 <?php
938 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_delay_autoupdate', $delay_autoupdate );
939 esc_html_e( 'Advanced automatic updates delay', 'mainwp' );
940 ?>
941 </label>
942 <div class="ten wide column ui input" data-tooltip="<?php esc_attr_e( 'Set the number of days to delay automatic updates.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
943 <select name="mainwp_delay_autoupdate" id="mainwp_delay_autoupdate" class="ui dropdown settings-field-value-change-handler">
944 <option value="0" <?php echo 0 === $delay_autoupdate ? 'selected' : ''; ?>><?php esc_html_e( 'Delay off', 'mainwp' ); ?></option>
945 <option value="1" <?php echo 1 === $delay_autoupdate ? 'selected' : ''; ?>><?php esc_html_e( '1 day', 'mainwp' ); ?></option>
946 <option value="2" <?php echo 2 === $delay_autoupdate ? 'selected' : ''; ?>><?php esc_html_e( '2 days', 'mainwp' ); ?></option>
947 <option value="3" <?php echo 3 === $delay_autoupdate ? 'selected' : ''; ?>><?php esc_html_e( '3 days', 'mainwp' ); ?></option>
948 <option value="4" <?php echo 4 === $delay_autoupdate ? 'selected' : ''; ?>><?php esc_html_e( '4 days', 'mainwp' ); ?></option>
949 <option value="5" <?php echo 5 === $delay_autoupdate ? 'selected' : ''; ?>><?php esc_html_e( '5 days', 'mainwp' ); ?></option>
950 <option value="6" <?php echo 6 === $delay_autoupdate ? 'selected' : ''; ?>><?php esc_html_e( '6 days', 'mainwp' ); ?></option>
951 <option value="7" <?php echo 7 === $delay_autoupdate ? 'selected' : ''; ?>><?php esc_html_e( '7 days', 'mainwp' ); ?></option>
952 <option value="14" <?php echo 14 === $delay_autoupdate ? 'selected' : ''; ?>><?php esc_html_e( '14 days', 'mainwp' ); ?></option>
953 <option value="30" <?php echo 30 === $delay_autoupdate ? 'selected' : ''; ?>><?php esc_html_e( '30 days', 'mainwp' ); ?></option>
954 </select>
955 </div>
956 </div>
957 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-updates" default-indi-value="1">
958 <label class="six wide column middle aligned">
959 <?php
960 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_show_language_updates', $mainwp_show_language_updates );
961 esc_html_e( 'Show WordPress language updates', 'mainwp' );
962 ?>
963 </label>
964 <div class="ten wide column ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'Enable if you want to manage Translation updates', 'mainwp' ); ?>" data-inverted="" data-position="top left">
965 <input type="checkbox" name="mainwp_show_language_updates" class="settings-field-value-change-handler" id="mainwp_show_language_updates" <?php echo 1 === (int) $mainwp_show_language_updates ? 'checked="true"' : ''; ?>/>
966 </div>
967 </div>
968 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-updates">
969 <label class="six wide column middle aligned">
970 <?php
971 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_disable_update_confirmations', $disableUpdateConfirmations );
972 esc_html_e( 'Update confirmations', 'mainwp' );
973 ?>
974 </label>
975 <div class="ten wide column ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'Choose if you want to disable the popup confirmations when performing updates.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
976 <select name="mainwp_disable_update_confirmations" id="mainwp_disable_update_confirmations" class="ui dropdown settings-field-value-change-handler">
977 <option value="0" <?php echo 0 === $disableUpdateConfirmations ? 'selected' : ''; ?>><?php esc_html_e( 'Enable', 'mainwp' ); ?></option>
978 <option value="2" <?php echo 2 === $disableUpdateConfirmations ? 'selected' : ''; ?>><?php esc_html_e( 'Disable', 'mainwp' ); ?></option>
979 <option value="1" <?php echo 1 === $disableUpdateConfirmations ? 'selected' : ''; ?>><?php esc_html_e( 'Disable for single updates', 'mainwp' ); ?></option>
980 </select>
981 </div>
982 </div>
983 <?php if ( ( $enableLegacyBackupFeature && empty( $primaryBackup ) ) || ( empty( $enableLegacyBackupFeature ) && ! empty( $primaryBackup ) ) ) { ?>
984 <div class="ui grid field mainwp-parent-toggle settings-field-indicator-wrapper settings-field-indicator-updates">
985 <label class="six wide column middle aligned">
986 <?php
987 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_backup_before_upgrade', (int) $backup_before_upgrade );
988 esc_html_e( 'Require a backup before an update', 'mainwp' );
989 ?>
990 </label>
991 <div class="ten wide column ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'If enabled, your MainWP Dashboard will check if full backups exists before updating.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
992 <input type="checkbox" class="settings-field-value-change-handler" name="mainwp_backup_before_upgrade" id="mainwp_backup_before_upgrade" <?php echo 1 === (int) $backup_before_upgrade ? 'checked="true"' : ''; ?>/>
993 </div>
994 </div>
995 <div class="ui grid field mainwp-child-field settings-field-indicator-wrapper settings-field-indicator-updates" default-indi-value="7" <?php echo 1 === (int) $backup_before_upgrade ? '' : 'style="display:none"'; ?> >
996 <label class="six wide column middle aligned">
997 <?php
998 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_backup_before_upgrade_days', (int) $mainwp_backup_before_upgrade_days );
999 esc_html_e( 'Days without of a full backup tolerance', 'mainwp' );
1000 ?>
1001 </label>
1002 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Set the number of days without of backup tolerance.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1003 <input type="text" class="settings-field-value-change-handler" name="mainwp_backup_before_upgrade_days" id="mainwp_backup_before_upgrade_days" value="<?php echo esc_attr( $mainwp_backup_before_upgrade_days ); ?>" />
1004 </div>
1005 </div>
1006 <?php } ?>
1007
1008 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-updates" default-indi-value="365">
1009 <label class="six wide column middle aligned">
1010 <?php
1011 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_numberdays_Outdate_Plugin_Theme', (int) get_option( 'mainwp_numberdays_Outdate_Plugin_Theme', 365 ) );
1012
1013 esc_html_e( 'Abandoned plugins/themes tolerance', 'mainwp' );
1014 ?>
1015 </label>
1016 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Set how many days without an update before plugin or theme will be considered as abandoned.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1017 <input type="text" class="settings-field-value-change-handler" name="mainwp_numberdays_Outdate_Plugin_Theme" id="mainwp_numberdays_Outdate_Plugin_Theme" value="<?php echo false === get_option( 'mainwp_numberdays_Outdate_Plugin_Theme' ) ? 365 : intval( get_option( 'mainwp_numberdays_Outdate_Plugin_Theme' ) ); ?>"/>
1018 </div>
1019 </div>
1020
1021 <?php MainWP_Manage_Backups::render_settings(); ?>
1022 <?php
1023 /**
1024 * Action: mainwp_settings_form_bottom
1025 *
1026 * Fires at the bottom of settings form.
1027 *
1028 * @since 4.1
1029 */
1030 do_action( 'mainwp_settings_form_bottom' );
1031 ?>
1032 <div class="ui divider"></div>
1033 <input type="submit" name="submit" id="submit" class="ui button green big" value="<?php esc_attr_e( 'Save Settings', 'mainwp' ); ?>"/>
1034 <div style="clear:both"></div>
1035 </form>
1036 </div>
1037 </div>
1038 <?php
1039 static::render_footer( '' );
1040 }
1041
1042 /**
1043 * Method render_auto_updates_settings().
1044 */
1045 public static function render_auto_updates_settings() { // phpcs:ignore -- NOSONAR - complex.
1046
1047 $time_AutoUpdate = get_option( 'mainwp_time_AutoUpdate' );
1048 $dayinweek_AutoUpdate = (int) get_option( 'mainwp_dayinweek_AutoUpdate', 0 );
1049 $dayinmonth_AutoUpdate = (int) get_option( 'mainwp_dayinmonth_AutoUpdate', 1 );
1050 $frequency_AutoUpdate = get_option( 'mainwp_frequency_AutoUpdate', 'daily' );
1051
1052 if ( empty( $time_AutoUpdate ) ) {
1053 $time_AutoUpdate = '00:00';
1054 }
1055
1056 if ( ! in_array( $frequency_AutoUpdate, array( 'daily', 'weekly', 'monthly' ) ) ) {
1057 $frequency_AutoUpdate = 'daily';
1058 }
1059
1060 ?>
1061 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-general" default-indi-value="daily">
1062 <label class="six wide column middle aligned">
1063 <?php
1064 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_frequency_AutoUpdate', $frequency_AutoUpdate );
1065 esc_html_e( 'Frequency of automatic updates', 'mainwp' );
1066 ?>
1067 </label>
1068 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Set the frequency for automatic updates process.', 'mainwp' ); ?>" data-inverted="" data-position="top left" >
1069 <select name="mainwp_frequency_AutoUpdate" id="mainwp_frequency_AutoUpdate" class="ui dropdown settings-field-value-change-handler">
1070 <option value="daily" <?php echo 'daily' === $frequency_AutoUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Daily', 'mainwp' ); ?></option>
1071 <option value="weekly" <?php echo 'weekly' === $frequency_AutoUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Weekly', 'mainwp' ); ?></option>
1072 <option value="monthly" <?php echo 'monthly' === $frequency_AutoUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Monthly', 'mainwp' ); ?></option>
1073 </select>
1074 </div>
1075 </div>
1076
1077 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-general" id="mainwp-dayinmonth-autoupdate-wrapper" <?php echo in_array( $frequency_AutoUpdate, array( 'monthly' ) ) ? '' : 'style="display:none;"'; ?>>
1078 <label class="six wide column middle aligned">
1079 <?php
1080 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_dayinmonth_AutoUpdate', $dayinmonth_AutoUpdate );
1081 esc_html_e( 'Select day', 'mainwp' );
1082 ?>
1083 </label>
1084 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Choose a specific day in month to initiate automatic updates process.', 'mainwp' ); ?>" data-inverted="" data-position="top left" >
1085 <select name="mainwp_dayinmonth_AutoUpdate" id="mainwp_dayinmonth_AutoUpdate" class="ui dropdown settings-field-value-change-handler">
1086 <?php
1087 $day_suffix = array(
1088 1 => 'st',
1089 2 => 'nd',
1090 3 => 'rd',
1091 );
1092 for ( $x = 1; $x <= 31; $x++ ) {
1093 $_select = '';
1094 if ( $dayinmonth_AutoUpdate === $x ) {
1095 $_select = 'selected';
1096 }
1097 $remain = $x % 10;
1098 $day_sf = isset( $day_suffix[ $remain ] ) ? $day_suffix[ $remain ] : 'th';
1099 echo '<option value="' . intval( $x ) . '" ' . esc_html( $_select ) . '>' . esc_html( $x . $day_sf ) . ' of the month</option>';
1100 }
1101 ?>
1102 </select>
1103 </div>
1104 </div>
1105
1106 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-general" id="mainwp-dayinweek-autoupdate-wrapper" <?php echo in_array( $frequency_AutoUpdate, array( 'weekly' ) ) ? '' : 'style="display:none;"'; ?>>
1107 <label class="six wide column middle aligned">
1108 <?php
1109 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_dayinweek_AutoUpdate', $dayinweek_AutoUpdate );
1110 esc_html_e( 'Select day', 'mainwp' );
1111 ?>
1112 </label>
1113 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Choose a specific day in week to initiate automatic updates process.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1114 <select name="mainwp_dayinweek_AutoUpdate" id="mainwp_dayinweek_AutoUpdate" class="ui dropdown settings-field-value-change-handler">
1115 <option value="0" <?php echo 0 === $dayinweek_AutoUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Mon', 'mainwp' ); ?></option>
1116 <option value="1" <?php echo 1 === $dayinweek_AutoUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Tue', 'mainwp' ); ?></option>
1117 <option value="2" <?php echo 2 === $dayinweek_AutoUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Wed', 'mainwp' ); ?></option>
1118 <option value="3" <?php echo 3 === $dayinweek_AutoUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Thus', 'mainwp' ); ?></option>
1119 <option value="4" <?php echo 4 === $dayinweek_AutoUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Fri', 'mainwp' ); ?></option>
1120 <option value="5" <?php echo 5 === $dayinweek_AutoUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Sat', 'mainwp' ); ?></option>
1121 <option value="6" <?php echo 6 === $dayinweek_AutoUpdate ? 'selected' : ''; ?>><?php esc_html_e( 'Sun', 'mainwp' ); ?></option>
1122 </select>
1123 </div>
1124 </div>
1125 <div id="mainwp-time-autoupdate-wrapper" class="ui grid field settings-field-indicator-wrapper settings-field-indicator-general" default-indi-value="00:00">
1126 <label class="six wide column middle aligned">
1127 <?php
1128 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_time_AutoUpdate', $time_AutoUpdate );
1129 esc_html_e( 'Select time', 'mainwp' );
1130 $_last_start_auto_updates = get_option( 'mainwp_automatic_updates_start_lasttime', 0 );
1131 $_next_auto_updates = get_option( 'mainwp_automatic_update_next_run_timestamp', 0 );
1132 ?>
1133 </label>
1134 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Choose a specific time to initiate automatic updates process.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1135 <div class="time-selector">
1136 <div class="ui input left icon">
1137 <i class="clock icon"></i>
1138 <input type="text" class="settings-field-value-change-handler" current-utc-datetime="<?php echo date( 'Y-m-d H:i:s' ); ?>" auto-updates-last-start-time="<?php echo date( 'Y-m-d H:i:s', $_last_start_auto_updates ); ?>" auto-updates-next-time="<?php echo date( 'Y-m-d H:i:s', $_next_auto_updates ); ?>" local-datetime="<?php echo date( 'Y-m-d H:i:s', MainWP_Utility::get_timestamp() ); // phpcs:ignore -- to get local time. ?>" name="mainwp_time_AutoUpdate" id="mainwp_time_AutoUpdate" value="<?php echo esc_attr( $time_AutoUpdate ); ?>" />
1139 </div>
1140 </div>
1141 </div>
1142 </div>
1143 <script type="text/javascript">
1144 jQuery(document).on('change', '#mainwp_frequency_AutoUpdate', function () {
1145 if( jQuery(this).val() == 'monthly' ){
1146 jQuery('#mainwp-dayinweek-autoupdate-wrapper').hide();
1147 jQuery('#mainwp-dayinmonth-autoupdate-wrapper').show();
1148 } else if( jQuery(this).val() == 'weekly'){
1149 jQuery('#mainwp-dayinweek-autoupdate-wrapper').show();
1150 jQuery('#mainwp-dayinmonth-autoupdate-wrapper').hide();
1151 } else {
1152 jQuery('#mainwp-dayinweek-autoupdate-wrapper').hide();
1153 jQuery('#mainwp-dayinmonth-autoupdate-wrapper').hide();
1154 }
1155 });
1156 </script>
1157 <?php
1158 }
1159
1160 /**
1161 * Render Timezone settings.
1162 */
1163 public static function render_timezone_settings() { // phpcs:ignore -- NOSONAR - complex.
1164
1165 $current_offset = get_option( 'gmt_offset' );
1166 $tzstring = get_option( 'timezone_string' );
1167 $tzstring = MainWP_Utility::clean_wp_timezone_string( $tzstring );
1168
1169 $check_zone_info = true;
1170
1171 // Remove old Etc mappings. Fallback to gmt_offset.
1172 if ( false !== strpos( $tzstring, 'Etc/GMT' ) ) {
1173 $tzstring = '';
1174 }
1175
1176 if ( empty( $tzstring ) ) { // Create a UTC+- zone if no timezone string exists.
1177 $check_zone_info = false;
1178 if ( empty( $current_offset ) ) {
1179 $tzstring = 'UTC+0';
1180 } elseif ( $current_offset < 0 ) {
1181 $tzstring = 'UTC' . $current_offset;
1182 } else {
1183 $tzstring = 'UTC+' . $current_offset;
1184 }
1185 }
1186
1187 $timezone_format = _x( 'Y-m-d H:i:s', 'timezone date format', 'mainwp' );
1188
1189 ?>
1190 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-general">
1191 <label class="six wide column middle aligned"><?php esc_html_e( 'Timezone', 'mainwp' ); ?></label>
1192 <?php
1193 // translators: %s is the abbreviation "UTC".
1194 $timezone_tooltip = esc_attr__( 'Choose either a city in the same timezone as you or a %s (Coordinated Universal Time) time offset.', 'mainwp' );
1195 ?>
1196 <div class="ten wide column" data-tooltip="<?php echo $timezone_tooltip; // phpcs:ignore WordPress.Security.EscapeOutput ?>" data-inverted="" data-position="top left">
1197 <select id="timezone_string" class="ui dropdown" name="timezone_string" aria-describedby="timezone-description">
1198 <?php echo wp_timezone_choice( $tzstring, get_user_locale() ); // phpcs:ignore WordPress.Security.EscapeOutput ?>
1199 </select>
1200 <div class="ui hidden fitted divider"></div>
1201 <div class="ui secondary segment">
1202 <?php
1203 // translators: %s is the current UTC date and time.
1204 printf( esc_html__( 'Universal time is %s.', 'mainwp' ), '<code>' . esc_html( date_i18n( $timezone_format, false, true ) ) . '</code>' );
1205 ?>
1206 <div class="ui hidden fitted divider"></div>
1207 <?php if ( get_option( 'timezone_string' ) || ! empty( $current_offset ) ) : ?>
1208 <?php
1209 // translators: %s is the current local date and time.
1210 printf( esc_html__( 'Local time is %s.', 'mainwp' ), '<code>' . esc_html( date_i18n( $timezone_format ) ) . '</code>' );
1211 ?>
1212 <div class="ui hidden fitted divider"></div>
1213 <?php endif; ?>
1214 <?php if ( $check_zone_info && $tzstring ) : ?>
1215 <?php
1216 $now = new \DateTime( 'now', new \DateTimeZone( $tzstring ) );
1217 $dst = (bool) $now->format( 'I' );
1218
1219 if ( $dst ) {
1220 esc_html_e( 'This timezone is currently in daylight saving time.', 'mainwp' );
1221 } else {
1222 esc_html_e( 'This timezone is currently in standard time.', 'mainwp' );
1223 }
1224 ?>
1225 <div class="ui hidden fitted divider"></div>
1226 <?php
1227 if ( in_array( $tzstring, timezone_identifiers_list(), true ) ) {
1228 $transitions = timezone_transitions_get( timezone_open( $tzstring ), time() );
1229
1230 if ( ! empty( $transitions[1] ) ) {
1231 echo ' ';
1232 // translators: %s is the date and time when the timezone transition occurs.
1233 $message = $transitions[1]['isdst'] ? esc_html__( 'Daylight saving time begins on: %s.', 'mainwp' ) : esc_html__( 'Standard time begins on: %s.', 'mainwp' );
1234 printf( $message, '<code>' . wp_date( esc_html__( 'F j, Y', 'mainwp' ) . ' ' . esc_html__( 'g:i a', 'mainwp' ), esc_html( $transitions[1]['ts'] ) ) . '</code>' ); // phpcs:ignore WordPress.Security.EscapeOutput
1235 } else {
1236 esc_html_e( 'This timezone does not observe daylight saving time.', 'mainwp' );
1237 }
1238 }
1239 ?>
1240 <?php endif; ?>
1241 </div>
1242 </div>
1243 </div>
1244 <?php
1245 }
1246
1247 /**
1248 * Render Date/Time settings.
1249 */
1250 public static function render_datetime_settings() {
1251 ?>
1252 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-general" default-indi-value="F j, Y">
1253 <label class="six wide column middle aligned">
1254 <?php
1255 MainWP_Settings_Indicator::render_not_default_indicator( 'date_format', get_option( 'date_format' ) );
1256 esc_html_e( 'Date format', 'mainwp' );
1257 ?>
1258 </label>
1259 <div class="ten wide column fieldset-wrapper" data-tooltip="<?php esc_attr_e( 'Choose the display format for date.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1260 <?php
1261 /**
1262 * Filters the default date formats.
1263 *
1264 * @since 2.7.0
1265 * @since 4.0.0 Added ISO date standard YYYY-MM-DD format.
1266 *
1267 * @param string[] $default_date_formats Array of default date formats.
1268 */
1269 $date_formats = array_unique( apply_filters( 'date_formats', array( esc_html__( 'F j, Y', 'mainwp' ), 'Y-m-d', 'm/d/Y', 'd/m/Y' ) ) );
1270
1271 $custom = true;
1272
1273 foreach ( $date_formats as $format ) {
1274 echo "\t<label><input type='radio' name='date_format' value='" . esc_attr( $format ) . "'";
1275 if ( get_option( 'date_format' ) === $format ) { // checked() uses "==" rather than "===".
1276 echo " checked='checked'";
1277 $custom = false;
1278 }
1279 echo ' /> <span class="date-time-text format-i18n">' . esc_html( date_i18n( $format ) ) . '</span><code>' . esc_html( $format ) . "</code></label><br />\n";
1280 }
1281 echo '<label><input type="radio" name="date_format" id="date_format_custom_radio" value="\c\u\s\t\o\m"';
1282 checked( $custom );
1283 echo '/> <span class="date-time-text date-time-custom-text">' . esc_html__( 'Custom:', 'mainwp' ) . '<span class="screen-reader-text"> ' . esc_html__( 'enter a custom date format in the following field', 'mainwp' ) . '</span></span></label>' .
1284 '<label for="date_format_custom" class="screen-reader-text">' . esc_html__( 'Custom date format:', 'mainwp' ) . '</label>' .
1285 '<input type="text" name="date_format_custom" id="date_format_custom" value="' . esc_attr( get_option( 'date_format' ) ) . '" class="small-text settings-field-value-change-handler" />' .
1286 '<br />' .
1287 '<em><strong>' . esc_html__( 'Preview:', 'mainwp' ) . '</strong> <span class="example">' . esc_html( date_i18n( get_option( 'date_format' ) ) ) . '</span>' .
1288 "<span class='spinner'></span>\n" . '</em>';
1289 ?>
1290 </div>
1291 </div>
1292
1293 <div class="ui grid field settings-field-indicator-wrapper" default-indi-value="g:i a">
1294 <label class="six wide column middle aligned">
1295 <?php
1296 MainWP_Settings_Indicator::render_not_default_indicator( 'time_format', get_option( 'time_format' ) );
1297 esc_html_e( 'Time format', 'mainwp' );
1298 ?>
1299 </label>
1300 <div class="ten wide column fieldset-wrapper" data-tooltip="<?php esc_attr_e( 'Choose the display format for time.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1301 <?php
1302 /**
1303 * Filters the default time formats.
1304 *
1305 * @since 2.7.0
1306 *
1307 * @param string[] $default_time_formats Array of default time formats.
1308 */
1309 $time_formats = array_unique( apply_filters( 'time_formats', array( esc_html__( 'g:i a', 'mainwp' ), 'g:i A', 'H:i' ) ) );
1310
1311 $custom = true;
1312
1313 foreach ( $time_formats as $format ) {
1314 echo "\t<label><input type='radio' name='time_format' value='" . esc_attr( $format ) . "'";
1315 if ( get_option( 'time_format' ) === $format ) { // checked() uses "==" rather than "===".
1316 echo " checked='checked'";
1317 $custom = false;
1318 }
1319 echo ' /> <span class="date-time-text format-i18n">' . esc_html( date_i18n( $format ) ) . '</span><code>' . esc_html( $format ) . "</code></label><br />\n";
1320 }
1321 echo '<label><input type="radio" name="time_format" id="time_format_custom_radio" value="\c\u\s\t\o\m"';
1322 checked( $custom );
1323 echo '/> <span class="date-time-text date-time-custom-text">' . esc_html__( 'Custom:', 'mainwp' ) . '<span class="screen-reader-text"> ' . esc_html__( 'enter a custom time format in the following field', 'mainwp' ) . '</span></span></label>' .
1324 '<label for="time_format_custom" class="screen-reader-text">' . esc_html__( 'Custom time format:', 'mainwp' ) . '</label>' .
1325 '<input type="text" class="small-text settings-field-value-change-handler" name="time_format_custom" id="time_format_custom" value="' . esc_attr( get_option( 'time_format' ) ) . '" />' .
1326 '<br />' .
1327 '<em><strong>' . esc_html__( 'Preview:', 'mainwp' ) . '</strong> <span class="example">' . esc_html( date_i18n( get_option( 'time_format' ) ) ) . '</span>' .
1328 "<span class='spinner'></span>\n" . '</em>';
1329 ?>
1330 </div>
1331 </div>
1332 <script type="text/javascript">
1333 jQuery(function($) {
1334 $( 'input[name="date_format"]' ).on( 'click', function() {
1335 if ( 'date_format_custom_radio' !== $( this ).attr( 'id' ) ){
1336 $( 'input[name="date_format_custom"]' ).val( $( this ).val() ).closest( '.fieldset-wrapper' ).find( '.example' ).text( $( this ).parent( 'label' ).children( '.format-i18n' ).text() );
1337 $( 'input[name="date_format_custom"]' ).trigger("change"); // support indicator.
1338 }
1339 } );
1340
1341 $( 'input[name="date_format_custom"]' ).on( 'click input', function() {
1342 $( '#date_format_custom_radio' ).prop( 'checked', true );
1343 } );
1344
1345 $( 'input[name="time_format"]' ).on( 'click', function() {
1346 if ( 'time_format_custom_radio' !== $(this).attr( 'id' ) ){
1347 $( 'input[name="time_format_custom"]' ).val( $( this ).val() ).closest( '.fieldset-wrapper' ).find( '.example' ).text( $( this ).parent( 'label' ).children( '.format-i18n' ).text() );
1348 $( 'input[name="time_format_custom"]' ).trigger("change"); // support indicator.
1349 }
1350 } );
1351
1352 $( 'input[name="time_format_custom"]' ).on( 'click input', function() {
1353 $( '#time_format_custom_radio' ).prop( 'checked', true );
1354 } );
1355
1356 $( 'input[name="date_format_custom"], input[name="time_format_custom"]' ).on( 'input', function() {
1357 let format = $( this ),
1358 fieldset = format.closest( '.fieldset-wrapper' ),
1359 example = fieldset.find( '.example' ),
1360 spinner = fieldset.find( '.spinner' );
1361
1362 // Debounce the event callback while users are typing.
1363 clearTimeout( $.data( this, 'timer' ) );
1364 $( this ).data( 'timer', setTimeout( function() {
1365 // If custom date is not empty.
1366 if ( format.val() ) {
1367 spinner.addClass( 'is-active' );
1368
1369 $.post( ajaxurl, {
1370 action: 'date_format_custom' === format.attr( 'name' ) ? 'date_format' : 'time_format',
1371 date : format.val()
1372 }, function( d ) { spinner.removeClass( 'is-active' ); example.text( d ); } );
1373 }
1374 }, 500 ) );
1375 } );
1376 });
1377 </script>
1378 <?php
1379 }
1380
1381 /**
1382 * Method get_websites_automatic_update_time()
1383 *
1384 * Get websites automatic update time.
1385 *
1386 * @return mixed array
1387 *
1388 * @uses \MainWP\Dashboard\MainWP_Utility::format_timestamp()
1389 */
1390 public static function get_websites_automatic_update_time() {
1391 $lastAutomaticUpdate = MainWP_Auto_Updates_DB::instance()->get_websites_last_automatic_sync();
1392 $lasttimeAutomatic = get_option( 'mainwp_updatescheck_last_timestamp' );
1393 $lasttimeStartAutomatic = get_option( 'mainwp_updatescheck_start_last_timestamp' );
1394 $local_timestamp = MainWP_Utility::get_timestamp();
1395
1396 if ( empty( $lasttimeStartAutomatic ) && ! empty( $lasttimeAutomatic ) ) {
1397 $lasttimeStartAutomatic = $lasttimeAutomatic;
1398 }
1399
1400 if ( empty( $lastAutomaticUpdate ) ) {
1401 $nextAutomaticUpdate = esc_html__( 'Any minute', 'mainwp' );
1402 } elseif ( 0 < MainWP_Auto_Updates_DB::instance()->get_websites_check_updates_count( $lasttimeStartAutomatic ) ) {
1403 $nextAutomaticUpdate = esc_html__( 'Processing your websites.', 'mainwp' );
1404 } else {
1405 $next_time = MainWP_System_Cron_Jobs::get_next_time_automatic_update_to_show();
1406 if ( $next_time < $local_timestamp + 5 * MINUTE_IN_SECONDS ) {
1407 $nextAutomaticUpdate = esc_html__( 'Any minute', 'mainwp' );
1408 } else {
1409 $nextAutomaticUpdate = MainWP_Utility::format_timestamp( $next_time );
1410 }
1411 }
1412
1413 if ( empty( $lastAutomaticUpdate ) ) {
1414 $lastAutomaticUpdate = esc_html__( 'Never', 'mainwp' );
1415 } else {
1416 $lastAutomaticUpdate = MainWP_Utility::format_timestamp( $lastAutomaticUpdate );
1417 }
1418
1419 return array(
1420 'last' => $lastAutomaticUpdate,
1421 'next' => $nextAutomaticUpdate,
1422 );
1423 }
1424
1425 /**
1426 * Returns false or the location of the OpenSSL Lib File.
1427 *
1428 * @return mixed false|opensslLibLocation
1429 *
1430 * @uses \MainWP\Dashboard\MainWP_Server_Information_Handler::is_openssl_config_warning()
1431 */
1432 public static function show_openssl_lib_config() {
1433 return MainWP_Server_Information_Handler::is_openssl_config_warning() ? true : false;
1434 }
1435
1436 /**
1437 * Render Advanced Options Subpage.
1438 *
1439 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
1440 */
1441 public static function render_advanced() { //phpcs:ignore -- NOSONAR - complex method.
1442 if ( ! \mainwp_current_user_can( 'dashboard', 'manage_dashboard_settings' ) ) {
1443 \mainwp_do_not_have_permissions( esc_html__( 'manage dashboard settings', 'mainwp' ) );
1444 return;
1445 }
1446
1447 if ( isset( $_POST['submit'] ) && isset( $_POST['wp_nonce'] ) && wp_verify_nonce( sanitize_key( $_POST['wp_nonce'] ), 'SettingsAdvanced' ) ) {
1448
1449 $old_settings = static::get_all_settings_values();
1450
1451 /**
1452 * Action: mainwp_before_save_advanced_settings
1453 *
1454 * Fires before save advanced settings.
1455 *
1456 * @since 4.1
1457 */
1458 do_action( 'mainwp_before_save_advanced_settings', $_POST );
1459
1460 MainWP_Utility::update_option( 'mainwp_maximumRequests', ! empty( $_POST['mainwp_maximumRequests'] ) ? intval( $_POST['mainwp_maximumRequests'] ) : 4 );
1461 MainWP_Utility::update_option( 'mainwp_minimumDelay', ! empty( $_POST['mainwp_minimumDelay'] ) ? intval( $_POST['mainwp_minimumDelay'] ) : 200 );
1462 MainWP_Utility::update_option( 'mainwp_maximumIPRequests', ! empty( $_POST['mainwp_maximumIPRequests'] ) ? intval( $_POST['mainwp_maximumIPRequests'] ) : 1 );
1463 MainWP_Utility::update_option( 'mainwp_minimumIPDelay', ! empty( $_POST['mainwp_minimumIPDelay'] ) ? intval( $_POST['mainwp_minimumIPDelay'] ) : 1000 );
1464 MainWP_Utility::update_option( 'mainwp_maximumSyncRequests', ! empty( $_POST['mainwp_maximumSyncRequests'] ) ? intval( $_POST['mainwp_maximumSyncRequests'] ) : 8 );
1465 MainWP_Utility::update_option( 'mainwp_maximumInstallUpdateRequests', ! empty( $_POST['mainwp_maximumInstallUpdateRequests'] ) ? intval( $_POST['mainwp_maximumInstallUpdateRequests'] ) : 3 );
1466 MainWP_Utility::update_option( 'mainwp_sslVerifyCertificate', isset( $_POST['mainwp_sslVerifyCertificate'] ) ? 1 : 0 );
1467 MainWP_Utility::update_option( 'mainwp_connect_signature_algo', isset( $_POST['mainwp_settings_openssl_alg'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_settings_openssl_alg'] ) ) : 0 );
1468 MainWP_Utility::update_option( 'mainwp_verify_connection_method', isset( $_POST['mainwp_settings_verify_connection_method'] ) ? intval( $_POST['mainwp_settings_verify_connection_method'] ) : 0 );
1469 MainWP_Utility::update_option( 'mainwp_forceUseIPv4', isset( $_POST['mainwp_forceUseIPv4'] ) ? 1 : 0 );
1470 $use_wpcron = ! isset( $_POST['mainwp_options_wp_cron'] ) ? 0 : 1;
1471 MainWP_Utility::update_option( 'mainwp_wp_cron', $use_wpcron );
1472 MainWP_Utility::update_option( 'mainwp_warm_cache_pages_ttl', intval( $_POST['mainwp_warm_cache_pages_ttl'] ) );
1473
1474 MainWP_Utility::update_option( 'mainwp_optimize', ( ! isset( $_POST['mainwp_optimize'] ) ? 0 : 1 ) );
1475 MainWP_Utility::update_option( 'mainwp_maximum_uptime_monitoring_requests', ! empty( $_POST['mainwp_maximumUptimeMonitoringRequests'] ) ? intval( $_POST['mainwp_maximumUptimeMonitoringRequests'] ) : 10 );
1476 MainWP_Utility::update_option( 'mainwp_chunksitesnumber', isset( $_POST['mainwp_chunksitesnumber'] ) ? intval( $_POST['mainwp_chunksitesnumber'] ) : 10 );
1477 MainWP_Utility::update_option( 'mainwp_chunksleepinterval', isset( $_POST['mainwp_chunksleepinterval'] ) ? intval( $_POST['mainwp_chunksleepinterval'] ) : 5 );
1478
1479 $sync_data = array();
1480
1481 if ( isset( $_POST['mainwp_settings_sync_data'] ) && is_array( $_POST['mainwp_settings_sync_data'] ) ) {
1482 $selected_data = array_map( 'sanitize_text_field', wp_unslash( $_POST['mainwp_settings_sync_data'] ) );
1483 foreach ( $selected_data as $name ) {
1484 $sync_data[ $name ] = 1;
1485 }
1486 }
1487
1488 if ( isset( $_POST['mainwp_settings_sync_name'] ) && is_array( $_POST['mainwp_settings_sync_name'] ) ) {
1489 $name_data = array_map( 'sanitize_text_field', wp_unslash( $_POST['mainwp_settings_sync_name'] ) );
1490 foreach ( $name_data as $name ) {
1491 if ( ! isset( $sync_data[ $name ] ) ) {
1492 $sync_data[ $name ] = 0;
1493 }
1494 }
1495 }
1496
1497 MainWP_Utility::update_option( 'mainwp_settings_sync_data', wp_json_encode( $sync_data ) );
1498
1499 // required check.
1500 MainWP_Uptime_Monitoring_Schedule::instance()->check_to_disable_schedule_individual_uptime_monitoring(); // required a check to sync the settings.
1501
1502 if ( isset( $_POST['mainwp_openssl_lib_location'] ) ) {
1503 $openssl_loc = ! empty( $_POST['mainwp_openssl_lib_location'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_openssl_lib_location'] ) ) : '';
1504 MainWP_Utility::update_option( 'mainwp_opensslLibLocation', $openssl_loc );
1505 }
1506 /**
1507 * Action: mainwp_after_save_advanced_settings
1508 *
1509 * Fires after advanced settings save.
1510 *
1511 * @since 4.1
1512 */
1513 do_action( 'mainwp_after_save_advanced_settings', $_POST );
1514
1515 $new_settings = self::get_all_settings_values();
1516
1517 /**
1518 * Action: mainwp_after_save_settings
1519 *
1520 * Fires after save settings.
1521 *
1522 * @since 6.0
1523 *
1524 * @param array $new_settings The new settings.
1525 * @param array $old_settings The old settings.
1526 */
1527 do_action( 'mainwp_after_save_settings', $new_settings, $old_settings );
1528
1529 }
1530 static::render_header( 'Advanced' );
1531 ?>
1532
1533 <div id="mainwp-advanced-settings" class="ui padded segment">
1534 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-advanced-settings-info-notice' ) ) : ?>
1535 <div class="ui info message">
1536 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-advanced-settings-info-notice"></i>
1537 <?php echo esc_html__( 'Set how many requests are performed at once and delay between requests in order to optimize your MainWP Dashboard performance. Both Cross IP and IP Settings handle the majority of work connecting to your Child sites, while the sync, update, and installation request have specialized options under the Frontend Requests Settings section.', 'mainwp' ); ?>
1538 </div>
1539 <?php endif; ?>
1540 <?php if ( isset( $_POST['submit'] ) && isset( $_POST['wp_nonce'] ) && wp_verify_nonce( sanitize_key( $_POST['wp_nonce'] ), 'SettingsAdvanced' ) ) : ?>
1541 <div class="ui green message"><i class="close icon"></i><?php esc_html_e( 'Settings have been saved successfully!', 'mainwp' ); ?></div>
1542 <?php endif; ?>
1543 <div class="ui form">
1544 <form method="POST" action="">
1545 <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
1546 <input type="hidden" name="wp_nonce" value="<?php echo esc_attr( wp_create_nonce( 'SettingsAdvanced' ) ); ?>" />
1547 <?php
1548
1549 /**
1550 * Action: mainwp_advanced_settings_form_top
1551 *
1552 * Fires at the top of advanced settings form.
1553 *
1554 * @since 4.1
1555 */
1556 do_action( 'mainwp_advanced_settings_form_top' );
1557
1558 if ( static::show_openssl_lib_config() ) {
1559 $openssl_loc = MainWP_System_Utility::get_openssl_conf();
1560 ?>
1561 <h3 class="ui dividing header">
1562 <?php esc_html_e( 'OpenSSL Settings', 'mainwp' ); ?>
1563 <div class="sub header"><?php esc_html_e( 'Due to bug with PHP on some servers it is required to set the OpenSSL Library location so MainWP Dashboard can connect to your child sites.', 'mainwp' ); ?></div>
1564 </h3>
1565 <div class="ui grid field">
1566 <label class="six wide column middle aligned"><?php esc_html_e( 'OpenSSL.cnf location', 'mainwp' ); ?></label>
1567 <div class="ten wide column ui field">
1568 <input type="text" name="mainwp_openssl_lib_location" value="<?php echo esc_html( $openssl_loc ); ?>">
1569 <em><?php esc_html_e( 'If your openssl.cnf file is saved to a different path from what is entered please enter your exact path.', 'mainwp' ); ?>
1570 <?php
1571 // translators: 1: Opening anchor tag. 2: Closing anchor tag.
1572 printf( esc_html__( 'If you are not sure how to find the openssl.cnf location, please %1$scheck this help document%2$s.', 'mainwp' ), '<a href="https://docs.mainwp.com/troubleshooting/potential-issues#openssl-library-error-invalid-request" target="_blank">', '</a> <i class="external alternate icon"></i>' );
1573 ?>
1574 </em>
1575 <em><?php esc_html_e( 'If you have confirmed the placement of your openssl.cnf and are still receiving an error banner, click the "Error Fixed" button to dismiss it.', 'mainwp' ); ?></em>
1576 </div>
1577 </div>
1578 <?php } ?>
1579
1580 <h3 class="ui dividing header">
1581 <?php MainWP_Settings_Indicator::render_indicator( 'header', 'settings-field-indicator-cross-ip' ); ?>
1582 <?php esc_html_e( 'Rate Limiting & Concurrency Controls', 'mainwp' ); ?>
1583 <div class="sub header"><?php esc_html_e( 'Fine-tune how your system handles outgoing requests by managing both global and per-server concurrency limits.', 'mainwp' ); ?></div>
1584 </h3>
1585
1586 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-cross-ip" default-indi-value="4">
1587 <label class="six wide column middle aligned">
1588 <?php
1589 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_maximumRequests', (int) get_option( 'mainwp_maximumRequests', 4 ) );
1590 esc_html_e( 'Global request limit (Default: 4)', 'mainwp' );
1591 ?>
1592 </label>
1593 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Defines the overall maximum number of simultaneous requests that can be active. Adjust this setting to balance system throughput with resource constraints (default is 4).', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1594 <div class="ui bottom aligned labeled slider" id="mainwp_maximumRequests_slider"></div>
1595 <div class="ui input">
1596 <input type="hidden" class="settings-field-value-change-handler" name="mainwp_maximumRequests" id="mainwp_maximumRequests" value="<?php echo false === get_option( 'mainwp_maximumRequests' ) ? 4 : esc_attr( get_option( 'mainwp_maximumRequests' ) ); ?>"/>
1597 </div>
1598 </div>
1599 </div>
1600
1601 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-cross-ip" default-indi-value="200">
1602 <label class="six wide column middle aligned">
1603 <?php
1604 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_minimumDelay', (int) get_option( 'mainwp_minimumDelay', 200 ) );
1605 esc_html_e( 'Minimum delay between requests in milliseconds (Default: 200ms)', 'mainwp' );
1606 ?>
1607 </label>
1608 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'This option allows you to control minimum time delay between two requests.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1609 <div class="ui bottom aligned labeled slider" id="mainwp_minimumDelay_slider"></div>
1610 <div class="ui input">
1611 <input type="hidden" class="settings-field-value-change-handler" name="mainwp_minimumDelay" id="mainwp_minimumDelay" value="<?php echo false === get_option( 'mainwp_minimumDelay' ) ? 200 : esc_attr( get_option( 'mainwp_minimumDelay' ) ); ?>"/>
1612 </div>
1613 </div>
1614 </div>
1615
1616 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-per-ip" default-indi-value="1">
1617 <label class="six wide column middle aligned">
1618 <?php
1619 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_maximumIPRequests', (int) get_option( 'mainwp_maximumIPRequests', 1 ) );
1620 esc_html_e( 'Per-IP request limit (Default: 1)', 'mainwp' );
1621 ?>
1622 </label>
1623 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Sets the maximum number of concurrent requests allowed for any individual website\'s IP address. This setting safeguards target servers from excessive load (default is 1).', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1624 <div class="ui bottom aligned labeled slider" id="mainwp_maximumIPRequests_slider"></div>
1625 <div class="ui input">
1626 <input type="hidden" class="settings-field-value-change-handler" name="mainwp_maximumIPRequests" id="mainwp_maximumIPRequests" value="<?php echo false === get_option( 'mainwp_maximumIPRequests' ) ? 1 : esc_attr( get_option( 'mainwp_maximumIPRequests' ) ); ?>"/>
1627 </div>
1628 </div>
1629 </div>
1630
1631 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-per-ip" default-indi-value="1000">
1632 <label class="six wide column middle aligned">
1633 <?php
1634 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_minimumIPDelay', (int) get_option( 'mainwp_minimumIPDelay', 1000 ) );
1635 esc_html_e( 'Minimum delay between requests to the same IP in milliseconds (Default: 1000ms)', 'mainwp' );
1636 ?>
1637 </label>
1638 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'This option allows you to control minimum time delay between two requests.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1639 <div class="ui bottom aligned labeled slider" id="mainwp_minimumIPDelay_slider"></div>
1640 <div class="ui input">
1641 <input type="hidden" class="settings-field-value-change-handler" name="mainwp_minimumIPDelay" id="mainwp_minimumIPDelay" value="<?php echo false === get_option( 'mainwp_minimumIPDelay' ) ? 1000 : esc_attr( get_option( 'mainwp_minimumIPDelay' ) ); ?>"/>
1642 </div>
1643 </div>
1644 </div>
1645
1646 <h3 class="ui dividing header">
1647 <?php MainWP_Settings_Indicator::render_indicator( 'header', 'settings-field-indicator-chunk-site' ); ?>
1648 <?php esc_html_e( 'Batch Processing Settings', 'mainwp' ); ?>
1649 <div class="sub header"><?php esc_html_e( 'Configure how many websites are processed at once and the delay between each batch to optimize system performance and prevent server overload.', 'mainwp' ); ?></div>
1650 </h3>
1651
1652 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-cross-ip" default-indi-value="10">
1653 <label class="six wide column middle aligned">
1654 <?php
1655 MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', 10 === (int) get_option( 'mainwp_chunksitesnumber', 10 ) ? '' : 1 );
1656 esc_html_e( 'Maximum sites per batch (Default: 10)', 'mainwp' );
1657 ?>
1658 </label>
1659 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'The maximum number of websites processed concurrently. If too many requests are sent out, they will begin to time out.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1660 <div class="ui bottom aligned labeled slider" id="mainwp_chunksitesnumber_slider"></div>
1661 <div class="ui input">
1662 <input type="hidden" class="settings-field-value-change-handler" name="mainwp_chunksitesnumber" id="mainwp_chunksitesnumber" value="<?php echo false === get_option( 'mainwp_chunksitesnumber' ) ? 10 : (int) get_option( 'mainwp_chunksitesnumber' ); ?>"/>
1663 </div>
1664 </div>
1665 </div>
1666
1667 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-cross-ip" default-indi-value="5">
1668 <label class="six wide column middle aligned">
1669 <?php
1670 MainWP_Settings_Indicator::render_not_default_indicator( 'none_preset_value', 5 === (int) get_option( 'mainwp_chunksleepinterval', 5 ) ? '' : 1 );
1671 esc_html_e( 'Delay between batches (Default: 5ms)', 'mainwp' );
1672 ?>
1673 </label>
1674 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'The pause duration between processing each batch of websites.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1675 <div class="ui bottom aligned labeled slider" id="mainwp_chunksleepinterval_slider"></div>
1676 <div class="ui input">
1677 <input type="hidden" class="settings-field-value-change-handler" name="mainwp_chunksleepinterval" id="mainwp_chunksleepinterval" value="<?php echo false === get_option( 'mainwp_chunksleepinterval' ) ? 5 : (int) get_option( 'mainwp_chunksleepinterval' ); ?>"/>
1678 </div>
1679 </div>
1680 </div>
1681
1682 <h3 class="ui dividing header">
1683 <?php MainWP_Settings_Indicator::render_indicator( 'header', 'settings-field-indicator-frontend-request' ); ?>
1684 <?php esc_html_e( 'Frontend Request Settings', 'mainwp' ); ?>
1685 <div class="sub header"><?php esc_html_e( 'Configure limits for concurrent background tasks such as synchronization, installation/updating, and uptime monitoring, ensuring efficient resource use and system stability.', 'mainwp' ); ?></div>
1686 </h3>
1687
1688 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-frontend-request" default-indi-value="8">
1689 <label class="six wide column middle aligned">
1690 <?php
1691 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_maximumSyncRequests', (int) get_option( 'mainwp_maximumSyncRequests', 8 ) );
1692 esc_html_e( 'Maximum simultaneous sync requests (Default: 8)', 'mainwp' );
1693 ?>
1694 </label>
1695 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'This option allows you to control how many sites your MainWP Dashboard should sync at once.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1696 <div class="ui bottom aligned labeled slider" id="mainwp_maximumSyncRequests_slider"></div>
1697 <div class="ui input">
1698 <input type="hidden" class="settings-field-value-change-handler" name="mainwp_maximumSyncRequests" id="mainwp_maximumSyncRequests" value="<?php echo false === get_option( 'mainwp_maximumSyncRequests' ) ? 8 : esc_attr( get_option( 'mainwp_maximumSyncRequests' ) ); ?>"/>
1699 </div>
1700 </div>
1701 </div>
1702
1703 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-frontend-request" default-indi-value="3">
1704 <label class="six wide column middle aligned">
1705 <?php
1706 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_maximumInstallUpdateRequests', (int) get_option( 'mainwp_maximumInstallUpdateRequests', 3 ) );
1707 esc_html_e( 'Maximum simultaneous install and update requests (Default: 3)', 'mainwp' );
1708 ?>
1709 </label>
1710 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'This option allows you to control how many update and install requests your MainWP Dashboard should process at once.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1711 <div class="ui bottom aligned labeled slider" id="mainwp_maximumInstallUpdateRequests_slider"></div>
1712 <div class="ui input">
1713 <input type="hidden" class="settings-field-value-change-handler" name="mainwp_maximumInstallUpdateRequests" id="mainwp_maximumInstallUpdateRequests" value="<?php echo false === get_option( 'mainwp_maximumInstallUpdateRequests' ) ? 3 : esc_attr( get_option( 'mainwp_maximumInstallUpdateRequests' ) ); ?>"/>
1714 </div>
1715 </div>
1716 </div>
1717
1718 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-frontend-request" default-indi-value="10">
1719 <label class="six wide column middle aligned">
1720 <?php
1721 $maximum_monitoring_requests = (int) get_option( 'mainwp_maximum_uptime_monitoring_requests', 10 );
1722 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_maximum_uptime_monitoring_requests', $maximum_monitoring_requests );
1723 esc_html_e( 'Maximum simultaneous uptime monitoring requests (Default: 10)', 'mainwp' );
1724 ?>
1725 </label>
1726 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'This option allows you to control how many uptime monitoring requests your MainWP Dashboard should process at once.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1727 <div class="ui bottom aligned labeled slider settings-field-value-change-handler" id="mainwp_maximumUptimeMonitoringRequests_slider"></div>
1728 <div class="ui input">
1729 <input type="hidden" class="settings-field-value-change-handler" name="mainwp_maximumUptimeMonitoringRequests" id="mainwp_maximumUptimeMonitoringRequests" value="<?php echo false === get_option( 'mainwp_maximum_uptime_monitoring_requests' ) ? 10 : esc_attr( get_option( 'mainwp_maximum_uptime_monitoring_requests' ) ); ?>"/>
1730 </div>
1731 </div>
1732 </div>
1733
1734 <h3 class="ui dividing header">
1735 <?php MainWP_Settings_Indicator::render_indicator( 'header', 'settings-field-indicator-miscellaneous' ); ?>
1736 <?php esc_html_e( 'Miscellaneous Settings', 'mainwp' ); ?></h3>
1737 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-miscellaneous" default-indi-value="1">
1738 <label class="six wide column middle aligned">
1739 <?php
1740 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_optimize', (int) get_option( 'mainwp_optimize', 1 ) );
1741 esc_html_e( 'Optimize data loading', 'mainwp' );
1742 ?>
1743 </label>
1744 <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="bottom left">
1745 <input type="checkbox" class="settings-field-value-change-handler" name="mainwp_optimize" id="mainwp_optimize" <?php echo 1 === (int) get_option( 'mainwp_optimize', 1 ) ? 'checked="true"' : ''; ?> /><label><?php esc_html_e( 'Default: Enabled', 'mainwp' ); ?></label>
1746 </div>
1747 </div>
1748 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-miscellaneous" default-indi-value="10">
1749 <label class="six wide column middle aligned">
1750 <?php
1751 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_warm_cache_pages_ttl', (int) get_option( 'mainwp_warm_cache_pages_ttl', 10 ) );
1752 esc_html_e( 'Browser cache expiration time', 'mainwp' );
1753 $browser_cache_ttl = (int) get_option( 'mainwp_warm_cache_pages_ttl', 10 );
1754 ?>
1755 </label>
1756 <div class="five wide column" data-tooltip="<?php esc_attr_e( 'Set how many minutes the browser cache should retain page content before it expires', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1757 <input type="number" class="settings-field-value-change-handler small-text" name="mainwp_warm_cache_pages_ttl" id="mainwp_warm_cache_pages_ttl" placeholder="" min="1" max="24" step="1" value="<?php echo intval( $browser_cache_ttl ); ?>">
1758 </div>
1759 </div>
1760 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-miscellaneous" default-indi-value="1">
1761 <label class="six wide column middle aligned">
1762 <?php
1763 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_wp_cron', (int) get_option( 'mainwp_wp_cron', 1 ) );
1764 esc_html_e( 'Use WP Cron', 'mainwp' );
1765 ?>
1766 </label>
1767 <div class="ten wide column ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'Disabling this option will disable the WP Cron so all scheduled events will stop working.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1768 <input type="checkbox" class="settings-field-value-change-handler" name="mainwp_options_wp_cron" id="mainwp_options_wp_cron" <?php echo 1 === (int) get_option( 'mainwp_wp_cron' ) || ( false === get_option( 'mainwp_wp_cron' ) ) ? 'checked="true"' : ''; ?>/><label><?php esc_html_e( 'Default: Enabled', 'mainwp' ); ?></label>
1769 </div>
1770 </div>
1771 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-miscellaneous" default-indi-value="1" >
1772 <label class="six wide column middle aligned">
1773 <?php
1774 $indi_val = (int) get_option( 'mainwp_sslVerifyCertificate', 1 );
1775 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_sslVerifyCertificate', $indi_val );
1776 esc_html_e( 'Verify SSL certificate', 'mainwp' );
1777 ?>
1778 </label>
1779 <div class="ten wide column ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'If enabled, your MainWP Dashboard will verify the SSL Certificate on your Child Site (if exists) while connecting the Child Site.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1780 <input type="checkbox" class="settings-field-value-change-handler" name="mainwp_sslVerifyCertificate" id="mainwp_sslVerifyCertificate" value="checked" <?php echo false === get_option( 'mainwp_sslVerifyCertificate' ) || 1 === (int) get_option( 'mainwp_sslVerifyCertificate' ) ? 'checked="checked"' : ''; ?>/><label><?php esc_html_e( 'Default: Enabled', 'mainwp' ); ?></label>
1781 </div>
1782 </div>
1783 <?php
1784 $general_verify_con = (int) get_option( 'mainwp_verify_connection_method', 1 );
1785 ?>
1786 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-miscellaneous" default-indi-value="1">
1787 <label class="six wide column middle aligned">
1788 <?php
1789 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_verify_connection_method', (int) $general_verify_con );
1790 esc_html_e( 'Verify connection method', 'mainwp' );
1791 ?>
1792 </label>
1793 <div class="ui six wide column" data-tooltip="<?php esc_attr_e( 'Select Verify connection method. If you are not sure, select "Default".', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1794 <select class="ui dropdown settings-field-value-change-handler" id="mainwp_settings_verify_connection_method" name="mainwp_settings_verify_connection_method">
1795 <option <?php echo ( empty( $general_verify_con ) || 1 === $general_verify_con ) ? 'selected' : ''; ?> value="1"><?php esc_html_e( 'OpenSSL (default)', 'mainwp' ); ?></option>
1796 <option <?php echo ( 2 === $general_verify_con ) ? 'selected' : ''; ?> value="2"><?php esc_html_e( 'PHPSECLIB (fallback)', 'mainwp' ); ?></option>
1797 </select>
1798 </div>
1799 </div>
1800 <?php
1801 $sign_note = MainWP_Connect_Lib::get_connection_algo_settings_note();
1802 $sign_algs = MainWP_System_Utility::get_open_ssl_sign_algos();
1803 $general_sign_alg = get_option( 'mainwp_connect_signature_algo', false );
1804 if ( false === $general_sign_alg ) {
1805 $general_sign_alg = defined( 'OPENSSL_ALGO_SHA256' ) ? OPENSSL_ALGO_SHA256 : 1;
1806 MainWP_Utility::update_option( 'mainwp_connect_signature_algo', $general_sign_alg );
1807 } else {
1808 $general_sign_alg = intval( $general_sign_alg );
1809 }
1810 $algo_def = defined( 'OPENSSL_ALGO_SHA256' ) ? (int) OPENSSL_ALGO_SHA256 : 1;
1811 ?>
1812 <div default-indi-value="<?php echo esc_attr( $algo_def ); ?>" class="ui grid field mainwp-hide-elemenent-sign-algo settings-field-indicator-wrapper settings-field-indicator-miscellaneous" <?php echo ( 2 === $general_verify_con ) ? 'style="display:none;"' : ''; ?> >
1813 <label class="six wide column middle aligned">
1814 <?php
1815 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_connect_signature_algo', (int) $general_sign_alg );
1816 esc_html_e( 'OpenSSL signature algorithm', 'mainwp' );
1817 ?>
1818 </label>
1819 <div class="ui six wide column" data-tooltip="<?php esc_attr_e( 'Select OpenSSL signature algorithm. If you are not sure, select "Default".', 'mainwp' ); ?>" data-inverted="" data-position="top left">
1820 <select class="ui dropdown settings-field-value-change-handler" id="mainwp_settings_openssl_alg" name="mainwp_settings_openssl_alg">
1821 <?php
1822 foreach ( $sign_algs as $val => $text ) {
1823 ?>
1824 <option <?php echo ( $val === $general_sign_alg ) ? 'selected' : ''; ?> value="<?php echo esc_attr( $val ); ?>"><?php echo esc_html( $text ); ?></option>
1825 <?php
1826 }
1827 ?>
1828 </select>
1829 <div class="ui yellow message mainwp-hide-elemenent-sign-algo-note" <?php echo ( 1 === $general_sign_alg ) ? '' : 'style="display:none;"'; ?>><?php echo esc_html( $sign_note ); ?></div>
1830 </div>
1831 </div>
1832 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-miscellaneous">
1833 <label class="six wide column middle aligned">
1834 <?php
1835 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_forceUseIPv4', (int) get_option( 'mainwp_forceUseIPv4' ) );
1836 esc_html_e( 'Force IPv4', 'mainwp' );
1837 ?>
1838 </label>
1839 <div class="ten wide column ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'Enable if you want to force your MainWP Dashboard to use IPv4 while trying to connect child sites.', 'mainwp' ); ?>" data-inverted="" data-position="bottom left">
1840 <input type="checkbox" class="settings-field-value-change-handler" name="mainwp_forceUseIPv4" id="mainwp_forceUseIPv4" value="checked" <?php echo ( 1 === (int) get_option( 'mainwp_forceUseIPv4' ) ) ? 'checked="checked"' : ''; ?>/><label><?php esc_html_e( 'Default: Disabled', 'mainwp' ); ?></label>
1841 </div>
1842 </div>
1843 <?php
1844 static::render_sync_data_selection();
1845 /**
1846 * Action: mainwp_advanced_settings_form_bottom
1847 *
1848 * Fires at the bottom of advanced settings form.
1849 *
1850 * @since 4.1
1851 */
1852 do_action( 'mainwp_advanced_settings_form_bottom' );
1853
1854 ?>
1855 <div class="ui divider"></div>
1856 <input type="submit" name="submit" id="submit" class="ui green big button" value="<?php esc_attr_e( 'Save Settings', 'mainwp' ); ?>"/>
1857 </form>
1858 </div>
1859 </div>
1860 <?php static::render_disable_installed_plugins_sync_modal(); ?>
1861 <script>
1862 jQuery(document).ready(function() {
1863 const maximumRequests = <?php echo ! empty( get_option( 'mainwp_maximumRequests' ) ) ? esc_js( get_option( 'mainwp_maximumRequests' ) ) : 4; ?>;
1864 jQuery('#mainwp_maximumRequests_slider').slider({
1865 min: 1,
1866 max: 20,
1867 start: maximumRequests,
1868 step: 1,
1869 restrictedLabels: [1,20],
1870 showThumbTooltip: true,
1871 tooltipConfig: {
1872 position: 'top center',
1873 variation: 'small visible black'
1874 },
1875 onChange: function(value) {
1876 jQuery('#mainwp_maximumRequests').val(value);
1877 }
1878 });
1879 const minimumDelay = <?php echo ! empty( get_option( 'mainwp_minimumDelay' ) ) ? esc_js( get_option( 'mainwp_minimumDelay' ) ) : 200; ?>;
1880 jQuery('#mainwp_minimumDelay_slider').slider({
1881 min: 100,
1882 max: 5000,
1883 start: minimumDelay,
1884 step: 100,
1885 restrictedLabels: [100,5000],
1886 showThumbTooltip: true,
1887 tooltipConfig: {
1888 position: 'top center',
1889 variation: 'small visible black'
1890 },
1891 onChange: function(value) {
1892 jQuery('#mainwp_minimumDelay').val(value);
1893 }
1894 });
1895 const maximumIPRequests = <?php echo ! empty( get_option( 'mainwp_maximumIPRequests' ) ) ? esc_js( get_option( 'mainwp_maximumIPRequests' ) ) : 1; ?>;
1896 jQuery('#mainwp_maximumIPRequests_slider').slider({
1897 min: 1,
1898 max: 10,
1899 start: maximumIPRequests,
1900 step: 1,
1901 restrictedLabels: [1,10],
1902 showThumbTooltip: true,
1903 tooltipConfig: {
1904 position: 'top center',
1905 variation: 'small visible black'
1906 },
1907 onChange: function(value) {
1908 jQuery('#mainwp_maximumIPRequests').val(value);
1909 }
1910 });
1911 const minimumIPDelay = <?php echo ! empty( get_option( 'mainwp_minimumIPDelay' ) ) ? esc_js( get_option( 'mainwp_minimumIPDelay' ) ) : 1000; ?>;
1912 jQuery('#mainwp_minimumIPDelay_slider').slider({
1913 min: 500,
1914 max: 5000,
1915 start: minimumIPDelay,
1916 step: 100,
1917 restrictedLabels: [500,5000],
1918 showThumbTooltip: true,
1919 tooltipConfig: {
1920 position: 'top center',
1921 variation: 'small visible black'
1922 },
1923 onChange: function(value) {
1924 jQuery('#mainwp_minimumIPDelay').val(value);
1925 }
1926 });
1927 const maximumSyncRequests = <?php echo ! empty( get_option( 'mainwp_maximumSyncRequests' ) ) ? esc_js( get_option( 'mainwp_maximumSyncRequests' ) ) : 8; ?>;
1928 jQuery('#mainwp_maximumSyncRequests_slider').slider({
1929 min: 1,
1930 max: 20,
1931 start: maximumSyncRequests,
1932 step: 1,
1933 restrictedLabels: [1,20],
1934 showThumbTooltip: true,
1935 tooltipConfig: {
1936 position: 'top center',
1937 variation: 'small visible black'
1938 },
1939 onChange: function(value) {
1940 jQuery('#mainwp_maximumSyncRequests').val(value);
1941 }
1942 });
1943 const maximumInstallUpdateRequests = <?php echo ! empty( get_option( 'mainwp_maximumInstallUpdateRequests' ) ) ? esc_js( get_option( 'mainwp_maximumInstallUpdateRequests' ) ) : 3; ?>;
1944 jQuery('#mainwp_maximumInstallUpdateRequests_slider').slider({
1945 min: 1,
1946 max: 20,
1947 start: maximumInstallUpdateRequests,
1948 step: 1,
1949 restrictedLabels: [1,20],
1950 showThumbTooltip: true,
1951 tooltipConfig: {
1952 position: 'top center',
1953 variation: 'small visible black'
1954 },
1955 onChange: function(value) {
1956 jQuery('#mainwp_maximumInstallUpdateRequests').val(value);
1957 }
1958 });
1959 const maximumUptimeMonitoringRequests = <?php echo ! empty( get_option( 'mainwp_maximum_uptime_monitoring_requests' ) ) ? esc_js( get_option( 'mainwp_maximum_uptime_monitoring_requests' ) ) : 10; ?>;
1960 jQuery('#mainwp_maximumUptimeMonitoringRequests_slider').slider({
1961 min: 1,
1962 max: 100,
1963 start: maximumUptimeMonitoringRequests,
1964 step: 1,
1965 restrictedLabels: [1,100],
1966 showThumbTooltip: true,
1967 tooltipConfig: {
1968 position: 'top center',
1969 variation: 'small visible black'
1970 },
1971 onChange: function(value) {
1972 jQuery('#mainwp_maximumUptimeMonitoringRequests').val(value).change();
1973 }
1974 });
1975 jQuery('#mainwp_maximumUptimeMonitoringRequests_slider').slider('set value', maximumUptimeMonitoringRequests);
1976
1977 jQuery('#mainwp_chunksitesnumber_slider').slider({
1978 min: 1,
1979 max: 30,
1980 start: <?php echo false !== get_option( 'mainwp_chunksitesnumber' ) ? intval( get_option( 'mainwp_chunksitesnumber' ) ) : 10; ?>,
1981 step: 1,
1982 restrictedLabels: [1,30],
1983 showThumbTooltip: true,
1984 tooltipConfig: {
1985 position: 'top center',
1986 variation: 'small visible black'
1987 },
1988 onChange: function(value) {
1989 jQuery('#mainwp_chunksitesnumber').val(value).change();
1990 }
1991 });
1992
1993 jQuery('#mainwp_chunksleepinterval_slider').slider({
1994 min: 0,
1995 max: 20,
1996 start: <?php echo false !== get_option( 'mainwp_chunksleepinterval' ) ? intval( get_option( 'mainwp_chunksleepinterval' ) ) : 5; ?>,
1997 step: 1,
1998 restrictedLabels: [0,20],
1999 showThumbTooltip: true,
2000 tooltipConfig: {
2001 position: 'top center',
2002 variation: 'small visible black'
2003 },
2004 onChange: function(value) {
2005 jQuery('#mainwp_chunksleepinterval').val(value).change();
2006 }
2007 });
2008 });
2009 </script>
2010 <?php
2011 static::render_footer( 'Advanced' );
2012 }
2013
2014 /**
2015 * Method render_sync_data_selection().
2016 *
2017 * @return void
2018 */
2019 public static function render_sync_data_selection() {
2020
2021 $default_sync = static::get_data_sync_default();
2022
2023 $sync_data_settings = get_option( 'mainwp_settings_sync_data' );
2024
2025 $sync_data_settings = ! empty( $sync_data_settings ) ? json_decode( $sync_data_settings, true ) : array();
2026
2027 if ( ! is_array( $sync_data_settings ) ) {
2028 $sync_data_settings = array();
2029 }
2030
2031 $setting_page = true;
2032
2033 ?>
2034 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-miscellaneous">
2035 <label class="six wide column top aligned">
2036 <?php
2037 MainWP_Settings_Indicator::render_indicator( 'header', 'settings-field-indicator-sync-data' );
2038 esc_html_e( 'Select data to sync', 'mainwp' );
2039 ?>
2040 </label>
2041 <div class="ten wide column" <?php echo $setting_page ? 'data-tooltip="' . esc_attr__( 'Select data that you want to sync.', 'mainwp' ) . '"' : ''; ?> data-inverted="" data-position="top left">
2042 <ul class="mainwp_hide_wpmenu_checkboxes">
2043 <?php
2044 foreach ( $default_sync as $name => $title ) {
2045 $_selected = '';
2046 if ( ! isset( $sync_data_settings[ $name ] ) || 1 === (int) $sync_data_settings[ $name ] ) {
2047 $_selected = 'checked';
2048 }
2049 ?>
2050 <li>
2051 <div class="ui checkbox">
2052 <input type="checkbox" class="settings-field-value-change-handler" id="mainwp_select_sync_<?php echo esc_attr( $name ); ?>" name="mainwp_settings_sync_data[]" <?php echo esc_html( $_selected ); ?> value="<?php echo esc_attr( $name ); ?>">
2053 <label for="mainwp_select_sync_<?php echo esc_attr( $name ); ?>" ><?php echo esc_html( $title ); ?></label>
2054 </div>
2055 <input type="hidden" name="mainwp_settings_sync_name[]" value="<?php echo esc_attr( $name ); ?>">
2056 </li>
2057 <?php
2058 }
2059 ?>
2060 </ul>
2061 </div>
2062 </div>
2063 <?php
2064 }
2065
2066 /**
2067 * Render the Installed plugins sync warning modal.
2068 *
2069 * @since 6.1.3
2070 *
2071 * @return void
2072 */
2073 public static function render_disable_installed_plugins_sync_modal() {
2074 ?>
2075 <div class="ui small modal" id="mainwp-disable-installed-plugins-sync-modal">
2076 <div class="header"><?php esc_html_e( 'Disable Installed Plugins Sync?', 'mainwp' ); ?></div>
2077 <div class="content">
2078 <div class="ui yellow message">
2079 <div class="header"><?php esc_html_e( 'MainWP Add-ons may not work as expected', 'mainwp' ); ?></div>
2080 <p><?php esc_html_e( 'Some MainWP Add-ons need the installed plugins data to detect required plugins on your Child Sites. If you disable this option, those Add-ons may not work as expected.', 'mainwp' ); ?></p>
2081 </div>
2082 </div>
2083 <div class="actions">
2084 <div class="ui basic cancel button"><?php esc_html_e( 'Cancel', 'mainwp' ); ?></div>
2085 <div class="ui green approve button"><?php esc_html_e( 'I understand', 'mainwp' ); ?></div>
2086 </div>
2087 </div>
2088 <script type="text/javascript">
2089 jQuery( document ).ready( function () {
2090 const installedPluginsCheckbox = jQuery( '#mainwp_select_sync_plugins' );
2091 const warningModal = jQuery( '#mainwp-disable-installed-plugins-sync-modal' );
2092 let disableConfirmed = false;
2093
2094 installedPluginsCheckbox.on( 'change', function () {
2095 if ( installedPluginsCheckbox.is( ':checked' ) ) {
2096 disableConfirmed = false;
2097 return;
2098 }
2099
2100 if ( disableConfirmed ) {
2101 return;
2102 }
2103
2104 warningModal.modal( {
2105 closable: false,
2106 onApprove: function () {
2107 disableConfirmed = true;
2108 },
2109 onDeny: function () {
2110 installedPluginsCheckbox.prop( 'checked', true ).trigger( 'change' );
2111 }
2112 } ).modal( 'show' );
2113 } );
2114 } );
2115 </script>
2116 <?php
2117 }
2118
2119 /**
2120 * Method get_data_sync_default().
2121 *
2122 * @return array data.
2123 */
2124 public static function get_data_sync_default() {
2125 return array(
2126 'wp_updates' => __( 'WordPress updates information', 'mainwp' ),
2127 'plugin_updates' => __( 'Plugins updates information', 'mainwp' ),
2128 'theme_updates' => __( 'Themes updates information', 'mainwp' ),
2129 'translation_updates' => __( 'Translations updates information', 'mainwp' ),
2130 'recent_comments' => __( 'Recent comments', 'mainwp' ),
2131 'recent_posts' => __( 'Recent posts', 'mainwp' ),
2132 'recent_pages' => __( 'Recent pages', 'mainwp' ),
2133 'securityStats' => __( 'Site hardening information', 'mainwp' ),
2134 'directories' => __( 'Site directory listing (needed for legacy backup feature)', 'mainwp' ),
2135 'categories' => __( 'Posts catetegories', 'mainwp' ),
2136 'totalsize' => __( 'Website size (needed for Clone and legacy backup features)', 'mainwp' ),
2137 'dbsize' => __( 'Database size information', 'mainwp' ),
2138 'plugins' => __( 'Installed plugins', 'mainwp' ),
2139 'themes' => __( 'Installed Themes', 'mainwp' ),
2140 'users' => __( 'Users information', 'mainwp' ),
2141 'plugins_outdate_info' => __( 'Abandoned plugins information', 'mainwp' ),
2142 'themes_outdate_info' => __( 'Abandoned themes information', 'mainwp' ),
2143 'health_site_status' => __( 'Site health information', 'mainwp' ),
2144 'child_site_actions_data' => __( 'Non-MainWP changes data', 'mainwp' ),
2145 'othersData' => __( 'Other data (required by some extensions)', 'mainwp' ),
2146 );
2147 }
2148
2149 /**
2150 * Method get_data_list_to_sync().
2151 *
2152 * @return array Data list to sync.
2153 */
2154 public function get_data_list_to_sync() {
2155 $sync_data_settings = get_option( 'mainwp_settings_sync_data' );
2156
2157 if ( false === $sync_data_settings ) {
2158 $default_sync = static::get_data_sync_default();
2159 $sync_lists = array_fill_keys( array_keys( $default_sync ), 1 );
2160 MainWP_Utility::update_option( 'mainwp_settings_sync_data', wp_json_encode( $sync_lists ) );
2161 return $sync_lists;
2162 }
2163
2164 $sync_lists = ! empty( $sync_data_settings ) ? json_decode( $sync_data_settings, true ) : array();
2165
2166 if ( ! is_array( $sync_lists ) ) {
2167 $sync_lists = array();
2168 }
2169 return $sync_lists;
2170 }
2171
2172
2173 /**
2174 * Render MainWP Tools SubPage.
2175 *
2176 * @uses \MainWP\Dashboard\MainWP_UI::render_screen_options()
2177 */
2178 public static function render_mainwp_tools() { // phpcs:ignore -- NOSONAR - complex.
2179 if ( ! \mainwp_current_user_can( 'dashboard', 'manage_dashboard_settings' ) ) {
2180 \mainwp_do_not_have_permissions( esc_html__( 'manage dashboard settings', 'mainwp' ) );
2181 return;
2182 }
2183 static::render_header( 'MainWPTools' );
2184 ?>
2185 <div id="mainwp-tools-settings" class="ui padded segment">
2186 <div id="mainwp-message-zone" style="display:none;" class="ui message"></div>
2187 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-tools-info-message' ) ) : ?>
2188 <div class="ui info message">
2189 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-tools-info-message"></i>
2190 <?php
2191 // translators: 1: Opening anchor tag. 2: Closing anchor tag.
2192 printf( esc_html__( 'Use MainWP tools to adjust your MainWP Dashboard to your needs and perform specific actions when needed. For additional help, review this %1$shelp document%2$s.', 'mainwp' ), '<a href="https://docs.mainwp.com/sites/management/mainwp-dashboard-settings#mainwp-dashboard-settings" target="_blank">', '</a> <i class="external alternate icon"></i>' );
2193 ?>
2194 </div>
2195 <?php endif; ?>
2196 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-tools-info-custom-theme' ) ) : ?>
2197 <div class="ui info message">
2198 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-tools-info-custom-theme"></i>
2199 <div><?php esc_html_e( 'Here you can select a theme for your MainWP Dashboard.', 'mainwp' ); ?></div>
2200 <div><?php esc_html_e( 'To create a custom theme, copy the `mainwp-dark-theme.css` file from the MainWP Custom Dashboard Extension located in the `css` directory, make your edits and upload the file to the `../wp-content/uploads/mainwp/custom-dashboard/` directory.', 'mainwp' ); ?></div>
2201 </div>
2202 <?php endif; ?>
2203 <?php
2204 $show_saved_message = false;
2205 if ( isset( $_POST['submit'] ) && isset( $_POST['wp_nonce'] ) && wp_verify_nonce( sanitize_key( $_POST['wp_nonce'] ), 'MainWPTools' ) ) {
2206 $show_saved_message = true;
2207 } elseif ( get_transient( 'mainwp_settings_saved' ) ) {
2208 $show_saved_message = true;
2209 delete_transient( 'mainwp_settings_saved' ); // Remove transient after showing message.
2210 }
2211 ?>
2212 <?php if ( $show_saved_message ) : ?>
2213 <div class="ui green message">
2214 <i class="close icon"></i>
2215 <?php esc_html_e( 'Settings have been saved successfully!', 'mainwp' ); ?>
2216 </div>
2217 <?php endif; ?>
2218 <?php if ( isset( $_POST['mainwp_restore_info_messages'] ) && isset( $_POST['wp_nonce'] ) && wp_verify_nonce( sanitize_key( $_POST['wp_nonce'] ), 'MainWPTools' ) ) : ?>
2219 <div class="ui green message"><i class="close icon"></i><?php esc_html_e( 'Info messages have been restored successfully!', 'mainwp' ); ?></div>
2220 <?php endif; ?>
2221 <div class="ui form">
2222 <form method="POST" action="">
2223 <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
2224 <input type="hidden" name="wp_nonce" value="<?php echo esc_attr( wp_create_nonce( 'MainWPTools' ) ); ?>" />
2225
2226 <?php
2227 /**
2228 * Action: mainwp_tools_form_top
2229 *
2230 * Fires at the top of MainWP tools form.
2231 *
2232 * @since 4.1
2233 */
2234 do_action( 'mainwp_tools_form_top' );
2235
2236 $show_qsw = apply_filters( 'mainwp_show_qsw', true );
2237
2238 static::get_instance()->render_select_custom_themes();
2239
2240 ?>
2241 <?php if ( get_option( 'mainwp_not_start_encrypt_keys' ) ) { ?>
2242 <div class="ui grid field">
2243 <label class="six wide column middle aligned"><?php esc_html_e( 'OpenSSL Key Encryption', 'mainwp' ); ?></label>
2244 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'To enhance security, we\'ve added a feature to encrypt your private keys stored in the database.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
2245 <input type="button" name="" id="increase-connection-security-btn" data-inverted="" data-position="top right" data-tooltip="<?php esc_attr_e( 'To enhance security, we\'ve added a feature to encrypt your private keys stored in the database.', 'mainwp' ); ?>" class="ui green basic button" value="<?php esc_attr_e( 'Encrypt Keys Now', 'mainwp' ); ?>" />
2246 </div>
2247 </div>
2248 <?php } ?>
2249 <div class="ui grid field">
2250 <label class="six wide column middle aligned"><?php esc_html_e( 'Force your MainWP Dashboard to establish a new connection', 'mainwp' ); ?></label>
2251 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Force your MainWP Dashboard to reconnect with your child sites. Only needed if suggested by MainWP Support.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
2252 <input type="button" name="" id="force-destroy-sessions-button" data-inverted="" data-position="top right" data-tooltip="<?php esc_attr_e( 'Forces your dashboard to reconnect with your child sites. This feature will log out any currently logged in users on the Child sites and require them to re-log in. Only needed if suggested by MainWP Support.', 'mainwp' ); ?>" class="ui green basic button" value="<?php esc_attr_e( 'Re-establish Connections', 'mainwp' ); ?>" />
2253 </div>
2254 </div>
2255 <div class="ui grid field">
2256 <label class="six wide column middle aligned"><?php esc_html_e( 'Force your MainWP Dashboard to set a new pair of OpenSSL Keys', 'mainwp' ); ?></label>
2257 <div class="ten wide column" id="mainwp-renew-connections-tool" data-content="<?php esc_attr_e( 'This will function renew connection and reconnect site right away.', 'mainwp' ); ?>" data-variation="inverted" data-position="top left">
2258 <a href="javascript:void(0)" onclick="mainwp_tool_renew_connections_show(); return false;" class="ui button green basic"><?php esc_html_e( 'Reset OpenSSL Key Pair', 'mainwp' ); ?></a>
2259 </div>
2260 </div>
2261 <?php if ( $show_qsw ) { ?>
2262 <div class="ui grid field">
2263 <label class="six wide column middle aligned"><?php esc_html_e( 'Start the MainWP Quick Setup Wizard', 'mainwp' ); ?></label>
2264 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Click this button to start the Quick Setup Wizard', 'mainwp' ); ?>" data-inverted="" data-position="top left"><a href="admin.php?page=mainwp-setup" class="ui green button basic" ><?php esc_html_e( 'Start Quick Setup Wizard', 'mainwp' ); ?></a></div>
2265 </div>
2266 <?php } ?>
2267 <div class="ui grid field">
2268 <label class="six wide column middle aligned"><?php esc_html_e( 'Export child sites to CSV file', 'mainwp' ); ?></label>
2269 <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_attr( wp_create_nonce( 'export_sites' ) ); ?>" class="ui button green basic"><?php esc_html_e( 'Export Child Sites', 'mainwp' ); ?></a></div>
2270 </div>
2271 <div class="ui grid field">
2272 <label class="six wide column middle aligned"><?php esc_html_e( 'Import child sites', 'mainwp' ); ?></label>
2273 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Click this button to import websites to your MainWP Dashboard.', 'mainwp' ); ?>" data-inverted="" data-position="top left"><a href="admin.php?page=managesites&do=bulknew" class="ui button green basic"><?php esc_html_e( 'Import Child Sites', 'mainwp' ); ?></a></div>
2274 </div>
2275 <div class="ui grid field">
2276 <label class="six wide column middle aligned"><?php esc_html_e( 'Disconnect all child sites', 'mainwp' ); ?></label>
2277 <div class="ten wide column" id="mainwp-disconnect-sites-tool" data-content="<?php esc_attr_e( 'This will function will break the connection and leave the MainWP Child plugin active and which makes your sites vulnerable. Use only if you attend to reconnect site to the same or a different dashboard right away.', 'mainwp' ); ?>" data-variation="inverted" data-position="top left">
2278 <a href="admin.php?page=MainWPTools&disconnectSites=yes&_wpnonce=<?php echo esc_attr( wp_create_nonce( 'disconnect_sites' ) ); ?>" onclick="mainwp_tool_disconnect_sites(); return false;" class="ui button green basic"><?php esc_html_e( 'Disconnect Sites', 'mainwp' ); ?></a>
2279 </div>
2280 </div>
2281 <div class="ui grid field">
2282 <label class="six wide column middle aligned"><?php esc_html_e( 'Delete add-ons API Activation data', 'mainwp' ); ?></label>
2283 <div class="ten wide column" id="mainwp-clear-activation-data" data-content="<?php esc_attr_e( 'This does not affect extensions settings, it just removes API activation data.', 'mainwp' ); ?>" data-variation="inverted" data-position="top left">
2284 <a href="admin.php?page=MainWPTools&clearActivationData=yes&_wpnonce=<?php echo esc_attr( wp_create_nonce( 'clear_activation_data' ) ); ?>" onclick="mainwp_tool_confirm_to_process(this); return false;" class="ui button green basic"><?php esc_html_e( 'Delete Add-ons API Activation Data', 'mainwp' ); ?></a>
2285 </div>
2286 </div>
2287 <div class="ui grid field">
2288 <label class="six wide column middle aligned"><?php esc_html_e( 'Delete archived Network Activity data', 'mainwp' ); ?></label>
2289 <div class="ten wide column" id="mainwp-clear-archived-sites-changes-data" data-content="<?php esc_attr_e( 'Delete archived sNetwork Activity data.', 'mainwp' ); ?>" data-variation="inverted" data-position="top left">
2290 <a href="admin.php?page=MainWPTools&clearArchivedSitesChangesData=yes&_wpnonce=<?php echo esc_attr( wp_create_nonce( 'clear_archived_sites_changes' ) ); ?>" onclick="mainwp_tool_confirm_to_process(this); return false;" class="ui button green basic"><?php esc_html_e( 'Delete Archived Network Activity Data', 'mainwp' ); ?></a>
2291 </div>
2292 </div>
2293 <div class="ui grid field">
2294 <label class="six wide column middle aligned"><?php esc_html_e( 'Restore all info messages', 'mainwp' ); ?></label>
2295 <div class="ten wide column" data-tooltip="<?php esc_attr_e( 'Click this button to restore all info messages in your MainWP Dashboard and Extensions.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
2296 <input type="submit" name="mainwp_restore_info_messages" id="mainwp_restore_info_messages" class="ui button" value="<?php esc_attr_e( 'Restore Info Messages', 'mainwp' ); ?>"/>
2297 </div>
2298 </div>
2299
2300 <h3 class="ui dividing header">
2301 <?php esc_html_e( 'Privacy & Third-Party Services Permissions', 'mainwp' ); ?>
2302 <div class="sub header"><?php esc_html_e( 'These tools are implemented using JavaScript and are subject to their respective privacy policies. You can choose which services to enable below, and update preferences at any time.', 'mainwp' ); ?></div>
2303 </h3>
2304
2305 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-tools">
2306 <label class="six wide column middle aligned">
2307 <?php
2308 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_enable_guided_tours', (int) get_option( 'mainwp_enable_guided_tours', 0 ) );
2309 esc_html_e( 'Usetiful (Interactive Guides & Tips)', 'mainwp' );
2310 ?>
2311 <span class="ui blue mini label"><?php esc_html_e( 'BETA', 'mainwp' ); ?></span>
2312 </label>
2313 <div class="ten wide column " data-tooltip="<?php esc_attr_e( 'Check this option to enable, or uncheck to disable MainWP guided tours.', 'mainwp' ); ?>" data-inverted="" data-position="bottom left">
2314 <div class="ui toggle checkbox">
2315 <input type="checkbox" class="settings-field-value-change-handler" name="mainwp-guided-tours-option" id="mainwp-guided-tours-option" <?php echo 1 === (int) get_option( 'mainwp_enable_guided_tours', 0 ) ? 'checked="true"' : ''; ?> />
2316 <label><?php esc_html_e( 'Enable guided tours, tooltips, and onboarding assistance to help you navigate MainWP more efficiently.', 'mainwp' ); ?></label>
2317 </div>
2318 </div>
2319 </div>
2320
2321 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-tools">
2322 <label class="six wide column middle aligned">
2323 <?php
2324 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_enable_guided_chatbase', (int) get_option( 'mainwp_enable_guided_chatbase', 0 ) );
2325 esc_html_e( 'Chatbase (AI-Powered Chat Support)', 'mainwp' );
2326 ?>
2327 <span class="ui blue mini label"><?php esc_html_e( 'BETA', 'mainwp' ); ?></span>
2328 </label>
2329 <div class="ten wide column " data-tooltip="<?php esc_attr_e( 'Check this option to enable, or uncheck to disable MainWP AI drive support.', 'mainwp' ); ?>" data-inverted="" data-position="bottom left">
2330 <div class="ui toggle checkbox">
2331 <input type="checkbox" class="settings-field-value-change-handler" name="mainwp-guided-chatbase-option" id="mainwp-guided-chatbase-option" <?php echo 1 === (int) get_option( 'mainwp_enable_guided_chatbase', 0 ) ? 'checked="true"' : ''; ?> />
2332 <label><?php esc_html_e( 'Get AI-driven support within the MainWP Dashboard for quick answers to common questions.', 'mainwp' ); ?></label>
2333 </div>
2334 </div>
2335 </div>
2336
2337 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-tools">
2338 <label class="six wide column middle aligned">
2339 <?php
2340 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_enable_guided_video', (int) get_option( 'mainwp_enable_guided_video', 0 ) );
2341 esc_html_e( 'Youtube Embeds (Video Tutorials)', 'mainwp' );
2342 ?>
2343 </label>
2344 <div class="ten wide column " data-tooltip="<?php esc_attr_e( 'Check this option to enable, or uncheck to disable MainWP video tutorials.', 'mainwp' ); ?>" data-inverted="" data-position="bottom left">
2345 <div class="ui toggle checkbox">
2346 <input type="checkbox" class="settings-field-value-change-handler" name="mainwp-guided-video-option" id="mainwp-guided-video-option" <?php echo 1 === (int) get_option( 'mainwp_enable_guided_video', 0 ) ? 'checked="true"' : ''; ?> />
2347 <label><?php esc_html_e( 'Enable embedded YouTube video tutorials within MainWP for step-by-step guidance.', 'mainwp' ); ?></label>
2348 </div>
2349 </div>
2350 </div>
2351 <?php
2352 /**
2353 * Action: mainwp_tools_form_bottom
2354 *
2355 * Fires at the bottom of mainwp tools form.
2356 *
2357 * @since 4.1
2358 */
2359 do_action( 'mainwp_tools_form_bottom' );
2360 $el_id_sbm_btn_1 = 'submit';
2361 ?>
2362 <div class="ui divider"></div>
2363 <input type="submit" name="submit" id="<?php echo esc_attr( $el_id_sbm_btn_1 ); ?>" class="ui green big button" value="<?php esc_attr_e( 'Save Settings', 'mainwp' ); ?>"/>
2364 </form>
2365 </div>
2366 </div>
2367 <script type="text/javascript">
2368 jQuery( '#mainwp-disconnect-sites-tool' ).popup();
2369 jQuery( '#mainwp-clear-activation-data' ).popup();
2370 </script>
2371 <?php
2372 static::render_footer( 'MainWPTools' );
2373 MainWP_Connect_Helper::render_renew_connections_modal();
2374 }
2375
2376 /**
2377 * Method is_basic_auth_dashboard_enabled.
2378 *
2379 * @return bool true|false.
2380 */
2381 public static function is_basic_auth_dashboard_enabled() { // phpcs:ignore -- NOSONAR - complex.
2382 $response = wp_remote_get( get_site_url() . '/wp-json' );
2383 $code = wp_remote_retrieve_response_code( $response );
2384 if ( 404 === (int) $code || 401 === (int) $code ) {
2385 return true;
2386 }
2387 return false;
2388 }
2389
2390
2391 /**
2392 * Render MainWP themes selection.
2393 */
2394 public function render_select_custom_themes() { // phpcs:ignore -- NOSONAR - complex.
2395 $custom_theme = $this->get_current_user_theme();
2396 if ( false === $custom_theme ) {
2397 // to compatible with Custom Dashboard extension settings.
2398 $compat_settings = get_option( 'mainwp_custom_dashboard_settings' );
2399 if ( is_array( $compat_settings ) && isset( $compat_settings['theme'] ) ) {
2400 $compat_theme = $compat_settings['theme'];
2401 }
2402 if ( null !== $compat_theme ) {
2403 $custom_theme = $compat_theme;
2404 }
2405 }
2406 $themes_files = static::get_instance()->get_custom_themes_files();
2407 if ( empty( $themes_files ) ) {
2408 $themes_files = array();
2409 }
2410 ?>
2411 <div class="ui grid field settings-field-indicator-wrapper settings-field-indicator-tools" default-indi-value="default">
2412 <label class="six wide column middle aligned">
2413 <?php
2414 MainWP_Settings_Indicator::render_not_default_indicator( 'mainwp_selected_theme', $custom_theme );
2415 esc_html_e( 'Select MainWP Dashboard theme', 'mainwp' );
2416 ?>
2417 </label>
2418 <div class="ten wide column" tabindex="0" data-tooltip="<?php esc_attr_e( 'Select your MainWP Dashboard theme.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
2419 <select name="mainwp_settings_custom_theme" id="mainwp_settings_custom_theme" class="ui dropdown selection settings-field-value-change-handler">
2420 <option value="default" <?php echo ( 'default' === $custom_theme || empty( $custom_theme ) ) ? 'selected' : ''; ?>><?php esc_html_e( 'Light', 'mainwp' ); ?></option>
2421 <option value="default-dark" <?php echo ( 'default-dark' === $custom_theme || empty( $custom_theme ) ) ? 'selected' : ''; ?>><?php esc_html_e( 'Dark', 'mainwp' ); ?></option>
2422 <?php if ( 'default-2024' === $custom_theme ) { ?>
2423 <option value="default-2024" <?php echo ( 'default-2024' === $custom_theme ) ? 'selected' : ''; ?>><?php esc_html_e( 'Default 2024', 'mainwp' ); ?></option>
2424 <?php } ?>
2425 <?php if ( 'dark' === $custom_theme ) { ?>
2426 <option value="dark" <?php echo ( 'dark' === $custom_theme ) ? 'selected' : ''; ?>><?php esc_html_e( 'Dark 2024', 'mainwp' ); ?></option>
2427 <?php } ?>
2428 <?php if ( 'classic' === $custom_theme ) { ?>
2429 <option value="classic" <?php echo ( 'classic' === $custom_theme ) ? 'selected' : ''; ?>><?php esc_html_e( 'Classic (Legacy)', 'mainwp' ); ?></option>
2430 <?php } ?>
2431 <?php if ( 'wpadmin' === $custom_theme ) { ?>
2432 <option value="wpadmin" <?php echo ( 'wpadmin' === $custom_theme ) ? 'selected' : ''; ?>><?php esc_html_e( 'WP Admin (Legacy)', 'mainwp' ); ?></option>
2433 <?php } ?>
2434 <?php if ( 'minimalistic' === $custom_theme ) { ?>
2435 <option value="minimalistic" <?php echo ( 'minimalistic' === $custom_theme ) ? 'selected' : ''; ?>><?php esc_html_e( 'Minimalistic (Legacy)', 'mainwp' ); ?></option>
2436 <?php } ?>
2437 <?php
2438 foreach ( $themes_files as $file_name => $theme ) {
2439 $theme = ucfirst( $theme );
2440 $_select = '';
2441 if ( $custom_theme === $file_name ) {
2442 $_select = 'selected';
2443 }
2444 echo '<option value="' . esc_attr( $file_name ) . '" ' . esc_attr( $_select ) . '>' . esc_html( $theme ) . '</option>';
2445 }
2446 ?>
2447 </select>
2448 </div>
2449 </div>
2450 <?php
2451 }
2452
2453 /**
2454 * Get custom themes files.
2455 */
2456 public function get_custom_themes_files() {
2457 // get themes files.
2458 $dirs = $this->get_custom_theme_folder();
2459 $scan_dir = $dirs[0];
2460 $handle = opendir( $scan_dir );
2461 $themes = array();
2462 if ( $handle ) {
2463 $filename = readdir( $handle );
2464 while ( false !== $filename ) {
2465 $correct_file = true;
2466 if ( '.' === substr( $filename, 0, 1 ) || 'index.php' === $filename || '.css' !== substr( $filename, - 4 ) ) {
2467 $correct_file = false;
2468 }
2469 if ( $correct_file ) {
2470 $theme = basename( $filename, '.css' );
2471 $theme = str_replace( '-theme', '', $theme );
2472 $themes[ $filename ] = trim( $theme );
2473 }
2474 $filename = readdir( $handle ); // to while loop.
2475 }
2476 closedir( $handle );
2477 }
2478 return $themes;
2479 }
2480
2481 /**
2482 * Get selected MainWP theme name.
2483 */
2484 public function get_selected_theme() {
2485 $selected_theme = false;
2486
2487 $custom_theme = $this->get_current_user_theme();
2488
2489 if ( false === $custom_theme ) {
2490 // to compatible with Custom Dashboard extension settings.
2491 $compat_settings = get_option( 'mainwp_custom_dashboard_settings' );
2492 if ( is_array( $compat_settings ) && isset( $compat_settings['theme'] ) ) {
2493 $compat_theme = $compat_settings['theme'];
2494 }
2495
2496 if ( null !== $compat_theme ) {
2497 $custom_theme = $compat_theme;
2498 }
2499 }
2500
2501 if ( ! empty( $custom_theme ) ) {
2502 if ( 'default' === $custom_theme || 'default-dark' === $custom_theme || 'default-2024' === $custom_theme || 'dark' === $custom_theme || 'wpadmin' === $custom_theme || 'minimalistic' === $custom_theme ) {
2503 return $custom_theme;
2504 }
2505 $dirs = $this->get_custom_theme_folder();
2506 $theme_dir = $dirs[0];
2507 $file = $theme_dir . $custom_theme;
2508 if ( file_exists( $file ) && '.css' === substr( $file, - 4 ) ) {
2509 $selected_theme = $custom_theme;
2510 }
2511 }
2512 return $selected_theme;
2513 }
2514
2515
2516 /**
2517 * Get custom MainWP theme folder.
2518 */
2519 public function get_custom_theme_folder() {
2520 $dirs = MainWP_System_Utility::get_mainwp_dir();
2521 global $wp_filesystem;
2522 if ( is_array( $dirs ) && ! $wp_filesystem->exists( $dirs[0] . 'themes' ) && $wp_filesystem->exists( $dirs[0] . 'custom-dashboard' ) ) {
2523 // re-name the custom-dashboard folder to compatible.
2524 $wp_filesystem->move( $dirs[0] . 'custom-dashboard', $dirs[0] . 'themes' );
2525 }
2526 return MainWP_System_Utility::get_mainwp_dir_allow_access( 'themes' );
2527 }
2528
2529
2530 /**
2531 * Get current user's selected theme.
2532 */
2533 public function get_current_user_theme() {
2534 $custom_theme = get_user_option( 'mainwp_selected_theme' );
2535 if ( empty( $custom_theme ) ) {
2536 $custom_theme = get_option( 'mainwp_selected_theme', 'default' );
2537 }
2538 return $custom_theme;
2539 }
2540
2541 /**
2542 * Export Child Sites and save as .csv file.
2543 *
2544 * @uses \MainWP\Dashboard\MainWP_DB::query()
2545 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_for_current_user()
2546 * @uses \MainWP\Dashboard\MainWP_DB::data_seek()
2547 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
2548 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
2549 */
2550 public static function export_sites() {
2551 if ( isset( $_GET['doExportSites'] ) && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_GET['_wpnonce'] ), 'export_sites' ) ) {
2552
2553 $sql = MainWP_DB::instance()->get_sql_websites_for_current_user( true );
2554 $websites = MainWP_DB::instance()->query( $sql );
2555
2556 if ( ! $websites ) {
2557 die( 'Not found sites' );
2558 }
2559
2560 $keys = array( 'name', 'url', 'adminname', 'adminpasswd', 'wpgroups', 'uniqueId', 'http_user', 'http_pass', 'verify_certificate', 'ssl_version' );
2561 $allowedHeaders = array( 'site name', 'url', 'admin name', 'admin password', 'tag', 'security id', 'http username', 'http password', 'verify certificate', 'ssl version' );
2562 $csv = "#\r";
2563 $csv .= '# 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.' . "\r";
2564 $csv .= "#\r";
2565 $csv .= implode( ',', $allowedHeaders ) . "\r";
2566 MainWP_DB::data_seek( $websites, 0 );
2567 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
2568 if ( empty( $website ) ) {
2569 continue;
2570 }
2571 $row = MainWP_Utility::map_site( $website, $keys, false );
2572 // MWP-1548: decrypt http_user / http_pass before they hit
2573 // the CSV. The export file is meant for cross-install
2574 // transfer (admin re-imports on another dashboard); a
2575 // file_key envelope from this install would be unreadable
2576 // there. Plaintext on disk preserves today's portability
2577 // contract -- the export was already plaintext pre-fix,
2578 // and this hop neither widens nor narrows that exposure.
2579 if ( isset( $row['http_user'] ) ) {
2580 $row['http_user'] = MainWP_Credential_Storage::decrypt_credential( $row['http_user'] );
2581 }
2582 if ( isset( $row['http_pass'] ) ) {
2583 $row['http_pass'] = MainWP_Credential_Storage::decrypt_credential( $row['http_pass'] );
2584 }
2585
2586 $row = array_map(
2587 static function ( $value ) {
2588 return str_replace( '"', '""', (string) $value );
2589 },
2590 $row
2591 );
2592
2593 $csv .= '"' . implode( '","', $row ) . '"' . "\r";
2594 }
2595
2596 header( 'Content-Type: text/csv; charset=utf-8' );
2597 header( 'Content-Disposition: attachment; filename=export-sites.csv' );
2598 echo $csv; // phpcs:ignore WordPress.Security.EscapeOutput
2599 exit();
2600 }
2601 }
2602
2603 /**
2604 * Render MainWP Email Settings SubPage.
2605 *
2606 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::get_notification_types()
2607 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::render_edit_settings()
2608 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::emails_general_settings_handle()
2609 * @uses \MainWP\Dashboard\MainWP_Notification_Settings::render_all_settings()
2610 * @uses \MainWP\Dashboard\MainWP_Notification_Template::handle_template_file_action()
2611 */
2612 public static function render_email_settings() {
2613 $notification_emails = MainWP_Notification_Settings::get_notification_types();
2614 static::render_header( 'Emails' );
2615 $edit_email = isset( $_GET['edit-email'] ) ? sanitize_text_field( wp_unslash( $_GET['edit-email'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2616 if ( ! empty( $edit_email ) && isset( $notification_emails[ $edit_email ] ) ) {
2617 $updated_templ = MainWP_Notification_Template::instance()->handle_template_file_action();
2618 MainWP_Notification_Settings::instance()->render_edit_settings( $edit_email, $updated_templ );
2619 } else {
2620 $updated = MainWP_Notification_Settings::emails_general_settings_handle();
2621 MainWP_Notification_Settings::instance()->render_all_settings( $updated );
2622 }
2623 static::render_footer( 'Emails' );
2624 }
2625
2626 /**
2627 * Method mainwp_help_content()
2628 *
2629 * Creates the MainWP Help Documentation List for the help component in the sidebar.
2630 */
2631 public static function mainwp_help_content() {
2632 if ( isset( $_GET['page'] ) && ( 'Settings' === $_GET['page'] || 'SettingsAdvanced' === $_GET['page'] || 'MainWPTools' === $_GET['page'] || 'MonitoringSettings' === $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2633 ?>
2634 <p><?php esc_html_e( 'If you need help with your MainWP Dashboard settings, please review following help documents', 'mainwp' ); ?></p>
2635 <div class="ui list">
2636 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/management/mainwp-dashboard-settings#mainwp-dashboard-settings" target="_blank">MainWP Dashboard Settings</a></div>
2637 </div>
2638 <?php
2639 /**
2640 * Action: mainwp_settings_help_item
2641 *
2642 * Fires at the bottom of the help articles list in the Help sidebar on the Settings page.
2643 *
2644 * Suggested HTML markup:
2645 *
2646 * <div class="item"><a href="Your custom URL">Your custom text</a></div>
2647 *
2648 * @since 5.2
2649 */
2650 do_action( 'mainwp_settings_help_item' );
2651
2652 }
2653 }
2654
2655 /**
2656 * Method render_monitoring()
2657 *
2658 * Render Monitoring Settings.
2659 *
2660 * @uses \MainWP\Dashboard\MainWP_Monitoring_View::render_settings()
2661 */
2662 public static function render_monitoring() {
2663 if ( ! \mainwp_current_user_can( 'dashboard', 'manage_dashboard_settings' ) ) {
2664 \mainwp_do_not_have_permissions( esc_html__( 'manage dashboard settings', 'mainwp' ) );
2665 return;
2666 }
2667 static::render_header( 'Monitoring' );
2668 ?>
2669 <div id="mainwp-monitoring-settings" class="ui padded segment">
2670 <?php if ( isset( $_GET['message'] ) && 'saved' === sanitize_text_field( wp_unslash( $_GET['message'] ) ) ) : // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?>
2671 <div class="ui green message"><i class="close icon"></i><?php esc_html_e( 'Monitoring settings have been saved successfully!', 'mainwp' ); ?></div>
2672 <?php endif; ?>
2673 <div class="ui form">
2674 <form method="POST" action="">
2675 <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
2676 <input type="hidden" name="wp_nonce" value="<?php echo esc_attr( wp_create_nonce( 'MonitoringSettings' ) ); ?>" />
2677 <?php
2678 /**
2679 * Action: mainwp_monitoring_settings_form_top
2680 *
2681 * Fires at the top of monitoring settings form.
2682 *
2683 * @since 4.1
2684 */
2685 do_action( 'mainwp_monitoring_settings_form_top' );
2686 ?>
2687 <?php MainWP_Monitoring_View::render_settings(); ?>
2688 <?php
2689 /**
2690 * Action: mainwp_monitoring_form_bottom
2691 *
2692 * Fires at the bottom of mainwp monitoring form.
2693 *
2694 * @since 4.1
2695 */
2696 do_action( 'mainwp_monitoring_settings_form_bottom' );
2697 ?>
2698 <div class="ui divider"></div>
2699 <input type="submit" name="submit" id="submit-monitoring" class="ui green big button" value="<?php esc_attr_e( 'Save Settings', 'mainwp' ); ?>"/>
2700 </form>
2701 </div>
2702 </div>
2703 <?php
2704 static::render_footer( 'Monitoring' );
2705 }
2706 }
2707