PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / trunk
MainWP Dashboard: Self-hosted WordPress Management for Agencies vtrunk
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 5.2.2 5.3 All 153 releases
← All changes | class/class-mainwp-ui.php +1353 -305 5.2trunk View file →
@@ -6,8 +6,13 @@
6 6 */
7 7
8 8 namespace MainWP\Dashboard;
9 9
10 +// Exit if accessed directly.
11 +if ( ! defined( 'ABSPATH' ) ) {
12 + exit;
13 +}
14 +
10 15 /**
11 16 * Class MainWP_UI
12 17 *
13 18 * @package MainWP\Dashboard
@@ -25,8 +30,73 @@
25 30 return __CLASS__;
26 31 }
27 32
28 33 /**
34 + * Normalize a site URL before building an mShots request.
35 + *
36 + * @param string $url Child site URL.
37 + *
38 + * @return string Normalized site URL.
39 + */
40 + public static function get_normalized_mshots_target_url( $url ) {
41 + if ( ! is_string( $url ) ) {
42 + return '';
43 + }
44 +
45 + return esc_url_raw( trim( $url ) );
46 + }
47 +
48 + /**
49 + * Build an mShots image URL for a site.
50 + *
51 + * @param string $url Child site URL.
52 + * @param int $width Requested thumbnail width.
53 + * @param bool $requeue Whether to force a requeue request.
54 + *
55 + * @return string mShots URL.
56 + */
57 + public static function get_mshots_image_url( $url, $width = 0, $requeue = false ) {
58 + $site_url = static::get_normalized_mshots_target_url( $url );
59 +
60 + if ( empty( $site_url ) ) {
61 + return '';
62 + }
63 +
64 + $mshots_url = '//s0.wp.com/mshots/v1/' . rawurlencode( $site_url );
65 + $query_args = array();
66 + $width = intval( $width );
67 +
68 + if ( 0 < $width ) {
69 + $query_args['w'] = $width;
70 + }
71 +
72 + if ( $requeue ) {
73 + $query_args['requeue'] = 'true';
74 + }
75 +
76 + if ( ! empty( $query_args ) ) {
77 + $mshots_url .= '?' . http_build_query( $query_args, '', '&', PHP_QUERY_RFC3986 );
78 + }
79 +
80 + return $mshots_url;
81 + }
82 +
83 + /**
84 + * Build the primary and requeue mShots URLs for a site.
85 + *
86 + * @param string $url Child site URL.
87 + * @param int $width Requested thumbnail width.
88 + *
89 + * @return array mShots source URLs.
90 + */
91 + public static function get_mshots_image_sources( $url, $width = 0 ) {
92 + return array(
93 + 'src' => static::get_mshots_image_url( $url, $width ),
94 + 'requeue_src' => static::get_mshots_image_url( $url, $width, true ),
95 + );
96 + }
97 +
98 + /**
29 99 * Method select_sites_box()
30 100 *
31 101 * Select sites box.
32 102 *
@@ -186,8 +256,39 @@
186 256 * @devtodo Move to view folder.
187 257 */
188 258 public static function render_select_sites_header( $tab_id, $staging_enabled, $selectedby, $show_group = true, $show_client = false ) {
189 259
260 + static $rendered_count = 0;
261 +
262 + $rand_id_prefix = '';
263 +
264 + if ( ! empty( $rendered_count ) ) {
265 + $rand_id_prefix = '-' . MainWP_Utility::gen_rand_id();
266 + }
267 +
268 + ++$rendered_count;
269 +
270 + ?>
271 + <input type="hidden" name="select_by" value="<?php echo esc_attr( $selectedby ); ?>" id="select_by<?php echo esc_attr( $rand_id_prefix ); // empty prefix to ensure compatibility with extensions. ?>"/>
272 + <input type="hidden" name="select_sites_tab" id="select_sites_tab<?php echo esc_attr( $rand_id_prefix ); // empty prefix to ensure compatibility with extensions. ?>" value="<?php echo esc_attr( $selectedby ); ?>"/>
273 +
274 + <div class="mainwp-select-sites-header" id="mainwp-select-sites-header<?php echo esc_attr( $rand_id_prefix ); // empty prefix to ensure compatibility with extensions. ?>" >
275 + <div class="ui secondary mini horizontal menu" id="mainwp-select-sites-menu">
276 + <a class="item ui tab <?php echo ( 'site' === $selectedby ) ? 'active' : ''; ?>" data-tab="mainwp-select-sites-<?php echo esc_attr( $tab_id ); ?>" select-by="site"><?php esc_html_e( 'Sites', 'mainwp' ); ?></a>
277 + <?php if ( $show_group ) : ?>
278 + <a class="item ui tab <?php echo ( 'group' === $selectedby ) ? 'active' : ''; ?>" data-tab="mainwp-select-groups-<?php echo esc_attr( $tab_id ); ?>" select-by="group"><?php esc_html_e( 'Tags', 'mainwp' ); ?></a>
279 + <?php endif; ?>
280 + <?php if ( $show_client ) : ?>
281 + <a class="item ui tab <?php echo ( 'client' === $selectedby ) ? 'active' : ''; ?>" data-tab="mainwp-select-clients-<?php echo esc_attr( $tab_id ); ?>" select-by="client"><?php esc_html_e( 'Clients', 'mainwp' ); ?></a>
282 + <?php endif; ?>
283 + <?php if ( $staging_enabled ) : ?>
284 + <a class="item ui text tab" data-tab="mainwp-select-staging-sites-<?php echo esc_attr( $tab_id ); ?>" select-by="staging"><?php esc_html_e( 'Staging', 'mainwp' ); ?></a>
285 + <?php endif; ?>
286 + </div>
287 + </div>
288 +
289 +
290 + <?php
190 291 /**
191 292 * Action: mainwp_before_select_sites_filters
192 293 *
193 294 * Fires before the Select Sites box filters.
@@ -196,13 +297,13 @@
196 297 */
197 298 do_action( 'mainwp_before_select_sites_filters' );
198 299 ?>
199 300 <div id="mainwp-select-sites-filters">
200 - <div class="ui mini fluid icon input">
201 - <input type="text" id="mainwp-select-sites-filter" value="" placeholder="<?php esc_attr_e( 'Type to filter your sites', 'mainwp' ); ?>" <?php echo 'site' === $selectedby ? '' : 'style="display: none;"'; ?> />
202 - <i class="filter icon"></i>
203 - </div>
204 - </div>
301 + <div class="ui mini fluid icon input">
302 + <input type="text" id="mainwp-select-sites-filter" value="" placeholder="<?php esc_attr_e( 'Search...', 'mainwp' ); ?>" />
303 + <i class="filter icon"></i>
304 + </div>
305 + </div>
205 306 <?php
206 307 /**
207 308 * Action: mainwp_after_select_sites_filters
208 309 *
@@ -210,26 +311,8 @@
210 311 *
211 312 * @since 4.1
212 313 */
213 314 do_action( 'mainwp_after_select_sites_filters' );
214 - ?>
215 - <input type="hidden" name="select_by" id="select_by" value="<?php echo esc_attr( $selectedby ); ?>"/>
216 - <input type="hidden" id="select_sites_tab" value="<?php echo esc_attr( $selectedby ); ?>"/>
217 - <div id="mainwp-select-sites-header">
218 - <div class="ui pointing green secondary menu">
219 - <a class="item ui tab <?php echo ( 'site' === $selectedby ) ? 'active' : ''; ?>" data-tab="mainwp-select-sites-<?php echo esc_attr( $tab_id ); ?>" select-by="site"><?php esc_html_e( 'Sites', 'mainwp' ); ?></a>
220 - <?php if ( $show_group ) : ?>
221 - <a class="item ui tab <?php echo ( 'group' === $selectedby ) ? 'active' : ''; ?>" data-tab="mainwp-select-groups-<?php echo esc_attr( $tab_id ); ?>" select-by="group"><?php esc_html_e( 'Tags', 'mainwp' ); ?></a>
222 - <?php endif; ?>
223 - <?php if ( $show_client ) : ?>
224 - <a class="item ui tab <?php echo ( 'client' === $selectedby ) ? 'active' : ''; ?>" data-tab="mainwp-select-clients-<?php echo esc_attr( $tab_id ); ?>" select-by="client"><?php esc_html_e( 'Clients', 'mainwp' ); ?></a>
225 - <?php endif; ?>
226 - <?php if ( $staging_enabled ) : ?>
227 - <a class="item ui tab" data-tab="mainwp-select-staging-sites-<?php echo esc_attr( $tab_id ); ?>" select-by="staging"><?php esc_html_e( 'Staging', 'mainwp' ); ?></a>
228 - <?php endif; ?>
229 - </div>
230 - </div>
231 - <?php
232 315 }
233 316
234 317 /**
235 318 * Method render_select_sites()
@@ -259,14 +342,28 @@
259 342 * @since 4.1
260 343 */
261 344 do_action( 'mainwp_before_select_sites_list', $websites );
262 345 $count_disc = 0;
346 +
347 + static $rendered_count = 0;
348 +
349 + $rand_id_prefix = '';
350 +
351 + if ( ! empty( $rendered_count ) ) {
352 + $rand_id_prefix = '-' . MainWP_Utility::gen_rand_id();
353 + }
354 +
355 + ++$rendered_count;
356 +
263 357 ?>
264 - <div id="mainwp-select-sites-body">
265 - <div class="ui relaxed divided list" id="mainwp-select-sites-list">
358 + <div id="mainwp-select-sites-body<?php echo esc_attr( $rand_id_prefix ); ?>" class="mainwp-select-sites-items-body">
359 + <div class="ui relaxed selection list mainwp-select-sites-list" id="mainwp-select-sites-list">
266 360 <?php if ( ! $websites ) : ?>
267 361 <div id="mainwp-select-sites-placeholder" class="ui segment">
268 - <?php static::render_empty_element_placeholder( __( 'No sites connected.', 'mainwp' ) ); ?>
362 + <?php static::render_empty_element_placeholder( __( 'No sites yet', 'mainwp' ), __( 'Connect your first WordPress site to start managing it from MainWP.', 'mainwp' ), '<em data-emoji=":link:" class="medium"></em>' ); ?>
363 + <div class="ui center aligned segment">
364 + <a href="admin.php?page=managesites&do=new" class="ui mini green button"><?php esc_html_e( 'Connect a Site', 'mainwp' ); ?></a> <a href="https://docs.mainwp.com/getting-started/get-started-with-mainwp#add-a-site-to-your-dashboard" class="ui mini grey basic button" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Learn How', 'mainwp' ); ?></a>
365 + </div>
269 366 </div>
270 367 <?php
271 368 else :
272 369 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
@@ -301,21 +398,23 @@
301 398 if ( '' !== $website->sync_errors ) {
302 399 $disconnected = true;
303 400 ++$count_disc;
304 401 }
402 + $sel_id_prefix = MainWP_Utility::gen_rand_id( $website->id, true );
305 403 ?>
306 404 <div title="<?php echo esc_html( $website->url ); ?>" class="mainwp_selected_sites_item ui <?php echo esc_html( $type ); ?> item <?php echo $selected ? 'selected_sites_item_checked' : ''; ?> <?php echo esc_html( $disconnected ? 'warning' : '' ); ?>">
307 - <input <?php echo esc_html( $disabled ); ?> type="<?php echo esc_html( $type ); ?>" name="<?php echo 'radio' === $type ? 'selected_sites' : 'selected_sites[]'; ?>" siteid="<?php echo intval( $website->id ); ?>" value="<?php echo intval( $website->id ); ?>" id="selected_sites_<?php echo intval( $website->id ); ?>" <?php echo $selected ? 'checked="true"' : ''; ?> />
308 - <label for="selected_sites_<?php echo intval( $website->id ); ?>">
405 + <input <?php echo esc_html( $disabled ); ?> type="<?php echo esc_html( $type ); ?>" name="<?php echo 'radio' === $type ? 'selected_sites' : 'selected_sites[]'; ?>" siteid="<?php echo intval( $website->id ); ?>" value="<?php echo intval( $website->id ); ?>" id="selected_sites_<?php echo esc_attr( $sel_id_prefix ); ?>" <?php echo $selected ? 'checked="true"' : ''; ?> />
406 + <label for="selected_sites_<?php echo esc_attr( $sel_id_prefix ); ?>">
309 407 <?php echo esc_html( stripslashes( $website->name ) ); ?> <span class="url"><?php echo esc_html( $website->url ); ?></span>
310 408 </label>
311 409 </div>
312 410 <?php
313 411 } else {
412 + $sel_id_prefix2 = MainWP_Utility::gen_rand_id( $website->id, true );
314 413 ?>
315 414 <div title="<?php echo esc_html( $website->url ); ?>" class="mainwp_selected_sites_item item ui <?php echo esc_html( $type ); ?> <?php echo $selected ? 'selected_sites_item_checked' : ''; ?>">
316 - <input type="<?php echo esc_html( $type ); ?>" disabled="disabled" id="selected_sites_<?php echo intval( $website->id ); ?>"/>
317 - <label for="selected_sites_<?php echo intval( $website->id ); ?>">
415 + <input type="<?php echo esc_html( $type ); ?>" disabled="disabled" id="selected_sites_<?php echo esc_attr( $sel_id_prefix2 ); ?>"/>
416 + <label for="selected_sites_<?php echo esc_attr( $sel_id_prefix2 ); ?>">
318 417 <?php echo esc_html( stripslashes( $website->name ) ); ?> <span class="url"><?php echo esc_html( $website->url ); ?></span>
319 418 </label>
320 419 </div>
321 420 <?php
@@ -358,11 +457,21 @@
358 457 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
359 458 */
360 459 public static function render_select_sites_staging( $selected_websites, $edit_site_id, $type = 'checkbox' ) { //phpcs:ignore -- NOSONAR - complex.
361 460 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user( false, null, 'wp.url', false, false, null, false, array( 'favi_icon' ), 'yes' ) );
461 +
462 + static $rendered_count = 0;
463 +
464 + $rand_id_prefix2 = '';
465 +
466 + if ( ! empty( $rendered_count ) ) {
467 + $rand_id_prefix2 = '-' . MainWP_Utility::gen_rand_id();
468 + }
469 +
470 + ++$rendered_count;
362 471 ?>
363 - <div id="mainwp-select-sites-body">
364 - <div class="ui relaxed divided list" id="mainwp-select-staging-sites-list">
472 + <div id="mainwp-select-sites-body<?php echo esc_attr( $rand_id_prefix2 ); ?>" class="mainwp-select-sites-items-body">
473 + <div class="ui relaxed selection list" id="mainwp-select-staging-sites-list">
365 474 <?php if ( ! $websites ) : ?>
366 475 <h2 class="ui icon header">
367 476 <i class="folder open outline icon"></i>
368 477 <div class="content"><?php esc_html_e( 'No staging websites have been found!', 'mainwp' ); ?></div>
@@ -376,12 +485,13 @@
376 485 $disabled = '';
377 486 if ( $edit_site_id && $website->id !== $edit_site_id ) {
378 487 $disabled = 'disabled="disabled"';
379 488 }
489 + $sel_id_prefix3 = MainWP_Utility::gen_rand_id( $website->id, true );
380 490 ?>
381 491 <div title="<?php echo esc_html( $website->url ); ?>" class="mainwp_selected_sites_item ui <?php echo esc_html( $type ); ?> item <?php echo $selected ? 'selected_sites_item_checked' : ''; ?>">
382 - <input <?php echo esc_html( $disabled ); ?> type="<?php echo esc_html( $type ); ?>" name="<?php echo 'radio' === $type ? 'selected_sites' : 'selected_sites[]'; ?>" siteid="<?php echo intval( $website->id ); ?>" value="<?php echo intval( $website->id ); ?>" id="selected_sites_<?php echo intval( $website->id ); ?>" <?php echo $selected ? 'checked="true"' : ''; ?> />
383 - <label for="selected_sites_<?php echo intval( $website->id ); ?>">
492 + <input <?php echo esc_html( $disabled ); ?> type="<?php echo esc_html( $type ); ?>" name="<?php echo 'radio' === $type ? 'selected_sites' : 'selected_sites[]'; ?>" siteid="<?php echo intval( $website->id ); ?>" value="<?php echo intval( $website->id ); ?>" id="selected_sites_<?php echo esc_attr( $sel_id_prefix3 ); ?>" <?php echo $selected ? 'checked="true"' : ''; ?> />
493 + <label for="selected_sites_<?php echo esc_attr( $sel_id_prefix3 ); ?>">
384 494 <?php echo esc_html( stripslashes( $website->name ) ); ?> <span class="url"><?php echo esc_html( $website->url ); ?></span>
385 495 </label>
386 496 </div>
387 497 <?php
@@ -388,9 +498,9 @@
388 498 } else {
389 499 ?>
390 500 <div title="<?php echo esc_html( $website->url ); ?>" class="mainwp_selected_sites_item item ui <?php echo esc_html( $type ); ?> <?php echo $selected ? 'selected_sites_item_checked' : ''; ?>">
391 501 <input type="<?php echo esc_html( $type ); ?>" disabled="disabled"/>
392 - <label for="selected_sites_<?php echo intval( $website->id ); ?>">
502 + <label>
393 503 <?php echo esc_html( stripslashes( $website->name ) ); ?> <span class="url"><?php echo esc_html( $website->url ); ?></span>
394 504 </label>
395 505 </div>
396 506 <?php
@@ -425,11 +535,22 @@
425 535 *
426 536 * @since 4.1
427 537 */
428 538 do_action( 'mainwp_before_select_groups_list', $groups );
539 +
540 + static $rendered_count = 0;
541 +
542 + $rand_id_prefix3 = '';
543 +
544 + if ( ! empty( $rendered_count ) ) {
545 + $rand_id_prefix3 = '-' . MainWP_Utility::gen_rand_id();
546 + }
547 +
548 + ++$rendered_count;
549 +
429 550 ?>
430 - <div id="mainwp-select-sites-body">
431 - <div class="ui relaxed divided list" id="mainwp-select-groups-list">
551 + <div id="mainwp-select-sites-body<?php echo esc_attr( $rand_id_prefix3 ); ?>" class="mainwp-select-sites-items-body">
552 + <div class="ui relaxed selection list mainwp-select-groups-list" id="mainwp-select-groups-list<?php echo esc_attr( $rand_id_prefix3 ); // empty prefix to ensure compatibility with extensions. ?>">
432 553 <?php
433 554 if ( empty( $groups ) ) {
434 555 ?>
435 556 <h2 class="ui icon header">
@@ -541,14 +662,14 @@
541 662 $page = isset( $_GET['page'] ) ? wp_unslash( $_GET['page'] ) : '';
542 663
543 664 $tour_id = '';
544 665 if ( 'mainwp_tab' === $page ) {
545 - $tour_id = '13112';
666 + $tour_id = '30496';
546 667 } elseif ( 'managesites' === $page ) {
547 668 if ( isset( $_GET['do'] ) && 'new' === $_GET['do'] ) {
548 669 $tour_id = '13210';
549 670 } elseif ( isset( $_GET['do'] ) && 'bulknew' === $_GET['do'] ) {
550 - $tour_id = '27274';
671 + $tour_id = '60206';
551 672 } elseif ( ! isset( $_GET['dashboard'] ) && ! isset( $_GET['id'] ) && ! isset( $_GET['updateid'] ) && ! isset( $_GET['emailsettingsid'] ) && ! isset( $_GET['scanid'] ) ) {
552 673 if ( 'grid' === $siteViewMode ) {
553 674 $tour_id = '27217';
554 675 } else {
@@ -615,8 +736,10 @@
615 736 } elseif ( 'UserBulkManage' === $page ) {
616 737 $tour_id = '28574';
617 738 } elseif ( 'UserBulkAdd' === $page ) {
618 739 $tour_id = '28575';
740 + } elseif ( 'PasswordPolicy' === $page ) {
741 + $tour_id = '80725';
619 742 } elseif ( 'BulkImportUsers' === $page ) {
620 743 $tour_id = '28736';
621 744 } elseif ( 'UpdateAdminPasswords' === $page ) {
622 745 $tour_id = '28737';
@@ -635,12 +758,16 @@
635 758 } elseif ( 'SettingsAdvanced' === $page ) {
636 759 $tour_id = '28886';
637 760 } elseif ( 'SettingsEmail' === $page ) {
638 761 $tour_id = '29054';
762 + } elseif ( 'MonitoringSettings' === $page ) {
763 + $tour_id = '80726';
639 764 } elseif ( 'MainWPTools' === $page ) {
640 765 $tour_id = '29272';
641 766 } elseif ( 'RESTAPI' === $page ) {
642 767 $tour_id = '29273';
768 + } elseif ( 'ApplicationPasswords' === $page ) {
769 + $tour_id = '80727';
643 770 } elseif ( 'ServerInformation' === $page ) {
644 771 $tour_id = '28873';
645 772 } elseif ( 'ServerInformationCron' === $page ) {
646 773 $tour_id = '28874';
@@ -676,9 +803,13 @@
676 803 $tour_id = '33167';
677 804 } elseif ( 'Extensions-Mainwp-Maintenance-Extension' === $page ) {
678 805 $tour_id = '33301';
679 806 } elseif ( 'Extensions-Mainwp-Domain-Monitor-Extension' === $page ) {
680 - $tour_id = '33300';
807 + $tour_id = '66031';
808 + } elseif ( 'Extensions-Mainwp-Favorites-Extension' === $page ) {
809 + $tour_id = '66035';
810 + } elseif ( 'Extensions-Mainwp-Regression-Testing-Extension' === $page ) {
811 + $tour_id = '66037';
681 812 }
682 813 // phpcs:enable
683 814 ?>
684 815 <div class="ui segment right sites sidebar" style="padding:0px" id="mainwp-sites-menu-sidebar">
@@ -703,9 +834,9 @@
703 834 <div class="ui hiden divider"></div>
704 835 <div class="ui fluid relaxed list">
705 836 <div class="item" >
706 837 <i class="grid layout icon"></i>
707 - <a href="<?php echo 'admin.php?page=managesites&dashboard=' . intval( $website->id ); ?>"><?php esc_html_e( 'Overview', 'mainwp' ); ?></a>
838 + <a href="<?php echo 'admin.php?page=managesites&dashboard=' . intval( $website->id ); ?>"><?php esc_html_e( 'Operations', 'mainwp' ); ?></a>
708 839 </div>
709 840 <div class="item" >
710 841 <i class="redo icon"></i>
711 842 <a href="<?php echo 'admin.php?page=managesites&updateid=' . intval( $website->id ); ?>"><?php esc_html_e( 'Updates', 'mainwp' ); ?></a>
@@ -711,12 +842,12 @@
711 842 <a href="<?php echo 'admin.php?page=managesites&updateid=' . intval( $website->id ); ?>"><?php esc_html_e( 'Updates', 'mainwp' ); ?></a>
712 843 </div>
713 844 <div class="item">
714 845 <i class="edit icon"></i>
715 - <a href="<?php echo 'admin.php?page=managesites&id=' . intval( $website->id ); ?>"><?php esc_html_e( 'Edit Site', 'mainwp' ); ?></a>
846 + <a href="<?php echo 'admin.php?page=managesites&id=' . intval( $website->id ); ?>"><?php esc_html_e( 'Settings', 'mainwp' ); ?></a>
716 847 </div>
717 848 <div class="item">
718 - <i class="sync alt icon"></i>
849 + <i class="sync alternate icon"></i>
719 850 <a href="#" siteid="<?php echo intval( $website->id ); ?>" onClick="updatesoverview_wp_sync( '<?php echo intval( $website->id ); ?>' )"><?php esc_html_e( 'Sync Site', 'mainwp' ); ?></a>
720 851 </div>
721 852 <div class="item">
722 853 <i class="shield icon"></i>
@@ -723,14 +854,15 @@
723 854 <a href="<?php echo 'admin.php?page=managesites&scanid=' . intval( $website->id ); ?>"><?php esc_html_e( 'Site Hardening', 'mainwp' ); ?></a>
724 855 </div>
725 856 <div class="item">
726 857 <i class="sign in icon"></i>
727 - <a target="_blank" href="<?php echo 'admin.php?page=SiteOpen&newWindow=yes&websiteid=' . intval( $website->id ); ?>&_opennonce=<?php echo esc_attr( wp_create_nonce( 'mainwp-admin-nonce' ) ); ?>"><?php esc_html_e( 'Go to WP Admin', 'mainwp' ); ?></a>
858 + <a target="_blank" href="<?php MainWP_Site_Open::get_open_site_admin_link( $website->id, true ); //phpcs:ignore -- ok. ?>"><?php esc_html_e( 'Go to WP Admin', 'mainwp' ); ?></a>
728 859 </div>
729 860 <div class="item">
730 861 <i class="globe icon"></i>
731 862 <a target="_blank" href="<?php echo esc_url( $website->url ); ?>"><?php esc_html_e( 'Visit Site', 'mainwp' ); ?></a>
732 863 </div>
864 +
733 865 <?php
734 866 /**
735 867 * Action: mainwp_quick_sites_shortcut
736 868 *
@@ -758,25 +890,18 @@
758 890 <div class="ui segment right wide help sidebar" id="mainwp-documentation-sidebar">
759 891 <div class="ui header"><?php esc_html_e( 'MainWP Guided Tours', 'mainwp' ); ?> <span class="ui blue mini label"><?php esc_html_e( 'BETA', 'mainwp' ); ?></span></div>
760 892 <div class="ui hidden divider"></div>
761 893 <div class="ui info message" style="display:block!important;">
762 - <?php printf( esc_html__( 'This feature is implemented using Javascript provided by Usetiful and is subject to the %1$sUsetiful Privacy Policy%2$s.', 'mainwp' ), '<a href="https://www.usetiful.com/privacy-policy" target="_blank">', '</a>' ); ?>
894 + <?php /* translators: 1: Opening anchor tag for privacy policy link, 2: Closing anchor tag. */ printf( esc_html__( 'This feature is implemented using Javascript provided by Usetiful and is subject to the %1$sUsetiful Privacy Policy%2$s.', 'mainwp' ), '<a href="https://www.usetiful.com/privacy-policy" target="_blank">', '</a>' ); ?>
763 895 </div>
764 896 <div class="ui hidden divider"></div>
765 - <div class="ui toggle checkbox">
766 - <input type="checkbox" id="mainwp-select-guided-tours-option" onchange="mainwp_guidedtours_onchange(this);"<?php echo 1 === (int) get_option( 'mainwp_enable_guided_tours', 0 ) ? 'checked="true"' : ''; ?> /> <label><?php esc_html_e( 'Switch to enable or disable tours.', 'mainwp' ); ?></label>
767 - </div>
768 - <div class="ui hidden divider"></div>
769 897 <?php if ( 1 === (int) get_option( 'mainwp_enable_guided_tours', 0 ) ) : ?>
770 898 <p><?php esc_html_e( 'MainWP guided tours are designed to provide information about all essential features on each MainWP Dashboard page.', 'mainwp' ); ?></p>
771 899 <p><?php esc_html_e( 'Click the Start Page Tour button to start the guided tour for the current page.', 'mainwp' ); ?></p>
772 900 <div class="ui hidden divider"></div>
773 901 <button id="mainwp-start-page-tour-button" class="ui big green fluid basic button" tour-id="<?php echo esc_attr( $tour_id ); ?>"><?php esc_html_e( 'Start Page Tour', 'mainwp' ); ?></button>
774 - <?php if ( 'mainwp_tab' === $page ) : ?>
775 - <div class="ui hidden divider"></div>
776 - <button id="mainwp-interface-tour-button" class="ui big green fluid basic button"><?php esc_html_e( 'MainWP Interface Basics Tour', 'mainwp' ); ?></button>
902 +
777 903 <?php endif; ?>
778 - <?php endif; ?>
779 904 <div class="ui header"><?php esc_html_e( 'MainWP Knowledge Base', 'mainwp' ); ?></div>
780 905 <div class="ui hidden divider"></div>
781 906 <?php
782 907 /**
@@ -788,12 +913,12 @@
788 913 */
789 914 do_action( 'mainwp_help_sidebar_content' );
790 915 ?>
791 916 <div class="ui hidden divider"></div>
792 - <a href="https://kb.mainwp.com/" class="ui big green fluid button"><?php esc_html_e( 'Help Documentation', 'mainwp' ); // NOSONAR - noopener - open safe. ?></a>
917 + <a href="https://docs.mainwp.com/" class="ui big green fluid button"><?php esc_html_e( 'Help Documentation', 'mainwp' ); // NOSONAR - noopener - open safe. ?></a>
793 918 <div class="ui hidden divider"></div>
794 919 <div id="mainwp-sticky-help-button" class="" style="position: absolute; bottom: 1em; left: 1em; right: 1em;">
795 - <a href="https://managers.mainwp.com/" target="_blank" class="ui fluid button"><?php esc_html_e( 'Still Need Help?', 'mainwp' ); ?></a>
920 + <a href="https://community.mainwp.com/" target="_blank" class="ui fluid button"><?php esc_html_e( 'Still Need Help?', 'mainwp' ); ?></a>
796 921 </div>
797 922 </div>
798 923 <?php
799 924 /**
@@ -822,9 +947,9 @@
822 947 <?php
823 948 /**
824 949 * Action: mainwp_overview_screen_options_top
825 950 *
826 - * Fires at the top of the Sceen Options modal on the Overview page.
951 + * Fires at the top of the Sceen Options modal on the Operations page.
827 952 *
828 953 * @since 4.1
829 954 */
830 955 do_action( 'mainwp_overview_screen_options_top' );
@@ -829,9 +954,9 @@
829 954 */
830 955 do_action( 'mainwp_overview_screen_options_top' );
831 956 ?>
832 957 <form method="POST" action="" name="mainwp_overview_screen_options_form" id="mainwp-overview-screen-options-form">
833 - <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
958 + <?php self::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
834 959 <input type="hidden" name="wp_nonce" value="<?php echo esc_html( wp_create_nonce( 'MainWPScrOptions' ) ); ?>" />
835 960 <?php static::render_screen_options( false ); ?>
836 961 <?php
837 962 /**
@@ -836,9 +961,9 @@
836 961 <?php
837 962 /**
838 963 * Action: mainwp_overview_screen_options_bottom
839 964 *
840 - * Fires at the bottom of the Sceen Options modal on the Overview page.
965 + * Fires at the bottom of the Sceen Options modal on the Operations page.
841 966 *
842 967 * @since 4.1
843 968 */
844 969 do_action( 'mainwp_overview_screen_options_bottom' );
@@ -914,9 +1039,9 @@
914 1039 " id="mainwp-navigation-icon" />
915 1040 </a>
916 1041 </div>
917 1042 <div class="left aligned middle aligned column" style="width:calc( 50% - 72px )!important">
918 - <h2 class="mainwp-page-title ui small header"><?php echo $left; // phpcs:ignore WordPress.Security.EscapeOutput ?></h2>
1043 + <h1 class="mainwp-page-title ui small header"><?php echo $left; // phpcs:ignore WordPress.Security.EscapeOutput ?></h1>
919 1044 </div>
920 1045 <div class="right aligned middle aligned column" style="width:50%!important">
921 1046 <?php echo $right; // phpcs:ignore WordPress.Security.EscapeOutput ?>
922 1047 </div>
@@ -921,8 +1046,27 @@
921 1046 <?php echo $right; // phpcs:ignore WordPress.Security.EscapeOutput ?>
922 1047 </div>
923 1048 </div>
924 1049 </div>
1050 + <script type="text/javascript">
1051 + jQuery( document ).ready( function($) {
1052 + $('#mainwp-top-header').prevAll().each(function () {
1053 + let strId=$(this).attr('id');
1054 + if(strId?.includes('mainwp')){
1055 + return;
1056 + }
1057 + let strCls=$(this).attr('class');
1058 + if(strCls?.includes('mainwp')){
1059 + return;
1060 + }
1061 + if($(this).is(':visible')){
1062 + $(this).prependTo('.mainwp-content-wrap'); // to fix display.
1063 + $(this).css( 'margin-left', '0px' );
1064 + }
1065 + });
1066 + });
1067 + </script>
1068 +
925 1069 <?php
926 1070 if ( $show_menu ) {
927 1071 MainWP_Menu::render_left_menu();
928 1072 MainWP_Menu::render_mobile_menu();
@@ -973,9 +1117,9 @@
973 1117 jQuery( '#mainwp-start-page-tour-button' ).on( 'click', function() {
974 1118 let tourId = jQuery( this ).attr( 'tour-id' );
975 1119 jQuery( '#mainwp-documentation-sidebar' ).sidebar( 'toggle' );
976 1120 if(tourId){
977 - window.USETIFUL.tour.start( parseInt( tourId ) );
1121 + window.USETIFUL.tour.start( Number.parseInt( tourId ) );
978 1122 } else {
979 1123 console.warn('Error: empty tour ID. Please set valid tour ID.');
980 1124 }
981 1125 } );
@@ -995,13 +1139,12 @@
995 1139 _try_start_usetiful_tour = function () {
996 1140 setTimeout(
997 1141 function () {
998 1142 try {
999 - window.USETIFUL.tour.start( parseInt( 40279 ) );
1143 + window.USETIFUL.tour.start( Number.parseInt( 40279 ) );
1000 1144 } catch ( e ) {
1001 1145 if ( _count_retry < 10 ) {
1002 1146 _count_retry++;
1003 - console.log('retry:' + _count_retry);
1004 1147 _try_start_usetiful_tour();
1005 1148 }
1006 1149 }
1007 1150 },
@@ -1015,21 +1158,92 @@
1015 1158 );
1016 1159 </script>
1017 1160 <?php
1018 1161 endif;
1162 +
1163 + $fix_dom_issue_for_wp_editor = isset( $_GET['page'] ) && 'Extensions-Mainwp-Pro-Reports-Extension' === $_GET['page'] && isset( $_GET['tab'] ) && 'report' === $_GET['tab'] ? true : false; //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended --NOSONAR - ok.
1164 +
1165 + if ( $fix_dom_issue_for_wp_editor ) {
1166 + ?>
1167 + <style type="text/css">
1168 + .mainwp-overlay-open #mainwp-main-mobile-navigation-container{
1169 + top: 58px !important;
1170 + }
1171 + </style>
1172 + <script type="text/javascript">
1173 + jQuery(function ($) {
1174 + const $body = $('body');
1175 + const $flyout = $('#mainwp-main-mobile-navigation-container');
1176 + const $overlay = $('#mainwp-overlay');
1177 +
1178 + // Ensure elements are in body (safe move).
1179 + if ($flyout.parent()[0] !== document.body) {
1180 + $flyout.appendTo('body');
1181 + $body.addClass('pushable');
1182 + }
1183 + if ($overlay.parent()[0] !== document.body) {
1184 + $overlay.appendTo('body');
1185 + $body.addClass('pushable');
1186 + }
1187 +
1188 + // Toggle
1189 + $('#mainwp-mobile-menu-trigger').on('click', function () {
1190 + $body.toggleClass('mainwp-overlay-open');
1191 +
1192 + $(this).find('i.icon')
1193 + .toggleClass('bars times');
1194 + $flyout.toggleClass('overlay visible');
1195 + $overlay.toggleClass('pusher dimmed');
1196 + });
1197 +
1198 + // Close on overlay click
1199 + $overlay.on('click', function () {
1200 + $body.removeClass('mainwp-overlay-open');
1201 + $flyout.removeClass('overlay visible');
1202 + $overlay.removeClass('pusher dimmed');
1203 +
1204 + $('#mainwp-mobile-menu-trigger i.icon')
1205 + .removeClass('times')
1206 + .addClass('bars');
1207 + });
1208 +
1209 + $(document).on('keydown', function (e) {
1210 + if (e.key === 'Escape') {
1211 + $('body').removeClass('mainwp-overlay-open');
1212 + $flyout.removeClass('overlay visible');
1213 + $overlay.removeClass('pusher dimmed');
1214 + $('#mainwp-mobile-menu-trigger i.icon')
1215 + .removeClass('times')
1216 + .addClass('bars');
1217 + }
1218 + });
1219 + });
1220 + </script>
1221 + <?php
1222 + }
1019 1223 ?>
1020 1224
1021 1225 <script type="text/javascript">
1022 - jQuery( document ).ready( function () {
1226 + jQuery( document ).ready( function ($) {
1023 1227
1024 - jQuery( '#mainwp-jump-to-site-overview-dropdown' ).on( 'change', function() {
1025 - let site_id = jQuery( this ).val();
1026 - window.location.href = 'admin.php?page=managesites&dashboard=' + site_id;
1027 - } );
1228 + let pulse = jQuery( '#mainwp-screen-options-pulse-control' ).val();
1028 1229
1230 + if (pulse == 1) {
1231 + jQuery('#mainwp-top-header .cog.icon').parent('.button').transition({
1232 + animation: 'pulse',
1233 + duration: 1000,
1234 + interval: 5500,
1235 + onStart: function () {
1236 + jQuery(this).removeClass('basic').addClass('green');
1237 + },
1238 + onComplete: function () {
1239 + jQuery(this).addClass('basic').removeClass('green');
1240 + }
1241 + });
1242 + }
1243 +
1029 1244 jQuery( '#mainwp-sites-menu-sidebar' ).prependTo( 'body' );
1030 1245 jQuery( '#mainwp-documentation-sidebar' ).prependTo( 'body' );
1031 - jQuery( 'body > div#wpwrap' ).addClass( 'pusher' );
1032 1246
1033 1247 jQuery( '#mainwp-help-sidebar' ).on( 'click', function() {
1034 1248 jQuery( '.ui.help.sidebar' ).sidebar( {
1035 1249 transition: 'overlay'
@@ -1047,11 +1261,51 @@
1047 1261 jQuery( '.ui.sites.sidebar' ).sidebar( 'toggle' );
1048 1262 return false;
1049 1263 } );
1050 1264 jQuery( '#mainwp-sites-sidebar-menu' ).accordion();
1265 + jQuery( '#mainwp-sites-sidebar-menu' ).on( 'click', '.mainwp-site-menu-item', function ( e ) {
1266 + if ( ! jQuery( e.target ).closest( '.content' ).length && ! jQuery( e.target ).closest( '.title' ).length ) {
1267 + jQuery( this ).find( '.title' ).first().trigger( 'click' );
1268 + }
1269 + } );
1270 +
1271 + <?php if ( ! $fix_dom_issue_for_wp_editor ) { ?>
1272 +
1273 + if( jQuery( '#mainwp-main-mobile-navigation-container' ).length ){
1274 + jQuery('<div class="pusher"></div>')
1275 + .append($('#wpwrap'))
1276 + .prependTo('body');
1277 + jQuery( '#mainwp-main-mobile-navigation-container' ).prependTo( 'body' );
1278 + setTimeout(function () {
1279 + // Initialize flyout
1280 + $('#mainwp-main-mobile-navigation-container.ui.flyout')
1281 + .flyout({
1282 + dimPage: true,
1283 + onShow: function() {
1284 + $(this).css({
1285 + 'top': '58px',
1286 + });
1287 + $('#mainwp-mobile-menu-trigger').find('i.icon').removeClass('bars').addClass('times');
1288 + },
1289 + onHide: function() {
1290 + $('#mainwp-mobile-menu-trigger').find('i.icon').removeClass('times').addClass('bars');
1291 + }
1292 + });
1293 + }, 2000);
1294 +
1295 + // Trigger button
1296 + $('#mainwp-mobile-menu-trigger').on('click', function() {
1297 + $('#mainwp-main-mobile-navigation-container.ui.flyout').flyout('toggle');
1298 + });
1299 + }
1300 + <?php } ?>
1051 1301 } );
1052 1302 </script>
1303 +
1304 + <?php static::render_help_modal(); ?>
1305 + <?php static::render_loader_element(); ?>
1053 1306 <?php
1307 + ob_start();
1054 1308 /**
1055 1309 * Action: mainwp_after_header
1056 1310 *
1057 1311 * Fires after the MainWP header element.
@@ -1060,8 +1314,19 @@
1060 1314 *
1061 1315 * @since 4.0
1062 1316 */
1063 1317 do_action( 'mainwp_after_header', $websites );
1318 + $after_header_content = ob_get_clean();
1319 + if ( ! empty( trim( $after_header_content ) ) ) {
1320 + $has_extension_update_failure_notice = false !== strpos( $after_header_content, 'mainwp-extension-update-failure-notice' );
1321 + $admin_notices_style = $has_extension_update_failure_notice ? 'padding-bottom:0 !important;' : '';
1322 + $admin_notices_class = $has_extension_update_failure_notice ? ' mainwp-extension-update-failure-notice-segment' : '';
1323 + ?>
1324 + <div class="ui padded segment<?php echo esc_attr( $admin_notices_class ); ?>" id="mainwp-admin-notices-segment" style="<?php echo esc_attr( $admin_notices_style ); ?>">
1325 + <?php echo $after_header_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
1326 + </div>
1327 + <?php
1328 + }
1064 1329 ?>
1065 1330 <?php
1066 1331 }
1067 1332
@@ -1261,19 +1526,53 @@
1261 1526 * @return mixed $output Render header action buttons html.
1262 1527 *
1263 1528 * @uses \MainWP\Dashboard\MainWP_DB::get_websites_count()
1264 1529 */
1265 - public static function render_header_actions() { //phpcs:ignore -- NOSONAR - complex method.
1530 + public static function render_header_actions() { // phpcs:ignore -- NOSONAR - complex method.
1266 1531 $sites_count = MainWP_DB::instance()->get_websites_count();
1267 1532 $sidebar_pages = array( 'ManageGroups', 'PostBulkManage', 'PostBulkAdd', 'PageBulkManage', 'PageBulkAdd', 'ThemesManage', 'ThemesInstall', 'ThemesAutoUpdate', 'PluginsManage', 'PluginsInstall', 'PluginsAutoUpdate', 'UserBulkManage', 'UserBulkAdd', 'UpdateAdminPasswords', 'Extensions' );
1268 1533 $sidebar_pages = apply_filters( 'mainwp_sidbar_pages', $sidebar_pages ); // deprecated filter.
1269 1534 $sidebar_pages = apply_filters( 'mainwp_sidebar_pages', $sidebar_pages );
1535 + $current_user = get_current_user_id();
1536 + $custom_theme = MainWP_Settings::get_instance()->get_current_user_theme();
1537 + $screen = get_current_screen();
1538 + $show_command_palette_trigger = wp_script_is( 'wp-core-commands', 'enqueued' );
1539 + $command_palette_shortcut = '';
1540 + $command_palette_label = '';
1270 1541
1542 + if ( $show_command_palette_trigger ) {
1543 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Used only to mirror WordPress core shortcut labels.
1544 + $is_apple_os = (bool) preg_match( '/Macintosh|Mac OS X|Mac_PowerPC/i', $_SERVER['HTTP_USER_AGENT'] ?? '' );
1545 +
1546 + $command_palette_shortcut = $is_apple_os
1547 + ? _x( '⌘K', 'keyboard shortcut to open the command palette', 'mainwp' )
1548 + : _x( 'Ctrl+K', 'keyboard shortcut to open the command palette', 'mainwp' );
1549 +
1550 + /* translators: %s: Keyboard shortcut label. */
1551 + $command_palette_label = sprintf( esc_attr__( 'Open command palette (%s)', 'mainwp' ), $command_palette_shortcut );
1552 + }
1553 +
1554 + if ( false === $custom_theme ) {
1555 + $compat_theme = null;
1556 + // to compatible with Custom Dashboard extension settings.
1557 + $compat_settings = get_option( 'mainwp_custom_dashboard_settings' );
1558 + if ( is_array( $compat_settings ) && isset( $compat_settings['theme'] ) ) {
1559 + $compat_theme = $compat_settings['theme'];
1560 + }
1561 + if ( null !== $compat_theme ) {
1562 + $custom_theme = $compat_theme;
1563 + }
1564 + }
1565 + $themes_files = MainWP_Settings::get_instance()->get_custom_themes_files();
1566 + if ( empty( $themes_files ) ) {
1567 + $themes_files = array();
1568 + }
1569 +
1271 1570 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1272 - $page = isset( $_GET['page'] ) ? wp_unslash( $_GET['page'] ) : '';
1273 - ob_start();
1274 - if ( isset( $_GET['dashboard'] ) || isset( $_GET['id'] ) || isset( $_GET['updateid'] ) || isset( $_GET['emailsettingsid'] ) || isset( $_GET['scanid'] ) ) :
1275 - $id = 0;
1571 + $page = isset( $_GET['page'] ) ? wp_unslash( $_GET['page'] ) : '';
1572 + $id = 0;
1573 + $website = null;
1574 + if ( isset( $_GET['dashboard'] ) || ( isset( $_GET['id'] ) && 'CostTrackerAdd' !== $page ) || isset( $_GET['updateid'] ) || isset( $_GET['emailsettingsid'] ) || isset( $_GET['scanid'] ) ) {
1276 1575 if ( isset( $_GET['dashboard'] ) ) {
1277 1576 $id = intval( $_GET['dashboard'] );
1278 1577 } elseif ( isset( $_GET['id'] ) ) {
1279 1578 $id = intval( $_GET['id'] );
@@ -1282,65 +1581,145 @@
1282 1581 } elseif ( isset( $_GET['emailsettingsid'] ) ) {
1283 1582 $id = intval( $_GET['emailsettingsid'] );
1284 1583 } elseif ( isset( $_GET['scanid'] ) ) {
1285 1584 $id = intval( $_GET['scanid'] );
1585 + } elseif ( isset( $_GET['monitor_wpid'] ) ) {
1586 + $id = intval( $_GET['monitor_wpid'] );
1286 1587 }
1287 -
1288 - $website = MainWP_DB::instance()->get_website_by_id( $id );
1588 + if ( $id ) {
1589 + $website = MainWP_DB::instance()->get_website_by_id( $id );
1590 + }
1591 + }
1592 + ob_start();
1593 + if ( $show_command_palette_trigger ) :
1289 1594 ?>
1595 + <span id="mainwp-header-command-palette-actions" class="mainwp-768-hide">
1596 + <a href="#" class="ui button hide-if-no-js" id="mainwp-command-palette-trigger" data-tooltip="<?php echo esc_attr( $command_palette_label ); ?>" data-inverted="" data-position="left center" aria-label="<?php echo esc_attr( $command_palette_label ); ?>" onclick='if ( window.wp && wp.data && wp.data.dispatch ) { wp.data.dispatch( "core/commands" ).open(); } return false;'>
1597 + <kbd><?php echo esc_html( $command_palette_shortcut ); ?></kbd>
1598 + </a>
1599 + </span>
1600 + <?php
1601 + endif;
1602 + if ( $website ) :
1603 + ?>
1290 1604 <?php if ( $id && $website && '' !== $website->sync_errors ) : ?>
1291 - <a href="#" class="mainwp-updates-overview-reconnect-site ui green icon button" siteid="<?php echo intval( $website->id ); ?>" data-position="bottom right" aria-label="Reconnect <?php echo esc_html( stripslashes( $website->name ) ); ?>" data-tooltip="Reconnect <?php echo esc_html( stripslashes( $website->name ) ); ?>" data-inverted=""><i class="undo alternate icon"></i></a>
1292 - <?php else : ?>
1293 - <a class="ui icon button green <?php echo 0 < $sites_count ? '' : 'disabled'; ?>" id="mainwp-sync-sites" data-tooltip="<?php esc_attr_e( 'Get fresh data from your child sites.', 'mainwp' ); ?>" data-inverted="" data-position="bottom right" aria-label="<?php esc_attr_e( 'Get fresh data from your child sites.', 'mainwp' ); ?>" >
1294 - <i class="sync icon"></i>
1605 + <a href="#" class="mainwp-updates-overview-reconnect-site ui green button" adminuser="<?php echo esc_attr( $website->adminname ); ?>" siteid="<?php echo intval( $website->id ); ?>" data-position="bottom right" aria-label="Reconnect <?php echo esc_html( stripslashes( $website->name ) ); ?>" data-tooltip="Reconnect <?php echo esc_html( stripslashes( $website->name ) ); ?>" data-inverted=""><i class="undo alternate icon"></i> <?php echo esc_html__( 'Reconnect', 'mainwp' ); ?></a>
1606 + <?php
1607 + else :
1608 + $site_sync_info = MainWP_Utility::get_last_sync_info( $id );
1609 + $site_sync_tooltip = '';
1610 + $site_sync_outdated = false;
1611 + $current_time = time();
1612 + $twenty_four_h = 24 * HOUR_IN_SECONDS;
1613 +
1614 + $site_name = stripslashes( $website->name );
1615 + if ( ! empty( $site_sync_info['timestamp'] ) && ( $current_time - $site_sync_info['timestamp'] ) > $twenty_four_h ) {
1616 + $site_sync_outdated = true;
1617 + /* translators: 1: Site name. */
1618 + $site_sync_tooltip = sprintf( esc_attr__( 'Data not synced for more than 24h. Click here to sync %1$s.', 'mainwp' ), $site_name );
1619 + } elseif ( ! empty( $site_sync_info['formatted'] ) ) {
1620 + /* translators: 1: Last sync date/time, 2: Site name. */
1621 + $site_sync_tooltip = sprintf( esc_attr__( 'Last sync: %1$s. Click here to sync %2$s.', 'mainwp' ), $site_sync_info['formatted'], $site_name );
1622 + } else {
1623 + /* translators: 1: Site name. */
1624 + $site_sync_tooltip = sprintf( esc_attr__( 'Get fresh data from %1$s.', 'mainwp' ), $site_name );
1625 + }
1626 + ?>
1627 + <a class="ui green <?php echo 0 < $sites_count ? '' : 'disabled'; ?> button" id="mainwp-sync-sites" data-tooltip="<?php echo esc_attr( $site_sync_tooltip ); ?>" data-inverted="" data-position="left center" aria-label="<?php echo esc_attr( $site_sync_tooltip ); ?>" style="position: relative;">
1628 + <?php if ( $site_sync_outdated ) : ?>
1629 + <span class="ui red empty circular looping pulsating transition label" style="position: absolute; top: -4px; right: -4px;"></span>
1630 + <?php endif; ?>
1631 + <i class="sync alternate icon"></i> <span class="mainwp-768-hide"><?php echo esc_html__( 'Sync', 'mainwp' ); ?></span>
1295 1632 </a>
1296 1633 <?php endif; ?>
1297 - <?php else : ?>
1298 - <a class="ui icon button green <?php echo 0 < $sites_count ? '' : 'disabled'; ?> " id="mainwp-sync-sites" data-tooltip="<?php esc_attr_e( 'Click here to sync data now.', 'mainwp' ); ?>" data-inverted="" data-position="bottom right" aria-label="<?php esc_attr_e( 'Click here to sync data now.', 'mainwp' ); ?>">
1299 - <i class="sync alternate icon"></i>
1634 + <?php
1635 + else :
1636 + $el_id_syc_1 = 'mainwp-sync-sites';
1637 + $sync_info = MainWP_Utility::get_last_sync_info();
1638 + $sync_tooltip = '';
1639 + $sync_outdated = false;
1640 + $current_time = time();
1641 + $twenty_four_h = 24 * HOUR_IN_SECONDS;
1642 +
1643 + if ( ! empty( $sync_info['timestamp'] ) && ( $current_time - $sync_info['timestamp'] ) > $twenty_four_h ) {
1644 + $sync_outdated = true;
1645 + $sync_tooltip = esc_attr__( 'Data not synced for more than 24h. Click here to sync all sites.', 'mainwp' );
1646 + } elseif ( ! empty( $sync_info['formatted'] ) ) {
1647 + /* translators: 1: Last sync date/time. */
1648 + $sync_tooltip = sprintf( esc_attr__( 'Last sync: %1$s. Click here to sync all sites.', 'mainwp' ), $sync_info['formatted'] );
1649 + } else {
1650 + $sync_tooltip = esc_attr__( 'Click here to sync all sites.', 'mainwp' );
1651 + }
1652 + ?>
1653 + <a class="ui green <?php echo 0 < $sites_count ? '' : 'disabled'; ?> button" id="<?php echo esc_attr( $el_id_syc_1 ); ?>" data-tooltip="<?php echo esc_attr( $sync_tooltip ); ?>" data-inverted="" data-position="left center" aria-label="<?php echo esc_attr( $sync_tooltip ); ?>" style="position: relative;">
1654 + <?php if ( $sync_outdated ) : ?>
1655 + <span class="ui red empty circular looping pulsating transition label" style="position: absolute; top: -4px; right: -4px;"></span>
1656 + <?php endif; ?>
1657 + <i class="sync alternate icon"></i> <span class="mainwp-768-hide"><?php echo esc_html__( 'Sync', 'mainwp' ); ?></span>
1300 1658 </a>
1301 1659 <?php endif; ?>
1302 1660
1303 - <div class="ui icon top left pointing dropdown <?php echo empty( $sites_count ) ? 'green' : ''; ?> button" id="mainwp-add-new-buttons" aria-label="<?php esc_attr_e( 'Add new item to your MainWP Dashboard', 'mainwp' ); ?>" data-tooltip="<?php esc_attr_e( 'Add new item to your MainWP Dashboard.', 'mainwp' ); ?>" data-inverted="" data-position="left center">
1304 - <i class="plus icon"></i>
1661 + <div class="ui top left pointing dropdown <?php echo empty( $sites_count ) ? 'green' : ''; ?> button" id="mainwp-add-new-buttons" aria-label="<?php esc_attr_e( 'Add new item to your MainWP Dashboard', 'mainwp' ); ?>">
1662 + <i class="plus icon"></i> <?php echo esc_html__( 'Add', 'mainwp' ); ?>
1305 1663 <div class="menu">
1306 - <a class="item" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Add a new Website to your MainWP Dashboard', 'mainwp' ); ?>" href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&do=new' ) ); ?>"><?php esc_html_e( 'Add Website', 'mainwp' ); ?></a>
1307 - <a class="item" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Add a new Client to your MainWP Dashboard', 'mainwp' ); ?>" href="<?php echo esc_url( admin_url( 'admin.php?page=ClientAddNew' ) ); ?>"><?php esc_html_e( 'Add Client', 'mainwp' ); ?></a>
1308 - <a class="item" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Add a new Cost to for tracking', 'mainwp' ); ?>" href="<?php echo esc_url( admin_url( 'admin.php?page=CostTrackerAdd' ) ); ?>"><?php esc_html_e( 'Add Cost', 'mainwp' ); ?></a>
1309 - <a class="item" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Add a new Post to your child sites', 'mainwp' ); ?>" href="<?php echo esc_url( admin_url( 'admin.php?page=PostBulkAdd' ) ); ?>"><?php esc_html_e( 'Create Post', 'mainwp' ); ?></a>
1310 - <a class="item" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Add a new Page to your child sites', 'mainwp' ); ?>" href="<?php echo esc_url( admin_url( 'admin.php?page=PageBulkAdd' ) ); ?>"><?php esc_html_e( 'Create Page', 'mainwp' ); ?></a>
1311 - <a class="item" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Install a new Plugin to your child sites', 'mainwp' ); ?>" href="<?php echo esc_url( admin_url( 'admin.php?page=PluginsInstall' ) ); ?>"><?php esc_html_e( 'Install Plugin', 'mainwp' ); ?></a>
1312 - <a class="item" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Install a new Theme to your child sites', 'mainwp' ); ?>" href="<?php echo esc_url( admin_url( 'admin.php?page=ThemesInstall' ) ); ?>"><?php esc_html_e( 'Install Theme', 'mainwp' ); ?></a>
1313 - <a class="item" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Create a new User to your child sites', 'mainwp' ); ?>" href="<?php echo esc_url( admin_url( 'admin.php?page=UserBulkAdd' ) ); ?>"><?php esc_html_e( ' Create User', 'mainwp' ); ?></a>
1664 + <a class="item" href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&do=new' ) ); ?>"><?php esc_html_e( 'Add Website', 'mainwp' ); ?></a>
1665 + <?php if ( \mainwp_current_user_can( 'dashboard', 'manage_clients' ) ) { ?>
1666 + <a class="item" href="<?php echo esc_url( admin_url( 'admin.php?page=ClientAddNew' ) ); ?>"><?php esc_html_e( 'Add Client', 'mainwp' ); ?></a>
1667 + <?php } ?>
1668 + <a class="item" href="<?php echo esc_url( admin_url( 'admin.php?page=CostTrackerAdd' ) ); ?>"><?php esc_html_e( 'Add Cost', 'mainwp' ); ?></a>
1669 + <a class="item" href="<?php echo esc_url( admin_url( 'admin.php?page=PostBulkAdd' ) ); ?>"><?php esc_html_e( 'Create Post', 'mainwp' ); ?></a>
1670 + <a class="item" href="<?php echo esc_url( admin_url( 'admin.php?page=PageBulkAdd' ) ); ?>"><?php esc_html_e( 'Create Page', 'mainwp' ); ?></a>
1671 + <a class="item" href="<?php echo esc_url( admin_url( 'admin.php?page=PluginsInstall' ) ); ?>"><?php esc_html_e( 'Install Plugin', 'mainwp' ); ?></a>
1672 + <a class="item" href="<?php echo esc_url( admin_url( 'admin.php?page=ThemesInstall' ) ); ?>"><?php esc_html_e( 'Install Theme', 'mainwp' ); ?></a>
1673 + <a class="item" href="<?php echo esc_url( admin_url( 'admin.php?page=UserBulkAdd' ) ); ?>"><?php esc_html_e( ' Create User', 'mainwp' ); ?></a>
1314 1674 </div>
1315 1675 </div>
1316 1676
1317 - <?php if ( ( 'mainwp_tab' === $page ) || isset( $_GET['dashboard'] ) || in_array( $page, $sidebar_pages ) ) : // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended ?>
1318 - <a id="mainwp-screen-options-button" class="ui button icon" onclick="jQuery( '#mainwp-overview-screen-options-modal' ).modal({allowMultiple:true}).modal( 'show' ); return false;" data-inverted="" data-position="bottom right" href="#" aria-label="<?php esc_attr_e( 'Page Settings', 'mainwp' ); ?>" data-tooltip="<?php esc_html_e( 'Page Settings', 'mainwp' ); ?>">
1319 - <i class="cog icon"></i>
1320 - </a>
1677 + <?php if ( $screen && ( ( 'mainwp_tab' === $page ) || isset( $_GET['dashboard'] ) || ( ( 'ManageClients' === $page ) && isset( $_GET['client_id'] ) ) || ( 'CostSummary' === $page ) || ( 'InsightsOverview' === $page ) ) ) : ?>
1678 + <span id="mainwp-header-layout-actions">
1679 + <?php MainWP_Ui_Manage_Widgets_Layout::render_edit_layout( $screen->id ); ?>
1680 + </span>
1321 1681 <?php endif; ?>
1322 - <?php
1323 - // phpcs:enable
1324 - /**
1325 - * Filter: mainwp_header_actions_right
1326 - *
1327 - * Filters the MainWP header element actions.
1328 - *
1329 - * @since 4.0
1330 - */
1331 - $actions = apply_filters( 'mainwp_header_actions_right', '' );
1332 - if ( ! empty( $actions ) ) {
1333 - echo $actions; // phpcs:ignore WordPress.Security.EscapeOutput
1334 - }
1335 - ?>
1336 - <a class="ui button icon" id="mainwp-sites-sidebar" aria-label="<?php esc_attr_e( 'Open sites shortcuts sidebar', 'mainwp' ); ?>" data-inverted="" data-position="bottom right" href="#" data-tooltip="<?php esc_attr_e( 'Quick sites shortcuts', 'mainwp' ); ?>">
1337 - <i class="globe icon"></i>
1338 - </a>
1339 - <div id="mainwp-select-theme-button" class="ui button icon mainwp-selecte-theme-button" aria-label="<?php esc_attr_e( 'Select MainWP theme', 'mainwp' ); ?>" custom-theme="default" data-inverted="" data-position="bottom right" data-tooltip="<?php esc_html_e( 'Select MainWP theme', 'mainwp' ); ?>">
1340 - <i class="palette icon"></i>
1341 - </div>
1342 1682
1683 + <span id="mainwp-header-secondary-actions" class="mainwp-768-hide">
1684 + <?php if ( ( 'mainwp_tab' === $page ) || isset( $_GET['dashboard'] ) || in_array( $page, $sidebar_pages ) ) : // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Recommended ?>
1685 + <a id="mainwp-screen-options-button" class="ui icon button" onclick="jQuery( '#mainwp-overview-screen-options-modal' ).modal({allowMultiple:true}).modal( 'show' ); return false;" data-inverted="" data-position="bottom right" href="#" aria-label="<?php esc_attr_e( 'Page Settings', 'mainwp' ); ?>" data-tooltip="<?php esc_html_e( 'Page Settings', 'mainwp' ); ?>">
1686 + <i class="cog icon"></i>
1687 + </a>
1688 +
1689 + <?php endif; ?>
1690 + <?php
1691 + // phpcs:enable
1692 + /**
1693 + * Filter: mainwp_header_actions_right
1694 + *
1695 + * Filters the MainWP header element actions.
1696 + *
1697 + * @since 4.0
1698 + */
1699 + $actions = apply_filters( 'mainwp_header_actions_right', '' );
1700 + if ( ! empty( $actions ) ) {
1701 + echo $actions; // phpcs:ignore WordPress.Security.EscapeOutput
1702 + }
1703 + ?>
1704 + <a class="ui button icon" id="mainwp-sites-sidebar" aria-label="<?php esc_attr_e( 'Open sites shortcuts sidebar', 'mainwp' ); ?>">
1705 + <i class="globe icon"></i>
1706 + </a>
1707 + <?php if ( 'default-dark' === $custom_theme && empty( $themes_files ) ) : ?>
1708 + <a id="mainwp-select-light-theme-button" class="ui button icon" aria-label="<?php esc_attr_e( 'Select MainWP Light theme', 'mainwp' ); ?>" data-inverted="" data-position="bottom right" data-tooltip="<?php esc_html_e( 'Switch to Light mode', 'mainwp' ); ?>">
1709 + <i class="sun icon"></i>
1710 + </a>
1711 + <?php elseif ( 'default' === $custom_theme && empty( $themes_files ) ) : ?>
1712 + <a id="mainwp-select-dark-theme-button" class="ui button icon" aria-label="<?php esc_attr_e( 'Select MainWP Dark theme', 'mainwp' ); ?>" data-inverted="" data-position="bottom right" data-tooltip="<?php esc_html_e( 'Switch to Dark mode', 'mainwp' ); ?>">
1713 + <i class="moon icon"></i>
1714 + </a>
1715 + <?php else : ?>
1716 + <a id="mainwp-select-theme-button" class="ui button icon mainwp-selecte-theme-button" aria-label="<?php esc_attr_e( 'Select MainWP theme', 'mainwp' ); ?>" custom-theme="default" data-inverted="" data-position="bottom right" data-tooltip="<?php esc_html_e( 'Select MainWP theme', 'mainwp' ); ?>">
1717 + <i class="palette icon"></i>
1718 + </a>
1719 + <?php endif; ?>
1720 + </span>
1721 +
1343 1722 <?php
1344 1723 /**
1345 1724 * After select theme actions.
1346 1725 *
@@ -1346,51 +1725,79 @@
1346 1725 *
1347 1726 * @since 4.5.2
1348 1727 */
1349 1728 do_action( 'mainwp_header_actions_after_select_themes' );
1729 + $show_avar = get_option( 'show_avatars' );
1350 1730 ?>
1351 - <div class="ui icon top left pointing dropdown button" id="mainwp-help-menu-icon-button">
1352 - <i class="ellipsis horizontal icon"></i>
1731 + <div class="ui top right pointing dropdown <?php echo $show_avar ? '' : 'icon button'; ?> mainwp-768-hide" id="mainwp-user-menu-button">
1732 + <?php
1733 + if ( $show_avar ) {
1734 + echo get_avatar(
1735 + $current_user,
1736 + 38,
1737 + 'wavatar',
1738 + esc_html__( 'Settings', 'mainwp' ),
1739 + array(
1740 + 'extra_attr' => 'style="width:38px!important;height:38px!important;"',
1741 + 'class' => 'ui small avatar image',
1742 + )
1743 + );
1744 + } else {
1745 + ?>
1746 + <i class="user icon"></i>
1747 + <?php
1748 + }
1749 + ?>
1353 1750 <div class="menu">
1354 - <a class="item" id="mainwp-wp-admin-menu-item" href="<?php echo esc_url( admin_url( 'admin.php?page=Settings' ) ); ?>" data-inverted="" data-position="bottom right" data-tooltip="<?php esc_attr_e( 'Go to MainWP Settings', 'mainwp' ); ?>">
1355 - <i class="cog icon"></i> <?php esc_html_e( 'Settings', 'mainwp' ); ?></span>
1751 + <a class="item" id="mainwp-settings-menu-item" href="<?php echo esc_url( admin_url( 'admin.php?page=Settings' ) ); ?>">
1752 + <i class="cog grey icon"></i> <?php esc_html_e( 'MainWP Settings', 'mainwp' ); ?>
1356 1753 </a>
1357 - <a class="item" id="mainwp-wp-admin-menu-item" href="<?php echo esc_url( admin_url( 'admin.php?page=ServerInformation' ) ); ?>" data-inverted="" data-position="bottom right" data-tooltip="<?php esc_attr_e( 'Go to MainWP Info', 'mainwp' ); ?>">
1358 - <i class="circle info icon"></i> <?php esc_html_e( 'Info', 'mainwp' ); ?></span>
1754 + <a class="item" id="mainwp-tools-menu-item" href="<?php echo esc_url( admin_url( 'admin.php?page=MainWPTools' ) ); ?>">
1755 + <i class="tools grey icon"></i> <?php esc_html_e( 'MainWP Tools', 'mainwp' ); ?>
1359 1756 </a>
1360 - <a class="item" id="mainwp-wp-admin-menu-item" href="<?php echo esc_url( admin_url( 'index.php' ) ); ?>" data-inverted="" data-position="bottom right" data-tooltip="<?php esc_attr_e( 'Go to WP Admin', 'mainwp' ); ?>">
1361 - <i class="wordpress icon"></i> <?php //phpcs:ignore -- ignore wordpress icon. ?> <?php esc_html_e( 'WP Admin', 'mainwp' ); ?></span>
1757 + <a class="item" id="mainwp-system-info-menu-item" href="<?php echo esc_url( admin_url( 'admin.php?page=ServerInformation' ) ); ?>">
1758 + <i class="circle grey info icon"></i> <?php esc_html_e( 'System Info', 'mainwp' ); ?>
1362 1759 </a>
1363 - <a class="item" href="<?php echo wp_logout_url(); // phpcs:ignore WordPress.Security.EscapeOutput ?>" data-inverted="" data-position="bottom right" data-tooltip="<?php esc_attr_e( 'Log out of your MainWP Dashboard', 'mainwp' ); ?>">
1364 - <i class="sign out icon"></i> <?php esc_html_e( 'Log Out', 'mainwp' ); ?></span>
1760 + <a class="item" id="mainwp-privacy-policy-menu-item" href="<?php echo esc_url( admin_url( 'admin.php?page=PluginPrivacy' ) ); ?>">
1761 + <i class="file contract grey icon"></i> <?php esc_html_e( 'Privacy Policy', 'mainwp' ); ?>
1365 1762 </a>
1366 - <a id="mainwp-help-sidebar" class="item" data-inverted="" data-position="bottom right" href="#" target="_blank" data-tooltip="<?php esc_attr_e( 'Need help?', 'mainwp' ); ?>">
1367 - <i class="life ring icon"></i> <?php esc_html_e( 'Get Support', 'mainwp' ); ?>
1763 + <a id="mainwp-help-sidebar" class="item" href="#" target="_blank">
1764 + <i class="life ring grey icon"></i> <?php esc_html_e( 'Get Help', 'mainwp' ); ?>
1368 1765 </a>
1369 - <a class="item" id="mainwp-community-button" data-inverted="" data-position="bottom right" href="https://managers.mainwp.com/" target="_blank" data-tooltip="<?php esc_attr_e( 'MainWP Community', 'mainwp' ); ?>">
1370 - <i class="discourse icon"></i> <?php esc_html_e( 'Managers Community', 'mainwp' ); ?>
1766 + <div class="ui divider"></div>
1767 + <a class="item" id="mainwp-wp-admin-menu-item" href="<?php echo esc_url( admin_url( 'index.php' ) ); ?>">
1768 + <i class="wordpress grey icon"></i> <?php //phpcs:ignore -- ignore wordpress icon. ?> <?php esc_html_e( 'Go to WP Admin', 'mainwp' ); ?>
1371 1769 </a>
1372 - <a class="item" id="mainwp-account-button" data-inverted="" data-position="bottom right" data-tooltip="<?php esc_attr_e( 'Go to your MainWP Account at MainWP.com', 'mainwp' ); ?>" target="_blank" href="https://mainwp.com/my-account/"> <?php // NOSONAR - noopener - open safe. ?>
1373 - <i class="user icon"></i> <?php esc_html_e( 'My MainWP Account', 'mainwp' ); ?>
1770 + <?php $all_updates = wp_get_update_data(); ?>
1771 + <?php if ( is_array( $all_updates ) && isset( $all_updates['counts']['total'] ) && 0 < $all_updates['counts']['total'] ) : ?>
1772 + <a class="item" id="mainwp-available-updates-menu-item" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Your MainWP Dashboard sites needs your attention. Please check the available updates', 'mainwp' ); ?>" aria-label="<?php esc_attr_e( 'Your MainWP Dashboard sites needs your attention. Please check the available updates', 'mainwp' ); ?>" href="update-core.php">
1773 + <i class="exclamation triangle red icon"></i> <?php esc_html_e( 'Update Dashboard Site', 'mainwp' ); ?>
1374 1774 </a>
1775 + <?php endif; ?>
1776 + <div class="ui divider"></div>
1777 + <a class="item" id="mainwp-community-button" href="https://community.mainwp.com/" target="_blank">
1778 + <i class="discourse grey icon"></i> <?php esc_html_e( 'Managers Community', 'mainwp' ); ?>
1779 + </a>
1780 + <a class="item" id="mainwp-account-button" target="_blank" href="https://mainwp.com/my-account/"> <?php // NOSONAR - noopener - open safe. ?>
1781 + <i class="user grey icon"></i> <?php esc_html_e( 'My MainWP Account', 'mainwp' ); ?>
1782 + </a>
1783 + <div class="ui divider"></div>
1784 + <a class="item" id="mainwp-sign-out-button" href="<?php echo wp_logout_url(); // phpcs:ignore WordPress.Security.EscapeOutput ?>">
1785 + <i class="sign out grey icon"></i> <?php esc_html_e( 'Log Out', 'mainwp' ); ?>
1786 + </a>
1375 1787 </div>
1376 1788 </div>
1789 + <a class="ui icon button" href="javascript:void(0)" id="mainwp-mobile-menu-trigger">
1790 + <i class="bars icon"></i>
1791 + </a>
1792 + <?php $pulse = apply_filters( 'mainwp_screen_options_pulse_control', 1 ); ?>
1793 + <input type="hidden" id="mainwp-screen-options-pulse-control" value="<?php echo esc_attr( $pulse ); ?>">
1377 1794 <script>
1378 1795 jQuery( document ).ready( function( $ ) {
1379 - $( '#mainwp-help-menu-icon-button' ).dropdown();
1796 + $( '#mainwp-user-menu-button' ).dropdown();
1380 1797 } );
1381 1798 </script>
1382 -
1383 1799 <?php
1384 -
1385 - $all_updates = wp_get_update_data();
1386 - if ( is_array( $all_updates ) && isset( $all_updates['counts']['total'] ) && 0 < $all_updates['counts']['total'] ) {
1387 - ?>
1388 - <a id="mainwp-available-dashboard-updates-button" class="ui red icon button" data-inverted="" data-position="bottom right" data-tooltip="<?php esc_attr_e( 'Your MainWP Dashboard sites needs your attention. Please check the available updates', 'mainwp' ); ?>" aria-label="<?php esc_attr_e( 'Your MainWP Dashboard sites needs your attention. Please check the available updates', 'mainwp' ); ?>" href="update-core.php">
1389 - <i class="exclamation triangle icon"></i>
1390 - </a>
1391 - <?php
1392 - }
1393 1800 return ob_get_clean();
1394 1801 }
1395 1802
1396 1803 /**
@@ -1397,9 +1804,9 @@
1397 1804 * Method render_page_navigation()
1398 1805 *
1399 1806 * Render page navigation.
1400 1807 *
1401 - * @param array $subitems [access, active, style].
1808 + * @param array $subitems [access, active, style, target, rel].
1402 1809 * @param null $name_caller Menu Name.
1403 1810 */
1404 1811 public static function render_page_navigation( $subitems = array(), $name_caller = null ) { //phpcs:ignore -- NOSONAR - complex.
1405 1812
@@ -1412,10 +1819,39 @@
1412 1819 */
1413 1820 $subitems = apply_filters( 'mainwp_page_navigation', $subitems, $name_caller );
1414 1821 ?>
1415 1822 <div id="mainwp-page-navigation-wrapper">
1823 + <?php if ( isset( $_GET['dashboard'] ) || isset( $_GET['id'] ) || isset( $_GET['updateid'] ) || isset( $_GET['emailsettingsid'] ) || isset( $_GET['scanid'] ) || isset( $_GET['monitor_wpid'] ) ) : // phpcs:ignore WordPress.Security.NonceVerification ?>
1824 + <?php
1825 + //phpcs:disable WordPress.Security.NonceVerification
1826 + $id = 0;
1827 + if ( isset( $_GET['dashboard'] ) ) {
1828 + $id = intval( $_GET['dashboard'] );
1829 + } elseif ( isset( $_GET['id'] ) ) {
1830 + $id = intval( $_GET['id'] );
1831 + } elseif ( isset( $_GET['updateid'] ) ) {
1832 + $id = intval( $_GET['updateid'] );
1833 + } elseif ( isset( $_GET['emailsettingsid'] ) ) {
1834 + $id = intval( $_GET['emailsettingsid'] );
1835 + } elseif ( isset( $_GET['scanid'] ) ) {
1836 + $id = intval( $_GET['scanid'] );
1837 + } elseif ( isset( $_GET['monitor_wpid'] ) ) {
1838 + $id = intval( $_GET['monitor_wpid'] );
1839 + }
1840 + // phpcs:enable
1841 + $website = MainWP_DB::instance()->get_website_by_id( $id );
1416 1842
1843 + // To avoid error in case of direct access to page with wrong id.
1844 + if ( ! empty( $website ) && ! empty( $website->url ) ) {
1845 + $overview_mshot = static::get_mshots_image_sources( $website->url, 170 );
1846 + ?>
1847 + <img alt="<?php esc_attr_e( 'Website preview', 'mainwp' ); ?>" src="<?php echo esc_url( $overview_mshot['src'] ); ?>" data-mainwp-mshot-src="<?php echo esc_url( $overview_mshot['src'] ); ?>" data-mainwp-mshot-requeue-src="<?php echo esc_url( $overview_mshot['requeue_src'] ); ?>" id="mainwp-site-preview-image">
1848 + <?php
1849 + }
1850 + ?>
1851 + <?php endif; ?>
1417 1852 <div class="ui vertical menu mainwp-page-navigation">
1853 +
1418 1854 <?php
1419 1855
1420 1856 if ( is_array( $subitems ) ) {
1421 1857 foreach ( $subitems as $item ) {
@@ -1441,11 +1877,22 @@
1441 1877 if ( isset( $item['style'] ) ) {
1442 1878 $style = $item['style'];
1443 1879 }
1444 1880
1881 + $target = '';
1882 + if ( isset( $item['target'] ) ) {
1883 + $target = $item['target'];
1884 + }
1885 +
1886 + $rel = '';
1887 + if ( isset( $item['rel'] ) ) {
1888 + $rel = $item['rel'];
1889 + } elseif ( '_blank' === $target ) {
1890 + $rel = 'noopener noreferrer';
1891 + }
1892 +
1445 1893 ?>
1446 -
1447 - <a class="<?php echo esc_attr( $class ); ?> item" style="<?php echo esc_attr( $style ); ?>" href="<?php echo esc_url( $item['href'] ); ?>">
1894 + <a class="<?php echo esc_attr( $class ); ?> item" style="<?php echo esc_attr( $style ); ?>" href="<?php echo esc_url( $item['href'] ); ?>" <?php if ( ! empty( $target ) ) : ?>target="<?php echo esc_attr( $target ); ?>"<?php endif; ?> <?php if ( ! empty( $rel ) ) : ?>rel="<?php echo esc_attr( $rel ); ?>"<?php endif; ?>>
1448 1895 <?php echo isset( $item['before_title'] ) ? $item['before_title'] : ''; ?> <?php echo esc_html( $item['title'] ); ?> <?php echo isset( $item['after_title'] ) ? $item['after_title'] : ''; // phpcs:ignore WordPress.Security.EscapeOutput ?>
1449 1896 </a>
1450 1897 <?php
1451 1898 }
@@ -1458,24 +1905,21 @@
1458 1905 </div>
1459 1906 <?php
1460 1907 $is_site = MainWP_System::is_mainwp_site_page();
1461 1908 if ( $is_site ) {
1462 - ?>
1463 - <div id="mainwp-site-mode-wrap">
1464 - <?php } ?>
1465 -
1466 - <?php
1909 + echo '<div id="mainwp-site-mode-wrap">';
1910 + }
1467 1911 }
1468 1912
1469 - /**
1470 - * Method render_header()
1471 - *
1472 - * Render page title.
1473 - *
1474 - * @param string $title Page title.
1475 - *
1476 - * @return void Render page title and hidden divider html.
1477 - */
1913 + /**
1914 + * Method render_header()
1915 + *
1916 + * Render page title.
1917 + *
1918 + * @param string $title Page title.
1919 + *
1920 + * @return void Render page title and hidden divider html.
1921 + */
1478 1922 public static function render_header( $title = '' ) {
1479 1923 static::render_top_header( array( 'title' => $title ) );
1480 1924 echo '<div class="ui hidden clearing fitted divider"></div>';
1481 1925 echo '<div class="wrap">';
@@ -1554,14 +1998,40 @@
1554 1998 $page = MainWP_System_Utility::get_page_id( $screen_id );
1555 1999 if ( empty( $page ) ) {
1556 2000 return;
1557 2001 }
1558 - $wgsorted = get_user_option( 'mainwp_widgets_sorted_' . strtolower( $page ) );
1559 2002
2003 + $page_widget = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
2004 +
2005 + $wgsorted = false;
2006 + $selected_widget_layout = '';
2007 +
2008 + if ( ! empty( $_GET['page'] ) && ! empty( $_GET['select_layout'] ) && ! empty( $_GET['_opennonce'] ) && wp_verify_nonce( sanitize_key( $_GET['_opennonce'] ), 'mainwp-admin-nonce' ) && ! empty( $_GET['updated'] ) && ! empty( $_GET['screen_slug'] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
2009 + $layid = sanitize_text_field( wp_unslash( $_GET['updated'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
2010 + $screen_slug = sanitize_text_field( wp_unslash( $_GET['screen_slug'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
2011 +
2012 + $saved_layouts = MainWP_Ui_Manage_Widgets_Layout::set_get_widgets_layout( false, array(), $screen_slug );
2013 + $selected_layout = is_array( $saved_layouts ) && isset( $saved_layouts[ $layid ] ) ? $saved_layouts[ $layid ] : array();
2014 + if ( is_array( $selected_layout ) && isset( $selected_layout['layout'] ) ) {
2015 + $wgsorted = $selected_layout['layout'];
2016 + if ( isset( $selected_layout['name'] ) ) {
2017 + $selected_widget_layout = $selected_layout['name'];
2018 + }
2019 + }
2020 + }
2021 +
2022 + if ( empty( $wgsorted ) ) {
2023 + $wgsorted = get_user_option( 'mainwp_widgets_sorted_' . $page );
2024 + }
2025 +
1560 2026 if ( ! empty( $wgsorted ) && is_string( $wgsorted ) ) {
1561 2027 $wgsorted = json_decode( $wgsorted, true );
1562 2028 }
1563 2029
2030 + if ( ! is_array( $wgsorted ) ) {
2031 + $wgsorted = array();
2032 + }
2033 +
1564 2034 $client_id = 0;
1565 2035 if ( 'mainwp_page_manageclients' === $page ) {
1566 2036 $sorted_array = is_array( $wgsorted ) ? $wgsorted : array();
1567 2037 $wgsorted = array();
@@ -1572,12 +2042,8 @@
1572 2042 }
1573 2043
1574 2044 $wgsorted = apply_filters( 'mainwp_do_widget_boxes_sorted', $wgsorted, $page, $client_id );
1575 2045
1576 - if ( ! is_array( $wgsorted ) ) {
1577 - $wgsorted = array();
1578 - }
1579 -
1580 2046 if ( 'mainwp_page_manageclients' === $page ) {
1581 2047 $show_widgets = get_user_option( 'mainwp_clients_show_widgets' );
1582 2048 } elseif ( 'toplevel_page_mainwp_tab' === $page || 'mainwp_page_managesites' === $page ) {
1583 2049 $show_widgets = get_user_option( 'mainwp_settings_show_widgets' );
@@ -1588,8 +2054,17 @@
1588 2054 if ( ! is_array( $show_widgets ) ) {
1589 2055 $show_widgets = array();
1590 2056 }
1591 2057
2058 + if ( $selected_widget_layout ) {
2059 + // to support saving selected layout.
2060 + ?>
2061 + <input type="hidden" id="mainwp-widgets-selected-layout" layout-name="<?php echo esc_attr( $selected_layout['name'] ); ?>" layout-idx="<?php echo esc_attr( $layid ); ?>" data-save-on-load="true" >
2062 + <?php
2063 + }
2064 + ?>
2065 + <div id="mainwp-grid-stack-wrapper" class="grid-stack">
2066 + <?php
1592 2067 if ( isset( $mainwp_widget_boxes[ $page ] ) ) {
1593 2068 foreach ( (array) $mainwp_widget_boxes[ $page ] as $box ) {
1594 2069 if ( false === $box || ! isset( $box['callback'] ) ) {
1595 2070 continue;
@@ -1602,105 +2077,153 @@
1602 2077
1603 2078 $layout = array();
1604 2079 if ( isset( $wgsorted[ $box['id'] ] ) ) {
1605 2080 $val = $wgsorted[ $box['id'] ];
1606 - if ( is_array( $val ) && isset( $val['col'] ) ) {
2081 + if ( is_array( $val ) && ( isset( $val['x'] ) || isset( $val['w'] ) ) ) {
1607 2082 $layout = array(
1608 - 'col' => $val['col'],
1609 - 'row' => $val['row'],
1610 - 'size_x' => $val['size_x'],
1611 - 'size_y' => $val['size_y'],
2083 + 'x' => $val['x'],
2084 + 'y' => $val['y'],
2085 + 'w' => $val['w'],
2086 + 'h' => $val['h'],
1612 2087 );
1613 2088 }
1614 2089 }
1615 - if ( ! isset( $layout['col'] ) && isset( $box['layout'][0] ) ) {
2090 +
2091 + // init widget layout settings.
2092 + if ( ! isset( $layout['x'] ) && ! isset( $layout['w'] ) && isset( $box['layout']['2'] ) ) {
1616 2093 $layout = array(
1617 - 'col' => $box['layout'][0],
1618 - 'row' => $box['layout'][1],
1619 - 'size_x' => $box['layout'][2],
1620 - 'size_y' => $box['layout'][3],
2094 + 'x' => $box['layout']['0'],
2095 + 'y' => $box['layout']['1'],
2096 + 'w' => $box['layout']['2'],
2097 + 'h' => $box['layout']['3'],
1621 2098 );
1622 2099 }
1623 - $layout_attrs_escaped = ' data-row="' . ( isset( $layout['row'] ) ? esc_attr( $layout['row'] ) : '' ) . '" data-col="' . ( isset( $layout['col'] ) ? esc_attr( $layout['col'] ) : '' ) . '" data-sizex="' . ( isset( $layout['size_x'] ) ? esc_attr( $layout['size_x'] ) : '' ) . '" data-sizey="' . ( isset( $layout['size_y'] ) ? esc_attr( $layout['size_y'] ) : '' ) . '" ';
1624 - echo '<div id="widget-' . esc_html( $box['id'] ) . '" class="ui segment mainwp-widget" ' . $layout_attrs_escaped . '>' . "\n"; //phpcs:ignore -- escaped.
1625 - call_user_func( $box['callback'], $screen_id, $args );
1626 - echo '<span class="mainwp-resize-handle"></span>' . "\n";
2100 +
2101 + $layout_attrs_escaped = '';
2102 + if ( isset( $layout['x'] ) && (int) $layout['x'] >= 0 ) {
2103 + $layout_attrs_escaped .= ' gs-x="' . esc_attr( $layout['x'] ) . '"';
2104 + }
2105 + if ( isset( $layout['y'] ) && (int) $layout['y'] >= 0 ) {
2106 + $layout_attrs_escaped .= ' gs-y="' . esc_attr( $layout['y'] ) . '"';
2107 + }
2108 + if ( isset( $layout['w'] ) && (int) $layout['w'] > 0 ) {
2109 + $layout_attrs_escaped .= ' gs-w="' . esc_attr( $layout['w'] ) . '"';
2110 + }
2111 + if ( isset( $layout['h'] ) && (int) $layout['h'] > 0 ) {
2112 + $layout_attrs_escaped .= ' gs-h="' . esc_attr( $layout['h'] ) . '"';
2113 + }
2114 +
2115 + echo '<div id="widget-' . esc_html( $box['id'] ) . '" class="grid-stack-item" ' . $layout_attrs_escaped . '>' . "\n"; //phpcs:ignore -- escaped.
2116 + echo '<div class="grid-stack-item-content ui segment mainwp-widget">' . "\n";
2117 + call_user_func( $box['callback'], $screen_id, $args );
2118 + echo "</div>\n";
1627 2119 echo "</div>\n";
1628 2120
1629 2121 }
1630 2122 }
1631 - $breakpoint = apply_filters( 'mainwp_flexible_widgets_breakpoint', 1367 );
1632 2123 ?>
2124 + </div>
1633 2125 <script type="text/javascript">
1634 - let is_mobile = false;
1635 - if( jQuery( window ).width() < <?php echo intval( $breakpoint ); ?> ) {
1636 - is_mobile = true;
1637 - }
1638 - console.log('mobile: ' + is_mobile);
1639 -
1640 - if ( ! is_mobile ) {
1641 2126 let page_sortablewidgets = '<?php echo esc_js( $page ); ?>';
2127 + let page_widget = '<?php echo esc_js( $page_widget ); ?>';
1642 2128 jQuery( document ).ready( function( $ ) {
1643 - let wgIds = [];
1644 - jQuery( ".mainwp-widget" ).each( function () {
1645 - wgIds.push( jQuery( this ).attr('id') );
1646 - } );
2129 + let wgIds = [];
2130 + jQuery( ".mainwp-widget" ).each( function () {
2131 + wgIds.push( jQuery( this ).attr('id') );
2132 + } );
2133 + let gsOpts = {
2134 + auto: true,
2135 + cellHeight: '1rem',
2136 + float: false,
2137 + resizable: {
2138 + handles: 'e,se,s,sw,w'
2139 + },
2140 + margin: '1rem',
2141 + itemClass: 'grid-stack-item',
2142 + handleClass: 'handle-drag',
2143 + columnOpts: {
2144 + breakpointForWindow: true, // test window vs grid size
2145 + breakpoints: [{w:768, c:1}],
2146 + },
2147 + }
2148 + let grid = GridStack.init(gsOpts);
1647 2149
1648 - let $mainwp_gridster = jQuery( '.gridster' ).gridster( {
1649 - auto_init: true,
1650 - autogenerate_stylesheet: true,
1651 - shift_larger_widgets_down: false,
1652 - shift_widgets_up: true,
1653 - widget_selector: "div.mainwp-widget",
1654 - widget_margins: [20, 20],
1655 - widget_base_dimensions: ["auto", 20],
1656 - min_cols: 1,
1657 - max_cols: 12,
1658 - max_size_x: 12,
1659 - max_rows: 500,
1660 - avoid_overlapped_widgets: true,
1661 - collision: {
1662 - wait_for_mouseup: true
1663 - },
1664 - draggable: {
1665 - handle: '.handle-drag',
1666 - stop: function (e, ui, $widget) {
1667 - mainwp_overview_gridster_reorder(this);
1668 - }
1669 - },
1670 - resize: {
1671 - enabled: true,
1672 - handle_append_to: ".mainwp-resize-handle",
1673 - stop: function (e, ui, $widget) {
1674 - mainwp_overview_gridster_reorder(this);
1675 - }
1676 - }
1677 - } ).data('gridster');
2150 + grid.on('change', function() {
2151 + mainwp_overview_gridstack_save_layout(<?php echo (int) $client_id; ?>, grid);
2152 + });
1678 2153
1679 - mainwp_overview_gridster_reorder = function( $gridObj ){
1680 - let orders = $gridObj.serialize();
1681 - let postVars = {
1682 - action:'mainwp_widgets_order',
1683 - page: page_sortablewidgets,
1684 - order:JSON.stringify(orders),
1685 - wgids: JSON.stringify(wgIds),
1686 - item_id: <?php echo intval( $client_id ); ?>
1687 - };
1688 - jQuery.post( ajaxurl, mainwp_secure_data( postVars ), function ( res ) {
1689 - } );
1690 - }
1691 - });
2154 + if (jQuery('#mainwp-widgets-selected-layout[data-save-on-load="true"]').length) {
2155 + mainwp_overview_gridstack_save_layout(<?php echo (int) $client_id; ?>, grid);
2156 + }
1692 2157
1693 - }
2158 + jQuery('#mainwp-widgets-placeholder').dimmer('hide');
2159 + });
1694 2160 </script>
1695 - <?php
2161 + <?php
1696 2162 }
1697 2163
1698 - /**
1699 - * Method render_empty_bulk_actions()
1700 - *
1701 - * Render empty bulk actions when drop down is disabled.
1702 - */
2164 + /**
2165 + * Method add_bulkpost_widget_box()
2166 + *
2167 + * @param mixed $boxid box id.
2168 + * @param mixed $params parameters.
2169 + */
2170 + public static function add_bulkpost_widget_box( $boxid, $params ) {
2171 + /**
2172 + * MainWP widget boxes array.
2173 + *
2174 + * @global object
2175 + */
2176 + global $wp_meta_boxes;
2177 +
2178 + $screen_page_id = MainWP_System_Utility::get_page_id();
2179 +
2180 + if ( empty( $screen_page_id ) ) {
2181 + return;
2182 + }
2183 +
2184 + if ( ! is_array( $params ) ) {
2185 + $params = array();
2186 + }
2187 +
2188 + if ( ! isset( $wp_meta_boxes ) ) {
2189 + $wp_meta_boxes = array(); //phpcs:ignore -- NOSONAR - ok.
2190 + }
2191 +
2192 + $page = MainWP_Post::get_fix_metabox_page( $screen_page_id );
2193 +
2194 + if ( ! isset( $wp_meta_boxes[ $page ] ) ) {
2195 + $wp_meta_boxes[ $page ] = array(); //phpcs:ignore -- NOSONAR - ok.
2196 + }
2197 +
2198 + $context = ! empty( $params['context'] ) ? $params['context'] : 'normal';
2199 + $priority = ! empty( $params['priority'] ) ? $params['priority'] : 'default';
2200 +
2201 + if ( ! isset( $wp_meta_boxes[ $page ][ $context ] ) ) {
2202 + $wp_meta_boxes[ $page ][ $context ] = array(); //phpcs:ignore -- NOSONAR - ok.
2203 + }
2204 +
2205 + if ( ! isset( $wp_meta_boxes[ $page ][ $context ][ $priority ] ) ) {
2206 + $wp_meta_boxes[ $page ][ $context ][ $priority ] = array(); //phpcs:ignore -- NOSONAR - ok.
2207 + }
2208 +
2209 + if ( ! empty( $params['id'] ) ) {
2210 + $params['id'] = 'bulkpost-metabox-' . $params['id'];
2211 + } else {
2212 + $params['id'] = '';
2213 + }
2214 +
2215 + if ( empty( $params['metabox-custom'] ) ) {
2216 + $params['metabox-custom'] = 'bulkpost';
2217 + }
2218 + $wp_meta_boxes[ $page ][ $context ][ $priority ][ $boxid ] = $params; //phpcs:ignore -- NOSONAR - ok.
2219 + }
2220 +
2221 + /**
2222 + * Method render_empty_bulk_actions()
2223 + *
2224 + * Render empty bulk actions when drop down is disabled.
2225 + */
1703 2226 public static function render_empty_bulk_actions() {
1704 2227 ?>
1705 2228 <select class="ui disabled dropdown" id="mainwp-bulk-actions">
1706 2229 <option value=""><?php esc_html_e( 'Bulk Actions', 'mainwp' ); ?></option>
@@ -1718,9 +2241,9 @@
1718 2241 */
1719 2242 public static function render_modal_install_plugin_theme( $what = 'plugin' ) {
1720 2243 ?>
1721 2244 <div id="plugintheme-installation-progress-modal" class="ui modal">
1722 - <i class="close icon"></i>
2245 + <i class="close icon"></i>
1723 2246 <div class="header">
1724 2247 <?php
1725 2248 if ( 'plugin' === $what ) {
1726 2249 esc_html_e( 'Plugin Installation', 'mainwp' );
@@ -1766,9 +2289,9 @@
1766 2289 * @since 4.1
1767 2290 */
1768 2291 do_action( 'mainwp_install_plugin_theme_modal_action', $what );
1769 2292 ?>
1770 - <div class="ui cancel button"><?php esc_html_e( 'Close', 'mainwp' ); ?></div>
2293 +
1771 2294 </div>
1772 2295 </div>
1773 2296 <?php
1774 2297 }
@@ -1789,9 +2312,9 @@
1789 2312 ?>
1790 2313 </div>
1791 2314 <div class="content" id="mainwp-upload-custom-icon-content">
1792 2315 <form action="" method="post" enctype="multipart/form-data" name="uploadicon_form" id="uploadicon_form" class="">
1793 - <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
2316 + <?php self::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
1794 2317 <div class="ui message" id="mainwp-message-zone-upload" style="display:none;"></div>
1795 2318 <?php
1796 2319 /**
1797 2320 * Action: mainwp_after_upload_custom_icon
@@ -1840,18 +2363,18 @@
1840 2363 </div>
1841 2364 <?php
1842 2365 }
1843 2366
1844 - /**
1845 - * Method render_show_all_updates_button()
1846 - *
1847 - * Render show all updates button.
1848 - *
1849 - * @return void Render Show All Updates button html.
1850 - */
2367 + /**
2368 + * Method render_show_all_updates_button()
2369 + *
2370 + * Render show all updates button.
2371 + *
2372 + * @return void Render Show All Updates button html.
2373 + */
1851 2374 public static function render_show_all_updates_button() {
1852 2375 ?>
1853 - <a href="javascript:void(0)" class="ui mini button trigger-all-accordion">
2376 + <a href="javascript:void(0)" class="ui mini button trigger-all-accordion mainwp-show-all-updates-button">
1854 2377 <?php
1855 2378 /**
1856 2379 * Filter: mainwp_show_all_updates_button_text
1857 2380 *
@@ -1889,8 +2412,9 @@
1889 2412 */
1890 2413 public static function render_modal_edit_notes( $what = 'site' ) {
1891 2414 ?>
1892 2415 <div id="mainwp-notes-modal" class="ui modal">
2416 + <i class="close icon" id="mainwp-notes-cancel"></i>
1893 2417 <div class="header"><?php esc_html_e( 'Notes', 'mainwp' ); ?></div>
1894 2418 <div class="content" id="mainwp-notes-content">
1895 2419 <div id="mainwp-notes-status" class="ui message hidden"></div>
1896 2420 <?php
@@ -1928,9 +2452,8 @@
1928 2452 <input type="button" class="ui green button" id="mainwp-notes-save" value="<?php esc_attr_e( 'Save Note', 'mainwp' ); ?>" style="display:none;"/>
1929 2453 <input type="button" class="ui green button" id="mainwp-notes-edit" value="<?php esc_attr_e( 'Edit Note', 'mainwp' ); ?>"/>
1930 2454 </div>
1931 2455 <div class="eight wide column">
1932 - <input type="button" class="ui button" id="mainwp-notes-cancel" value="<?php esc_attr_e( 'Close', 'mainwp' ); ?>"/>
1933 2456 <input type="hidden" id="mainwp-notes-websiteid" value=""/>
1934 2457 <input type="hidden" id="mainwp-notes-slug" value=""/>
1935 2458 <input type="hidden" id="mainwp-which-note" value="<?php echo esc_html( $what ); ?>"/>
1936 2459 <input type="hidden" id="mainwp-notes-itemid" value=""/>
@@ -1959,14 +2482,14 @@
1959 2482 <div class="ui hidden divider"></div>
1960 2483 <div class="ui hidden divider"></div>
1961 2484 <a href="admin.php?page=managesites&do=new" class="ui big green button"><?php esc_html_e( 'Connect Your WordPress Site', 'mainwp' ); ?></a>
1962 2485 <div class="ui hidden fitted divider"></div>
1963 - <small><?php printf( esc_html__( 'or you can %1$sbulk import%2$s your sites.', 'mainwp' ), '<a href="admin.php?page=managesites&do=bulknew">', '</a>' ); ?></small>
2486 + <small><?php /* translators: 1: Opening anchor tag for bulk import link, 2: Closing anchor tag. */ printf( esc_html__( 'or you can %1$sbulk import%2$s your sites.', 'mainwp' ), '<a href="admin.php?page=managesites&do=bulknew">', '</a>' ); ?></small>
1964 2487 </div>
1965 2488 <div class="actions">
1966 2489 <div class="ui grid">
1967 2490 <div class="eight wide left aligned middle aligned column">
1968 - <a href="https://kb.mainwp.com/docs/add-site-to-your-dashboard/" class="ui basic green mini button" target="_blank"><?php esc_html_e( 'See How to Connect Sites', 'mainwp' ); // NOSONAR - noopener - open safe. ?></a>
2491 + <a href="https://docs.mainwp.com/getting-started/get-started-with-mainwp" class="ui basic green mini button" target="_blank"><?php esc_html_e( 'See How to Connect Sites', 'mainwp' ); // NOSONAR - noopener - open safe. ?></a>
1969 2492 </div>
1970 2493 <div class="eight wide column">
1971 2494 <input type="button" class="ui mini basic cancel button mainwp-notice-dismiss" notice-id="mainwp-no-sites-modal-notice" value="<?php esc_attr_e( 'Let Me Look Around', 'mainwp' ); ?>"/>
1972 2495 </div>
@@ -1984,13 +2507,411 @@
1984 2507 endif;
1985 2508 }
1986 2509
1987 2510 /**
2511 + * Help Modal
2512 + *
2513 + * Renders the help modal.
2514 + *
2515 + * @return void
2516 + */
2517 + public static function render_help_modal() { //phpcs:ignore -- NOSONAR - complex.
2518 + $siteViewMode = MainWP_Utility::get_siteview_mode();
2519 +
2520 + // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized.Recommended
2521 + $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
2522 +
2523 + $tour_id = '';
2524 + $video_id = '';
2525 + if ( 'mainwp_tab' === $page ) {
2526 + $tour_id = '13112';
2527 + $video_id = 'VZeUhuihddw';
2528 + } elseif ( 'managesites' === $page ) {
2529 + if ( isset( $_GET['do'] ) && 'new' === $_GET['do'] ) {
2530 + $tour_id = '13210';
2531 + $video_id = 'k1-4x6h0LfE';
2532 + } elseif ( isset( $_GET['do'] ) && 'bulknew' === $_GET['do'] ) {
2533 + $tour_id = '60206';
2534 + } elseif ( ! isset( $_GET['dashboard'] ) && ! isset( $_GET['id'] ) && ! isset( $_GET['updateid'] ) && ! isset( $_GET['emailsettingsid'] ) && ! isset( $_GET['scanid'] ) ) {
2535 + if ( 'grid' === $siteViewMode ) {
2536 + $tour_id = '27217';
2537 + } else {
2538 + $tour_id = '29331';
2539 + }
2540 + }
2541 + } elseif ( 'MonitoringSites' === $page ) {
2542 + $tour_id = '29003';
2543 + } elseif ( 'ManageClients' === $page ) {
2544 + if ( isset( $_GET['client_id'] ) ) {
2545 + $tour_id = '28258';
2546 + } else {
2547 + $tour_id = '28240';
2548 + }
2549 + } elseif ( 'ClientAddNew' === $page ) {
2550 + if ( isset( $_GET['client_id'] ) ) {
2551 + $tour_id = '28962';
2552 + } else {
2553 + $tour_id = '28256';
2554 + }
2555 + $video_id = '8Th7bSZAHjw';
2556 + } elseif ( 'ClientAddField' === $page ) {
2557 + $tour_id = '28257';
2558 + } elseif ( 'PluginsManage' === $page ) {
2559 + $tour_id = '28510';
2560 + $video_id = 'p0pB7mXoIYw';
2561 + } elseif ( 'ManageGroups' === $page ) {
2562 + $tour_id = '27275';
2563 + } elseif ( 'UpdatesManage' === $page ) {
2564 + $video_id = 'igOn8wOBcAQ';
2565 + $tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
2566 + if ( 'plugins-updates' === $tab ) {
2567 + $tour_id = '28259';
2568 + } elseif ( 'themes-updates' === $tab ) {
2569 + $tour_id = '28447';
2570 + } elseif ( 'wordpress-updates' === $tab ) {
2571 + $tour_id = '29005';
2572 + } elseif ( 'translations-updates' === $tab ) {
2573 + $tour_id = '29007';
2574 + } elseif ( 'abandoned-plugins' === $tab ) {
2575 + $tour_id = '29008';
2576 + } elseif ( 'abandoned-themes' === $tab ) {
2577 + $tour_id = '29009';
2578 + } elseif ( 'plugin-db-updates' === $tab ) {
2579 + $tour_id = '33161';
2580 + } else {
2581 + $tour_id = '28259';
2582 + }
2583 + } elseif ( 'PluginsInstall' === $page ) {
2584 + $tour_id = '29011';
2585 + } elseif ( 'PluginsAutoUpdate' === $page ) {
2586 + $tour_id = '29015';
2587 + } elseif ( 'PluginsIgnore' === $page ) {
2588 + $tour_id = '29018';
2589 + } elseif ( 'PluginsIgnoredAbandoned' === $page ) {
2590 + $tour_id = '29329';
2591 + } elseif ( 'ThemesManage' === $page ) {
2592 + $tour_id = '28511';
2593 + $video_id = 'fWYBTWNL9gw';
2594 + } elseif ( 'ThemesInstall' === $page ) {
2595 + $tour_id = '29010';
2596 + } elseif ( 'ThemesAutoUpdate' === $page ) {
2597 + $tour_id = '29016';
2598 + } elseif ( 'ThemesIgnore' === $page ) {
2599 + $tour_id = '29019';
2600 + } elseif ( 'ThemesIgnoredAbandoned' === $page ) {
2601 + $tour_id = '29330';
2602 + } elseif ( 'UserBulkManage' === $page ) {
2603 + $tour_id = '28574';
2604 + $video_id = 'lvzpE04nsTs';
2605 + } elseif ( 'UserBulkAdd' === $page ) {
2606 + $tour_id = '28575';
2607 + } elseif ( 'BulkImportUsers' === $page ) {
2608 + $tour_id = '28736';
2609 + } elseif ( 'UpdateAdminPasswords' === $page ) {
2610 + $tour_id = '28737';
2611 + } elseif ( 'PostBulkManage' === $page ) {
2612 + $tour_id = '28796';
2613 + $video_id = 'Z81gzO16K8o';
2614 + } elseif ( 'PostBulkAdd' === $page ) {
2615 + $tour_id = '28799';
2616 + } elseif ( 'PageBulkManage' === $page ) {
2617 + $tour_id = '29045';
2618 + $video_id = 'O4jG-GRHE2Q';
2619 + } elseif ( 'PageBulkAdd' === $page ) {
2620 + $tour_id = '29048';
2621 + } elseif ( 'Extensions' === $page ) {
2622 + $tour_id = '28800';
2623 + $video_id = 'FMkXqpRu6-E';
2624 + } elseif ( 'Settings' === $page ) {
2625 + $tour_id = '28883';
2626 + } elseif ( 'SettingsAdvanced' === $page ) {
2627 + $tour_id = '28886';
2628 + } elseif ( 'SettingsEmail' === $page ) {
2629 + $tour_id = '29054';
2630 + } elseif ( 'MainWPTools' === $page ) {
2631 + $tour_id = '29272';
2632 + } elseif ( 'RESTAPI' === $page ) {
2633 + $tour_id = '29273';
2634 + $video_id = 'BO-u1FlptY0';
2635 + } elseif ( 'ServerInformation' === $page ) {
2636 + $tour_id = '28873';
2637 + } elseif ( 'ServerInformationCron' === $page ) {
2638 + $tour_id = '28874';
2639 + } elseif ( 'ErrorLog' === $page ) {
2640 + $tour_id = '28876';
2641 + } elseif ( 'ActionLogs' === $page ) {
2642 + $tour_id = '28877';
2643 + } elseif ( 'ManageCostTracker' === $page ) {
2644 + $video_id = 'Q1aVVGpkJAQ';
2645 + } elseif ( 'CostTrackerAdd' === $page ) {
2646 + $video_id = 'Q1aVVGpkJAQ';
2647 + } elseif ( 'Extensions-Mainwp-Jetpack-Protect-Extension' === $page ) {
2648 + $tour_id = '31700';
2649 + } elseif ( 'Extensions-Mainwp-Jetpack-Scan-Extension' === $page ) {
2650 + $tour_id = '31694';
2651 + } elseif ( 'Extensions-Termageddon-For-Mainwp' === $page ) {
2652 + $tour_id = '32104';
2653 + $video_id = 'HAHySipH22I';
2654 + } elseif ( 'Extensions-Advanced-Uptime-Monitor-Extension' === $page ) {
2655 + $tour_id = '32149';
2656 + $video_id = '3PIsyNM3OM0';
2657 + } elseif ( 'Extensions-Mainwp-Custom-Dashboard-Extension' === $page ) {
2658 + $tour_id = '32150';
2659 + $video_id = 'T6jzvD3ogfw';
2660 + } elseif ( 'Extensions-Mainwp-Updraftplus-Extension' === $page ) {
2661 + $tour_id = '32151';
2662 + } elseif ( 'Extensions-Mainwp-Sucuri-Extension' === $page ) {
2663 + $tour_id = '32152';
2664 + $video_id = 'bykz9YabuA8';
2665 + } elseif ( 'Extensions-Mainwp-Clean-And-Lock-Extension' === $page ) {
2666 + $tour_id = '32153';
2667 + $video_id = 'uCCDiPbqXUc';
2668 + } elseif ( 'Extensions-Mainwp-Woocommerce-Shortcuts-Extension' === $page ) {
2669 + $tour_id = '32851';
2670 + } elseif ( 'Extensions-Mainwp-Buddy-Extension' === $page ) {
2671 + $tour_id = '33064';
2672 + } elseif ( 'Extensions-Mainwp-Backwpup-Extension' === $page ) {
2673 + $tour_id = '32923';
2674 + } elseif ( 'Extensions-Mainwp-Ssl-Monitor-Extension' === $page ) {
2675 + $tour_id = '33164';
2676 + $video_id = 'HYb9xZ7Lxe0';
2677 + } elseif ( 'Extensions-Mainwp-Cache-Control-Extension' === $page ) {
2678 + $tour_id = '33167';
2679 + } elseif ( 'Extensions-Mainwp-Maintenance-Extension' === $page ) {
2680 + $tour_id = '33301';
2681 + } elseif ( 'Extensions-Mainwp-Domain-Monitor-Extension' === $page ) {
2682 + $tour_id = '66031';
2683 + $video_id = 'QMziJ1BxEcE';
2684 + } elseif ( 'Extensions-Mainwp-Favorites-Extension' === $page ) {
2685 + $tour_id = '66035';
2686 + $video_id = 'JRn7SLC4028';
2687 + } elseif ( 'Extensions-Mainwp-Regression-Testing-Extension' === $page ) {
2688 + $tour_id = '66037';
2689 + $video_id = 'rrynCqVxKSw';
2690 + } elseif ( 'Extension-Mainwp-Google-Analytics-Extension' === $page ) {
2691 + $video_id = 'BV0xTftH7as';
2692 + } elseif ( 'Extensions-Mainwp-Code-Snippets-Extension' === $page ) {
2693 + $video_id = 'Bl7rJzGmNU0';
2694 + } elseif ( 'Extensions-Mainwp-Article-Uploader-Extension' === $page ) {
2695 + $video_id = 'e8WoikPFyB0';
2696 + } elseif ( 'Extensions-Mainwp-Branding-Extension' === $page ) {
2697 + $video_id = 'kWvEVIpPEss';
2698 + } elseif ( 'Extensions-Mainwp-Time-Tracker-Extension' === $page ) {
2699 + $video_id = 'nvsKRp_rtiA';
2700 + } elseif ( 'Extensions-Mainwp-Comments-Extension' === $page ) {
2701 + $video_id = 'tCSX3z1KOOg';
2702 + } elseif ( 'Extensions-Mainwp-Lighthouse-Extension' === $page ) {
2703 + $video_id = 'GNYKJsoJso8';
2704 + } elseif ( 'Extensions-Mainwp-Rocket-Extension' === $page ) {
2705 + $video_id = 'qahq6cR7Svo';
2706 + }
2707 +
2708 + $enable_guided_tours = get_option( 'mainwp_enable_guided_tours', 0 );
2709 + $enable_guided_chatbase = get_option( 'mainwp_enable_guided_chatbase', 0 );
2710 + $enable_guided_video = get_option( 'mainwp_enable_guided_video', 0 );
2711 +
2712 + ?>
2713 + <div id="mainwp-help-modal" class="ui modal">
2714 + <i class="close icon"></i>
2715 + <div class="header"><?php esc_html_e( 'Support', 'mainwp' ); ?></div>
2716 +
2717 + <div class="scrolling center aligned content" id="mainwp-help-modal-content">
2718 + <div class="ui two cards" id="mainwp-help-modal-options">
2719 +
2720 + <div class="ui secondary card">
2721 + <div class="content">
2722 + <a id="mainwp-start-chat-card" class="<?php echo $enable_guided_chatbase ? '' : 'mainwp-disabled-link'; ?>" onclick="jQuery('#mainwp-update-permissions-button').fadeOut(200);jQuery('#mainwp-help-back-button').fadeIn(200);mainwp_help_modal_start_content_onclick( false, false, true );return false;">
2723 + <div class="header"><?php esc_html_e( 'Support Assistant', 'mainwp' ); ?></div>
2724 + <div class="ui hidden divider"></div>
2725 + <i class="robot big grey icon" style="opacity:0.5"></i>
2726 + <div class="ui fitted hidden divider"></div><br/>
2727 + <span class="ui grey small text"><?php esc_html_e( 'Chat with our AI Support Assistant for quick guidance and troubleshooting. It\'s trained on MainWP documentation to help you find answers faster.', 'mainwp' ); ?> <span class="ui mini green label">BETA</span></span>
2728 + </a>
2729 + </div>
2730 + <div class="content">
2731 + <div class="ui tiny left aligned list">
2732 + <div class="item" style="padding:0 0 0.21428571em 0;">
2733 + <i class="times red icon"></i> <div class="content"><?php esc_html_e( 'Access to your Database', 'mainwp' ); ?></div>
2734 + </div>
2735 + <div class="item" style="padding:0.21428571em 0;">
2736 + <i class="times red icon"></i> <div class="content"><?php esc_html_e( 'Access to your Screeen', 'mainwp' ); ?></div>
2737 + </div>
2738 + <div class="item" style="padding:0 0 0 0.21428571em;">
2739 + <i class="check green icon"></i> <div class="content"><?php esc_html_e( 'Processes only information you submit', 'mainwp' ); ?></div>
2740 + </div>
2741 + </div>
2742 + </div>
2743 + <div class="left aligned extra content">
2744 + <div class="ui toggle checkbox" id="mainwp-guided-chatbase-check">
2745 + <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"' : ''; ?> />
2746 + <label><?php esc_html_e( 'Turn On / Turn Off', 'mainwp' ); ?></label>
2747 + </div>
2748 + </div>
2749 + </div>
2750 +
2751 + <div class="ui card">
2752 + <div class="content">
2753 + <a id="mainwp-start-tour-card" class="<?php echo $enable_guided_tours ? '' : 'mainwp-disabled-link'; ?>" onclick="jQuery('#mainwp-help-modal').modal('hide');mainwp_help_modal_start_content_onclick( <?php echo (int) $tour_id; ?> );" >
2754 + <div class="header"><?php esc_html_e( 'Take a Quick Tour', 'mainwp' ); ?></div>
2755 + <div class="ui hidden divider"></div>
2756 + <i class="map marked alternate big grey icon" style="opacity:0.5"></i>
2757 + <div class="ui fitted hidden divider"></div><br/>
2758 + <span class="ui grey small text"><?php esc_html_e( 'Learn how to navigate and use key features with an interactive step-by-step tour.', 'mainwp' ); ?></span>
2759 + </a>
2760 + <div class="ui mini green label"><?php esc_html_e( 'Recommended for first-time users.', 'mainwp' ); ?></div>
2761 + </div>
2762 + <div class="content">
2763 + <div class="ui tiny left aligned list">
2764 + <div class="item" style="padding:0 0 0.21428571em 0;">
2765 + <i class="times red icon"></i> <div class="content"><?php esc_html_e( 'Access to your Database', 'mainwp' ); ?></div>
2766 + </div>
2767 + <div class="item" style="padding:0.21428571em 0;">
2768 + <i class="times red icon"></i> <div class="content"><?php esc_html_e( 'Access to your Screen', 'mainwp' ); ?></div>
2769 + </div>
2770 + <div class="item" style="padding:0 0 0 0.21428571em;">
2771 + <i class="check green icon"></i> <div class="content"><?php esc_html_e( 'Processes only information you submit', 'mainwp' ); ?></div>
2772 + </div>
2773 + </div>
2774 + </div>
2775 + <div class="left aligned extra content">
2776 + <div class="ui toggle checkbox" id="mainwp-guided-tours-check" data-tooltip="<?php esc_attr_e( 'Changes apply after page reload', 'mainwp' ); ?>" data-position="top left" data-inverted="">
2777 + <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"' : ''; ?> />
2778 + <label><?php esc_html_e( 'Turn On / Turn Off', 'mainwp' ); ?></label>
2779 + </div>
2780 + </div>
2781 + </div>
2782 +
2783 + <div class="ui card">
2784 + <div class="content">
2785 + <a id="mainwp-start-video-card" class="<?php echo $enable_guided_video ? '' : 'mainwp-disabled-link'; ?>" <?php echo '' !== $video_id ? '' : 'style="display:none"'; ?> onclick="jQuery('#mainwp-update-permissions-button').fadeOut(200);jQuery('#mainwp-help-back-button').fadeIn(200);mainwp_help_modal_start_content_onclick( false, '<?php echo esc_js( $video_id ); ?>', false );return false;" >
2786 + <div class="header"><?php esc_html_e( 'MainWP 101 Video Tour', 'mainwp' ); ?></div>
2787 + <div class="ui hidden divider"></div>
2788 + <i class="youtube big grey icon" style="opacity:0.5"></i>
2789 + <div class="ui fitted hidden divider"></div><br/>
2790 + <span class="ui grey small text"><?php esc_html_e( 'Discover the essential features of this page in our quick, step-by-step video guide.', 'mainwp' ); ?></span>
2791 + </a>
2792 + </div>
2793 + <div class="content">
2794 + <div class="ui tiny left aligned list">
2795 + <div class="item" style="padding:0 0 0.21428571em 0;">
2796 + <i class="times red icon"></i> <div class="content"><?php esc_html_e( 'Access to your Database', 'mainwp' ); ?></div>
2797 + </div>
2798 + <div class="item" style="padding:0.21428571em 0;">
2799 + <i class="times red icon"></i> <div class="content"><?php esc_html_e( 'Access to your Screen', 'mainwp' ); ?></div>
2800 + </div>
2801 + <div class="item" style="padding:0 0 0 0.21428571em;">
2802 + <i class="check green icon"></i> <div class="content"><?php esc_html_e( 'Plays only when you activate it', 'mainwp' ); ?></div>
2803 + </div>
2804 + </div>
2805 + </div>
2806 + <div class="left aligned extra content">
2807 + <div class="ui toggle checkbox" id="mainwp-guided-video-check">
2808 + <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"' : ''; ?> />
2809 + <label><?php esc_html_e( 'Turn On / Turn Off', 'mainwp' ); ?></label>
2810 + </div>
2811 + </div>
2812 + </div>
2813 +
2814 + <div class="ui card">
2815 + <div class="content">
2816 + <a id="mainwp-ticket-form-card" target="_blank" href="https://community.mainwp.com/">
2817 + <div class="header"><?php esc_html_e( 'Contact MainWP Support', 'mainwp' ); ?></div>
2818 + <div class="ui hidden divider"></div>
2819 + <i class="ticket big grey icon" style="opacity:0.5"></i>
2820 + <div class="ui fitted hidden divider"></div><br/>
2821 + <span class="ui grey small text"><?php esc_html_e( 'Get in touch with our team for any inquiries or support ? we\'re here to help you.', 'mainwp' ); ?></span>
2822 +
2823 + </a>
2824 + </div>
2825 + <div class="content">
2826 + <div class="ui tiny left aligned list">
2827 + <div class="item" style="padding:0 0 0.21428571em 0;">
2828 + <i class="times red icon"></i> <div class="content"><?php esc_html_e( 'Access to your Database', 'mainwp' ); ?></div>
2829 + </div>
2830 + <div class="item" style="padding:0.21428571em 0;">
2831 + <i class="times red icon"></i> <div class="content"><?php esc_html_e( 'Access to your Screen', 'mainwp' ); ?></div>
2832 + </div>
2833 + <div class="item" style="padding:0 0 0 0.21428571em;">
2834 + <i class="check green icon"></i> <div class="content"><?php esc_html_e( 'Access to community knowledge', 'mainwp' ); ?></div>
2835 + </div>
2836 + </div>
2837 + </div>
2838 + <div class="left aligned extra content">
2839 + <div class="ui toggle disabled checked checkbox on-stop-propagation">
2840 + <input type="checkbox" class="" name="" id="" checked="true" />
2841 + <label><?php esc_html_e( 'Always On', 'mainwp' ); ?></label>
2842 + </div>
2843 + </div>
2844 + </div>
2845 +
2846 + </div>
2847 + <div style="display:none" id="mainwp-chatbase-chat-screen">
2848 + <iframe src="" width="100%" style="height: 100%; min-height: 600px;border: none;" title="MainWP Support Assistant"></iframe>
2849 + </div>
2850 + <div style="display:none;position:relative;padding-bottom:56.25%;height:0;" id="mainwp-chatbase-video-screen">
2851 + <iframe width="420" height="315" src="" style="position:absolute;top:0;left:0;width:100%;height:100%;border:none;" title="MainWP Video Tutorials"></iframe>
2852 + </div>
2853 + </div>
2854 + <div class="actions">
2855 + <div class="ui grid">
2856 + <div class="eight wide left aligned middle aligned column">
2857 + <a href="#" style="display:none" id="mainwp-help-back-button" class="ui mini basic button" onclick="jQuery('#mainwp-help-modal-options').fadeIn(200);jQuery('#mainwp-chatbase-video-screen').fadeOut(200);jQuery('#mainwp-chatbase-chat-screen').fadeOut(200);jQuery('#mainwp-help-back-button').fadeOut(200);jQuery('#mainwp-update-permissions-button').fadeIn(200);return false;"><i class="angle left icon"></i> <?php esc_html_e( 'Back to Support Options', 'mainwp' ); ?></a>
2858 + </div>
2859 + <div class="eight wide right aligned middle aligned column">
2860 + <a class="ui mini basic button" id="mainwp-update-permissions-button" onclick="mainwp_help_modal_content_onclick();return false;"><?php esc_html_e( 'Update Permissions', 'mainwp' ); ?></a>
2861 + </div>
2862 + </div>
2863 + </div>
2864 +
2865 + </div>
2866 + <script type="text/javascript">
2867 + // to fix not keyboard accessible issue.
2868 + document.querySelector('.ui.toggle.on-stop-propagation')
2869 + .addEventListener('keydown', function (event) {
2870 + if (event.key === 'Enter' || event.key === ' ') {
2871 + event.preventDefault();
2872 + event.stopPropagation();
2873 + }
2874 + });
2875 + </script>
2876 + <?php
2877 + }
2878 +
2879 + /**
2880 + * Method render_loader_element()
2881 + *
2882 + * Renders navigation loading dimmer element with click handlers.
2883 + *
2884 + * Displays a page dimmer with loading text that shows when users click
2885 + * on left menu items (level 0 and level 2). The dimmer provides visual
2886 + * feedback during page navigation transitions.
2887 + *
2888 + * @return void Outputs HTML dimmer element and JavaScript event handlers.
2889 + */
2890 + public static function render_loader_element() {
2891 + ?>
2892 + <div id="mainwp-nav-dimmer" class="ui page dimmer">
2893 + <div class="ui double text loader"><?php esc_html_e( 'Loading...', 'mainwp' ); ?></div>
2894 + </div>
2895 + <script>
2896 + jQuery( document ).ready( function () {
2897 + jQuery('#mainwp-first-level-navigation-menu .left-menu-item-level-0, #mainwp-second-level-navigation .left-menu-item-level-2:not(.extension-inactive)').on('click', function () {
2898 + jQuery('#mainwp-nav-dimmer').dimmer({
2899 + duration: 25,
2900 + opacity: 1,
2901 + }).dimmer('show');
2902 + });
2903 + } );
2904 + </script>
2905 + <?php
2906 + }
2907 +
2908 + /**
1988 2909 * Method render_screen_options()
1989 2910 *
1990 2911 * Render modal window for Page Settings.
1991 2912 *
1992 - * @param bool $setting_page Default: True. Widgets that you want to hide in the MainWP Overview page.
2913 + * @param bool $setting_page Default: True. Widgets that you want to hide in the MainWP Operations page.
1993 2914 *
1994 2915 * @return void Render modal window for Page Settings html.
1995 2916 */
1996 2917 public static function render_screen_options( $setting_page = true ) { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
@@ -1995,29 +2916,36 @@
1995 2916 */
1996 2917 public static function render_screen_options( $setting_page = true ) { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
1997 2918
1998 2919 $default_widgets = array(
1999 - 'overview' => esc_html__( 'Updates Overview', 'mainwp' ),
2000 - 'recent_posts' => esc_html__( 'Recent Posts', 'mainwp' ),
2001 - 'recent_pages' => esc_html__( 'Recent Pages', 'mainwp' ),
2002 - 'plugins' => esc_html__( 'Plugins (Individual Site Overview page)', 'mainwp' ),
2003 - 'themes' => esc_html__( 'Themes (Individual Site Overview page)', 'mainwp' ),
2004 - 'connection_status' => esc_html__( 'Connection Status', 'mainwp' ),
2005 - 'security_issues' => esc_html__( 'Security Issues', 'mainwp' ),
2006 - 'notes' => esc_html__( 'Notes (Individual Site Overview page)', 'mainwp' ),
2007 - 'clients' => esc_html__( 'Clients', 'mainwp' ),
2008 - 'child_site_info' => esc_html__( 'Child site info (Individual Site Overview page)', 'mainwp' ),
2009 - 'client_info' => esc_html__( 'Client info (Individual Site Overview page)', 'mainwp' ),
2010 - 'non_mainwp_changes' => esc_html__( 'Non-MainWP Changes', 'mainwp' ),
2011 - 'get-started' => esc_html__( 'Get Started with MainWP', 'mainwp' ),
2920 + 'overview' => esc_html__( 'Updates Overview', 'mainwp' ),
2921 + 'recent_posts' => esc_html__( 'Recent Posts', 'mainwp' ),
2922 + 'recent_pages' => esc_html__( 'Recent Pages', 'mainwp' ),
2923 + 'plugins' => esc_html__( 'Plugins (Individual Site Operations page)', 'mainwp' ),
2924 + 'themes' => esc_html__( 'Themes (Individual Site Operations page)', 'mainwp' ),
2925 + 'connection_status' => esc_html__( 'Connection Status', 'mainwp' ),
2926 + 'security_issues' => esc_html__( 'Site Hardening', 'mainwp' ),
2927 + 'notes' => esc_html__( 'Notes (Individual Site Operations page)', 'mainwp' ),
2928 + 'clients' => esc_html__( 'Clients', 'mainwp' ),
2929 + 'child_site_info' => esc_html__( 'Child site info (Individual Site Operations page)', 'mainwp' ),
2930 + 'client_info' => esc_html__( 'Client info (Individual Site Operations page)', 'mainwp' ),
2931 + 'non_mainwp_changes' => esc_html__( 'Network Activity', 'mainwp' ),
2932 + 'get-started' => esc_html__( 'Get Started with MainWP', 'mainwp' ),
2933 + 'uptime_monitoring_status' => esc_html__( 'Uptime Monitoring', 'mainwp' ),
2934 + 'uptime_monitoring_response_time' => esc_html__( 'Uptime Monitoring (Individual Site Operations page)', 'mainwp' ),
2012 2935 );
2013 2936
2937 + if ( ! MainWP_Uptime_Monitoring_Edit::is_enable_global_monitoring() ) {
2938 + unset( $default_widgets['uptime_monitoring_status'] );
2939 + unset( $default_widgets['uptime_monitoring_response_time'] );
2940 + }
2941 +
2014 2942 $custom_opts = apply_filters_deprecated( 'mainwp-widgets-screen-options', array( array() ), '4.0.7.2', 'mainwp_widgets_screen_options' ); // @deprecated Use 'mainwp_widgets_screen_options' instead. NOSONAR - not IP.
2015 2943
2016 2944 /**
2017 2945 * Filter: mainwp_widgets_screen_options
2018 2946 *
2019 - * Filters available widgets on the Overview page allowing users to unsent unwanted widgets.
2947 + * Filters available widgets on the Operations page allowing users to unset unwanted widgets.
2020 2948 *
2021 2949 * @since 4.0
2022 2950 */
2023 2951 $custom_opts = apply_filters( 'mainwp_widgets_screen_options', $custom_opts );
@@ -2099,9 +3027,9 @@
2099 3027 }
2100 3028 esc_html_e( 'Show widgets', 'mainwp' );
2101 3029 ?>
2102 3030 </label>
2103 - <div class="ten wide column" <?php echo $setting_page ? 'data-tooltip="' . esc_attr__( 'Select widgets that you want to hide in the MainWP Overview page.', 'mainwp' ) . '"' : ''; ?> data-inverted="" data-position="top left">
3031 + <div class="ten wide column" <?php echo $setting_page ? 'data-tooltip="' . esc_attr__( 'Select widgets that you want to hide in the MainWP Operations page.', 'mainwp' ) . '"' : ''; ?> data-inverted="" data-position="top left">
2104 3032 <ul class="mainwp_hide_wpmenu_checkboxes">
2105 3033 <?php
2106 3034 foreach ( $default_widgets as $name => $title ) {
2107 3035 $_selected = '';
@@ -2123,8 +3051,9 @@
2123 3051 </div>
2124 3052 </div>
2125 3053 <?php
2126 3054 endif;
3055 + // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized.Recommended
2127 3056 ?>
2128 3057 <input type="hidden" name="reset_overview_which_settings" value="<?php echo esc_html( $which_settings ); ?>" />
2129 3058 <?php
2130 3059 /**
@@ -2150,12 +3079,12 @@
2150 3079 <i class="close icon"></i>
2151 3080 <div class="header"><?php esc_html_e( 'Select MainWP Theme', 'mainwp' ); ?></div>
2152 3081 <div class="content ui form">
2153 3082 <div class="ui blue message">
2154 - <div class=""><?php printf( esc_html__( 'Did you know you can create your custom theme? %1$sSee here how to do it%2$s!', '' ), '<a href="https://kb.mainwp.com/docs/how-to-change-the-theme-for-mainwp/" target="_blank">', '</a>' ); // NOSONAR - noopener - open safe. ?></div>
3083 + <div class=""><?php /* translators: 1: Opening anchor tag for documentation link, 2: Closing anchor tag. */ printf( esc_html__( 'Did you know you can create your custom theme? %1$sSee here how to do it%2$s!', 'mainwp' ), '<a href="https://docs.mainwp.com/sites/management/mainwp-dashboard-settings#select-mainwp-theme" target="_blank">', '</a>' ); // NOSONAR - noopener - open safe. ?></div>
2155 3084 </div>
2156 3085 <form method="POST" action="" name="mainwp_select_mainwp_themes_form" id="mainwp_select_mainwp_themes_form">
2157 - <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
3086 + <?php self::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
2158 3087 <input type="hidden" name="wp_scr_options_nonce" value="<?php echo esc_attr( wp_create_nonce( 'MainWPSelectThemes' ) ); ?>" />
2159 3088 <?php
2160 3089 /**
2161 3090 * Action: mainwp_select_themes_modal_top
@@ -2200,15 +3129,15 @@
2200 3129 $mainwp_api_key = MainWP_Api_Manager_Key::instance()->get_decrypt_master_api_key();
2201 3130 ?>
2202 3131 <div class="ui small modal" id="mainwp-install-extensions-promo-modal">
2203 3132 <i class="close icon"></i>
2204 - <?php if ( empty( $mainwp_api_key ) ) : ?>
3133 + <?php if ( empty( $mainwp_api_key ) ) : ?>
2205 3134 <div class="header"><?php esc_html_e( 'Get MainWP Pro', 'mainwp' ); ?></div>
2206 3135 <div class="content">
2207 3136 <div class="ui header"><?php esc_html_e( 'With your MainWP Pro subscription, you get access to:', 'mainwp' ); ?></div>
2208 3137 <div class="ui bulleted list">
2209 - <div class="item"><?php esc_html_e( 'All 30+ Existing Premium Extensions', 'mainwp' ); ?></div>
2210 - <div class="item"><?php esc_html_e( 'All Future Extensions', 'mainwp' ); ?></div>
3138 + <div class="item"><?php esc_html_e( 'All 30+ Existing Premium Add-ons', 'mainwp' ); ?></div>
3139 + <div class="item"><?php esc_html_e( 'All Future Add-ons', 'mainwp' ); ?></div>
2211 3140 <div class="item"><?php esc_html_e( 'Critical Security & Performance Updates', 'mainwp' ); ?></div>
2212 3141 <div class="item"><?php esc_html_e( 'Priority Support with Subscription', 'mainwp' ); ?></div>
2213 3142 <div class="item"><?php esc_html_e( 'Manage Unlimited Websites', 'mainwp' ); ?></div>
2214 3143 </div>
@@ -2214,49 +3143,100 @@
2214 3143 </div>
2215 3144 <a href="https://mainwp.com/signup/?utm_campaign=Dashboard%20-%20Upgrade%20to%20Pro&utm_source=Dashboard&utm_medium=grey%20link%20modal&utm_term=get%20mainwp%20pro" class="ui big green button" target="_blank">Get MainWP Pro</a> <?php // NOSONAR - noopener - open safe. ?>
2216 3145 </div>
2217 3146 <?php else : ?>
2218 - <div class="header"><?php esc_html_e( 'Install Extensions', 'mainwp' ); ?></div>
3147 + <div class="header"><?php esc_html_e( 'Install Add-ons', 'mainwp' ); ?></div>
2219 3148 <div class="content">
2220 - <div class="ui header"><?php esc_html_e( 'Extension not activated', 'mainwp' ); ?></div>
2221 - <div><?php esc_html_e( 'Go to the ', 'mainwp' ); ?><a href="admin.php?page=Extensions">MainWP > Extensions</a><?php esc_html_e( ' page to install and activate extensions', 'mainwp' ); ?></div>
3149 + <div class="ui header"><?php esc_html_e( 'Add-on not activated', 'mainwp' ); ?></div>
3150 + <div><?php esc_html_e( 'Go to the ', 'mainwp' ); ?><a href="admin.php?page=Extensions">MainWP > Add-ons</a><?php esc_html_e( ' page to install and activate add-ons.', 'mainwp' ); ?></div>
2222 3151 </div>
2223 3152 <?php endif; ?>
2224 3153 </div>
2225 - <?php
3154 + <?php
2226 3155 }
2227 3156
2228 - /**
2229 - * Method render_empty_element_placeholder()
2230 - *
2231 - * Renders the content for empty elements.
2232 - *
2233 - * @param string $placeholder Placelolder text.
2234 - */
2235 - public static function render_empty_element_placeholder( $placeholder = '' ) {
3157 + /**
3158 + * Method render_empty_element_placeholder()
3159 + *
3160 + * Renders the content for empty elements.
3161 + *
3162 + * @param string $title Title text.
3163 + * @param string $message Message text.
3164 + * @param string $icon Icon HTML markup.
3165 + */
3166 + public static function render_empty_element_placeholder( $title = '', $message = '', $icon = '' ) {
2236 3167 ?>
2237 - <div class="ui one column grid">
2238 - <div class="middle aligned center aligned column">
2239 - <img alt="<?php esc_attr_e( 'Nothing to show here, check back later!', 'mainwp' ); ?>" src="<?php echo esc_url( MAINWP_PLUGIN_URL ); ?>assets/images/mainwp-widget-placeholder.png" style="max-width:200px" class="mainwp-no-results-placeholder ui middle aligned image"/>
2240 - <?php if ( '' !== $placeholder ) : ?>
2241 - <p><?php echo $placeholder; //phpcs:ignore -- requires escaped. ?></p>
3168 + <div class="mainwp-empty-widget-placeholder">
3169 + <h3 class="ui big icon header">
3170 + <?php if ( '' !== $icon ) : ?>
3171 + <?php echo $icon; //phpcs:ignore -- requires escaped. ?>
2242 3172 <?php else : ?>
2243 - <p><?php echo esc_html__( 'Nothing to show here, check back later!', 'mainwp' ); ?></p>
3173 + <i class="search icon"></i>
2244 3174 <?php endif; ?>
2245 - </div>
3175 + <div class="content">
3176 + <?php if ( '' !== $title ) : ?>
3177 + <?php echo $title; //phpcs:ignore -- requires escaped. ?>
3178 + <?php else : ?>
3179 + <?php echo esc_html__( 'Nothing to show right now.', 'mainwp' ); ?>
3180 + <?php endif; ?>
3181 + <?php if ( '' !== $message ) : ?>
3182 + <div class="sub header">
3183 + <?php echo $message; //phpcs:ignore -- requires escaped. ?>
3184 + </div>
3185 + <?php endif; ?>
3186 + </div>
3187 + </h3>
2246 3188 </div>
2247 - <?php
3189 + <?php
2248 3190 }
2249 3191
2250 - /**
2251 - * Method render_modal_save_segment()
2252 - *
2253 - * Render modal window.
2254 - *
2255 - * @return void
2256 - */
2257 - public static function render_modal_save_segment() {
3192 + /**
3193 + * Method render_empty_page_placeholder()
3194 + *
3195 + * Renders the content for empty pages.
3196 + *
3197 + * @param string $title Title text.
3198 + * @param string $message Message text.
3199 + * @param string $icon Icon HTML markup.
3200 + */
3201 + public static function render_empty_page_placeholder( $title = '', $message = '', $icon = '' ) {
2258 3202 ?>
3203 + <div class="mainwp-empty-page-placeholder ui center aligned middle aligned very padded segment">
3204 + <div class="ui hidden divider"></div>
3205 + <h2 class="ui icon header">
3206 + <?php if ( '' !== $icon ) : ?>
3207 + <?php echo $icon; //phpcs:ignore -- requires escaped. ?>
3208 + <?php else : ?>
3209 + <i class="massive green check tada transition icon"></i>
3210 + <?php endif; ?>
3211 + <div class="content">
3212 + <?php if ( '' !== $title ) : ?>
3213 + <?php echo $title; //phpcs:ignore -- requires escaped. ?>
3214 + <?php else : ?>
3215 + <?php echo esc_html__( 'Nothing to show here!', 'mainwp' ); ?>
3216 + <?php endif; ?>
3217 + <?php if ( '' !== $message ) : ?>
3218 + <div class="sub header"><?php echo $message; //phpcs:ignore -- requires escaped. ?></div>
3219 + <?php else : ?>
3220 + <div class="sub header"><?php echo esc_html__( 'Check back later.', 'mainwp' ); ?></div>
3221 + <?php endif; ?>
3222 + </div>
3223 + </h2>
3224 + </div>
3225 + <?php
3226 + }
3227 +
3228 + /**
3229 + * Method render_modal_save_segment()
3230 + *
3231 + * Render modal window.
3232 + *
3233 + * @param string $name Model segment name.
3234 + *
3235 + * @return void
3236 + */
3237 + public static function render_modal_save_segment( $name = '' ) {
3238 + ?>
2259 3239 <div id="mainwp-common-filter-segment-modal" class="ui tiny modal">
2260 3240 <i class="close icon" id="mainwp-common-filter-segment-cancel"></i>
2261 3241 <div class="header"><?php esc_html_e( 'Save Segment', 'mainwp' ); ?></div>
2262 3242 <div class="content" id="mainwp-common-filter-segment-content">
@@ -2289,13 +3269,81 @@
2289 3269
2290 3270 </div>
2291 3271 </div>
2292 3272 </div>
3273 + <input type="hidden" id="mainwp-common-filter-segments-model-name" value="<?php echo esc_attr( $name ); ?>" />
2293 3274 </div>
3275 + <?php
3276 + }
2294 3277
2295 - <?php
3278 +
3279 + /**
3280 + * Method generate_wp_nonce()
3281 + *
3282 + * @param mixed $act Action.
3283 + * @param mixed $name Input name.
3284 + * @param mixed $id Input id.
3285 + * @param mixed $echo_out Echo or not.
3286 + * @return mixed Output.
3287 + */
3288 + public static function generate_wp_nonce( $act, $name = '_wpnonce', $id = '__auto__', $echo_out = true ) {
3289 +
3290 + if ( '__auto__' === $id ) {
3291 + $id = wp_generate_password( 12, false );
3292 + }
3293 +
3294 + $nonce = wp_create_nonce( $act );
3295 + $out = '<input type="hidden" name="' . esc_attr( $name ) . '" id="' . esc_attr( $id ) . '" value="' . esc_attr( $nonce ) . '" />';
3296 +
3297 + if ( $echo_out ) {
3298 + echo $out; //phpcs:ignore --ok.
3299 + return '';
3300 + }
3301 + return $out;
2296 3302 }
2297 3303
3304 + /**
3305 + * Method render_modal_reconnect()
3306 + *
3307 + * Render modal window.
3308 + *
3309 + * @return void
3310 + */
3311 + public static function render_modal_reconnect() {
3312 + ?>
3313 + <div class="ui modal" id="mainwp-reconnect-site-with-user-passwd-modal">
3314 + <i class="close icon"></i>
3315 + <div class="header"><?php esc_html_e( 'Reconnect Site', 'mainwp' ); ?></div>
3316 + <div class="content">
3317 + <div class="ui message" id="mainwp-message-zone-reconnect" style="display:none;"></div>
3318 + <div class="ui grid field" >
3319 + <label class="six wide column middle aligned"><?php esc_html_e( 'Administrator username', 'mainwp' ); ?></label>
3320 + <div class="ui ten wide fluid column" data-tooltip="<?php esc_attr_e( 'Enter the website Administrator username.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
3321 + <div class="ui left fluid labeled input" tabindex="0">
3322 + <input type="text" id="mainwp_managesites_add_wpadmin" name="mainwp_managesites_add_wpadmin" value="" />
3323 + </div>
3324 + </div>
3325 + </div>
3326 + <div id="mainwp-administrator-password-field">
3327 + <input type="password" id="fake-disable-autofill" style="display:none;" name="fake-disable-autofill" />
3328 + <div class="ui grid field">
3329 + <label class="six wide column top aligned"><?php esc_html_e( 'Administrator password', 'mainwp' ); ?></label>
3330 + <div class="ui ten wide column" data-tooltip="<?php esc_attr_e( 'Enter the website Administrator password.', 'mainwp' ); ?>" data-inverted="" data-position="top left">
3331 + <div class="ui left fluid labeled input">
3332 + <input type="password" id="mainwp_managesites_add_admin_pwd" name="mainwp_managesites_add_admin_pwd" autocomplete="one-time-code" autocorrect="off" autocapitalize="none" spellcheck="false" value="" />
3333 + </div>
3334 + <div class="ui hidden fitted divider"></div>
3335 + <span class="ui small text"><?php esc_html_e( 'Your password is never stored by your Dashboard and never sent to MainWP.com. Once this initial connection is complete, your MainWP Dashboard generates a secure Public and Private key pair (2048 bits) using OpenSSL, allowing future connections without needing your password again. For added security, you can even change this admin password once connected, just be sure not to delete the admin account, as this would disrupt the connection.', 'mainwp' ); ?></span>
3336 + </div>
3337 + </div>
3338 + </div>
3339 + </div>
3340 + <div class="actions">
3341 + <input type="button" autofocus name="mainwp-popup-reconnect-site-btn" id="mainwp-popup-reconnect-site-btn" class="ui button green big focus" value="<?php esc_attr_e( 'Reconnect', 'mainwp' ); ?>" />
3342 + </div>
3343 + </div>
3344 + <?php
3345 + }
2298 3346
2299 3347 /**
2300 3348 * Method get_default_icons().
2301 3349 *